Merge branch 'development' into prerelease-14.6.0

This commit is contained in:
Theo Arends 2025-04-14 14:06:59 +02:00
commit 16e4211c4d
179 changed files with 22233 additions and 10725 deletions

View File

@ -32,7 +32,7 @@ _Make sure your have performed every step and checked the applicable boxes befor
- [ ] Searched the problem in [discussions](https://github.com/arendst/Tasmota/discussions) - [ ] Searched the problem in [discussions](https://github.com/arendst/Tasmota/discussions)
- [ ] Searched the problem in the [docs](https://tasmota.github.io/docs/FAQ) - [ ] Searched the problem in the [docs](https://tasmota.github.io/docs/FAQ)
- [ ] Searched the problem in the [chat](https://discord.gg/Ks2Kzd4) - [ ] Searched the problem in the [chat](https://discord.gg/Ks2Kzd4)
- [ ] Problem is not scripter related, in this case open a discussion and tag @gemu2015 - [ ] Problem is not scripter related, in this case open a discussion and tag gemu2015
- [ ] Device used (e.g., Sonoff Basic): _____ - [ ] Device used (e.g., Sonoff Basic): _____
- [ ] Tasmota binary firmware version number used: _____ - [ ] Tasmota binary firmware version number used: _____
- [ ] Pre-compiled - [ ] Pre-compiled

View File

@ -7,7 +7,7 @@
- [ ] Only relevant files were touched - [ ] Only relevant files were touched
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings - [ ] 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.8 - [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.8
- [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.1.250203 - [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.3.250411
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). - [ ] 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**_ _NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_

3
.gitignore vendored
View File

@ -49,6 +49,9 @@ lib/libesp32/berry/berry
*.bak *.bak
*.code-workspace *.code-workspace
## IntelliJ ######
.idea
## Python virtual environments for Platformio ## ## Python virtual environments for Platformio ##
venv venv
.venv .venv

View File

@ -14,10 +14,13 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
| USE_HOME_ASSISTANT | - | - / - | - | - | - | - | | USE_HOME_ASSISTANT | - | - / - | - | - | - | - |
| USE_TASMOTA_DISCOVERY | x | x / x | x | x | x | x | | USE_TASMOTA_DISCOVERY | x | x / x | x | x | x | x |
| USE_MQTT_TLS\* | - | - / x | - | - | - | - | | USE_MQTT_TLS\* | - | - / x | - | - | - | - |
| USE_MQTT_CLIENT_CERT | - | - / - | - | - | - | - |
| USE_MQTT_AWS_IOT | - | - / - | - | - | - | - | | USE_MQTT_AWS_IOT | - | - / - | - | - | - | - |
| USE_4K_RSA | - | - / - | - | - | - | - | | USE_4K_RSA | - | - / - | - | - | - | - |
| USE_TELEGRAM | - | - / - | - | - | - | - | | USE_TELEGRAM | - | - / - | - | - | - | - |
| USE_KNX | - | - / x | x | - | - | - | | USE_KNX | - | - / x | x | - | - | - |
| USE_TELNET | - | - / - | - | - | - | - |
| USE_XYZMODEM | - | - / - | - | - | - | - |
| USE_WEBSERVER | x | x / x | x | x | x | x | | USE_WEBSERVER | x | x / x | x | x | x | x |
| USE_WEBSEND_RESPONSE | - | - / - | - | - | - | - | | USE_WEBSEND_RESPONSE | - | - / - | - | - | - | - |
| USE_EMULATION_HUE | x | x / x | - | x | - | - | | USE_EMULATION_HUE | x | x / x | - | x | - | - |
@ -228,7 +231,9 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
| USE_MIEL_HVAC | - | - / - | - | - | - | - | | USE_MIEL_HVAC | - | - / - | - | - | - | - |
| USE_PROJECTOR_CTRL | - | - / - | - | - | - | - | | USE_PROJECTOR_CTRL | - | - / - | - | - | - | - |
| USE_AS608 | - | - / - | - | - | - | - | | USE_AS608 | - | - / - | - | - | - | - |
| USE_LD2402 | - | - / - | - | - | - | - |
| USE_LD2410 | - | - / - | - | - | - | - | | USE_LD2410 | - | - / - | - | - | - | - |
| USE_LD2410S | - | - / - | - | - | - | - |
| USE_GM861 | - | - / - | - | - | - | - | | USE_GM861 | - | - / - | - | - | - | - |
| USE_TCP_BRIDGE | - | - / - | - | - | - | - | zbbridge / zbbrdgpro | | USE_TCP_BRIDGE | - | - / - | - | - | - | - | zbbridge / zbbrdgpro |
| USE_HC8 | - | - / - | - | - | - | - | | USE_HC8 | - | - / - | - | - | - | - |

View File

@ -3,6 +3,77 @@ All notable changes to this project will be documented in this file.
## [Released] ## [Released]
## [14.6.0] 20250416
- Release Ryan
## [14.5.0.3]
### Added
- Extend command `GPIO` with different display options and allowing updating of module GPIO's in one go
- Berry `bytes.add()` now accepts 3-bytes values (#23200)
- Berry expose `esp_http_server` for websockets (#23206)
- AlpineJS 2.8.2 - optional for now (#23259)
- Support for XMODEM over serial and telnet if enabled with `#define USE_XYZMODEM`
### Breaking Changed
- HASPmota added `y2_min` and `y2_max` to control the second series of `chart` (#23287)
- HASPmota default theme is now Tasmota-style (#23288)
### Changed
- Output of commands `GPIO` and `GPIOs` swapped
- Smoothen light gamma curve when using `Fade` (#23230)
- ESP32 Platform from 2025.03.30 to 2025.04.30, Framework (Arduino Core) from v3.1.3.250302 to v3.1.3.250411 and IDF from v5.3.2.250228 to 5.3.2.250403 (#23280)
- HLK-LD2402 updates for firmware 3.3.5+ (#23281)
### Fixed
- INA226 driver fixes (#23197)
- TLS increase timeout and fix crash (#23249)
- Berry `readline` when a line is exactly 98 characters (#23276)
## [14.5.0.2] 20250325
### Added
- Berry load `.tapp` files in `/.extensions/` then in `/` (#23113)
- Support Vango Technologies V924x ultralow power, single-phase, power measurement (#23127)
- Support for HLK-LD2402 24GHz smart wave motion sensor (#23133)
- Matter prepare for ICD cluster (#23158)
- Berry `re.dump()` (#23162)
- Support for Telnet server using command `Telnet <0|1|port>[,<IP filter>]` if enabled with `#define USE_TELNET`
- HASPmota autostart when `pages.jsonl` exists (#23181)
### Breaking Changed
- Berry remove `Leds.create_matrix` from the standard library waiting for reimplementation (#23114)
### Changed
- ESP32 Platform from 2025.02.30 to 2025.03.30, Framework (Arduino Core) from v3.1.1.250203 to v3.1.3.250302 and IDF from v5.3.2.250120 to 5.3.2.250228 (#23088)
- ESP32 enable webcam version 2 (#18732)
- ESP8266 enable FTP for >= 4MB variants (#23120)
- Berry update flasher for Sonoff ZBBridge Pro (#23136)
- Berry `re` now accepts `bytes()` as precompiled patterns, added `re.compilebytes()` (#23149)
- RCSwitch `RCSWITCH_SEPARATION_LIMIT` from 4100 to 3600
### Fixed
- Berry prevent `import` from hiding a solidified class (#23112)
- ESP32-C3 WiFi sleep (#23096)
- ESP32 intermittent exception on WiFi AP cannot be reached (#23115)
- ESP32 receive incomplete serial data over 128 bytes (#23156)
## [14.5.0.1] 20250302
### Added
- Berry experimental driver for AXP2101 for M5Core2v1.1 (#23039)
- LVGL experimental mirroring of display on Web UI (#23041)
- Allow acl in mqtt when client certificate is in use with `#define USE_MQTT_CLIENT_CERT` (#22998)
- Berry `tasmota.when_network_up()` and simplified Matter using it (#23057)
- Berry `introspect.solidified()` to know if a Berry object is solidified or in RAM (#23063)
- Berry `global.undef()` to undefine a global variable (#23073)
### Changed
- LVGL, prepare for HASPmota theme, change: no-grow when clicked, DPI set to 160 (#23040)
- LVGL Mirroring add checkbox to enable/disable the feature (in the iterim for a better solution) (#23047)
- Leds Panel add checkbox to enable/disable the feature (in the iterim for a better solution) (#23048)
- GPIOViewer from v1.6.1 to v1.6.2 (No functional change)
### Fixed
- Too many zeros in RCSwitch received data regression from v14.4.1.4 (#23050)
## [14.5.0] 20250219 ## [14.5.0] 20250219
- Release Ruth - Release Ruth

View File

@ -89,8 +89,9 @@ In addition to @arendst the following code is mainly owned by:
| xdrv_75_dali | @eeak, @arendst | xdrv_75_dali | @eeak, @arendst
| xdrv_76_serial_i2c | @s-hadinger | xdrv_76_serial_i2c | @s-hadinger
| xdrv_77_wizmote | @arendst | xdrv_77_wizmote | @arendst
| xdrv_78 | | xdrv_78_telnet | @arendst
| xdrv_79_esp32_ble | @staars, @btsimonh | xdrv_79_esp32_ble | @staars, @btsimonh
| xdrv_80 |
| xdrv_81_esp32_webcam | @gemu, @philrich | xdrv_81_esp32_webcam | @gemu, @philrich
| xdrv_82_esp32_ethernet | @arendst | xdrv_82_esp32_ethernet | @arendst
| xdrv_83_esp32_watch | @gemu | xdrv_83_esp32_watch | @gemu
@ -105,6 +106,7 @@ In addition to @arendst the following code is mainly owned by:
| xdrv_93_ | | xdrv_93_ |
| xdrv_94_ | | xdrv_94_ |
| | | |
| xdrv_120_xyzmodem | @arendst
| xdrv_121_gpioviewer | @arendst | xdrv_121_gpioviewer | @arendst
| xdrv_122_file_settings_demo | @arendst | xdrv_122_file_settings_demo | @arendst
| xdrv_122_file_json_settings_demo | @arendst | xdrv_122_file_json_settings_demo | @arendst

View File

@ -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.8** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. This release will be supported from ESP8266/Arduino library Core version **2.7.8** 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 **v3.1.1.250203**. This release will be supported from ESP32/Arduino library Core version **v3.1.3.250411**.
Support of ESP8266 Core versions before 2.7.8 and ESP32 Core versions before v3.1.1.250203 have been removed. Support of ESP8266 Core versions before 2.7.8 and ESP32 Core versions before v3.1.3.250411 have been removed.
## Support of TLS ## Support of TLS
@ -75,12 +75,12 @@ Latest released binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release - http://ota.tasmota.com/tasmota/release
Historical binaries can be downloaded from Historical binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release-14.5.0 - http://ota.tasmota.com/tasmota/release-14.6.0
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
### ESP32, ESP32-C2, ESP32-C3, ESP32-C6, ESP32-S2 and ESP32-S3 based ### ESP32, ESP32-C2, ESP32-C3, ESP32-C6, ESP32-S2 and ESP32-S3 based
The following binary downloads have been compiled with ESP32/Arduino library core version **v3.1.1.250203**. The following binary downloads have been compiled with ESP32/Arduino library core version **v3.1.3.250411**.
- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY** - **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY**
- **tasmota32solo1.bin** = The Tasmota version with most drivers including additional sensors and KNX for single core ESP32 and 4M+ flash. - **tasmota32solo1.bin** = The Tasmota version with most drivers including additional sensors and KNX for single core ESP32 and 4M+ flash.
@ -88,7 +88,7 @@ The following binary downloads have been compiled with ESP32/Arduino library cor
- **tasmota32s2cdc.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S2 with serial over embedded USB CDC only and 4M+ flash. - **tasmota32s2cdc.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S2 with serial over embedded USB CDC only and 4M+ flash.
- **tasmota32s3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S3 with USB HWCDC and fallback to serial and 4M+ flash. - **tasmota32s3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S3 with USB HWCDC and fallback to serial and 4M+ flash.
- **tasmota32c2.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C2 with serial and 4M+ flash. - **tasmota32c2.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C2 with serial and 4M+ flash.
- **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C2 with USB HWCDC and fallback to serial and 4M+ flash. - **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3 with USB HWCDC and fallback to serial and 4M+ flash.
- **tasmota32c6.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C6 with USB HWCDC and fallback to serial and 4M+ flash. - **tasmota32c6.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C6 with USB HWCDC and fallback to serial and 4M+ flash.
- **tasmota32-AD.bin** to **tasmota32-VN.bin** = The Tasmota version in different languages for 4M+ flash. - **tasmota32-AD.bin** to **tasmota32-VN.bin** = The Tasmota version in different languages for 4M+ flash.
- **tasmota32-bluetooth.bin** = The Bluetooth version adds BLE support for 4M+ flash. - **tasmota32-bluetooth.bin** = The Bluetooth version adds BLE support for 4M+ flash.
@ -104,7 +104,7 @@ Latest released binaries can be downloaded from
- https://ota.tasmota.com/tasmota32/release - https://ota.tasmota.com/tasmota32/release
Historical binaries can be downloaded from Historical binaries can be downloaded from
- https://ota.tasmota.com/tasmota32/release-14.5.0 - https://ota.tasmota.com/tasmota32/release-14.6.0
The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin`` The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin``
@ -114,76 +114,55 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
[Complete list](BUILDS.md) of available feature and sensors. [Complete list](BUILDS.md) of available feature and sensors.
## Changelog v14.5.0 Ruth ## Changelog v14.6.0 Ryan
### Added ### Added
- Command `SetOption163 1` to disable display of Device name in GUI header - Extend command `GPIO` with different display options and allowing updating of module GPIO's in one go
- Command `FileLog 0..4` to enable logging to filesystem using up to 16 rotating log files of 100kB (`#define FILE_LOG_SIZE 100`) - Support Vango Technologies V924x ultralow power, single-phase, power measurement [#23127](https://github.com/arendst/Tasmota/issues/23127)
- Command `FileLog 10..14` to enable logging to filesystem using up to 16 log files of 100kB (`#define FILE_LOG_SIZE 100`) - Support for HLK-LD2402 24GHz smart wave motion sensor [#23133](https://github.com/arendst/Tasmota/issues/23133)
- Command I2sLoop [#22807](https://github.com/arendst/Tasmota/issues/22807) - Support for Telnet server using command `Telnet <0|1|port>[,<IP filter>]` if enabled with `#define USE_TELNET`
- Support for Lithuanian language translations by zzdovydas [#22971](https://github.com/arendst/Tasmota/issues/22971) - Support for XMODEM over serial and telnet if enabled with `#define USE_XYZMODEM`
- Support for PCF85063 RTC [#22727](https://github.com/arendst/Tasmota/issues/22727) - Allow acl in mqtt when client certificate is in use with `#define USE_MQTT_CLIENT_CERT` [#22998](https://github.com/arendst/Tasmota/issues/22998)
- Support for Senseair S88 CO2 sensor [#22733](https://github.com/arendst/Tasmota/issues/22733) - AlpineJS 2.8.2 - optional for now [#23259](https://github.com/arendst/Tasmota/issues/23259)
- Support for C8-CO2-5K CO2 sensor [#22905](https://github.com/arendst/Tasmota/issues/22905) - Berry experimental driver for AXP2101 for M5Core2v1.1 [#23039](https://github.com/arendst/Tasmota/issues/23039)
- Support for ESP32 Two-Wire Automotive Interface (TWAI) or Controller Area Network (CAN) busses - Berry `tasmota.when_network_up()` and simplified Matter using it [#23057](https://github.com/arendst/Tasmota/issues/23057)
- `#define FIX_JSON_HEXADECIMAL` to change JSON hexadecimal value "FF5F78" into "0xFF5F78" [#22919](https://github.com/arendst/Tasmota/issues/22919) - Berry `introspect.solidified()` to know if a Berry object is solidified or in RAM [#23063](https://github.com/arendst/Tasmota/issues/23063)
- Support for RC-switch decoding of 64-bit received data - Berry `global.undef()` to undefine a global variable [#23073](https://github.com/arendst/Tasmota/issues/23073)
- Support for WiZ Smart Remote using `#define USE_WIZMOTE` and command `SetOption164 1` - Berry load `.tapp` files in `/.extensions/` then in `/` [#23113](https://github.com/arendst/Tasmota/issues/23113)
- `MqttTLS` field in `Status 6` to indicate if the MQTT connection is encrypted [#22995](https://github.com/arendst/Tasmota/issues/22995) - Berry `re.dump()` [#23162](https://github.com/arendst/Tasmota/issues/23162)
- Formatter `%_U` for `ext_snprintf_P()` to print uint64_t variable as decimal equivalent to `%llu` - Berry `bytes.add()` now accepts 3-bytes values [#23200](https://github.com/arendst/Tasmota/issues/23200)
- GPS driver select baudrate using GPIO GPS_RX1 (9600bps), GPS_RX2 (19200bps) or GPS_RX3 (38400bps) [#22869](https://github.com/arendst/Tasmota/issues/22869) - Berry expose `esp_http_server` for websockets [#23206](https://github.com/arendst/Tasmota/issues/23206)
- I2S AAC support for web radio [#22787](https://github.com/arendst/Tasmota/issues/22787) - Matter prepare for ICD cluster [#23158](https://github.com/arendst/Tasmota/issues/23158)
- I2S Opus stream and file support for opus/aac [#22795](https://github.com/arendst/Tasmota/issues/22795) - LVGL experimental mirroring of display on Web UI [#23041](https://github.com/arendst/Tasmota/issues/23041)
- ESP32 command `PixelType` to change the WS2812 color order and channel number [#22876](https://github.com/arendst/Tasmota/issues/22876) - HASPmota autostart when `pages.jsonl` exists [#23181](https://github.com/arendst/Tasmota/issues/23181)
- ESP32 TasmotaLED change dynamically the number of pixels [#22754](https://github.com/arendst/Tasmota/issues/22754)
- ESP32 expand `Pixels` with reverse, height and alternate [#22755](https://github.com/arendst/Tasmota/issues/22755) ### Breaking Changed
- Display template for Waveshare ESP32-C6 LCD 1.47 [#22863](https://github.com/arendst/Tasmota/issues/22863) - Berry remove `Leds.create_matrix` from the standard library waiting for reimplementation [#23114](https://github.com/arendst/Tasmota/issues/23114)
- Berry `animate.crenel` primitive [#22673](https://github.com/arendst/Tasmota/issues/22673) - HASPmota added `y2_min` and `y2_max` to control the second series of `chart` [#23287](https://github.com/arendst/Tasmota/issues/23287)
- Berry `tasmota.int(v, min, max)` function [#22723](https://github.com/arendst/Tasmota/issues/22723) - HASPmota default theme is now Tasmota-style [#23288](https://github.com/arendst/Tasmota/issues/23288)
- Berry `bytes().appendhex()` [#22767](https://github.com/arendst/Tasmota/issues/22767)
- Berry `serial.read()` read only `n` bytes [#22835](https://github.com/arendst/Tasmota/issues/22835)
- Berry `tasmota.global.tele_period` and `tasmota.settings.tele_period` [#22865](https://github.com/arendst/Tasmota/issues/22865)
- Berry `tasmota.settings` entries for PixelType [#22912](https://github.com/arendst/Tasmota/issues/22912)
- Berry `tasmota.add_rule_once` and auto-remove rules with same pattern and id [#22900](https://github.com/arendst/Tasmota/issues/22900)
- Berry driver for M5Stack 8encoder [#22724](https://github.com/arendst/Tasmota/issues/22724)
- Berry driver for AXP2102 and M5CoreS3 [#22878](https://github.com/arendst/Tasmota/issues/22878)
- Berry driver for PN532 NFC/Mifare reader [#22899](https://github.com/arendst/Tasmota/issues/22899)
- Berry example for HeatFan WiFi Controller
- Berry WS2812 real-time Leds panel as app [#22788](https://github.com/arendst/Tasmota/issues/22788)
- Berry scroll to Leds_matrix [#22693](https://github.com/arendst/Tasmota/issues/22693)
- Berry unicode encoding to string parsing [#22713](https://github.com/arendst/Tasmota/issues/22713)
- Berry light_pixels values to `tasmota.settings` [#22762](https://github.com/arendst/Tasmota/issues/22762)
- Berry `tasmota.defer()` [#22976](https://github.com/arendst/Tasmota/issues/22976)
- Berry `bytes().appendb64()` [#22767](https://github.com/arendst/Tasmota/issues/22767)
- LVLG/HASPmota add color names from OpenHASP [#22879](https://github.com/arendst/Tasmota/issues/22879)
- LVGL `lv.set_paint_cb()` to register a callback when screen is refreshed [#22909](https://github.com/arendst/Tasmota/issues/22909)
- HASPmota support for `buttonmatrix` events [#22898](https://github.com/arendst/Tasmota/issues/22898)
### Changed ### Changed
- ESP32 Platform from 2024.12.30 to 2025.02.30, Framework (Arduino Core) from v3.1.0.241206 to v3.1.1.250203 and IDF to 5.3.2 [#22943](https://github.com/arendst/Tasmota/issues/22943) - ESP32 Platform from 2025.02.30 to 2025.04.30, Framework (Arduino Core) from v3.1.1.250203 to v3.1.3.250411 and IDF from v5.3.2.250120 to 5.3.2.250403 [#23280](https://github.com/arendst/Tasmota/issues/23280)
- GPIOViewer from v1.5.6 to v1.6.1 (No functional change) - Output of commands `GPIO` and `GPIOs` swapped
- Postpone save_data during light animation when fade is Off - Smoothen light gamma curve when using `Fade` [#23230](https://github.com/arendst/Tasmota/issues/23230)
- Allow negative values for AdcParam/AdcGpio INPUT, TEMP and RANGE parameters [#22809](https://github.com/arendst/Tasmota/issues/22809) - RCSwitch `RCSWITCH_SEPARATION_LIMIT` from 4100 to 3600
- Command `Pixels` has backwards compatible arguments fixing #22755 [#22791](https://github.com/arendst/Tasmota/issues/22791) - GPIOViewer from v1.6.1 to v1.6.2 (No functional change)
- ESP32 disable PSRAM check (and on restart some relay toggles) with `#define DISABLE_PSRAMCHECK true` [#21266](https://github.com/arendst/Tasmota/issues/21266) - HLK-LD2402 updates for firmware 3.3.5+ [#23281](https://github.com/arendst/Tasmota/issues/23281)
- ESP32 Webcam resolution changes since v14.4.0 [#22901](https://github.com/arendst/Tasmota/issues/22901) - ESP8266 enable FTP for >= 4MB variants [#23120](https://github.com/arendst/Tasmota/issues/23120)
- Berry `gpio.pin_mode` frees PWM on pin - ESP32 enable webcam version 2 [#18732](https://github.com/arendst/Tasmota/issues/18732)
- Berry bit-shift operators to `int64` [#22709](https://github.com/arendst/Tasmota/issues/22709) - Berry update flasher for Sonoff ZBBridge Pro [#23136](https://github.com/arendst/Tasmota/issues/23136)
- Berry callback now passes 5 arguments instead of 4 (in line with documentation) [#22908](https://github.com/arendst/Tasmota/issues/22908) - Berry `re` now accepts `bytes()` as precompiled patterns, added `re.compilebytes()` [#23149](https://github.com/arendst/Tasmota/issues/23149)
- HASPmota use 'roboto.ttf' for automatic sizing of default font [#22697](https://github.com/arendst/Tasmota/issues/22697) - LVGL, prepare for HASPmota theme, change: no-grow when clicked, DPI set to 160 [#23040](https://github.com/arendst/Tasmota/issues/23040)
- HASPmota add 'tag' attribute for free-form JSON [#22698](https://github.com/arendst/Tasmota/issues/22698) - LVGL Mirroring add checkbox to enable/disable the feature (in the iterim for a better solution) [#23047](https://github.com/arendst/Tasmota/issues/23047)
- HASPmota support for `tabview` [#22707](https://github.com/arendst/Tasmota/issues/22707) - Leds Panel add checkbox to enable/disable the feature (in the iterim for a better solution) [#23048](https://github.com/arendst/Tasmota/issues/23048)
### Fixed ### Fixed
- Shutter discovery message regression from v14.4.1 [#22730](https://github.com/arendst/Tasmota/issues/22730) - Too many zeros in RCSwitch received data regression from v14.4.1.4 [#23050](https://github.com/arendst/Tasmota/issues/23050)
- LoraWan decoding of Dragino LDS02 and MerryIoT DW10 [#22880](https://github.com/arendst/Tasmota/issues/22880) - INA226 driver fixes [#23197](https://github.com/arendst/Tasmota/issues/23197)
- ESP32 TasMesh broker MAC address all zeros [#23005](https://github.com/arendst/Tasmota/issues/23005) - TLS increase timeout and fix crash [#23249](https://github.com/arendst/Tasmota/issues/23249)
- ESP32-Cx compilation fails on Windows [#22832](https://github.com/arendst/Tasmota/issues/22832) - ESP32 receive incomplete serial data over 128 bytes [#23156](https://github.com/arendst/Tasmota/issues/23156)
- Wrong RMT channels for ESP32S3, now depends on `soc_caps.h` [#23021](https://github.com/arendst/Tasmota/issues/23021) - ESP32 intermittent exception on WiFi AP cannot be reached [#23115](https://github.com/arendst/Tasmota/issues/23115)
- Sonoff SPM `PowerOnState` overrules `SSPMPowerOnState` in mixed 4Relay setup with 4Relay version 1.0.0 - ESP32-C3 WiFi sleep [#23096](https://github.com/arendst/Tasmota/issues/23096)
- Webcam compilation with `define USE_WEBCAM` but without `define ENABLE_RTSPSERVER` [#22686](https://github.com/arendst/Tasmota/issues/22686) - Berry prevent `import` from hiding a solidified class [#23112](https://github.com/arendst/Tasmota/issues/23112)
- Berry Zigbee fix wrong attributes [#22684](https://github.com/arendst/Tasmota/issues/22684) - Berry `readline` when a line is exactly 98 characters [#23276](https://github.com/arendst/Tasmota/issues/23276)
- Berry walrus operator [#22685](https://github.com/arendst/Tasmota/issues/22685)
- Berry parser error in rare case [#22997](https://github.com/arendst/Tasmota/issues/22997) ### Removed
- LVGL updated `Antiburn.tapp` [#22699](https://github.com/arendst/Tasmota/issues/22699)
- HASPmota exception when clicking on a checkbox [#23022](https://github.com/arendst/Tasmota/issues/23022)
- Matter Air Quality sensor [#22708](https://github.com/arendst/Tasmota/issues/22708)

View File

@ -168,6 +168,12 @@ void TasmotaSerial::Esp32Begin(void) {
if (m_speed <= 9600) { if (m_speed <= 9600) {
// At 9600, 10 chars are ~10ms // At 9600, 10 chars are ~10ms
uart_set_rx_full_threshold(m_uart, 10); uart_set_rx_full_threshold(m_uart, 10);
} else {
// At 19200, 120 chars are ~60ms
// At 76800, 120 chars are ~15ms
uart_set_rx_full_threshold(m_uart, 120);
}
/*
} else if (m_speed < 115200) { } else if (m_speed < 115200) {
// At 19200, 120 chars are ~60ms // At 19200, 120 chars are ~60ms
// At 76800, 120 chars are ~15ms // At 76800, 120 chars are ~15ms
@ -180,6 +186,7 @@ void TasmotaSerial::Esp32Begin(void) {
// At even higher speeds set 75% of the buffer // At even higher speeds set 75% of the buffer
uart_set_rx_full_threshold(m_uart, serial_buffer_size * 3 / 4); uart_set_rx_full_threshold(m_uart, serial_buffer_size * 3 / 4);
} }
*/
// For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10 // For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
if (m_speed < 115200) { if (m_speed < 115200) {
// At 76800 the timeout is ~1ms // At 76800 the timeout is ~1ms

View File

@ -9,11 +9,7 @@
}, },
"version": "2.6.7", "version": "2.6.7",
"frameworks": "arduino", "frameworks": "arduino",
"platforms": "*", "libCompatMode": "strict",
"dependencies": [ "platforms": ["espressif8266"]
{
"name": "SPI"
}
]
} }

View File

@ -11,6 +11,7 @@
"url": "https://github.com/arendst/Tasmota/lib/lib_basic/TasmotaLED" "url": "https://github.com/arendst/Tasmota/lib/lib_basic/TasmotaLED"
}, },
"frameworks": "arduino", "frameworks": "arduino",
"libCompatMode": "strict",
"platforms": [ "platforms": [
"espressif32" "espressif32"
] ]

View File

@ -97,7 +97,7 @@ enum uColorType { uCOLOR_BW, uCOLOR_COLOR };
#define UDISP_WHITE 0xFFFF /* 255, 255, 255 */ #define UDISP_WHITE 0xFFFF /* 255, 255, 255 */
#define UDISP_ORANGE 0xFD20 /* 255, 165, 0 */ #define UDISP_ORANGE 0xFD20 /* 255, 165, 0 */
#define UDISP_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ #define UDISP_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
#define UDISP_PINK 0xF81F #define UDISP_PINK 0xFc18 /* 255, 128, 192 */
#ifdef ESP8266 #ifdef ESP8266
#define PIN_OUT_SET 0x60000304 #define PIN_OUT_SET 0x60000304

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Frank
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.

View File

@ -0,0 +1,56 @@
FastCRC
=======
Fast CRC Arduino library
Up to 30 times faster than crc16.h (_avr_libc)
- uses the on-chip hardware for Teensy 3.0 / 3.1 / 3.2 / 3.5 / 3.6
- uses fast table-algorithms for other chips
List of supported CRC calculations:
-
7 BIT:
CRC7
(poly=0x09 init=0x00 refin=false refout=false xorout=0x00 check=0x75)
MultiMediaCard interface
8 BIT:
SMBUS
(poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4)
MAXIM
(poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1)
16 BIT:
KERMIT (Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT)
(poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189
Attention: sometimes you'll find byteswapped presentation of result in other implementations)
CCITT-FALSE
(poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1)
MCRF4XX
(poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91)
MODBUS
(poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37)
XMODEM (Alias ZMODEM, CRC-16/ACORN)
(poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3)
X25 (Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B)
(poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff check=0x906e)
32 BIT:
CRC32, CRC-32/ADCCP, PKZIP, ETHERNET, 802.3
(poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926)
CKSUM, CRC-32/POSIX
(poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680)

View File

@ -0,0 +1,59 @@
#######################################
# Syntax Coloring Map For FastCRC
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
FastCRC7 KEYWORD1
FastCRC8 KEYWORD1
FastCRC14 KEYWORD1
FastCRC16 KEYWORD1
FastCRC32 KEYWORD1
CRC7 KEYWORD1
CRC8 KEYWORD1
CRC14 KEYWORD1
CRC16 KEYWORD1
CRC32 KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
crc7 KEYWORD2
crc7_upd KEYWORD2
ccitt KEYWORD2
ccitt_upd KEYWORD2
kermit KEYWORD2
kermit_upd KEYWORD2
mcrf4xx KEYWORD2
mcrf4xx_upd KEYWORD2
modbus KEYWORD2
modbus_upd KEYWORD2
xmodem KEYWORD2
xmodem_upd KEYWORD2
x25 KEYWORD2
x25_upd KEYWORD2
update KEYWORD2
update_upd KEYWORD2
generic KEYWORD2
crc32 KEYWORD2
crc32_upd KEYWORD2
cksum KEYWORD2
cksum_upd KEYWORD2
darc KEYWORD2
darc_upd KEYWORD2
gsm KEYWORD2
gsm_upd KEYWORD2
eloran KEYWORD2
eloran_upd KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
CRC_FLAG_NOREFLECT LITERAL1
CRC_FLAG_REFLECT LITERAL1
CRC_FLAG_XOR LITERAL1
CRC_FLAG_NOREFLECT_8 LITERAL1
CRC_FLAG_REFLECT_SWAP LITERAL1

View File

@ -0,0 +1,26 @@
{
"name": "FastCRC",
"keywords": "CRC7, CRC8, CRC16, CRC32",
"description": "Fast CRC routines for Arduino and PC (Teensy 3.x: CRC in hardware)",
"exclude": [
"examples",
"examples_PC"
],
"repository":
{
"type": "git",
"url": "https://github.com/FrankBoesing/FastCRC"
},
"authors":
[
{
"name": "Frank Bösing",
"email": "f.boesing@gmx.de",
"url": "https://github.com/FrankBoesing/FastCRC",
"maintainer": true
}
],
"version": "1.44",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -0,0 +1,10 @@
name=FastCRC
version=1.44
author=Frank Bösing
maintainer=Frank Boesing<f.boesing@gmx.de>
sentence=Fast CRC routines
paragraph=
category=Data Processing
url=https://github.com/FrankBoesing/FastCRC
architectures=*
#dot_a_linkage=true

View File

@ -0,0 +1,189 @@
/* FastCRC library code is placed under the MIT license
* Copyright (c) 2014 - 2021 Frank Bösing
*
* 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.
*/
// Teensy 3.0, Teensy 3.1:
// See K20P64M72SF1RM.pdf (Kinetis), Pages 638 - 641 for documentation of CRC Device
// See KINETIS_4N30D.pdf for Errata (Errata ID 2776)
//
// So, ALL HW-calculations are done as 32 bit.
//
//
//
// Thanks to:
// - Catalogue of parametrised CRC algorithms, CRC RevEng
// http://reveng.sourceforge.net/crc-catalogue/
//
// - Danjel McGougan (CRC-Table-Generator)
//
// Set this to 0 for smaller 32BIT-CRC-Tables:
#if !defined(CRC_BIGTABLES)
#define CRC_BIGTABLES 1
#endif
#if !defined(FastCRC_h)
#define FastCRC_h
#if defined(ARDUINO)
#include <Arduino.h>
#endif
#include <inttypes.h>
// ================= DEFINES ===================
#if defined(KINETISK)
#define CRC_SW 0
#define CRC_FLAG_NOREFLECT (((1<<31) | (1<<30)) | ((0<<29) | (0<<28))) //refin=false refout=false
#define CRC_FLAG_REFLECT (((1<<31) | (0<<30)) | ((1<<29) | (0<<28))) //Reflect in- and outgoing bytes (refin=true refout=true)
#define CRC_FLAG_XOR (1<<26) //Perform XOR on result
#define CRC_FLAG_NOREFLECT_8 (0) //For 8-Bit CRC
#define CRC_FLAG_REFLECT_SWAP (((1<<31) | (0<<30)) | ((0<<29) | (1<<28))) //For 16-Bit CRC (byteswap)
#else
#define CRC_SW 1
#endif
// ================= 7-BIT CRC ===================
class FastCRC7
{
public:
FastCRC7();
uint8_t crc7(const uint8_t *data, const size_t datalen); // (MultiMediaCard interface)
uint8_t crc7_upd(const uint8_t *data, const size_t datalen); // Call for subsequent calculations with previous seed.
#if !CRC_SW
uint8_t generic(const uint8_t polyom, const uint8_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen); //Not available in non-hw-variant (not T3.x)
#endif
private:
#if CRC_SW
uint8_t seed;
#else
uint8_t update(const uint8_t *data, const size_t datalen);
#endif
};
// ================= 8-BIT CRC ===================
class FastCRC8
{
public:
FastCRC8();
uint8_t smbus(const uint8_t *data, const size_t datalen); // Alias CRC-8
uint8_t maxim(const uint8_t *data, const size_t datalen); // Equivalent to _crc_ibutton_update() in crc16.h from avr_libc
uint8_t smbus_upd(const uint8_t *data, size_t datalen); // Call for subsequent calculations with previous seed.
uint8_t maxim_upd(const uint8_t *data, size_t datalen); // Call for subsequent calculations with previous seed.
#if !CRC_SW
uint8_t generic(const uint8_t polyom, const uint8_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen); //Not available in non-hw-variant (not T3.x)
#endif
private:
#if CRC_SW
uint8_t seed;
#else
uint8_t update(const uint8_t *data, const size_t datalen);
#endif
};
// ================= 14-BIT CRC ===================
class FastCRC14
{
public:
#if !CRC_SW //NO Software-implemenation so far
FastCRC14();
uint16_t darc(const uint8_t *data, const size_t datalen);
uint16_t gsm(const uint8_t *data, const size_t datalen);
uint16_t eloran(const uint8_t *data, const size_t datalen);
uint16_t ft4(const uint8_t *data, const size_t datalen);
uint16_t darc_upd(const uint8_t *data, size_t len);
uint16_t gsm_upd(const uint8_t *data, size_t len);
uint16_t eloran_upd(const uint8_t *data, size_t len);
uint16_t ft4_upd(const uint8_t *data, size_t len);
#endif
#if !CRC_SW
uint16_t generic(const uint16_t polyom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen); //Not available in non-hw-variant (not T3.x)
#endif
private:
#if CRC_SW
uint16_t seed;
#else
uint16_t update(const uint8_t *data, const size_t datalen);
#endif
};
// ================= 16-BIT CRC ===================
class FastCRC16
{
public:
FastCRC16();
uint16_t ccitt(const uint8_t *data, const size_t datalen); // Alias "false CCITT"
uint16_t mcrf4xx(const uint8_t *data,const size_t datalen); // Equivalent to _crc_ccitt_update() in crc16.h from avr_libc
uint16_t kermit(const uint8_t *data, const size_t datalen); // Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
uint16_t modbus(const uint8_t *data, const size_t datalen); // Equivalent to _crc_16_update() in crc16.h from avr_libc
uint16_t xmodem(const uint8_t *data, const size_t datalen); // Alias ZMODEM, CRC-16/ACORN
uint16_t x25(const uint8_t *data, const size_t datalen); // Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B
uint16_t ccitt_upd(const uint8_t *data, size_t len); // Call for subsequent calculations with previous seed
uint16_t mcrf4xx_upd(const uint8_t *data, size_t len); // Call for subsequent calculations with previous seed
uint16_t kermit_upd(const uint8_t *data, size_t len); // Call for subsequent calculations with previous seed
uint16_t modbus_upd(const uint8_t *data, size_t len); // Call for subsequent calculations with previous seed
uint16_t xmodem_upd(const uint8_t *data, size_t len); // Call for subsequent calculations with previous seed
uint16_t x25_upd(const uint8_t *data, size_t len); // Call for subsequent calculations with previous seed
#if !CRC_SW
uint16_t generic(const uint16_t polyom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen); //Not available in non-hw-variant (not T3.x)
#endif
private:
#if CRC_SW
uint16_t seed;
#else
uint16_t update(const uint8_t *data, const size_t datalen);
#endif
};
// ================= 32-BIT CRC ===================
class FastCRC32
{
public:
FastCRC32();
uint32_t crc32(const uint8_t *data, const size_t datalen); // Alias CRC-32/ADCCP, PKZIP, Ethernet, 802.3
uint32_t cksum(const uint8_t *data, const size_t datalen); // Alias CRC-32/POSIX
uint32_t crc32_upd(const uint8_t *data, size_t len); // Call for subsequent calculations with previous seed
uint32_t cksum_upd(const uint8_t *data, size_t len); // Call for subsequent calculations with previous seed
#if !CRC_SW
uint32_t generic(const uint32_t polyom, const uint32_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen); //Not available in non-hw-variant (not T3.x)
#endif
private:
#if CRC_SW
uint32_t seed;
#else
uint32_t update(const uint8_t *data, const size_t datalen);
#endif
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,567 @@
/* FastCRC library code is placed under the MIT license
* Copyright (c) 2014 - 2021 Frank Bösing
*
* 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.
*/
//
// HW-calculations are 32BIT
//
// Thanks to:
// - Catalogue of parametrised CRC algorithms, CRC RevEng
// http://reveng.sourceforge.net/crc-catalogue/
//
// - Danjel McGougan (CRC-Table-Generator)
//
#if defined(ARDUINO)
#include <Arduino.h>
#endif
#if defined(KINETISK)
#include "mk20dx128.h"
#include "FastCRC.h"
// ===============================================
typedef struct {
union {
uint32_t CRC; //CRC Data register
struct {
uint16_t CRC16;
uint16_t CRC16_1;
};
struct {
uint8_t CRC8;
uint8_t CRC8_1;
uint8_t CRC8_2;
uint8_t CRC8_3;
};
};
uint32_t GPOLY; //CRC Polynomial register
uint32_t CTRL; //CRC Control register
} CRC_T;
static volatile CRC_T * const rCRC = (CRC_T *)0x40032000;
#define CRC_CTRL_WAS 25 // Write CRC Data Register As Seed(1) / Data(0)
#define CRC_CTRL_TCRC 24 // Width of CRC protocol (0=16 BIT, 1=32 BIT)
#define CRC_CTRL_TOTR1 29 // TOTR[1]
// ================= 7-BIT CRC ===================
/** Constructor
* Enables CRC-clock
*/
FastCRC7::FastCRC7(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
/** CRC 7
* MultiMediaCard interface
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC7::crc7(const uint8_t *data, const size_t datalen)
{
// poly=0x09 init=0x00 refin=false refout=false xorout=0x00 check=0x75
return (generic(0x09, 0, CRC_FLAG_NOREFLECT, data, datalen));
}
/** Update
* Call for subsequent calculations with previous seed
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC7::update(const uint8_t *data, const size_t datalen)
{
const uint8_t *src = data;
const uint8_t *target = src + datalen;
while (((uintptr_t)src & 0x03) != 0 && (src < target)) {
rCRC->CRC8_3 = *src++; //Write 8 BIT
}
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; //Write 8 Bit
}
//TODO: Check handling of CRC_CTRL_TOTR1 for other CRC7s
/*
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
return rCRC->CRC8 >> 1;
else
*/
return rCRC->CRC8_3 >> 1;
}
/** generic function for all 7-Bit CRCs
* @param polynom Polynom
* @param seed Seed
* @param flags Flags
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC7::generic(const uint8_t polynom, const uint8_t seed, const uint32_t flags, const uint8_t *data,const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); // 32Bit Mode, Prepare to write seed(25)
rCRC->GPOLY = ((uint32_t)polynom)<<(24 + 1); // Set polynom
rCRC->CRC = ((uint32_t)seed<<(24 + 1)); // Write seed
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
return update(data, datalen);
}
uint8_t FastCRC7::crc7_upd(const uint8_t *data, size_t datalen){return update(data, datalen);}
// ================= 8-BIT CRC ===================
/** Constructor
* Enables CRC-clock
*/
FastCRC8::FastCRC8(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
/** SMBUS CRC
* aka CRC-8
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC8::smbus(const uint8_t *data, const size_t datalen)
{
// poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4
return generic(0x07, 0, CRC_FLAG_NOREFLECT, data, datalen);
}
/** MAXIM 8-Bit CRC
* equivalent to _crc_ibutton_update() in crc16.h from avr_libc
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC8::maxim(const uint8_t *data, const size_t datalen)
{
// poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1
return generic(0x31, 0, CRC_FLAG_REFLECT, data, datalen);
}
/** Update
* Call for subsequent calculations with previous seed
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC8::update(const uint8_t *data, const size_t datalen)
{
const uint8_t *src = data;
const uint8_t *target = src + datalen;
while (((uintptr_t)src & 0x03) != 0 && (src < target)) {
rCRC->CRC8_3 = *src++; //Write 8 BIT
}
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; //Write 8 Bit
}
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
return rCRC->CRC8;
else
return rCRC->CRC8_3;
}
/** generic function for all 8-Bit CRCs
* @param polynom Polynom
* @param seed Seed
* @param flags Flags
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC8::generic(const uint8_t polynom, const uint8_t seed, const uint32_t flags, const uint8_t *data,const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); // 32Bit Mode, Prepare to write seed(25)
rCRC->GPOLY = ((uint32_t)polynom)<<24; // Set polynom
rCRC->CRC = ((uint32_t)seed<<24); // Write seed
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
return update(data, datalen);
}
uint8_t FastCRC8::smbus_upd(const uint8_t *data, size_t datalen){return update(data, datalen);}
uint8_t FastCRC8::maxim_upd(const uint8_t *data, size_t datalen){return update(data, datalen);}
// ================= 14-BIT CRC ===================
/** Constructor
* Enables CRC-clock
*/
FastCRC14::FastCRC14(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
/** CRC-14/DARC
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC14::darc(const uint8_t *data,const size_t datalen)
{
// poly=0x0805 init=0x0000 refin=true refout=true xorout=0x0000 check=0x082d residue=0x0000
return generic(0x0805, 0x0000, CRC_FLAG_REFLECT, data, datalen);
}
/** CRC-14/GSM
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC14::gsm(const uint8_t *data,const size_t datalen)
{
// poly=0x202d init=0x0000 refin=false refout=false xorout=0x3fff check=0x30ae residue=0x031e
return generic(0x202d, 0x0000, CRC_FLAG_NOREFLECT | CRC_FLAG_XOR, data, datalen);
}
/** CRC-14/ELORAN
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC14::eloran(const uint8_t *data,const size_t datalen)
{
// poly=0x60b1 init=0x0000 refin=false refout=false xorout=0x0000 check=0x38d1
return generic(0x60b1, 0x0, CRC_FLAG_NOREFLECT , data, datalen);
}
/** CRC-14/ft4 : TODO
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
/*
uint16_t FastCRC14::ft4(const uint8_t *data,const size_t datalen)
{
return generic(, , , data, datalen);
}
*/
/** Update
* Call for subsequent calculations with previous seed
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC14::update(const uint8_t *data, const size_t datalen)
{
const uint8_t *src = data;
const uint8_t *target = src + datalen;
while (((uintptr_t)src & 0x03) !=0 && (src < target)) {
rCRC->CRC8_3 = *src++; //Write 8 BIT
}
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; //Write 8 Bit
}
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
return rCRC->CRC16;
else
return rCRC->CRC >> (32 - 14);
}
/** generic function for all 14-Bit CRCs
* @param polynom Polynom
* @param seed Seed
* @param flags Flags
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC14::generic(const uint16_t polynom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS);// 32-Bit Mode, prepare to write seed(25)
rCRC->GPOLY = ((uint32_t)polynom) << (32 - 14); // set polynom
rCRC->CRC = ((uint32_t)seed << (32 - 14) ); // this is the seed
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
return update(data, datalen);
}
uint16_t FastCRC14::darc_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC14::gsm_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC14::eloran_upd(const uint8_t *data, size_t len) {return update(data, len);}
//uint16_t FastCRC14::ft4(const uint8_t *data, size_t len) {return update(data, len);}
// ================= 16-BIT CRC ===================
/** Constructor
* Enables CRC-clock
*/
FastCRC16::FastCRC16(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
/** CCITT
* Alias "false CCITT"
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::ccitt(const uint8_t *data,const size_t datalen)
{
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1
return generic(0x1021, 0XFFFF, CRC_FLAG_NOREFLECT, data, datalen);
}
/** MCRF4XX
* equivalent to _crc_ccitt_update() in crc16.h from avr_libc
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::mcrf4xx(const uint8_t *data,const size_t datalen)
{
// poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91
return generic(0x1021, 0XFFFF, CRC_FLAG_REFLECT , data, datalen);
}
/** MODBUS
* equivalent to _crc_16_update() in crc16.h from avr_libc
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::modbus(const uint8_t *data, const size_t datalen)
{
// poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37
return generic(0x8005, 0XFFFF, CRC_FLAG_REFLECT, data, datalen);
}
/** KERMIT
* Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::kermit(const uint8_t *data, const size_t datalen)
{
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189
// sometimes byteswapped presentation of result
return generic(0x1021, 0x00, CRC_FLAG_REFLECT, data, datalen);
}
/** XMODEM
* Alias ZMODEM, CRC-16/ACORN
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::xmodem(const uint8_t *data, const size_t datalen)
{
//width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3
return generic(0x1021, 0, CRC_FLAG_NOREFLECT, data, datalen);
}
/** X25
* Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::x25(const uint8_t *data, const size_t datalen)
{
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff check=0x906e
return generic(0x1021, 0XFFFF, CRC_FLAG_REFLECT | CRC_FLAG_XOR, data, datalen);
}
/** Update
* Call for subsequent calculations with previous seed
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::update(const uint8_t *data, const size_t datalen)
{
const uint8_t *src = data;
const uint8_t *target = src + datalen;
while (((uintptr_t)src & 0x03) !=0 && (src < target)) {
rCRC->CRC8_3 = *src++; //Write 8 BIT
}
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; //Write 8 Bit
}
if (rCRC->CTRL & (1<<CRC_CTRL_TOTR1))
return rCRC->CRC16;
else
return rCRC->CRC16_1;
}
/** generic function for all 16-Bit CRCs
* @param polynom Polynom
* @param seed Seed
* @param flags Flags
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::generic(const uint16_t polynom, const uint16_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS);// 32-Bit Mode, prepare to write seed(25)
rCRC->GPOLY = ((uint32_t)polynom)<<16; // set polynom
rCRC->CRC = ((uint32_t)seed<<16); // this is the seed
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
return update(data, datalen);
}
uint16_t FastCRC16::ccitt_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC16::mcrf4xx_upd(const uint8_t *data, size_t len){return update(data, len);}
uint16_t FastCRC16::kermit_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC16::modbus_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC16::xmodem_upd(const uint8_t *data, size_t len) {return update(data, len);}
uint16_t FastCRC16::x25_upd(const uint8_t *data, size_t len) {return update(data, len);}
// ================= 32-BIT CRC ===================
/** Constructor
* Enables CRC-clock
*/
FastCRC32::FastCRC32(){
SIM_SCGC6 |= SIM_SCGC6_CRC;
}
/** CRC32
* Alias CRC-32/ADCCP, PKZIP, Ethernet, 802.3
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint32_t FastCRC32::crc32(const uint8_t *data, const size_t datalen)
{
// poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926
return generic(0x04C11DB7L, 0XFFFFFFFFL, CRC_FLAG_REFLECT | CRC_FLAG_XOR, data, datalen);
}
/** CKSUM
* Alias CRC-32/POSIX
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint32_t FastCRC32::cksum(const uint8_t *data, const size_t datalen)
{
// width=32 poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680
return generic(0x04C11DB7L, 0, CRC_FLAG_NOREFLECT | CRC_FLAG_XOR, data, datalen);
}
/** Update
* Call for subsequent calculations with previous seed
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
//#pragma GCC diagnostic ignored "-Wpointer-arith"
uint32_t FastCRC32::update(const uint8_t *data, const size_t datalen)
{
const uint8_t *src = data;
const uint8_t *target = src + datalen;
while (((uintptr_t)src & 0x03) != 0 && (src < target)) {
rCRC->CRC8_3 = *src++; //Write 8 BIT
}
while (src <= target-4) {
rCRC->CRC = *( uint32_t *)src; //Write 32 BIT
src += 4;
}
while (src < target) {
rCRC->CRC8_3 = *src++; //Write 8 Bit
}
return rCRC->CRC;
}
/** generic function for all 32-Bit CRCs
* @param polynom Polynom
* @param seed Seed
* @param flags Flags
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint32_t FastCRC32::generic(const uint32_t polynom, const uint32_t seed, const uint32_t flags, const uint8_t *data, const size_t datalen)
{
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); // 32Bit Mode, prepare to write seed(25)
rCRC->GPOLY = polynom; // Set polynom
rCRC->CRC = seed; // This is the seed
rCRC->CTRL = flags | (1<<CRC_CTRL_TCRC); // Clear WAS Bit - prepare to write data
return update(data, datalen);
}
uint32_t FastCRC32::crc32_upd(const uint8_t *data, size_t len){return update(data, len);}
uint32_t FastCRC32::cksum_upd(const uint8_t *data, size_t len){return update(data, len);}
#endif // #if defined(KINETISK)

View File

@ -0,0 +1,541 @@
/* FastCRC library code is placed under the MIT license
* Copyright (c) 2014 - 2021 Frank Bösing
*
* 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.
*/
//
// Thanks to:
// - Catalogue of parametrised CRC algorithms, CRC RevEng
// http://reveng.sourceforge.net/crc-catalogue/
//
// - Danjel McGougan (CRC-Table-Generator)
//
#if defined(ARDUINO)
#include <Arduino.h>
#endif
#if !defined(KINETISK)
#if !defined(ARDUINO)
#define PROGMEM
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) ({ \
typeof(addr) _addr = (addr); \
*(const unsigned short *)(_addr); \
})
#define pgm_read_dword(addr) ({ \
typeof(addr) _addr = (addr); \
*(const unsigned long *)(_addr); \
})
#endif
#include "FastCRC.h"
#include "FastCRC_tables.h"
static inline
uint32_t REV16( uint32_t value)
{
return (value >> 8) | ((value & 0xff) << 8);
}
static inline
uint32_t REV32( uint32_t value)
{
value = (value >> 16) | ((value & 0xffff) << 16);
return ((value >> 8) & 0xff00ff) | ((value & 0xff00ff) << 8);
}
// ================= 7-BIT CRC ===================
/** Constructor
*/
FastCRC7::FastCRC7(){}
/** SMBUS CRC
* aka CRC-8
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC7::crc7_upd(const uint8_t *data, size_t datalen)
{
uint8_t crc = seed;
if (datalen) do {
crc = pgm_read_byte(&crc_table_crc7[crc ^ *data]);
data++;
} while (--datalen);
seed = crc;
return crc >> 1;
}
uint8_t FastCRC7::crc7(const uint8_t *data, const size_t datalen)
{
// poly=0x09 init=0x00 refin=false refout=false xorout=0x00 check=0x75
seed = 0x00;
return crc7_upd(data, datalen);
}
// ================= 8-BIT CRC ===================
/** Constructor
*/
FastCRC8::FastCRC8(){}
/** SMBUS CRC
* aka CRC-8
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC8::smbus_upd(const uint8_t *data, size_t datalen)
{
uint8_t crc = seed;
if (datalen) do {
crc = pgm_read_byte(&crc_table_smbus[crc ^ *data]);
data++;
} while (--datalen);
seed = crc;
return crc;
}
uint8_t FastCRC8::smbus(const uint8_t *data, const size_t datalen)
{
// poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4
seed = 0x00;
return smbus_upd(data, datalen);
}
/** MAXIM 8-Bit CRC
* equivalent to _crc_ibutton_update() in crc16.h from avr_libc
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint8_t FastCRC8::maxim_upd(const uint8_t *data, size_t datalen)
{
uint8_t crc = seed;
if (datalen) do {
crc = pgm_read_byte(&crc_table_maxim[crc ^ *data]);
data++;
} while (--datalen);
seed = crc;
return crc;
}
uint8_t FastCRC8::maxim(const uint8_t *data, const size_t datalen)
{
// poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1
seed = 0x00;
return maxim_upd(data, datalen);
}
// ================= 16-BIT CRC ===================
/** Constructor
*/
FastCRC16::FastCRC16(){}
#define crc_n4(crc, data, table) crc ^= data; \
crc = pgm_read_word(&table[(crc & 0xff) + 0x300]) ^ \
pgm_read_word(&table[((crc >> 8) & 0xff) + 0x200]) ^ \
pgm_read_word(&table[((data >> 16) & 0xff) + 0x100]) ^ \
pgm_read_word(&table[data >> 24]);
/** CCITT
* Alias "false CCITT"
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::ccitt_upd(const uint8_t *data, size_t len)
{
uint16_t crc = seed;
while (((uintptr_t)data & 3) && len) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_ccitt[(crc & 0xff) ^ *data++]);
len--;
}
while (len >= 16) {
len -= 16;
crc_n4(crc, ((uint32_t *)data)[0], crc_table_ccitt);
crc_n4(crc, ((uint32_t *)data)[1], crc_table_ccitt);
crc_n4(crc, ((uint32_t *)data)[2], crc_table_ccitt);
crc_n4(crc, ((uint32_t *)data)[3], crc_table_ccitt);
data += 16;
}
while (len--) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_ccitt[(crc & 0xff) ^ *data++]);
}
seed = crc;
crc = REV16(crc);
return crc;
}
uint16_t FastCRC16::ccitt(const uint8_t *data,const size_t datalen)
{
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1
seed = 0xffff;
return ccitt_upd(data, datalen);
}
/** MCRF4XX
* equivalent to _crc_ccitt_update() in crc16.h from avr_libc
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::mcrf4xx_upd(const uint8_t *data, size_t len)
{
uint16_t crc = seed;
while (((uintptr_t)data & 3) && len) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_mcrf4xx[(crc & 0xff) ^ *data++]);
len--;
}
while (len >= 16) {
len -= 16;
crc_n4(crc, ((uint32_t *)data)[0], crc_table_mcrf4xx);
crc_n4(crc, ((uint32_t *)data)[1], crc_table_mcrf4xx);
crc_n4(crc, ((uint32_t *)data)[2], crc_table_mcrf4xx);
crc_n4(crc, ((uint32_t *)data)[3], crc_table_mcrf4xx);
data += 16;
}
while (len--) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_mcrf4xx[(crc & 0xff) ^ *data++]);
}
seed = crc;
return crc;
}
uint16_t FastCRC16::mcrf4xx(const uint8_t *data,const size_t datalen)
{
// poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91
seed = 0xffff;
return mcrf4xx_upd(data, datalen);
}
/** MODBUS
* equivalent to _crc_16_update() in crc16.h from avr_libc
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::modbus_upd(const uint8_t *data, size_t len)
{
uint16_t crc = seed;
while (((uintptr_t)data & 3) && len) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_modbus[(crc & 0xff) ^ *data++]);
len--;
}
while (len >= 16) {
len -= 16;
crc_n4(crc, ((uint32_t *)data)[0], crc_table_modbus);
crc_n4(crc, ((uint32_t *)data)[1], crc_table_modbus);
crc_n4(crc, ((uint32_t *)data)[2], crc_table_modbus);
crc_n4(crc, ((uint32_t *)data)[3], crc_table_modbus);
data += 16;
}
while (len--) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_modbus[(crc & 0xff) ^ *data++]);
}
seed = crc;
return crc;
}
uint16_t FastCRC16::modbus(const uint8_t *data, const size_t datalen)
{
// poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37
seed = 0xffff;
return modbus_upd(data, datalen);
}
/** KERMIT
* Alias CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::kermit_upd(const uint8_t *data, size_t len)
{
uint16_t crc = seed;
while (((uintptr_t)data & 3) && len) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_kermit[(crc & 0xff) ^ *data++]);
len--;
}
while (len >= 16) {
len -= 16;
crc_n4(crc, ((uint32_t *)data)[0], crc_table_kermit);
crc_n4(crc, ((uint32_t *)data)[1], crc_table_kermit);
crc_n4(crc, ((uint32_t *)data)[2], crc_table_kermit);
crc_n4(crc, ((uint32_t *)data)[3], crc_table_kermit);
data += 16;
}
while (len--) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_kermit[(crc & 0xff) ^ *data++]);
}
seed = crc;
return crc;
}
uint16_t FastCRC16::kermit(const uint8_t *data, const size_t datalen)
{
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189
// sometimes byteswapped presentation of result
seed = 0x0000;
return kermit_upd(data, datalen);
}
/** XMODEM
* Alias ZMODEM, CRC-16/ACORN
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::xmodem_upd(const uint8_t *data, size_t len)
{
uint16_t crc = seed;
while (((uintptr_t)data & 3) && len) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_xmodem[(crc & 0xff) ^ *data++]);
len--;
}
while (len >= 16) {
len -= 16;
crc_n4(crc, ((uint32_t *)data)[0], crc_table_xmodem);
crc_n4(crc, ((uint32_t *)data)[1], crc_table_xmodem);
crc_n4(crc, ((uint32_t *)data)[2], crc_table_xmodem);
crc_n4(crc, ((uint32_t *)data)[3], crc_table_xmodem);
data += 16;
}
while (len--) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_xmodem[(crc & 0xff) ^ *data++]);
}
seed = crc;
crc = REV16(crc);
return crc;
}
uint16_t FastCRC16::xmodem(const uint8_t *data, const size_t datalen)
{
//width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3
seed = 0x0000;
return xmodem_upd(data, datalen);
}
/** X25
* Alias CRC-16/IBM-SDLC, CRC-16/ISO-HDLC, CRC-B
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
uint16_t FastCRC16::x25_upd(const uint8_t *data, size_t len)
{
uint16_t crc = seed;
while (((uintptr_t)data & 3) && len) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_x25[(crc & 0xff) ^ *data++]);
len--;
}
while (len >= 16) {
len -= 16;
crc_n4(crc, ((uint32_t *)data)[0], crc_table_x25);
crc_n4(crc, ((uint32_t *)data)[1], crc_table_x25);
crc_n4(crc, ((uint32_t *)data)[2], crc_table_x25);
crc_n4(crc, ((uint32_t *)data)[3], crc_table_x25);
data += 16;
}
while (len--) {
crc = (crc >> 8) ^ pgm_read_word(&crc_table_x25[(crc & 0xff) ^ *data++]);
}
seed = crc;
crc = ~crc;
return crc;
}
uint16_t FastCRC16::x25(const uint8_t *data, const size_t datalen)
{
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff check=0x906e
seed = 0xffff;
return x25_upd(data, datalen);
}
// ================= 32-BIT CRC ===================
/** Constructor
*/
FastCRC32::FastCRC32(){}
#define crc_n4d(crc, data, table) crc ^= data; \
crc = pgm_read_dword(&table[(crc & 0xff) + 0x300]) ^ \
pgm_read_dword(&table[((crc >> 8) & 0xff) + 0x200]) ^ \
pgm_read_dword(&table[((crc >> 16) & 0xff) + 0x100]) ^ \
pgm_read_dword(&table[(crc >> 24) & 0xff]);
#define crcsm_n4d(crc, data, table) crc ^= data; \
crc = (crc >> 8) ^ pgm_read_dword(&table[crc & 0xff]); \
crc = (crc >> 8) ^ pgm_read_dword(&table[crc & 0xff]); \
crc = (crc >> 8) ^ pgm_read_dword(&table[crc & 0xff]); \
crc = (crc >> 8) ^ pgm_read_dword(&table[crc & 0xff]);
/** CRC32
* Alias CRC-32/ADCCP, PKZIP, Ethernet, 802.3
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
#if CRC_BIGTABLES
#define CRC_TABLE_CRC32 crc_table_crc32_big
#else
#define CRC_TABLE_CRC32 crc_table_crc32
#endif
uint32_t FastCRC32::crc32_upd(const uint8_t *data, size_t len)
{
uint32_t crc = seed;
while (((uintptr_t)data & 3) && len) {
crc = (crc >> 8) ^ pgm_read_dword(&CRC_TABLE_CRC32[(crc & 0xff) ^ *data++]);
len--;
}
while (len >= 16) {
len -= 16;
#if CRC_BIGTABLES
crc_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CRC32);
crc_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CRC32);
crc_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CRC32);
crc_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CRC32);
#else
crcsm_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CRC32);
crcsm_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CRC32);
crcsm_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CRC32);
crcsm_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CRC32);
#endif
data += 16;
}
while (len--) {
crc = (crc >> 8) ^ pgm_read_dword(&CRC_TABLE_CRC32[(crc & 0xff) ^ *data++]);
}
seed = crc;
crc = ~crc;
return crc;
}
uint32_t FastCRC32::crc32(const uint8_t *data, const size_t datalen)
{
// poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926
seed = 0xffffffff;
return crc32_upd(data, datalen);
}
/** CKSUM
* Alias CRC-32/POSIX
* @param data Pointer to Data
* @param datalen Length of Data
* @return CRC value
*/
#if CRC_BIGTABLES
#define CRC_TABLE_CKSUM crc_table_cksum_big
#else
#define CRC_TABLE_CKSUM crc_table_cksum
#endif
uint32_t FastCRC32::cksum_upd(const uint8_t *data, size_t len)
{
uint32_t crc = seed;
while (((uintptr_t)data & 3) && len) {
crc = (crc >> 8) ^ pgm_read_dword(&CRC_TABLE_CKSUM[(crc & 0xff) ^ *data++]);
len--;
}
while (len >= 16) {
len -= 16;
#if CRC_BIGTABLES
crc_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CKSUM);
crc_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CKSUM);
crc_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CKSUM);
crc_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CKSUM);
#else
crcsm_n4d(crc, ((uint32_t *)data)[0], CRC_TABLE_CKSUM);
crcsm_n4d(crc, ((uint32_t *)data)[1], CRC_TABLE_CKSUM);
crcsm_n4d(crc, ((uint32_t *)data)[2], CRC_TABLE_CKSUM);
crcsm_n4d(crc, ((uint32_t *)data)[3], CRC_TABLE_CKSUM);
#endif
data += 16;
}
while (len--) {
crc = (crc >> 8) ^ pgm_read_dword(&CRC_TABLE_CKSUM[(crc & 0xff) ^ *data++]);
}
seed = crc;
crc = ~REV32(crc);
return crc;
}
uint32_t FastCRC32::cksum(const uint8_t *data, const size_t datalen)
{
// width=32 poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680
seed = 0x00;
return cksum_upd(data, datalen);
}
#endif // #if !defined(KINETISK)

View File

@ -6,7 +6,7 @@
#include "DataParsers.h" #include "DataParsers.h"
#include "DataParser.h" #include "DataParser.h"
#include "Cosem.h" #include "Cosem.h"
#include "ntohll.h" #include "ntohll_ams.h"
#define BUF_SIZE_HAN (1280) #define BUF_SIZE_HAN (1280)

View File

@ -1,5 +1,5 @@
#include "ntohll.h" #include "ntohll_ams.h"
uint64_t ntohll(uint64_t x) { uint64_t ntohll_ams(uint64_t x) {
return (((uint64_t)ntohl((uint32_t)x)) << 32) + ntohl(x >> 32); return (((uint64_t)ntohl((uint32_t)x)) << 32) + ntohl(x >> 32);
} }

View File

@ -3,6 +3,6 @@
#include "lwip/def.h" #include "lwip/def.h"
uint64_t ntohll(uint64_t x); uint64_t ntohll_ams(uint64_t x);
#endif #endif

View File

@ -59,13 +59,14 @@
// Number of maximum high/Low changes per packet. // Number of maximum high/Low changes per packet.
// We can handle up to 36 bit * 2 H/L changes per bit + 2 for sync // We can handle up to 36 bit * 2 H/L changes per bit + 2 for sync
// Для keeloq нужно увеличить RCSWITCH_MAX_CHANGES до 23+1+66*2+1=157 // Для keeloq нужно увеличить RCSWITCH_MAX_CHANGES до 23+1+66*2+1=157
#define RCSWITCH_MAX_CHANGES 75 // default 75 - longest protocol that requires this buffer size is 38/nexus //#define RCSWITCH_MAX_CHANGES 75 // default 75 - longest protocol that requires this buffer size is 38/nexus
#define RCSWITCH_MAX_CHANGES 131 // default 75 - Supports 64 too
// separationLimit: minimum microseconds between received codes, closer codes are ignored. // separationLimit: minimum microseconds between received codes, closer codes are ignored.
// according to discussion on issue #14 it might be more suitable to set the separation // according to discussion on issue #14 it might be more suitable to set the separation
// limit to the same time as the 'low' part of the sync signal for the current protocol. // limit to the same time as the 'low' part of the sync signal for the current protocol.
// should be set to the minimum value of pulselength * the sync signal // should be set to the minimum value of pulselength * the sync signal
#define RCSWITCH_SEPARATION_LIMIT 4100 #define RCSWITCH_SEPARATION_LIMIT 3600
class RCSwitch { class RCSwitch {

View File

@ -44,7 +44,7 @@ uint32_t *stack_thunk_light_save = NULL; /* Saved A1 while in BearSSL */
uint32_t stack_thunk_light_refcnt = 0; uint32_t stack_thunk_light_refcnt = 0;
//#define _stackSize (5600/4) //#define _stackSize (5600/4)
#if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_AWS_IOT_LIGHT) || defined(USE_MQTT_AZURE_IOT) #if defined(USE_MQTT_CLIENT_CERT) || defined(USE_MQTT_AWS_IOT_LIGHT) || defined(USE_MQTT_AZURE_IOT)
#define _stackSize (5300/4) // using a light version of bearssl we can save 300 bytes #define _stackSize (5300/4) // using a light version of bearssl we can save 300 bytes
#else #else
#define _stackSize (4800/4) // no private key, we can reduce a little, max observed 4300 #define _stackSize (4800/4) // no private key, we can reduce a little, max observed 4300

View File

@ -303,7 +303,9 @@ int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port, int32_t timeout
setLastError(ERR_TCP_CONNECT); setLastError(ERR_TCP_CONNECT);
return 0; return 0;
} }
return _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str()); bool success = _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str());
if (!success) { stop(); }
return success;
} }
#else // ESP32 #else // ESP32
int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) { int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) {
@ -313,7 +315,9 @@ int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) {
setLastError(ERR_TCP_CONNECT); setLastError(ERR_TCP_CONNECT);
return 0; return 0;
} }
return _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str()); bool success = _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str());
if (!success) { stop(); }
return success;
} }
#endif #endif
@ -570,6 +574,7 @@ int WiFiClientSecure_light::_run_until(unsigned target, bool blocking) {
if (((int32_t)(millis() - (t + this->_loopTimeout)) >= 0)){ if (((int32_t)(millis() - (t + this->_loopTimeout)) >= 0)){
DEBUG_BSSL("_run_until: Timeout\n"); DEBUG_BSSL("_run_until: Timeout\n");
setLastError(ERR_TLS_TIMEOUT);
return -1; return -1;
} }
@ -994,16 +999,16 @@ bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
// ============================================================ // ============================================================
// allocate Private key if needed, only if USE_MQTT_AWS_IOT // allocate Private key if needed, only if USE_MQTT_CLIENT_CERT
LOG_HEAP_SIZE("_connectSSL before PrivKey allocation"); LOG_HEAP_SIZE("_connectSSL before PrivKey allocation");
#ifdef USE_MQTT_AWS_IOT #if defined(USE_MQTT_CLIENT_CERT)
// ============================================================ // ============================================================
// Set the EC Private Key, only USE_MQTT_AWS_IOT // Set the EC Private Key, only USE_MQTT_CLIENT_CERT
// limited to P256 curve // limited to P256 curve
br_ssl_client_set_single_ec(_sc.get(), _chain_P, 1, br_ssl_client_set_single_ec(_sc.get(), _chain_P, 1,
_sk_ec_P, _allowed_usages, _sk_ec_P, _allowed_usages,
_cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default()); _cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default());
#endif // USE_MQTT_AWS_IOT #endif // USE_MQTT_CLIENT_CERT
// ============================================================ // ============================================================
// Start TLS connection, ALL // Start TLS connection, ALL

View File

@ -137,7 +137,7 @@ class WiFiClientSecure_light : public WiFiClient {
} }
private: private:
uint32_t _loopTimeout=5000; uint32_t _loopTimeout=10000;
void _clear(); void _clear();
bool _ctx_present; bool _ctx_present;
std::shared_ptr<br_ssl_client_context> _sc; std::shared_ptr<br_ssl_client_context> _sc;
@ -192,7 +192,8 @@ class WiFiClientSecure_light : public WiFiClient {
#define ERR_CANT_RESOLVE_IP -1001 #define ERR_CANT_RESOLVE_IP -1001
#define ERR_TCP_CONNECT -1002 #define ERR_TCP_CONNECT -1002
// #define ERR_MISSING_EC_KEY -1003 // deprecated, AWS IoT is not called if the private key is not present // #define ERR_MISSING_EC_KEY -1003 // deprecated, AWS IoT is not called if the private key is not present
#define ERR_MISSING_CA -1004 // #define ERR_MISSING_CA -1004 // deprecated
#define ERR_TLS_TIMEOUT -1005
// For reference, BearSSL error codes: // For reference, BearSSL error codes:
// #define BR_ERR_OK 0 // #define BR_ERR_OK 0

View File

@ -40,6 +40,17 @@ be_extern_native_module(gpio);
be_extern_native_module(display); be_extern_native_module(display);
be_extern_native_module(energy); be_extern_native_module(energy);
be_extern_native_module(webserver); be_extern_native_module(webserver);
#ifdef USE_BERRY_HTTPSERVER
be_extern_native_module(httpserver);
#ifdef USE_BERRY_WSSERVER
be_extern_native_module(wsserver);
#endif // USE_BERRY_WSSERVER
#ifdef USE_BERRY_WEBFILES
be_extern_native_module(webfiles);
#endif // USE_BERRY_WEBFILES
#endif // USE_BERRY_HTTPSERVER
be_extern_native_module(flash); be_extern_native_module(flash);
be_extern_native_module(path); be_extern_native_module(path);
be_extern_native_module(unishox); be_extern_native_module(unishox);
@ -170,6 +181,15 @@ BERRY_LOCAL const bntvmodule_t* const be_module_table[] = {
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
&be_native_module(webserver), &be_native_module(webserver),
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
#ifdef USE_BERRY_HTTPSERVER
&be_native_module(httpserver),
#ifdef USE_BERRY_WSSERVER
&be_native_module(wsserver),
#endif // USE_BERRY_WSSERVER
#ifdef USE_BERRY_WEBFILES
&be_native_module(webfiles),
#endif // USE_BERRY_WEBFILES
#endif // USE_BERRY_HTTPSERVER
#ifdef USE_ZIGBEE #ifdef USE_ZIGBEE
&be_native_module(zigbee), &be_native_module(zigbee),
&be_native_module(matter_zigbee), &be_native_module(matter_zigbee),
@ -283,7 +303,6 @@ BERRY_LOCAL bclass_array be_class_table = {
&be_native_class(AXP2102), &be_native_class(AXP2102),
#endif // USE_I2C #endif // USE_I2C
&be_native_class(md5), &be_native_class(md5),
#ifdef USE_WEBCLIENT
&be_native_class(udp), &be_native_class(udp),
&be_native_class(webclient), &be_native_class(webclient),
&be_native_class(tcpclient), &be_native_class(tcpclient),
@ -291,7 +310,6 @@ BERRY_LOCAL bclass_array be_class_table = {
#ifdef USE_BERRY_DEBUG #ifdef USE_BERRY_DEBUG
&be_native_class(webserver_async), // include only when USE_BERRY_DEBUG is enabled &be_native_class(webserver_async), // include only when USE_BERRY_DEBUG is enabled
#endif // USE_BERRY_DEBUG #endif // USE_BERRY_DEBUG
#endif // USE_WEBCLIENT
#ifdef USE_BERRY_TCPSERVER #ifdef USE_BERRY_TCPSERVER
&be_native_class(tcpserver), &be_native_class(tcpserver),
#endif // USE_BERRY_TCPSERVER #endif // USE_BERRY_TCPSERVER

View File

@ -64,6 +64,25 @@ int be_re_compile(bvm *vm) {
be_raise(vm, "type_error", NULL); be_raise(vm, "type_error", NULL);
} }
// Native functions be_const_func()
// Berry: `re.compilebytes(pattern:string) -> instance(bytes)`
int be_re_compilebytes(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 1 && be_isstring(vm, 1)) {
const char * regex_str = be_tostring(vm, 1);
int sz = re1_5_sizecode(regex_str);
if (sz < 0) {
be_raise(vm, "internal_error", "error in regex");
}
be_pushbytes(vm, NULL, sizeof(ByteProg) + sz);
ByteProg *code = (ByteProg*) be_tobytes(vm, -1, NULL);
re1_5_compilecode(code, regex_str);
be_return(vm);
}
be_raise(vm, "type_error", NULL);
}
// pushes either a list if matched, else `nil` // pushes either a list if matched, else `nil`
// return index of next offset, or -1 if not found // return index of next offset, or -1 if not found
const char *be_re_match_search_run(bvm *vm, ByteProg *code, const char *hay, bbool is_anchored, bbool size_only) { const char *be_re_match_search_run(bvm *vm, ByteProg *code, const char *hay, bbool is_anchored, bbool size_only) {
@ -99,9 +118,10 @@ const char *be_re_match_search_run(bvm *vm, ByteProg *code, const char *hay, bbo
int be_re_match_search(bvm *vm, bbool is_anchored, bbool size_only) { int be_re_match_search(bvm *vm, bbool is_anchored, bbool size_only) {
int32_t argc = be_top(vm); // Get the number of arguments int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { if (argc >= 2 && (be_isstring(vm, 1) || be_isbytes(vm, 1)) && be_isstring(vm, 2)) {
const char * regex_str = be_tostring(vm, 1);
const char * hay = be_tostring(vm, 2); const char * hay = be_tostring(vm, 2);
ByteProg *code = NULL;
int32_t offset = 0; int32_t offset = 0;
if (argc >= 3 && be_isint(vm, 3)) { if (argc >= 3 && be_isint(vm, 3)) {
offset = be_toint(vm, 3); offset = be_toint(vm, 3);
@ -111,12 +131,14 @@ int be_re_match_search(bvm *vm, bbool is_anchored, bbool size_only) {
if (offset >= hay_len) { be_return_nil(vm); } // any match of empty string returns nil, this catches implicitly when hay_len == 0 if (offset >= hay_len) { be_return_nil(vm); } // any match of empty string returns nil, this catches implicitly when hay_len == 0
hay += offset; // shift to offset hay += offset; // shift to offset
if (be_isstring(vm, 1)) {
const char * regex_str = be_tostring(vm, 1);
int sz = re1_5_sizecode(regex_str); int sz = re1_5_sizecode(regex_str);
if (sz < 0) { if (sz < 0) {
be_raise(vm, "internal_error", "error in regex"); be_raise(vm, "internal_error", "error in regex");
} }
ByteProg *code = be_os_malloc(sizeof(ByteProg) + sz); code = be_os_malloc(sizeof(ByteProg) + sz);
if (code == NULL) { if (code == NULL) {
be_throw(vm, BE_MALLOC_FAIL); /* lack of heap space */ be_throw(vm, BE_MALLOC_FAIL); /* lack of heap space */
} }
@ -125,8 +147,15 @@ int be_re_match_search(bvm *vm, bbool is_anchored, bbool size_only) {
be_os_free(code); be_os_free(code);
be_raise(vm, "internal_error", "error in regex"); be_raise(vm, "internal_error", "error in regex");
} }
} else {
code = (ByteProg *) be_tobytes(vm, 1, NULL);
}
// do the match
be_re_match_search_run(vm, code, hay, is_anchored, size_only); be_re_match_search_run(vm, code, hay, is_anchored, size_only);
// cleanup
if (be_isstring(vm, 1)) {
be_os_free(code); be_os_free(code);
}
be_return(vm); be_return(vm);
} }
be_raise(vm, "type_error", NULL); be_raise(vm, "type_error", NULL);
@ -134,19 +163,22 @@ int be_re_match_search(bvm *vm, bbool is_anchored, bbool size_only) {
int be_re_match_search_all(bvm *vm, bbool is_anchored) { int be_re_match_search_all(bvm *vm, bbool is_anchored) {
int32_t argc = be_top(vm); // Get the number of arguments int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { if (argc >= 2 && (be_isstring(vm, 1) || be_isbytes(vm, 1)) && be_isstring(vm, 2)) {
const char * regex_str = be_tostring(vm, 1);
const char * hay = be_tostring(vm, 2); const char * hay = be_tostring(vm, 2);
ByteProg *code = NULL;
int limit = -1; int limit = -1;
if (argc >= 3) { if (argc >= 3) {
limit = be_toint(vm, 3); limit = be_toint(vm, 3);
} }
if (be_isstring(vm, 1)) {
const char * regex_str = be_tostring(vm, 1);
int sz = re1_5_sizecode(regex_str); int sz = re1_5_sizecode(regex_str);
if (sz < 0) { if (sz < 0) {
be_raise(vm, "internal_error", "error in regex"); be_raise(vm, "internal_error", "error in regex");
} }
ByteProg *code = be_os_malloc(sizeof(ByteProg) + sz); code = be_os_malloc(sizeof(ByteProg) + sz);
if (code == NULL) { if (code == NULL) {
be_throw(vm, BE_MALLOC_FAIL); /* lack of heap space */ be_throw(vm, BE_MALLOC_FAIL); /* lack of heap space */
} }
@ -155,6 +187,9 @@ int be_re_match_search_all(bvm *vm, bbool is_anchored) {
be_os_free(code); be_os_free(code);
be_raise(vm, "internal_error", "error in regex"); be_raise(vm, "internal_error", "error in regex");
} }
} else {
code = (ByteProg *) be_tobytes(vm, 1, NULL);
}
be_newobject(vm, "list"); be_newobject(vm, "list");
for (int i = limit; i != 0 && hay != NULL; i--) { for (int i = limit; i != 0 && hay != NULL; i--) {
@ -165,7 +200,10 @@ int be_re_match_search_all(bvm *vm, bbool is_anchored) {
be_pop(vm, 1); be_pop(vm, 1);
} }
be_pop(vm, 1); be_pop(vm, 1);
// cleanup
if (be_isstring(vm, 1)) {
be_os_free(code); be_os_free(code);
}
be_return(vm); be_return(vm);
} }
be_raise(vm, "type_error", NULL); be_raise(vm, "type_error", NULL);
@ -193,6 +231,21 @@ int be_re_search_all(bvm *vm) {
return be_re_match_search_all(vm, bfalse); return be_re_match_search_all(vm, bfalse);
} }
// Berry: `re.dump(b:bytes) -> nil``
int be_re_dump(bvm *vm) {
#ifdef USE_BERRY_DEBUG
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 1 && be_isbytes(vm, 1)) {
ByteProg *code = (ByteProg*) be_tobytes(vm, 1, NULL);
re1_5_dumpcode(code);
be_return_nil(vm);
}
be_raise(vm, "type_error", NULL);
#else // USE_BERRY_DEBUG
be_return_nil(vm);
#endif
}
// Berry: `re_pattern.search(s:string [, offset:int]) -> list(string)` // Berry: `re_pattern.search(s:string [, offset:int]) -> list(string)`
int re_pattern_search(bvm *vm) { int re_pattern_search(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments int32_t argc = be_top(vm); // Get the number of arguments
@ -329,19 +382,21 @@ int re_pattern_split(bvm *vm) {
// Berry: `re.split(pattern:string, s:string [, split_limit:int]) -> list(string)` // Berry: `re.split(pattern:string, s:string [, split_limit:int]) -> list(string)`
int be_re_split(bvm *vm) { int be_re_split(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { if (argc >= 2 && (be_isstring(vm, 1) || be_isbytes(vm, 1)) && be_isstring(vm, 2)) {
const char * regex_str = be_tostring(vm, 1);
const char * hay = be_tostring(vm, 2); const char * hay = be_tostring(vm, 2);
ByteProg *code = NULL;
int split_limit = -1; int split_limit = -1;
if (argc >= 3) { if (argc >= 3) {
split_limit = be_toint(vm, 3); split_limit = be_toint(vm, 3);
} }
if (be_isstring(vm, 1)) {
const char * regex_str = be_tostring(vm, 1);
int sz = re1_5_sizecode(regex_str); int sz = re1_5_sizecode(regex_str);
if (sz < 0) { if (sz < 0) {
be_raise(vm, "internal_error", "error in regex"); be_raise(vm, "internal_error", "error in regex");
} }
ByteProg *code = be_os_malloc(sizeof(ByteProg) + sz); code = be_os_malloc(sizeof(ByteProg) + sz);
if (code == NULL) { if (code == NULL) {
be_throw(vm, BE_MALLOC_FAIL); /* lack of heap space */ be_throw(vm, BE_MALLOC_FAIL); /* lack of heap space */
} }
@ -350,8 +405,13 @@ int be_re_split(bvm *vm) {
be_os_free(code); be_os_free(code);
be_raise(vm, "internal_error", "error in regex"); be_raise(vm, "internal_error", "error in regex");
} }
ret = re_pattern_split_run(vm, code, hay, split_limit); } else {
code = (ByteProg *) be_tobytes(vm, 1, NULL);
}
int ret = re_pattern_split_run(vm, code, hay, split_limit);
if (be_isstring(vm, 1)) {
be_os_free(code); be_os_free(code);
}
return ret; return ret;
} }
be_raise(vm, "type_error", NULL); be_raise(vm, "type_error", NULL);
@ -363,12 +423,14 @@ int be_re_split(bvm *vm) {
@const_object_info_begin @const_object_info_begin
module re (scope: global) { module re (scope: global) {
compile, func(be_re_compile) compile, func(be_re_compile)
compilebytes, func(be_re_compilebytes)
search, func(be_re_search) search, func(be_re_search)
searchall, func(be_re_search_all) searchall, func(be_re_search_all)
match, func(be_re_match) match, func(be_re_match)
match2, func(be_re_match2) match2, func(be_re_match2)
matchall, func(be_re_match_all) matchall, func(be_re_match_all)
split, func(be_re_split) split, func(be_re_split)
dump, func(be_re_dump)
} }
@const_object_info_end @const_object_info_end

View File

@ -405,7 +405,7 @@ int main(int argc, char *argv[])
{ {
int res; int res;
bvm *vm = be_vm_new(); /* create a virtual machine instance */ bvm *vm = be_vm_new(); /* create a virtual machine instance */
be_set_ctype_func_hanlder(vm, be_call_ctype_func); be_set_ctype_func_handler(vm, be_call_ctype_func);
res = analysis_args(vm, argc, argv); res = analysis_args(vm, argc, argv);
be_vm_delete(vm); /* free all objects and vm */ be_vm_delete(vm); /* free all objects and vm */
return res; return res;

View File

@ -82,8 +82,8 @@ BERRY_API void be_regfunc(bvm *vm, const char *name, bntvfunc f)
bstring *s = be_newstr(vm, name); bstring *s = be_newstr(vm, name);
#if !BE_USE_PRECOMPILED_OBJECT #if !BE_USE_PRECOMPILED_OBJECT
int idx = be_builtin_find(vm, s); int idx = be_builtin_find(vm, s);
be_assert(idx == -1); be_assert(idx < 0);
if (idx == -1) { /* new function */ if (idx < 0) { /* new function */
idx = be_builtin_new(vm, s); idx = be_builtin_new(vm, s);
#else #else
int idx = be_global_find(vm, s); int idx = be_global_find(vm, s);
@ -102,8 +102,8 @@ BERRY_API void be_regclass(bvm *vm, const char *name, const bnfuncinfo *lib)
bstring *s = be_newstr(vm, name); bstring *s = be_newstr(vm, name);
#if !BE_USE_PRECOMPILED_OBJECT #if !BE_USE_PRECOMPILED_OBJECT
int idx = be_builtin_find(vm, s); int idx = be_builtin_find(vm, s);
be_assert(idx == -1); be_assert(idx < 0);
if (idx == -1) { /* new function */ if (idx < 0) { /* new function */
idx = be_builtin_new(vm, s); idx = be_builtin_new(vm, s);
#else #else
int idx = be_global_find(vm, s); int idx = be_global_find(vm, s);
@ -599,7 +599,7 @@ BERRY_API bbool be_getglobal(bvm *vm, const char *name)
{ {
int idx = be_global_find(vm, be_newstr(vm, name)); int idx = be_global_find(vm, be_newstr(vm, name));
bvalue *top = be_incrtop(vm); bvalue *top = be_incrtop(vm);
if (idx > -1) { if (idx >= 0) {
*top = *be_global_var(vm, idx); *top = *be_global_var(vm, idx);
return btrue; return btrue;
} }

View File

@ -258,6 +258,26 @@ static size_t buf_add2_be(buf_impl* attr, const uint16_t data) // append 16 bits
return attr->len; return attr->len;
} }
static size_t buf_add3_le(buf_impl* attr, const uint32_t data) // append 32 bits value
{
if (attr->len < attr->size - 2) { // do we have room for 4 bytes
attr->bufptr[attr->len++] = data;
attr->bufptr[attr->len++] = data >> 8;
attr->bufptr[attr->len++] = data >> 16;
}
return attr->len;
}
size_t buf_add3_be(buf_impl* attr, const uint32_t data) // append 32 bits value
{
if (attr->len < attr->size - 2) { // do we have room for 4 bytes
attr->bufptr[attr->len++] = data >> 16;
attr->bufptr[attr->len++] = data >> 8;
attr->bufptr[attr->len++] = data;
}
return attr->len;
}
static size_t buf_add4_le(buf_impl* attr, const uint32_t data) // append 32 bits value static size_t buf_add4_le(buf_impl* attr, const uint32_t data) // append 32 bits value
{ {
if (attr->len < attr->size - 3) { // do we have room for 4 bytes if (attr->len < attr->size - 3) { // do we have room for 4 bytes
@ -838,10 +858,12 @@ static int m_add(bvm *vm)
case -1: /* fallback below */ case -1: /* fallback below */
case 1: buf_add1(&attr, v); break; case 1: buf_add1(&attr, v); break;
case 2: buf_add2_le(&attr, v); break; case 2: buf_add2_le(&attr, v); break;
case 3: buf_add3_le(&attr, v); break;
case 4: buf_add4_le(&attr, v); break; case 4: buf_add4_le(&attr, v); break;
case -2: buf_add2_be(&attr, v); break; case -2: buf_add2_be(&attr, v); break;
case -3: buf_add3_be(&attr, v); break;
case -4: buf_add4_be(&attr, v); break; case -4: buf_add4_be(&attr, v); 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 between -4 and 4.");
} }
be_pop(vm, argc - 1); be_pop(vm, argc - 1);
m_write_attributes(vm, 1, &attr); /* update attributes */ m_write_attributes(vm, 1, &attr); /* update attributes */

View File

@ -354,9 +354,6 @@ const bntvmodule_t be_native_module(_module) = { \
#else #else
// #define be_define_const_bytes(_name, ...) \
// const uint8_t be_const_bin_##_name[] = { __VA_ARGS__ }
#define be_define_const_str_weak(_name, _s, _len) \ #define be_define_const_str_weak(_name, _s, _len) \
const bcstring be_const_str_##_name = { \ const bcstring be_const_str_##_name = { \
NULL, \ NULL, \

View File

@ -234,7 +234,9 @@ int be_nfunc_open(bvm *vm)
{ "flush", i_flush }, { "flush", i_flush },
{ "close", i_close }, { "close", i_close },
{ "deinit", i_close }, { "deinit", i_close },
#if BE_USE_BYTECODE_SAVER
{ "savecode", i_savecode }, { "savecode", i_savecode },
#endif
{ NULL, NULL } { NULL, NULL }
}; };
fname = argc >= 1 && be_isstring(vm, 1) ? be_tostring(vm, 1) : NULL; fname = argc >= 1 && be_isstring(vm, 1) ? be_tostring(vm, 1) : NULL;

View File

@ -27,6 +27,9 @@ static void dump_map_keys(bvm *vm, bmap *map)
bmapiter iter = be_map_iter(); bmapiter iter = be_map_iter();
while ((node = be_map_next(map, &iter)) != NULL) { while ((node = be_map_next(map, &iter)) != NULL) {
if (var_isstr(&node->key)) { if (var_isstr(&node->key)) {
/* check if the global was not undefined/removed */
int idx = var_toidx(&node->value);
if (idx >= 0) { /* the key is present in global, and the index is valid */
bstring *s = var_tostr(&node->key); bstring *s = var_tostr(&node->key);
be_pushstring(vm, str(s)); be_pushstring(vm, str(s));
be_data_push(vm, -2); be_data_push(vm, -2);
@ -34,6 +37,7 @@ static void dump_map_keys(bvm *vm, bmap *map)
} }
} }
} }
}
static int m_globals(bvm *vm) static int m_globals(bvm *vm)
{ {
@ -49,7 +53,7 @@ static int m_contains(bvm *vm)
if (top >= 1 && be_isstring(vm, 1)) { if (top >= 1 && be_isstring(vm, 1)) {
const char * name = be_tostring(vm, 1); const char * name = be_tostring(vm, 1);
int idx = be_global_find(vm, be_newstr(vm, name)); int idx = be_global_find(vm, be_newstr(vm, name));
be_pushbool(vm, idx > -1); be_pushbool(vm, idx >= 0);
be_return(vm); be_return(vm);
} }
be_return_nil(vm); be_return_nil(vm);
@ -76,12 +80,25 @@ static int m_setglobal(bvm *vm)
be_return_nil(vm); be_return_nil(vm);
} }
/* Remove a global variable from global scope */
/* Internally the global name cannot be removed but it's value is replaced with BE_NONE */
/* and global function pretend that BE_NONE is equivalent to the name being absent */
static int m_undef(bvm *vm)
{
int top = be_top(vm);
if (top >= 1 && be_isstring(vm, 1)) {
be_global_undef(vm, be_newstr(vm, be_tostring(vm, 1)));
}
be_return_nil(vm);
}
#if !BE_USE_PRECOMPILED_OBJECT #if !BE_USE_PRECOMPILED_OBJECT
be_native_module_attr_table(global) { be_native_module_attr_table(global) {
be_native_module_function("()", m_globals), be_native_module_function("()", m_globals),
be_native_module_function("contains", m_contains), be_native_module_function("contains", m_contains),
be_native_module_function("member", m_findglobal), be_native_module_function("member", m_findglobal),
be_native_module_function("setmember", m_setglobal), be_native_module_function("setmember", m_setglobal),
be_native_module_function("undef", m_undef),
}; };
be_define_native_module(global, NULL); be_define_native_module(global, NULL);
@ -92,6 +109,7 @@ module global (scope: global, depend: BE_USE_GLOBAL_MODULE) {
contains, func(m_contains) contains, func(m_contains)
member, func(m_findglobal) member, func(m_findglobal)
setmember, func(m_setglobal) setmember, func(m_setglobal)
undef, func(m_undef)
} }
@const_object_info_end */ @const_object_info_end */
#include "../generate/be_fixed_global.h" #include "../generate/be_fixed_global.h"

View File

@ -137,6 +137,20 @@ static int m_toptr(bvm *vm)
be_return_nil(vm); be_return_nil(vm);
} }
static int m_solidified(bvm *vm)
{
int top = be_top(vm);
if (top >= 1) {
bvalue *v = be_indexof(vm, 1);
if (var_basetype(v) >= BE_FUNCTION || var_type(v) == BE_COMPTR) {
bbool isconst = gc_isconst((bgcobject*)var_toobj(v));
be_pushbool(vm, isconst);
be_return(vm);
}
}
be_return_nil(vm);
}
static int m_fromptr(bvm *vm) static int m_fromptr(bvm *vm)
{ {
int top = be_top(vm); int top = be_top(vm);
@ -245,6 +259,7 @@ be_native_module_attr_table(introspect) {
be_native_module_function("toptr", m_toptr), be_native_module_function("toptr", m_toptr),
be_native_module_function("fromptr", m_fromptr), be_native_module_function("fromptr", m_fromptr),
be_native_module_function("solidified", m_solidified),
be_native_module_function("name", m_name), be_native_module_function("name", m_name),
@ -266,6 +281,7 @@ module introspect (scope: global, depend: BE_USE_INTROSPECT_MODULE) {
toptr, func(m_toptr) toptr, func(m_toptr)
fromptr, func(m_fromptr) fromptr, func(m_fromptr)
solidified, func(m_solidified)
name, func(m_name) name, func(m_name)

View File

@ -40,10 +40,15 @@
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define popcount(v) __popcnt(v) #define popcount(v) __popcnt(v)
// Find a free slot in the space bitmask
// Find the least significant 1-bit in x and return its 1-based index.
static int ffs(unsigned x) static int ffs(unsigned x)
{ {
unsigned long i; unsigned long i;
return _BitScanForward(&i, x) ? i : 0; // NOTE: _BitScanForward is 0-based, see:
// https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64?view=msvc-170
// _BitScanForward(&index, 12) populates index with 2
return _BitScanForward(&i, x) ? i + 1 : 0;
} }
#else #else
/* https://github.com/hcs0/Hackers-Delight/blob/master/pop.c.txt - count number of 1-bits */ /* https://github.com/hcs0/Hackers-Delight/blob/master/pop.c.txt - count number of 1-bits */

View File

@ -324,8 +324,8 @@ static void end_func(bparser *parser)
proto->codesize = finfo->pc; proto->codesize = finfo->pc;
proto->ktab = be_vector_release(vm, &finfo->kvec); proto->ktab = be_vector_release(vm, &finfo->kvec);
proto->nconst = be_vector_count(&finfo->kvec); proto->nconst = be_vector_count(&finfo->kvec);
proto->nproto = be_vector_count(&finfo->pvec);
proto->ptab = be_vector_release(vm, &finfo->pvec); proto->ptab = be_vector_release(vm, &finfo->pvec);
proto->nproto = be_vector_count(&finfo->pvec);
#if BE_USE_MEM_ALIGNED #if BE_USE_MEM_ALIGNED
proto->code = be_move_to_aligned(vm, proto->code, proto->codesize * sizeof(binstruction)); /* move `code` to 4-bytes aligned memory region */ proto->code = be_move_to_aligned(vm, proto->code, proto->codesize * sizeof(binstruction)); /* move `code` to 4-bytes aligned memory region */
proto->ktab = be_move_to_aligned(vm, proto->ktab, proto->nconst * sizeof(bvalue)); /* move `ktab` to 4-bytes aligned memory region */ proto->ktab = be_move_to_aligned(vm, proto->ktab, proto->nconst * sizeof(bvalue)); /* move `ktab` to 4-bytes aligned memory region */
@ -488,7 +488,10 @@ static void new_var(bparser *parser, bstring *name, bexpdesc *var)
var->v.idx = new_localvar(parser, name); /* if local, contains the index in current local var list */ var->v.idx = new_localvar(parser, name); /* if local, contains the index in current local var list */
} else { } else {
init_exp(var, ETGLOBAL, 0); init_exp(var, ETGLOBAL, 0);
var->v.idx = be_global_find(parser->vm, name);
if (var->v.idx < 0) {
var->v.idx = be_global_new(parser->vm, name); var->v.idx = be_global_new(parser->vm, name);
}
if (var->v.idx > (int)IBx_MASK) { if (var->v.idx > (int)IBx_MASK) {
push_error(parser, push_error(parser,
"too many global variables (in '%s')", str(name)); "too many global variables (in '%s')", str(name));

View File

@ -67,19 +67,39 @@ static int global_find(bvm *vm, bstring *name)
{ {
bvalue *res = be_map_findstr(vm, global(vm).vtab, name); bvalue *res = be_map_findstr(vm, global(vm).vtab, name);
if (res) { if (res) {
return var_toidx(res) + be_builtin_count(vm); int idx = var_toidx(res);
if (idx >= 0) {
return idx + be_builtin_count(vm);
} else {
return idx; /* the global does not exist (-1) or was underfined (< -1)*/
}
} }
return -1; /* not found */ return -1; /* not found */
} }
bbool be_global_undef(bvm *vm, bstring *name)
{
int idx = global_find(vm, name);
if (idx >= 0) {
bvalue *desc = be_map_findstr(vm, global(vm).vtab, name);
int index = var_toidx(desc);
var_setint(desc, -index - 2); /* negate the index to mark it as undefined */
bvalue* val = be_vector_at(&global(vm).vlist, index);
var_setnil(val);
return btrue;
}
return bfalse;
}
int be_global_find(bvm *vm, bstring *name) int be_global_find(bvm *vm, bstring *name)
{ {
int res = global_find(vm, name); int res = global_find(vm, name); /* returns negative if not found, -1 if does not exist, < -1 if existed but undefined */
if (res < 0) { if (res < 0) {
res = be_builtin_find(vm, name); res = be_builtin_find(vm, name); /* returns -1 if not found */
} }
if (res < 0) { if (res < 0) {
res = global_native_class_find(vm, name); res = global_native_class_find(vm, name); /* returns -1 if not found */
} }
return res; return res;
} }
@ -97,11 +117,18 @@ static int global_new_anonymous(bvm *vm)
int be_global_new(bvm *vm, bstring *name) int be_global_new(bvm *vm, bstring *name)
{ {
int idx = global_find(vm, name); int idx = global_find(vm, name);
if (idx == -1) { if (idx < 0) {
bvalue *desc; bvalue *desc;
if (idx == -1) {
idx = global_new_anonymous(vm); idx = global_new_anonymous(vm);
desc = be_map_insertstr(vm, global(vm).vtab, name, NULL); desc = be_map_insertstr(vm, global(vm).vtab, name, NULL);
var_setint(desc, idx); var_setint(desc, idx);
} else {
/* the global exists but was undefined */
idx = -idx - 2;
desc = be_map_findstr(vm, global(vm).vtab, name);
var_setint(desc, idx);
}
idx += be_builtin_count(vm); idx += be_builtin_count(vm);
} }
return idx; return idx;

View File

@ -20,6 +20,7 @@ void be_globalvar_init(bvm *vm);
void be_globalvar_deinit(bvm *vm); void be_globalvar_deinit(bvm *vm);
int be_global_find(bvm *vm, bstring *name); int be_global_find(bvm *vm, bstring *name);
int be_global_new(bvm *vm, bstring *name); int be_global_new(bvm *vm, bstring *name);
bbool be_global_undef(bvm *vm, bstring *name);
bvalue* be_global_var(bvm *vm, int index); bvalue* be_global_var(bvm *vm, int index);
void be_global_release_space(bvm *vm); void be_global_release_space(bvm *vm);
int be_builtin_find(bvm *vm, bstring *name); int be_builtin_find(bvm *vm, bstring *name);

View File

@ -591,7 +591,7 @@ newframe: /* a new call frame */
if (var_isstr(b)) { if (var_isstr(b)) {
bstring *name = var_tostr(b); bstring *name = var_tostr(b);
int idx = be_global_find(vm, name); int idx = be_global_find(vm, name);
if (idx > -1) { if (idx >= 0) {
*v = *be_global_var(vm, idx); *v = *be_global_var(vm, idx);
} else { } else {
vm_error(vm, "attribute_error", "'%s' undeclared", str(name)); vm_error(vm, "attribute_error", "'%s' undeclared", str(name));
@ -1408,7 +1408,7 @@ BERRY_API void be_set_obs_micros(bvm *vm, bmicrosfnct micros)
vm->microsfnct = micros; vm->microsfnct = micros;
} }
BERRY_API void be_set_ctype_func_hanlder(bvm *vm, bctypefunc handler) BERRY_API void be_set_ctype_func_handler(bvm *vm, bctypefunc handler)
{ {
vm->ctypefunc = handler; vm->ctypefunc = handler;
} }

View File

@ -2168,14 +2168,14 @@ BERRY_API void be_set_obs_micros(bvm *vm, bmicrosfnct micros);
/** /**
* @fn void be_set_ctype_func_hanlder(bvm*, bctypefunc) * @fn void be_set_ctype_func_handler(bvm*, bctypefunc)
* @note Observability hook * @note Observability hook
* @brief (???) * @brief (???)
* *
* @param vm virtual machine instance * @param vm virtual machine instance
* @param handler * @param handler
*/ */
BERRY_API void be_set_ctype_func_hanlder(bvm *vm, bctypefunc handler); BERRY_API void be_set_ctype_func_handler(bvm *vm, bctypefunc handler);
/** /**
* @fn bctypefunc be_get_ctype_func_hanlder(bvm*) * @fn bctypefunc be_get_ctype_func_hanlder(bvm*)

View File

@ -53,6 +53,11 @@ b.add(0x12345678, -2)
assert(str(b) == "bytes('2278785678563412785678')") assert(str(b) == "bytes('2278785678563412785678')")
b.add(0x12345678, -4) b.add(0x12345678, -4)
assert(str(b) == "bytes('227878567856341278567812345678')") assert(str(b) == "bytes('227878567856341278567812345678')")
b.add(0xAABBCC, 3)
assert(str(b) == "bytes('227878567856341278567812345678CCBBAA')")
b.add(0x998877, -3)
assert(str(b) == "bytes('227878567856341278567812345678CCBBAA998877')")
#- get -# #- get -#
b=bytes("000102030405") b=bytes("000102030405")

View File

@ -0,0 +1,52 @@
# test regex from re1.5
import re
# standard use of lib
assert(re.search("a.*?b(z+)", "zaaaabbbccbbzzzee") == ['aaaabbbccbbzzz', 'zzz'])
assert(re.searchall('<([a-zA-Z]+)>', '<abc> yeah <xyz>') == [['<abc>', 'abc'], ['<xyz>', 'xyz']])
assert(re.match("a.*?b(z+)", "aaaabbbccbbzzzee") == ['aaaabbbccbbzzz', 'zzz'])
assert(re.match2("a.*?b(z+)", "aaaabbbccbbzzzee") == [14, 'zzz'])
assert(re.matchall('<([a-zA-Z]+)>', '<abc> yeah <xyz>') == [['<abc>', 'abc']])
assert(re.matchall('<([a-zA-Z]+)>', '<abc><xyz>') == [['<abc>', 'abc'], ['<xyz>', 'xyz']])
assert(re.split('/', "foo/bar//baz") == ['foo', 'bar', '', 'baz'])
# pre-compile
var rr
rr = re.compile("a.*?b(z+)")
assert(rr.search("zaaaabbbccbbzzzee") == ['aaaabbbccbbzzz', 'zzz'])
rr = re.compile('<([a-zA-Z]+)>')
assert(rr.searchall('<abc> yeah <xyz>') == [['<abc>', 'abc'], ['<xyz>', 'xyz']])
rr = re.compile("a.*?b(z+)")
assert(rr.match("aaaabbbccbbzzzee") == ['aaaabbbccbbzzz', 'zzz'])
assert(rr.match2("aaaabbbccbbzzzee") == [14, 'zzz'])
rr = re.compile('<([a-zA-Z]+)>')
assert(rr.matchall('<abc> yeah <xyz>') == [['<abc>', 'abc']])
assert(rr.matchall('<abc><xyz>') == [['<abc>', 'abc'], ['<xyz>', 'xyz']])
rr = re.compile('/')
assert(rr.split("foo/bar//baz") == ['foo', 'bar', '', 'baz'])
# compile to bytes
var rb
rb = re.compilebytes("a.*?b(z+)")
assert(re.search(rb, "zaaaabbbccbbzzzee") == ['aaaabbbccbbzzz', 'zzz'])
assert(rb == bytes('1B0000000F0000000100000062030260FB7E00016162030260FB01627E02017A62FC7E037E017F'))
rb = re.compilebytes('<([a-zA-Z]+)>')
assert(re.searchall(rb, '<abc> yeah <xyz>') == [['<abc>', 'abc'], ['<xyz>', 'xyz']])
assert(rb == bytes('1A0000000C0000000100000062030260FB7E00013C7E020302617A415A62F87E03013E7E017F'))
rb = re.compilebytes("a.*?b(z+)")
assert(re.match(rb, "aaaabbbccbbzzzee") == ['aaaabbbccbbzzz', 'zzz'])
assert(re.match2(rb, "aaaabbbccbbzzzee") == [14, 'zzz'])
assert(rb == bytes('1B0000000F0000000100000062030260FB7E00016162030260FB01627E02017A62FC7E037E017F'))
rb = re.compilebytes('<([a-zA-Z]+)>')
assert(re.matchall(rb, '<abc> yeah <xyz>') == [['<abc>', 'abc']])
assert(re.matchall(rb, '<abc><xyz>') == [['<abc>', 'abc'], ['<xyz>', 'xyz']])
assert(rb == bytes('1A0000000C0000000100000062030260FB7E00013C7E020302617A415A62F87E03013E7E017F'))
rb = re.compilebytes('/')
assert(re.split(rb, "foo/bar//baz") == ['foo', 'bar', '', 'baz'])
assert(rb == bytes('0C000000070000000000000062030260FB7E00012F7E017F'))

View File

@ -171,7 +171,7 @@ You need to register the ctype function handler at the launch of the Berry VM:
void berry_launch(boid) void berry_launch(boid)
{ {
bvm *vm = be_vm_new(); /* Construct a VM */ bvm *vm = be_vm_new(); /* Construct a VM */
be_set_ctype_func_hanlder(berry.vm, be_call_ctype_func); /* register the ctype function handler */ be_set_ctype_func_handler(berry.vm, be_call_ctype_func); /* register the ctype function handler */
} }
``` ```

View File

@ -27,26 +27,26 @@ static int call_berry_cb(int num, int v0, int v1, int v2, int v3, int v4);
#define BERRY_CB(n) int berry_cb_##n(int v0, int v1, int v2, int v3, int v4) { return call_berry_cb(n, v0, v1, v2, v3, v4); } #define BERRY_CB(n) int berry_cb_##n(int v0, int v1, int v2, int v3, int v4) { return call_berry_cb(n, v0, v1, v2, v3, v4); }
// list the callbacks // list the callbacks
BERRY_CB(0); BERRY_CB(0)
BERRY_CB(1); BERRY_CB(1)
BERRY_CB(2); BERRY_CB(2)
BERRY_CB(3); BERRY_CB(3)
BERRY_CB(4); BERRY_CB(4)
BERRY_CB(5); BERRY_CB(5)
BERRY_CB(6); BERRY_CB(6)
BERRY_CB(7); BERRY_CB(7)
BERRY_CB(8); BERRY_CB(8)
BERRY_CB(9); BERRY_CB(9)
BERRY_CB(10); BERRY_CB(10)
BERRY_CB(11); BERRY_CB(11)
BERRY_CB(12); BERRY_CB(12)
BERRY_CB(13); BERRY_CB(13)
BERRY_CB(14); BERRY_CB(14)
BERRY_CB(15); BERRY_CB(15)
BERRY_CB(16); BERRY_CB(16)
BERRY_CB(17); BERRY_CB(17)
BERRY_CB(18); BERRY_CB(18)
BERRY_CB(19); BERRY_CB(19)
// array of callbacks // array of callbacks
static const berry_callback_t berry_callback_array[BE_MAX_CB] = { static const berry_callback_t berry_callback_array[BE_MAX_CB] = {

View File

@ -87,9 +87,18 @@ matter.inspect = inspect
# #
# Build a consolidated map of all the `CLUSTERS` static vars # Build a consolidated map of all the `CLUSTERS` static vars
# from the inheritance hierarchy # from the inheritance hierarchy
#
# `cl` can be a the class to get the superclass, or a `map`
#@ solidify:matter.consolidate_clusters,weak #@ solidify:matter.consolidate_clusters,weak
def consolidate_clusters(cl, m) def consolidate_clusters(cl, m)
var cl_parent = (super(cl) != nil) ? super(cl).CLUSTERS : {} var cl_parent
if cl == nil
cl_parent = {}
elif type(cl) == 'class'
cl_parent = (super(cl) != nil) ? super(cl).CLUSTERS : {}
elif type(cl) == 'instance'
cl_parent = cl
end
var ret = {} var ret = {}
# clone cl_parent # clone cl_parent
for k: cl_parent.keys() for k: cl_parent.keys()

View File

@ -48,6 +48,7 @@ class Matter_Plugin
# `FEATURE_MAPS` contains any non-zero value per cluster, if not present default to `0` # `FEATURE_MAPS` contains any non-zero value per cluster, if not present default to `0`
static var FEATURE_MAPS = { # feature map per cluster static var FEATURE_MAPS = { # feature map per cluster
0x0031: 0x04, # Put Eth for now which should work for any on-network 0x0031: 0x04, # Put Eth for now which should work for any on-network
# 0x0046: 0x04, # LITS: LongIdleTimeSupport
0x0102: 1 + 4, # Lift + PA_LF 0x0102: 1 + 4, # Lift + PA_LF
0x0202: 2, # Fan: Auto 0x0202: 2, # Fan: Auto
} }
@ -77,6 +78,7 @@ class Matter_Plugin
# 0x0040: 1, # Initial Release # 0x0040: 1, # Initial Release
# 0x0041: 1, # Initial Release # 0x0041: 1, # Initial Release
# 0x0042: 1, # Initial Release # 0x0042: 1, # Initial Release
# 0x0046: 3, # ICD v3
# 0x005B: 1, # Initial Release # 0x005B: 1, # Initial Release
# 0x005C: 1, # Initial Release # 0x005C: 1, # Initial Release
0x0101: 7, # Added support for European door locks (unbolt feature) 0x0101: 7, # Added support for European door locks (unbolt feature)
@ -283,20 +285,20 @@ matter_device.events.dump()
return self.endpoint return self.endpoint
end end
def get_cluster_list_sorted() def get_cluster_list_sorted()
return self.device.k2l(self.CLUSTERS) return self.device.k2l(self.get_clusters())
end end
def contains_cluster(cluster) def contains_cluster(cluster)
return self.CLUSTERS.contains(cluster) return self.get_clusters().contains(cluster)
end end
# def get_attribute_list(cluster) # def get_attribute_list(cluster)
# return self.clusters.find(cluster, []) # return self.clusters.find(cluster, [])
# end # end
# returns as a constant bytes of 16-bit ints, big endian # returns as a constant bytes of 16-bit ints, big endian
def get_attribute_list_bytes(cluster) def get_attribute_list_bytes(cluster)
return self.CLUSTERS.find(cluster, nil) return self.get_clusters().find(cluster, nil)
end end
def contains_attribute(cluster, attribute) def contains_attribute(cluster, attribute)
var attr_list = self.CLUSTERS.find(cluster) var attr_list = self.get_clusters().find(cluster)
# log(f"MTR: contains_attribute {cluster=} {attribute=} {attr_list=}") # log(f"MTR: contains_attribute {cluster=} {attribute=} {attr_list=}")
if attr_list != nil if attr_list != nil
var idx = 0 var idx = 0

View File

@ -43,16 +43,42 @@ class Matter_Plugin_Root : Matter_Plugin
0x003E: [0,1,2,3,4,5], # Node Operational Credentials Cluster 11.17 p.704 0x003E: [0,1,2,3,4,5], # Node Operational Credentials Cluster 11.17 p.704
0x003F: [] # Group Key Management Cluster 11.2 p.572 0x003F: [] # Group Key Management Cluster 11.2 p.572
}) })
# static var CLUSTERS_ICD = matter.consolidate_clusters(_class.CLUSTERS, {
# 0x0046: [0,1,2] # ICD Management Cluster
# })
static var TYPES = { 0x0016: 1 } # Root node static var TYPES = { 0x0016: 1 } # Root node
# # ICD options
# var icd_idle, icd_active, icd_threshold
############################################################# #############################################################
# Constructor # Constructor
def init(device, endpoint, config) def init(device, endpoint, config)
super(self).init(device, endpoint, config) super(self).init(device, endpoint, config)
# # check if we have ICD parameters
# self.icd_idle = config.find("icd_idle", nil)
# if (self.icd_idle != nil)
# self.icd_active = config.find("icd_active", 5000) # default 5s
# self.icd_threshold = config.find("icd_threshold", 300) # default 300ms
# end
# publish mandatory events
self.publish_event(0x0028, 0x00, matter.EVENT_CRITICAL, matter.TLV.Matter_TLV_item().set(matter.TLV.U4, tasmota.version())) # Event StartUp - Software Version self.publish_event(0x0028, 0x00, matter.EVENT_CRITICAL, matter.TLV.Matter_TLV_item().set(matter.TLV.U4, tasmota.version())) # Event StartUp - Software Version
self.publish_event(0x0033, 0x03, matter.EVENT_CRITICAL, matter.TLV.Matter_TLV_item().set(matter.TLV.U1, 1)) # Event BootReason - PowerOnReboot - TODO if we need to refine self.publish_event(0x0033, 0x03, matter.EVENT_CRITICAL, matter.TLV.Matter_TLV_item().set(matter.TLV.U1, 1)) # Event BootReason - PowerOnReboot - TODO if we need to refine
end end
#############################################################
# consolidate_clusters
#
# Build a consolidated map of all the `CLUSTERS` static vars
# from the inheritance hierarchy
# def get_clusters()
# if (self.icd_idle == nil)
# return self.CLUSTERS
# else
# return self.CLUSTERS_ICD
# end
# end
############################################################# #############################################################
# read an attribute # read an attribute
# #
@ -323,6 +349,17 @@ class Matter_Plugin_Root : Matter_Plugin
return pl return pl
end end
# ====================================================================================================
# elif cluster == 0x0046 # ========== ICD Management Cluster ==========
# if attribute == 0x0000 # ---------- IdleModeDuration / uint32 (seconds) ----------
# return tlv_solo.set_or_nil(TLV.U4, self.icd_idle)
# elif attribute == 0x0001 # ---------- ActiveModeDuration / uint32 (milliseconds) ----------
# return tlv_solo.set_or_nil(TLV.U4, self.icd_active)
# elif attribute == 0x0002 # ---------- ActiveModeThreshold / uint16 (milliseconds) ----------
# return tlv_solo.set_or_nil(TLV.U2, self.icd_threshold)
# end
end end
return super(self).read_attribute(session, ctx, tlv_solo) return super(self).read_attribute(session, ctx, tlv_solo)
end end

View File

@ -40,7 +40,7 @@ class Matter_Autoconf
var plugins = self.device.plugins var plugins = self.device.plugins
# start with mandatory endpoint 0 for root node # start with mandatory endpoint 0 for root node
plugins.push(matter.Plugin_Root(self.device, 0, {})) plugins.push(matter.Plugin_Root(self.device, 0, config.find("0", {})))
log("MTR: Configuring endpoints", 2) log("MTR: Configuring endpoints", 2)
log(format("MTR: endpoint = %5i type:%s%s", 0, 'root', ''), 2) log(format("MTR: endpoint = %5i type:%s%s", 0, 'root', ''), 2)

View File

@ -110,18 +110,7 @@ class Matter_Commissioning
self.commissioning_L = L self.commissioning_L = L
self.commissioning_admin_fabric = admin_fabric self.commissioning_admin_fabric = admin_fabric
if tasmota.wifi()['up'] || tasmota.eth()['up'] tasmota.when_network_up(def () self.mdns_announce_PASE() end)
self.mdns_announce_PASE()
else
tasmota.add_rule("Wifi#Connected", def ()
self.mdns_announce_PASE()
tasmota.remove_rule("Wifi#Connected", "mdns_announce_PASE")
end, "mdns_announce_PASE")
tasmota.add_rule("Eth#Connected", def ()
self.mdns_announce_PASE()
tasmota.remove_rule("Eth#Connected", "mdns_announce_PASE")
end, "mdns_announce_PASE")
end
end end
############################################################# #############################################################
@ -236,23 +225,16 @@ class Matter_Commissioning
# When the announce is active, `hostname_wifi` and `hostname_eth` # When the announce is active, `hostname_wifi` and `hostname_eth`
# are defined # are defined
def start_mdns_announce_hostnames() def start_mdns_announce_hostnames()
if tasmota.wifi()['up'] tasmota.when_network_up(def ()
if tasmota.wifi('up')
self._mdns_announce_hostname(false) self._mdns_announce_hostname(false)
else end
tasmota.add_rule("Wifi#Connected", def () if tasmota.eth('up')
self._mdns_announce_hostname(false) self._mdns_announce_hostname(true)
tasmota.remove_rule("Wifi#Connected", "matter_mdns_host")
end, "matter_mdns_host")
end end
if tasmota.eth()['up'] end)
self._mdns_announce_hostname(true)
else
tasmota.add_rule("Eth#Connected", def ()
self._mdns_announce_hostname(true)
tasmota.remove_rule("Eth#Connected", "matter_mdns_host")
end, "matter_mdns_host")
end
end end
############################################################# #############################################################

View File

@ -27,7 +27,7 @@ class Matter_Device
static var PRODUCT_ID = 0x8000 static var PRODUCT_ID = 0x8000
static var FILENAME = "_matter_device.json" static var FILENAME = "_matter_device.json"
static var EP = 2 # first available endpoint number for devices static var EP = 2 # first available endpoint number for devices
var started # is the Matter Device started (configured, mDNS and UDPServer started) var started # is the Matter Device started (configured, mDNS and UDPServer started) - 'nil' means that we wait for Wifi to connect, 'false' means that the start is scheduled but not yet triggered
var plugins # list of plugins instances var plugins # list of plugins instances
var plugins_persist # true if plugins configuration needs to be saved var plugins_persist # true if plugins configuration needs to be saved
static var plugins_classes = matter.plugins_classes # map of registered classes by type name static var plugins_classes = matter.plugins_classes # map of registered classes by type name
@ -68,7 +68,6 @@ class Matter_Device
end # abort if SetOption 151 is not set end # abort if SetOption 151 is not set
matter.profiler = matter.Profiler() matter.profiler = matter.Profiler()
self.started = false
self.tick = 0 self.tick = 0
self.plugins = [] self.plugins = []
self.plugins_persist = false # plugins need to saved only when the first fabric is associated self.plugins_persist = false # plugins need to saved only when the first fabric is associated
@ -86,35 +85,22 @@ class Matter_Device
self.zigbee = self.init_zigbee() self.zigbee = self.init_zigbee()
self.ui = matter.UI(self, true) self.ui = matter.UI(self, true)
tasmota.when_network_up(def () self.start() end) # start when network is connected
self.commissioning.init_basic_commissioning() self.commissioning.init_basic_commissioning()
tasmota.add_driver(self) tasmota.add_driver(self)
self.register_commands() self.register_commands()
end end
#############################################################
# Check if the network just started
def check_network()
if self.started return end # abort if already started
if tasmota.wifi()['up'] || tasmota.eth()['up']
self.start()
end
end
############################################################# #############################################################
# Start Matter device server when the first network is coming up # Start Matter device server when the first network is coming up
def start() def start()
if self.started return end # abort if already started
# autoconfigure other plugins if needed # autoconfigure other plugins if needed
self.autoconf_device() self.autoconf_device()
self._start_udp(self.UDP_PORT) self._start_udp(self.UDP_PORT)
self.commissioning.start_mdns_announce_hostnames() self.commissioning.start_mdns_announce_hostnames()
self.started = true
end end
##################################################################### #####################################################################
@ -251,7 +237,6 @@ class Matter_Device
# dispatch every 50ms # dispatch every 50ms
# ticks # ticks
def every_50ms() def every_50ms()
self.check_network()
self.tick += 1 self.tick += 1
self.message_handler.every_50ms() self.message_handler.every_50ms()
end end
@ -747,11 +732,7 @@ class Matter_Device
var keys = [] var keys = []
for k: self.plugins_config.keys() keys.push(int(k)) end for k: self.plugins_config.keys() keys.push(int(k)) end
for ep: keys for ep: keys
if ep == 0 if ep == matter.AGGREGATOR_ENDPOINT
log("MTR: invalid entry with ep '0'", 2)
self.plugins_config.remove(str(ep))
dirty = true
elif ep == matter.AGGREGATOR_ENDPOINT
dirty = true dirty = true
log(f"MTR: endpoint {ep} collides wit aggregator, relocating to {self.next_ep}", 2) log(f"MTR: endpoint {ep} collides wit aggregator, relocating to {self.next_ep}", 2)
self.plugins_config[str(self.next_ep)] = self.plugins_config[str(ep)] self.plugins_config[str(self.next_ep)] = self.plugins_config[str(ep)]

View File

@ -257,204 +257,227 @@ be_local_closure(module_matter_consolidate_clusters, /* name */
0, /* has sup protos */ 0, /* has sup protos */
NULL, /* no sub protos */ NULL, /* no sub protos */
1, /* has constants */ 1, /* has constants */
( &(const bvalue[13]) { /* constants */ ( &(const bvalue[15]) { /* constants */
/* K0 */ be_nested_str_weak(CLUSTERS), /* K0 */ be_nested_str_weak(class),
/* K1 */ be_nested_str_weak(keys), /* K1 */ be_nested_str_weak(CLUSTERS),
/* K2 */ be_const_int(2), /* K2 */ be_nested_str_weak(instance),
/* K3 */ be_const_int(0), /* K3 */ be_nested_str_weak(keys),
/* K4 */ be_nested_str_weak(push), /* K4 */ be_const_int(2),
/* K5 */ be_nested_str_weak(get), /* K5 */ be_const_int(0),
/* K6 */ be_const_int(1), /* K6 */ be_nested_str_weak(push),
/* K7 */ be_nested_str_weak(stop_iteration), /* K7 */ be_nested_str_weak(get),
/* K8 */ be_nested_str_weak(contains), /* K8 */ be_const_int(1),
/* K9 */ be_nested_str_weak(find), /* K9 */ be_nested_str_weak(stop_iteration),
/* K10 */ be_nested_str_weak(matter), /* K10 */ be_nested_str_weak(contains),
/* K11 */ be_nested_str_weak(sort), /* K11 */ be_nested_str_weak(find),
/* K12 */ be_nested_str_weak(add), /* K12 */ be_nested_str_weak(matter),
/* K13 */ be_nested_str_weak(sort),
/* K14 */ be_nested_str_weak(add),
}), }),
be_str_weak(consolidate_clusters), be_str_weak(consolidate_clusters),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[180]) { /* code */ ( &(const binstruction[201]) { /* code */
0x60080003, // 0000 GETGBL R2 G3 0x4C080000, // 0000 LDNIL R2
0x5C0C0000, // 0001 MOVE R3 R0 0x4C0C0000, // 0001 LDNIL R3
0x7C080200, // 0002 CALL R2 1 0x1C0C0003, // 0002 EQ R3 R0 R3
0x4C0C0000, // 0003 LDNIL R3 0x780E0003, // 0003 JMPF R3 #0008
0x20080403, // 0004 NE R2 R2 R3 0x600C0013, // 0004 GETGBL R3 G19
0x780A0004, // 0005 JMPF R2 #000B 0x7C0C0000, // 0005 CALL R3 0
0x60080003, // 0006 GETGBL R2 G3 0x5C080600, // 0006 MOVE R2 R3
0x5C0C0000, // 0007 MOVE R3 R0 0x70020019, // 0007 JMP #0022
0x7C080200, // 0008 CALL R2 1 0x600C0004, // 0008 GETGBL R3 G4
0x88080500, // 0009 GETMBR R2 R2 K0 0x5C100000, // 0009 MOVE R4 R0
0x70020001, // 000A JMP #000D 0x7C0C0200, // 000A CALL R3 1
0x60080013, // 000B GETGBL R2 G19 0x1C0C0700, // 000B EQ R3 R3 K0
0x7C080000, // 000C CALL R2 0 0x780E000E, // 000C JMPF R3 #001C
0x600C0013, // 000D GETGBL R3 G19 0x600C0003, // 000D GETGBL R3 G3
0x7C0C0000, // 000E CALL R3 0 0x5C100000, // 000E MOVE R4 R0
0x60100010, // 000F GETGBL R4 G16 0x7C0C0200, // 000F CALL R3 1
0x8C140501, // 0010 GETMET R5 R2 K1 0x4C100000, // 0010 LDNIL R4
0x7C140200, // 0011 CALL R5 1 0x200C0604, // 0011 NE R3 R3 R4
0x7C100200, // 0012 CALL R4 1 0x780E0004, // 0012 JMPF R3 #0018
0xA802001A, // 0013 EXBLK 0 #002F 0x600C0003, // 0013 GETGBL R3 G3
0x5C140800, // 0014 MOVE R5 R4 0x5C100000, // 0014 MOVE R4 R0
0x7C140000, // 0015 CALL R5 0 0x7C0C0200, // 0015 CALL R3 1
0x60180012, // 0016 GETGBL R6 G18 0x880C0701, // 0016 GETMBR R3 R3 K1
0x7C180000, // 0017 CALL R6 0 0x70020001, // 0017 JMP #001A
0x941C0405, // 0018 GETIDX R7 R2 R5 0x600C0013, // 0018 GETGBL R3 G19
0x4C200000, // 0019 LDNIL R8 0x7C0C0000, // 0019 CALL R3 0
0x20200E08, // 001A NE R8 R7 R8 0x5C080600, // 001A MOVE R2 R3
0x78220004, // 001B JMPF R8 #0021 0x70020005, // 001B JMP #0022
0x6020000C, // 001C GETGBL R8 G12 0x600C0004, // 001C GETGBL R3 G4
0x5C240E00, // 001D MOVE R9 R7 0x5C100000, // 001D MOVE R4 R0
0x7C200200, // 001E CALL R8 1 0x7C0C0200, // 001E CALL R3 1
0x0C201102, // 001F DIV R8 R8 K2 0x1C0C0702, // 001F EQ R3 R3 K2
0x70020000, // 0020 JMP #0022 0x780E0000, // 0020 JMPF R3 #0022
0x58200003, // 0021 LDCONST R8 K3 0x5C080000, // 0021 MOVE R2 R0
0x58240003, // 0022 LDCONST R9 K3 0x600C0013, // 0022 GETGBL R3 G19
0x14281208, // 0023 LT R10 R9 R8 0x7C0C0000, // 0023 CALL R3 0
0x782A0007, // 0024 JMPF R10 #002D 0x60100010, // 0024 GETGBL R4 G16
0x8C280D04, // 0025 GETMET R10 R6 K4 0x8C140503, // 0025 GETMET R5 R2 K3
0x8C300F05, // 0026 GETMET R12 R7 K5 0x7C140200, // 0026 CALL R5 1
0x08381302, // 0027 MUL R14 R9 K2 0x7C100200, // 0027 CALL R4 1
0x543DFFFD, // 0028 LDINT R15 -2 0xA802001A, // 0028 EXBLK 0 #0044
0x7C300600, // 0029 CALL R12 3 0x5C140800, // 0029 MOVE R5 R4
0x7C280400, // 002A CALL R10 2 0x7C140000, // 002A CALL R5 0
0x00241306, // 002B ADD R9 R9 K6 0x60180012, // 002B GETGBL R6 G18
0x7001FFF5, // 002C JMP #0023 0x7C180000, // 002C CALL R6 0
0x980C0A06, // 002D SETIDX R3 R5 R6 0x941C0405, // 002D GETIDX R7 R2 R5
0x7001FFE4, // 002E JMP #0014 0x4C200000, // 002E LDNIL R8
0x58100007, // 002F LDCONST R4 K7 0x20200E08, // 002F NE R8 R7 R8
0xAC100200, // 0030 CATCH R4 1 0 0x78220004, // 0030 JMPF R8 #0036
0xB0080000, // 0031 RAISE 2 R0 R0 0x6020000C, // 0031 GETGBL R8 G12
0x60100010, // 0032 GETGBL R4 G16 0x5C240E00, // 0032 MOVE R9 R7
0x8C140301, // 0033 GETMET R5 R1 K1 0x7C200200, // 0033 CALL R8 1
0x7C140200, // 0034 CALL R5 1 0x0C201104, // 0034 DIV R8 R8 K4
0x7C100200, // 0035 CALL R4 1 0x70020000, // 0035 JMP #0037
0xA802001E, // 0036 EXBLK 0 #0056 0x58200005, // 0036 LDCONST R8 K5
0x5C140800, // 0037 MOVE R5 R4 0x58240005, // 0037 LDCONST R9 K5
0x7C140000, // 0038 CALL R5 0 0x14281208, // 0038 LT R10 R9 R8
0x8C180708, // 0039 GETMET R6 R3 K8 0x782A0007, // 0039 JMPF R10 #0042
0x5C200A00, // 003A MOVE R8 R5 0x8C280D06, // 003A GETMET R10 R6 K6
0x7C180400, // 003B CALL R6 2 0x8C300F07, // 003B GETMET R12 R7 K7
0x741A0002, // 003C JMPT R6 #0040 0x08381304, // 003C MUL R14 R9 K4
0x60180012, // 003D GETGBL R6 G18 0x543DFFFD, // 003D LDINT R15 -2
0x7C180000, // 003E CALL R6 0 0x7C300600, // 003E CALL R12 3
0x980C0A06, // 003F SETIDX R3 R5 R6 0x7C280400, // 003F CALL R10 2
0x60180010, // 0040 GETGBL R6 G16 0x00241308, // 0040 ADD R9 R9 K8
0x941C0205, // 0041 GETIDX R7 R1 R5 0x7001FFF5, // 0041 JMP #0038
0x7C180200, // 0042 CALL R6 1 0x980C0A06, // 0042 SETIDX R3 R5 R6
0xA802000D, // 0043 EXBLK 0 #0052 0x7001FFE4, // 0043 JMP #0029
0x5C1C0C00, // 0044 MOVE R7 R6 0x58100009, // 0044 LDCONST R4 K9
0x7C1C0000, // 0045 CALL R7 0 0xAC100200, // 0045 CATCH R4 1 0
0x94200605, // 0046 GETIDX R8 R3 R5 0xB0080000, // 0046 RAISE 2 R0 R0
0x8C201109, // 0047 GETMET R8 R8 K9 0x60100010, // 0047 GETGBL R4 G16
0x5C280E00, // 0048 MOVE R10 R7 0x8C140303, // 0048 GETMET R5 R1 K3
0x7C200400, // 0049 CALL R8 2 0x7C140200, // 0049 CALL R5 1
0x4C240000, // 004A LDNIL R9 0x7C100200, // 004A CALL R4 1
0x1C201009, // 004B EQ R8 R8 R9 0xA802001E, // 004B EXBLK 0 #006B
0x78220003, // 004C JMPF R8 #0051 0x5C140800, // 004C MOVE R5 R4
0x94200605, // 004D GETIDX R8 R3 R5 0x7C140000, // 004D CALL R5 0
0x8C201104, // 004E GETMET R8 R8 K4 0x8C18070A, // 004E GETMET R6 R3 K10
0x5C280E00, // 004F MOVE R10 R7 0x5C200A00, // 004F MOVE R8 R5
0x7C200400, // 0050 CALL R8 2 0x7C180400, // 0050 CALL R6 2
0x7001FFF1, // 0051 JMP #0044 0x741A0002, // 0051 JMPT R6 #0055
0x58180007, // 0052 LDCONST R6 K7 0x60180012, // 0052 GETGBL R6 G18
0xAC180200, // 0053 CATCH R6 1 0 0x7C180000, // 0053 CALL R6 0
0xB0080000, // 0054 RAISE 2 R0 R0 0x980C0A06, // 0054 SETIDX R3 R5 R6
0x7001FFE0, // 0055 JMP #0037 0x60180010, // 0055 GETGBL R6 G16
0x58100007, // 0056 LDCONST R4 K7 0x941C0205, // 0056 GETIDX R7 R1 R5
0xAC100200, // 0057 CATCH R4 1 0 0x7C180200, // 0057 CALL R6 1
0xB0080000, // 0058 RAISE 2 R0 R0 0xA802000D, // 0058 EXBLK 0 #0067
0x60100012, // 0059 GETGBL R4 G18 0x5C1C0C00, // 0059 MOVE R7 R6
0x7C100000, // 005A CALL R4 0 0x7C1C0000, // 005A CALL R7 0
0x5416FFF7, // 005B LDINT R5 65528 0x94200605, // 005B GETIDX R8 R3 R5
0x40140805, // 005C CONNECT R5 R4 R5 0x8C20110B, // 005C GETMET R8 R8 K11
0x5416FFF8, // 005D LDINT R5 65529 0x5C280E00, // 005D MOVE R10 R7
0x40140805, // 005E CONNECT R5 R4 R5 0x7C200400, // 005E CALL R8 2
0x5416FFF9, // 005F LDINT R5 65530 0x4C240000, // 005F LDNIL R9
0x40140805, // 0060 CONNECT R5 R4 R5 0x1C201009, // 0060 EQ R8 R8 R9
0x5416FFFA, // 0061 LDINT R5 65531 0x78220003, // 0061 JMPF R8 #0066
0x40140805, // 0062 CONNECT R5 R4 R5 0x94200605, // 0062 GETIDX R8 R3 R5
0x5416FFFB, // 0063 LDINT R5 65532 0x8C201106, // 0063 GETMET R8 R8 K6
0x40140805, // 0064 CONNECT R5 R4 R5 0x5C280E00, // 0064 MOVE R10 R7
0x5416FFFC, // 0065 LDINT R5 65533 0x7C200400, // 0065 CALL R8 2
0x40140805, // 0066 CONNECT R5 R4 R5 0x7001FFF1, // 0066 JMP #0059
0x60140010, // 0067 GETGBL R5 G16 0x58180009, // 0067 LDCONST R6 K9
0x8C180301, // 0068 GETMET R6 R1 K1 0xAC180200, // 0068 CATCH R6 1 0
0x7C180200, // 0069 CALL R6 1 0xB0080000, // 0069 RAISE 2 R0 R0
0x7C140200, // 006A CALL R5 1 0x7001FFE0, // 006A JMP #004C
0xA8020017, // 006B EXBLK 0 #0084 0x58100009, // 006B LDCONST R4 K9
0x5C180A00, // 006C MOVE R6 R5 0xAC100200, // 006C CATCH R4 1 0
0x7C180000, // 006D CALL R6 0 0xB0080000, // 006D RAISE 2 R0 R0
0x601C0010, // 006E GETGBL R7 G16 0x60100012, // 006E GETGBL R4 G18
0x5C200800, // 006F MOVE R8 R4 0x7C100000, // 006F CALL R4 0
0x7C1C0200, // 0070 CALL R7 1 0x5416FFF7, // 0070 LDINT R5 65528
0xA802000D, // 0071 EXBLK 0 #0080 0x40140805, // 0071 CONNECT R5 R4 R5
0x5C200E00, // 0072 MOVE R8 R7 0x5416FFF8, // 0072 LDINT R5 65529
0x7C200000, // 0073 CALL R8 0 0x40140805, // 0073 CONNECT R5 R4 R5
0x94240606, // 0074 GETIDX R9 R3 R6 0x5416FFF9, // 0074 LDINT R5 65530
0x8C241309, // 0075 GETMET R9 R9 K9 0x40140805, // 0075 CONNECT R5 R4 R5
0x5C2C1000, // 0076 MOVE R11 R8 0x5416FFFA, // 0076 LDINT R5 65531
0x7C240400, // 0077 CALL R9 2 0x40140805, // 0077 CONNECT R5 R4 R5
0x4C280000, // 0078 LDNIL R10 0x5416FFFB, // 0078 LDINT R5 65532
0x1C24120A, // 0079 EQ R9 R9 R10 0x40140805, // 0079 CONNECT R5 R4 R5
0x78260003, // 007A JMPF R9 #007F 0x5416FFFC, // 007A LDINT R5 65533
0x94240606, // 007B GETIDX R9 R3 R6 0x40140805, // 007B CONNECT R5 R4 R5
0x8C241304, // 007C GETMET R9 R9 K4 0x60140010, // 007C GETGBL R5 G16
0x5C2C1000, // 007D MOVE R11 R8 0x8C180303, // 007D GETMET R6 R1 K3
0x7C240400, // 007E CALL R9 2 0x7C180200, // 007E CALL R6 1
0x7001FFF1, // 007F JMP #0072 0x7C140200, // 007F CALL R5 1
0x581C0007, // 0080 LDCONST R7 K7 0xA8020017, // 0080 EXBLK 0 #0099
0xAC1C0200, // 0081 CATCH R7 1 0 0x5C180A00, // 0081 MOVE R6 R5
0xB0080000, // 0082 RAISE 2 R0 R0 0x7C180000, // 0082 CALL R6 0
0x7001FFE7, // 0083 JMP #006C 0x601C0010, // 0083 GETGBL R7 G16
0x58140007, // 0084 LDCONST R5 K7 0x5C200800, // 0084 MOVE R8 R4
0xAC140200, // 0085 CATCH R5 1 0 0x7C1C0200, // 0085 CALL R7 1
0xB0080000, // 0086 RAISE 2 R0 R0 0xA802000D, // 0086 EXBLK 0 #0095
0x60140010, // 0087 GETGBL R5 G16 0x5C200E00, // 0087 MOVE R8 R7
0x8C180701, // 0088 GETMET R6 R3 K1 0x7C200000, // 0088 CALL R8 0
0x7C180200, // 0089 CALL R6 1 0x94240606, // 0089 GETIDX R9 R3 R6
0x7C140200, // 008A CALL R5 1 0x8C24130B, // 008A GETMET R9 R9 K11
0xA8020008, // 008B EXBLK 0 #0095 0x5C2C1000, // 008B MOVE R11 R8
0x5C180A00, // 008C MOVE R6 R5 0x7C240400, // 008C CALL R9 2
0x7C180000, // 008D CALL R6 0 0x4C280000, // 008D LDNIL R10
0x941C0606, // 008E GETIDX R7 R3 R6 0x1C24120A, // 008E EQ R9 R9 R10
0xB8221400, // 008F GETNGBL R8 K10 0x78260003, // 008F JMPF R9 #0094
0x8C20110B, // 0090 GETMET R8 R8 K11 0x94240606, // 0090 GETIDX R9 R3 R6
0x5C280E00, // 0091 MOVE R10 R7 0x8C241306, // 0091 GETMET R9 R9 K6
0x7C200400, // 0092 CALL R8 2 0x5C2C1000, // 0092 MOVE R11 R8
0x980C0C08, // 0093 SETIDX R3 R6 R8 0x7C240400, // 0093 CALL R9 2
0x7001FFF6, // 0094 JMP #008C 0x7001FFF1, // 0094 JMP #0087
0x58140007, // 0095 LDCONST R5 K7 0x581C0009, // 0095 LDCONST R7 K9
0xAC140200, // 0096 CATCH R5 1 0 0xAC1C0200, // 0096 CATCH R7 1 0
0xB0080000, // 0097 RAISE 2 R0 R0 0xB0080000, // 0097 RAISE 2 R0 R0
0x60140010, // 0098 GETGBL R5 G16 0x7001FFE7, // 0098 JMP #0081
0x8C180701, // 0099 GETMET R6 R3 K1 0x58140009, // 0099 LDCONST R5 K9
0x7C180200, // 009A CALL R6 1 0xAC140200, // 009A CATCH R5 1 0
0x7C140200, // 009B CALL R5 1 0xB0080000, // 009B RAISE 2 R0 R0
0xA8020012, // 009C EXBLK 0 #00B0 0x60140010, // 009C GETGBL R5 G16
0x5C180A00, // 009D MOVE R6 R5 0x8C180703, // 009D GETMET R6 R3 K3
0x7C180000, // 009E CALL R6 0 0x7C180200, // 009E CALL R6 1
0x941C0606, // 009F GETIDX R7 R3 R6 0x7C140200, // 009F CALL R5 1
0x60200015, // 00A0 GETGBL R8 G21 0xA8020008, // 00A0 EXBLK 0 #00AA
0x7C200000, // 00A1 CALL R8 0 0x5C180A00, // 00A1 MOVE R6 R5
0x58240003, // 00A2 LDCONST R9 K3 0x7C180000, // 00A2 CALL R6 0
0x6028000C, // 00A3 GETGBL R10 G12 0x941C0606, // 00A3 GETIDX R7 R3 R6
0x5C2C0E00, // 00A4 MOVE R11 R7 0xB8221800, // 00A4 GETNGBL R8 K12
0x7C280200, // 00A5 CALL R10 1 0x8C20110D, // 00A5 GETMET R8 R8 K13
0x1428120A, // 00A6 LT R10 R9 R10 0x5C280E00, // 00A6 MOVE R10 R7
0x782A0005, // 00A7 JMPF R10 #00AE 0x7C200400, // 00A7 CALL R8 2
0x8C28110C, // 00A8 GETMET R10 R8 K12 0x980C0C08, // 00A8 SETIDX R3 R6 R8
0x94300E09, // 00A9 GETIDX R12 R7 R9 0x7001FFF6, // 00A9 JMP #00A1
0x5435FFFD, // 00AA LDINT R13 -2 0x58140009, // 00AA LDCONST R5 K9
0x7C280600, // 00AB CALL R10 3 0xAC140200, // 00AB CATCH R5 1 0
0x00241306, // 00AC ADD R9 R9 K6 0xB0080000, // 00AC RAISE 2 R0 R0
0x7001FFF4, // 00AD JMP #00A3 0x60140010, // 00AD GETGBL R5 G16
0x980C0C08, // 00AE SETIDX R3 R6 R8 0x8C180703, // 00AE GETMET R6 R3 K3
0x7001FFEC, // 00AF JMP #009D 0x7C180200, // 00AF CALL R6 1
0x58140007, // 00B0 LDCONST R5 K7 0x7C140200, // 00B0 CALL R5 1
0xAC140200, // 00B1 CATCH R5 1 0 0xA8020012, // 00B1 EXBLK 0 #00C5
0xB0080000, // 00B2 RAISE 2 R0 R0 0x5C180A00, // 00B2 MOVE R6 R5
0x80040600, // 00B3 RET 1 R3 0x7C180000, // 00B3 CALL R6 0
0x941C0606, // 00B4 GETIDX R7 R3 R6
0x60200015, // 00B5 GETGBL R8 G21
0x7C200000, // 00B6 CALL R8 0
0x58240005, // 00B7 LDCONST R9 K5
0x6028000C, // 00B8 GETGBL R10 G12
0x5C2C0E00, // 00B9 MOVE R11 R7
0x7C280200, // 00BA CALL R10 1
0x1428120A, // 00BB LT R10 R9 R10
0x782A0005, // 00BC JMPF R10 #00C3
0x8C28110E, // 00BD GETMET R10 R8 K14
0x94300E09, // 00BE GETIDX R12 R7 R9
0x5435FFFD, // 00BF LDINT R13 -2
0x7C280600, // 00C0 CALL R10 3
0x00241308, // 00C1 ADD R9 R9 K8
0x7001FFF4, // 00C2 JMP #00B8
0x980C0C08, // 00C3 SETIDX R3 R6 R8
0x7001FFEC, // 00C4 JMP #00B2
0x58140009, // 00C5 LDCONST R5 K9
0xAC140200, // 00C6 CATCH R5 1 0
0xB0080000, // 00C7 RAISE 2 R0 R0
0x80040600, // 00C8 RET 1 R3
}) })
) )
); );

View File

@ -4,8 +4,8 @@
\********************************************************************/ \********************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
extern const bclass be_class_Matter_Plugin; extern const bclass be_class_Matter_Plugin;
// compact class 'Matter_Plugin' ktab size: 65, total: 108 (saved 344 bytes) // compact class 'Matter_Plugin' ktab size: 66, total: 108 (saved 336 bytes)
static const bvalue be_ktab_class_Matter_Plugin[65] = { static const bvalue be_ktab_class_Matter_Plugin[66] = {
/* K0 */ be_nested_str_weak(json), /* K0 */ be_nested_str_weak(json),
/* K1 */ be_nested_str_weak(node_label), /* K1 */ be_nested_str_weak(node_label),
/* K2 */ be_nested_str_weak(_X2C_X22Name_X22_X3A_X25s), /* K2 */ be_nested_str_weak(_X2C_X22Name_X22_X3A_X25s),
@ -21,7 +21,7 @@ static const bvalue be_ktab_class_Matter_Plugin[65] = {
/* K12 */ be_nested_str_weak(message_handler), /* K12 */ be_nested_str_weak(message_handler),
/* K13 */ be_nested_str_weak(im), /* K13 */ be_nested_str_weak(im),
/* K14 */ be_nested_str_weak(send_ack_now), /* K14 */ be_nested_str_weak(send_ack_now),
/* K15 */ be_nested_str_weak(CLUSTERS), /* K15 */ be_nested_str_weak(get_clusters),
/* K16 */ be_nested_str_weak(find), /* K16 */ be_nested_str_weak(find),
/* K17 */ be_nested_str_weak(attribute_updated), /* K17 */ be_nested_str_weak(attribute_updated),
/* K18 */ be_nested_str_weak(update_next), /* K18 */ be_nested_str_weak(update_next),
@ -53,24 +53,25 @@ static const bvalue be_ktab_class_Matter_Plugin[65] = {
/* K44 */ be_nested_str_weak(_X25s_X2C_X25s_X3A_X25s), /* K44 */ be_nested_str_weak(_X25s_X2C_X25s_X3A_X25s),
/* K45 */ be_nested_str_weak(publish_command), /* K45 */ be_nested_str_weak(publish_command),
/* K46 */ be_nested_str_weak(MtrReceived), /* K46 */ be_nested_str_weak(MtrReceived),
/* K47 */ be_nested_str_weak(contains), /* K47 */ be_nested_str_weak(CLUSTERS),
/* K48 */ be_nested_str_weak(TLV), /* K48 */ be_nested_str_weak(contains),
/* K49 */ be_nested_str_weak(cluster), /* K49 */ be_nested_str_weak(TLV),
/* K50 */ be_nested_str_weak(attribute), /* K50 */ be_nested_str_weak(cluster),
/* K51 */ be_nested_str_weak(Matter_TLV_array), /* K51 */ be_nested_str_weak(attribute),
/* K52 */ be_nested_str_weak(TYPES), /* K52 */ be_nested_str_weak(Matter_TLV_array),
/* K53 */ be_nested_str_weak(keys), /* K53 */ be_nested_str_weak(TYPES),
/* K54 */ be_nested_str_weak(add_struct), /* K54 */ be_nested_str_weak(keys),
/* K55 */ be_nested_str_weak(add_TLV), /* K55 */ be_nested_str_weak(add_struct),
/* K56 */ be_nested_str_weak(U2), /* K56 */ be_nested_str_weak(add_TLV),
/* K57 */ be_nested_str_weak(stop_iteration), /* K57 */ be_nested_str_weak(U2),
/* K58 */ be_nested_str_weak(get_cluster_list_sorted), /* K58 */ be_nested_str_weak(stop_iteration),
/* K59 */ be_nested_str_weak(U4), /* K59 */ be_nested_str_weak(get_cluster_list_sorted),
/* K60 */ be_const_int(3), /* K60 */ be_nested_str_weak(U4),
/* K61 */ be_nested_str_weak(set), /* K61 */ be_const_int(3),
/* K62 */ be_nested_str_weak(get_attribute_list_bytes), /* K62 */ be_nested_str_weak(set),
/* K63 */ be_nested_str_weak(FEATURE_MAPS), /* K63 */ be_nested_str_weak(get_attribute_list_bytes),
/* K64 */ be_nested_str_weak(CLUSTER_REVISIONS), /* K64 */ be_nested_str_weak(FEATURE_MAPS),
/* K65 */ be_nested_str_weak(CLUSTER_REVISIONS),
}; };
@ -210,13 +211,14 @@ be_local_closure(class_Matter_Plugin_get_attribute_list_bytes, /* name */
&be_ktab_class_Matter_Plugin, /* shared constants */ &be_ktab_class_Matter_Plugin, /* shared constants */
be_str_weak(get_attribute_list_bytes), be_str_weak(get_attribute_list_bytes),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[ 6]) { /* code */ ( &(const binstruction[ 7]) { /* code */
0x8808010F, // 0000 GETMBR R2 R0 K15 0x8C08010F, // 0000 GETMET R2 R0 K15
0x8C080510, // 0001 GETMET R2 R2 K16 0x7C080200, // 0001 CALL R2 1
0x5C100200, // 0002 MOVE R4 R1 0x8C080510, // 0002 GETMET R2 R2 K16
0x4C140000, // 0003 LDNIL R5 0x5C100200, // 0003 MOVE R4 R1
0x7C080600, // 0004 CALL R2 3 0x4C140000, // 0004 LDNIL R5
0x80040400, // 0005 RET 1 R2 0x7C080600, // 0005 CALL R2 3
0x80040400, // 0006 RET 1 R2
}) })
) )
); );
@ -612,7 +614,7 @@ be_local_closure(class_Matter_Plugin_consolidate_update_commands, /* name */
********************************************************************/ ********************************************************************/
be_local_closure(class_Matter_Plugin_get_cluster_list_sorted, /* name */ be_local_closure(class_Matter_Plugin_get_cluster_list_sorted, /* name */
be_nested_proto( be_nested_proto(
4, /* nstack */ 5, /* nstack */
1, /* argc */ 1, /* argc */
10, /* varg */ 10, /* varg */
0, /* has upvals */ 0, /* has upvals */
@ -623,12 +625,13 @@ be_local_closure(class_Matter_Plugin_get_cluster_list_sorted, /* name */
&be_ktab_class_Matter_Plugin, /* shared constants */ &be_ktab_class_Matter_Plugin, /* shared constants */
be_str_weak(get_cluster_list_sorted), be_str_weak(get_cluster_list_sorted),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[ 5]) { /* code */ ( &(const binstruction[ 6]) { /* code */
0x88040109, // 0000 GETMBR R1 R0 K9 0x88040109, // 0000 GETMBR R1 R0 K9
0x8C040320, // 0001 GETMET R1 R1 K32 0x8C040320, // 0001 GETMET R1 R1 K32
0x880C010F, // 0002 GETMBR R3 R0 K15 0x8C0C010F, // 0002 GETMET R3 R0 K15
0x7C040400, // 0003 CALL R1 2 0x7C0C0200, // 0003 CALL R3 1
0x80040200, // 0004 RET 1 R1 0x7C040400, // 0004 CALL R1 2
0x80040200, // 0005 RET 1 R1
}) })
) )
); );
@ -820,33 +823,34 @@ be_local_closure(class_Matter_Plugin_contains_attribute, /* name */
&be_ktab_class_Matter_Plugin, /* shared constants */ &be_ktab_class_Matter_Plugin, /* shared constants */
be_str_weak(contains_attribute), be_str_weak(contains_attribute),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[26]) { /* code */ ( &(const binstruction[27]) { /* code */
0x880C010F, // 0000 GETMBR R3 R0 K15 0x8C0C010F, // 0000 GETMET R3 R0 K15
0x8C0C0710, // 0001 GETMET R3 R3 K16 0x7C0C0200, // 0001 CALL R3 1
0x5C140200, // 0002 MOVE R5 R1 0x8C0C0710, // 0002 GETMET R3 R3 K16
0x7C0C0400, // 0003 CALL R3 2 0x5C140200, // 0003 MOVE R5 R1
0x4C100000, // 0004 LDNIL R4 0x7C0C0400, // 0004 CALL R3 2
0x20100604, // 0005 NE R4 R3 R4 0x4C100000, // 0005 LDNIL R4
0x78120010, // 0006 JMPF R4 #0018 0x20100604, // 0006 NE R4 R3 R4
0x58100023, // 0007 LDCONST R4 K35 0x78120010, // 0007 JMPF R4 #0019
0x6014000C, // 0008 GETGBL R5 G12 0x58100023, // 0008 LDCONST R4 K35
0x5C180600, // 0009 MOVE R6 R3 0x6014000C, // 0009 GETGBL R5 G12
0x7C140200, // 000A CALL R5 1 0x5C180600, // 000A MOVE R6 R3
0x0C140B24, // 000B DIV R5 R5 K36 0x7C140200, // 000B CALL R5 1
0x14180805, // 000C LT R6 R4 R5 0x0C140B24, // 000C DIV R5 R5 K36
0x781A0009, // 000D JMPF R6 #0018 0x14180805, // 000D LT R6 R4 R5
0x8C180725, // 000E GETMET R6 R3 K37 0x781A0009, // 000E JMPF R6 #0019
0x08200924, // 000F MUL R8 R4 K36 0x8C180725, // 000F GETMET R6 R3 K37
0x5425FFFD, // 0010 LDINT R9 -2 0x08200924, // 0010 MUL R8 R4 K36
0x7C180600, // 0011 CALL R6 3 0x5425FFFD, // 0011 LDINT R9 -2
0x1C180C02, // 0012 EQ R6 R6 R2 0x7C180600, // 0012 CALL R6 3
0x781A0001, // 0013 JMPF R6 #0016 0x1C180C02, // 0013 EQ R6 R6 R2
0x50180200, // 0014 LDBOOL R6 1 0 0x781A0001, // 0014 JMPF R6 #0017
0x80040C00, // 0015 RET 1 R6 0x50180200, // 0015 LDBOOL R6 1 0
0x00100926, // 0016 ADD R4 R4 K38 0x80040C00, // 0016 RET 1 R6
0x7001FFF3, // 0017 JMP #000C 0x00100926, // 0017 ADD R4 R4 K38
0x50100000, // 0018 LDBOOL R4 0 0 0x7001FFF3, // 0018 JMP #000D
0x80040800, // 0019 RET 1 R4 0x50100000, // 0019 LDBOOL R4 0 0
0x80040800, // 001A RET 1 R4
}) })
) )
); );
@ -1086,7 +1090,7 @@ be_local_closure(class_Matter_Plugin_get_clusters, /* name */
be_str_weak(get_clusters), be_str_weak(get_clusters),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */ ( &(const binstruction[ 2]) { /* code */
0x8804010F, // 0000 GETMBR R1 R0 K15 0x8804012F, // 0000 GETMBR R1 R0 K47
0x80040200, // 0001 RET 1 R1 0x80040200, // 0001 RET 1 R1
}) })
) )
@ -1110,12 +1114,13 @@ be_local_closure(class_Matter_Plugin_contains_cluster, /* name */
&be_ktab_class_Matter_Plugin, /* shared constants */ &be_ktab_class_Matter_Plugin, /* shared constants */
be_str_weak(contains_cluster), be_str_weak(contains_cluster),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[ 5]) { /* code */ ( &(const binstruction[ 6]) { /* code */
0x8808010F, // 0000 GETMBR R2 R0 K15 0x8C08010F, // 0000 GETMET R2 R0 K15
0x8C08052F, // 0001 GETMET R2 R2 K47 0x7C080200, // 0001 CALL R2 1
0x5C100200, // 0002 MOVE R4 R1 0x8C080530, // 0002 GETMET R2 R2 K48
0x7C080400, // 0003 CALL R2 2 0x5C100200, // 0003 MOVE R4 R1
0x80040400, // 0004 RET 1 R2 0x7C080400, // 0004 CALL R2 2
0x80040400, // 0005 RET 1 R2
}) })
) )
); );
@ -1140,81 +1145,81 @@ be_local_closure(class_Matter_Plugin_read_attribute, /* name */
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[169]) { /* code */ ( &(const binstruction[169]) { /* code */
0xB8122600, // 0000 GETNGBL R4 K19 0xB8122600, // 0000 GETNGBL R4 K19
0x88100930, // 0001 GETMBR R4 R4 K48 0x88100931, // 0001 GETMBR R4 R4 K49
0x88140531, // 0002 GETMBR R5 R2 K49 0x88140532, // 0002 GETMBR R5 R2 K50
0x88180532, // 0003 GETMBR R6 R2 K50 0x88180533, // 0003 GETMBR R6 R2 K51
0x541E001C, // 0004 LDINT R7 29 0x541E001C, // 0004 LDINT R7 29
0x1C1C0A07, // 0005 EQ R7 R5 R7 0x1C1C0A07, // 0005 EQ R7 R5 R7
0x781E0050, // 0006 JMPF R7 #0058 0x781E0050, // 0006 JMPF R7 #0058
0x1C1C0D23, // 0007 EQ R7 R6 K35 0x1C1C0D23, // 0007 EQ R7 R6 K35
0x781E001B, // 0008 JMPF R7 #0025 0x781E001B, // 0008 JMPF R7 #0025
0x8C1C0933, // 0009 GETMET R7 R4 K51 0x8C1C0934, // 0009 GETMET R7 R4 K52
0x7C1C0200, // 000A CALL R7 1 0x7C1C0200, // 000A CALL R7 1
0x88200134, // 000B GETMBR R8 R0 K52 0x88200135, // 000B GETMBR R8 R0 K53
0x60240010, // 000C GETGBL R9 G16 0x60240010, // 000C GETGBL R9 G16
0x8C281135, // 000D GETMET R10 R8 K53 0x8C281136, // 000D GETMET R10 R8 K54
0x7C280200, // 000E CALL R10 1 0x7C280200, // 000E CALL R10 1
0x7C240200, // 000F CALL R9 1 0x7C240200, // 000F CALL R9 1
0xA802000E, // 0010 EXBLK 0 #0020 0xA802000E, // 0010 EXBLK 0 #0020
0x5C281200, // 0011 MOVE R10 R9 0x5C281200, // 0011 MOVE R10 R9
0x7C280000, // 0012 CALL R10 0 0x7C280000, // 0012 CALL R10 0
0x8C2C0F36, // 0013 GETMET R11 R7 K54 0x8C2C0F37, // 0013 GETMET R11 R7 K55
0x7C2C0200, // 0014 CALL R11 1 0x7C2C0200, // 0014 CALL R11 1
0x8C301737, // 0015 GETMET R12 R11 K55 0x8C301738, // 0015 GETMET R12 R11 K56
0x58380023, // 0016 LDCONST R14 K35 0x58380023, // 0016 LDCONST R14 K35
0x883C0938, // 0017 GETMBR R15 R4 K56 0x883C0939, // 0017 GETMBR R15 R4 K57
0x5C401400, // 0018 MOVE R16 R10 0x5C401400, // 0018 MOVE R16 R10
0x7C300800, // 0019 CALL R12 4 0x7C300800, // 0019 CALL R12 4
0x8C301737, // 001A GETMET R12 R11 K55 0x8C301738, // 001A GETMET R12 R11 K56
0x58380026, // 001B LDCONST R14 K38 0x58380026, // 001B LDCONST R14 K38
0x883C0938, // 001C GETMBR R15 R4 K56 0x883C0939, // 001C GETMBR R15 R4 K57
0x9440100A, // 001D GETIDX R16 R8 R10 0x9440100A, // 001D GETIDX R16 R8 R10
0x7C300800, // 001E CALL R12 4 0x7C300800, // 001E CALL R12 4
0x7001FFF0, // 001F JMP #0011 0x7001FFF0, // 001F JMP #0011
0x58240039, // 0020 LDCONST R9 K57 0x5824003A, // 0020 LDCONST R9 K58
0xAC240200, // 0021 CATCH R9 1 0 0xAC240200, // 0021 CATCH R9 1 0
0xB0080000, // 0022 RAISE 2 R0 R0 0xB0080000, // 0022 RAISE 2 R0 R0
0x80040E00, // 0023 RET 1 R7 0x80040E00, // 0023 RET 1 R7
0x70020032, // 0024 JMP #0058 0x70020032, // 0024 JMP #0058
0x1C1C0D26, // 0025 EQ R7 R6 K38 0x1C1C0D26, // 0025 EQ R7 R6 K38
0x781E0013, // 0026 JMPF R7 #003B 0x781E0013, // 0026 JMPF R7 #003B
0x8C1C0933, // 0027 GETMET R7 R4 K51 0x8C1C0934, // 0027 GETMET R7 R4 K52
0x7C1C0200, // 0028 CALL R7 1 0x7C1C0200, // 0028 CALL R7 1
0x60200010, // 0029 GETGBL R8 G16 0x60200010, // 0029 GETGBL R8 G16
0x8C24013A, // 002A GETMET R9 R0 K58 0x8C24013B, // 002A GETMET R9 R0 K59
0x7C240200, // 002B CALL R9 1 0x7C240200, // 002B CALL R9 1
0x7C200200, // 002C CALL R8 1 0x7C200200, // 002C CALL R8 1
0xA8020007, // 002D EXBLK 0 #0036 0xA8020007, // 002D EXBLK 0 #0036
0x5C241000, // 002E MOVE R9 R8 0x5C241000, // 002E MOVE R9 R8
0x7C240000, // 002F CALL R9 0 0x7C240000, // 002F CALL R9 0
0x8C280F37, // 0030 GETMET R10 R7 K55 0x8C280F38, // 0030 GETMET R10 R7 K56
0x4C300000, // 0031 LDNIL R12 0x4C300000, // 0031 LDNIL R12
0x8834093B, // 0032 GETMBR R13 R4 K59 0x8834093C, // 0032 GETMBR R13 R4 K60
0x5C381200, // 0033 MOVE R14 R9 0x5C381200, // 0033 MOVE R14 R9
0x7C280800, // 0034 CALL R10 4 0x7C280800, // 0034 CALL R10 4
0x7001FFF7, // 0035 JMP #002E 0x7001FFF7, // 0035 JMP #002E
0x58200039, // 0036 LDCONST R8 K57 0x5820003A, // 0036 LDCONST R8 K58
0xAC200200, // 0037 CATCH R8 1 0 0xAC200200, // 0037 CATCH R8 1 0
0xB0080000, // 0038 RAISE 2 R0 R0 0xB0080000, // 0038 RAISE 2 R0 R0
0x80040E00, // 0039 RET 1 R7 0x80040E00, // 0039 RET 1 R7
0x7002001C, // 003A JMP #0058 0x7002001C, // 003A JMP #0058
0x1C1C0D24, // 003B EQ R7 R6 K36 0x1C1C0D24, // 003B EQ R7 R6 K36
0x781E0003, // 003C JMPF R7 #0041 0x781E0003, // 003C JMPF R7 #0041
0x8C1C0933, // 003D GETMET R7 R4 K51 0x8C1C0934, // 003D GETMET R7 R4 K52
0x7C1C0200, // 003E CALL R7 1 0x7C1C0200, // 003E CALL R7 1
0x80040E00, // 003F RET 1 R7 0x80040E00, // 003F RET 1 R7
0x70020016, // 0040 JMP #0058 0x70020016, // 0040 JMP #0058
0x1C1C0D3C, // 0041 EQ R7 R6 K60 0x1C1C0D3D, // 0041 EQ R7 R6 K61
0x781E0003, // 0042 JMPF R7 #0047 0x781E0003, // 0042 JMPF R7 #0047
0x8C1C0933, // 0043 GETMET R7 R4 K51 0x8C1C0934, // 0043 GETMET R7 R4 K52
0x7C1C0200, // 0044 CALL R7 1 0x7C1C0200, // 0044 CALL R7 1
0x80040E00, // 0045 RET 1 R7 0x80040E00, // 0045 RET 1 R7
0x70020010, // 0046 JMP #0058 0x70020010, // 0046 JMP #0058
0x541EFFFB, // 0047 LDINT R7 65532 0x541EFFFB, // 0047 LDINT R7 65532
0x1C1C0C07, // 0048 EQ R7 R6 R7 0x1C1C0C07, // 0048 EQ R7 R6 R7
0x781E0005, // 0049 JMPF R7 #0050 0x781E0005, // 0049 JMPF R7 #0050
0x8C1C073D, // 004A GETMET R7 R3 K61 0x8C1C073E, // 004A GETMET R7 R3 K62
0x8824093B, // 004B GETMBR R9 R4 K59 0x8824093C, // 004B GETMBR R9 R4 K60
0x58280023, // 004C LDCONST R10 K35 0x58280023, // 004C LDCONST R10 K35
0x7C1C0600, // 004D CALL R7 3 0x7C1C0600, // 004D CALL R7 3
0x80040E00, // 004E RET 1 R7 0x80040E00, // 004E RET 1 R7
@ -1222,24 +1227,24 @@ be_local_closure(class_Matter_Plugin_read_attribute, /* name */
0x541EFFFC, // 0050 LDINT R7 65533 0x541EFFFC, // 0050 LDINT R7 65533
0x1C1C0C07, // 0051 EQ R7 R6 R7 0x1C1C0C07, // 0051 EQ R7 R6 R7
0x781E0004, // 0052 JMPF R7 #0058 0x781E0004, // 0052 JMPF R7 #0058
0x8C1C073D, // 0053 GETMET R7 R3 K61 0x8C1C073E, // 0053 GETMET R7 R3 K62
0x8824093B, // 0054 GETMBR R9 R4 K59 0x8824093C, // 0054 GETMBR R9 R4 K60
0x58280026, // 0055 LDCONST R10 K38 0x58280026, // 0055 LDCONST R10 K38
0x7C1C0600, // 0056 CALL R7 3 0x7C1C0600, // 0056 CALL R7 3
0x80040E00, // 0057 RET 1 R7 0x80040E00, // 0057 RET 1 R7
0x541EFFF7, // 0058 LDINT R7 65528 0x541EFFF7, // 0058 LDINT R7 65528
0x1C1C0C07, // 0059 EQ R7 R6 R7 0x1C1C0C07, // 0059 EQ R7 R6 R7
0x781E0003, // 005A JMPF R7 #005F 0x781E0003, // 005A JMPF R7 #005F
0x8C1C0933, // 005B GETMET R7 R4 K51 0x8C1C0934, // 005B GETMET R7 R4 K52
0x7C1C0200, // 005C CALL R7 1 0x7C1C0200, // 005C CALL R7 1
0x80040E00, // 005D RET 1 R7 0x80040E00, // 005D RET 1 R7
0x70020047, // 005E JMP #00A7 0x70020047, // 005E JMP #00A7
0x541EFFFA, // 005F LDINT R7 65531 0x541EFFFA, // 005F LDINT R7 65531
0x1C1C0C07, // 0060 EQ R7 R6 R7 0x1C1C0C07, // 0060 EQ R7 R6 R7
0x781E001B, // 0061 JMPF R7 #007E 0x781E001B, // 0061 JMPF R7 #007E
0x8C1C0933, // 0062 GETMET R7 R4 K51 0x8C1C0934, // 0062 GETMET R7 R4 K52
0x7C1C0200, // 0063 CALL R7 1 0x7C1C0200, // 0063 CALL R7 1
0x8C20013E, // 0064 GETMET R8 R0 K62 0x8C20013F, // 0064 GETMET R8 R0 K63
0x5C280A00, // 0065 MOVE R10 R5 0x5C280A00, // 0065 MOVE R10 R5
0x7C200400, // 0066 CALL R8 2 0x7C200400, // 0066 CALL R8 2
0x4C240000, // 0067 LDNIL R9 0x4C240000, // 0067 LDNIL R9
@ -1253,9 +1258,9 @@ be_local_closure(class_Matter_Plugin_read_attribute, /* name */
0x58280023, // 006F LDCONST R10 K35 0x58280023, // 006F LDCONST R10 K35
0x142C1409, // 0070 LT R11 R10 R9 0x142C1409, // 0070 LT R11 R10 R9
0x782E0009, // 0071 JMPF R11 #007C 0x782E0009, // 0071 JMPF R11 #007C
0x8C2C0F37, // 0072 GETMET R11 R7 K55 0x8C2C0F38, // 0072 GETMET R11 R7 K56
0x4C340000, // 0073 LDNIL R13 0x4C340000, // 0073 LDNIL R13
0x88380938, // 0074 GETMBR R14 R4 K56 0x88380939, // 0074 GETMBR R14 R4 K57
0x8C3C1125, // 0075 GETMET R15 R8 K37 0x8C3C1125, // 0075 GETMET R15 R8 K37
0x08441524, // 0076 MUL R17 R10 K36 0x08441524, // 0076 MUL R17 R10 K36
0x5449FFFD, // 0077 LDINT R18 -2 0x5449FFFD, // 0077 LDINT R18 -2
@ -1268,27 +1273,27 @@ be_local_closure(class_Matter_Plugin_read_attribute, /* name */
0x541EFFF9, // 007E LDINT R7 65530 0x541EFFF9, // 007E LDINT R7 65530
0x1C1C0C07, // 007F EQ R7 R6 R7 0x1C1C0C07, // 007F EQ R7 R6 R7
0x781E0003, // 0080 JMPF R7 #0085 0x781E0003, // 0080 JMPF R7 #0085
0x8C1C0933, // 0081 GETMET R7 R4 K51 0x8C1C0934, // 0081 GETMET R7 R4 K52
0x7C1C0200, // 0082 CALL R7 1 0x7C1C0200, // 0082 CALL R7 1
0x80040E00, // 0083 RET 1 R7 0x80040E00, // 0083 RET 1 R7
0x70020021, // 0084 JMP #00A7 0x70020021, // 0084 JMP #00A7
0x541EFFF8, // 0085 LDINT R7 65529 0x541EFFF8, // 0085 LDINT R7 65529
0x1C1C0C07, // 0086 EQ R7 R6 R7 0x1C1C0C07, // 0086 EQ R7 R6 R7
0x781E0003, // 0087 JMPF R7 #008C 0x781E0003, // 0087 JMPF R7 #008C
0x8C1C0933, // 0088 GETMET R7 R4 K51 0x8C1C0934, // 0088 GETMET R7 R4 K52
0x7C1C0200, // 0089 CALL R7 1 0x7C1C0200, // 0089 CALL R7 1
0x80040E00, // 008A RET 1 R7 0x80040E00, // 008A RET 1 R7
0x7002001A, // 008B JMP #00A7 0x7002001A, // 008B JMP #00A7
0x541EFFFB, // 008C LDINT R7 65532 0x541EFFFB, // 008C LDINT R7 65532
0x1C1C0C07, // 008D EQ R7 R6 R7 0x1C1C0C07, // 008D EQ R7 R6 R7
0x781E000A, // 008E JMPF R7 #009A 0x781E000A, // 008E JMPF R7 #009A
0x881C013F, // 008F GETMBR R7 R0 K63 0x881C0140, // 008F GETMBR R7 R0 K64
0x8C1C0F10, // 0090 GETMET R7 R7 K16 0x8C1C0F10, // 0090 GETMET R7 R7 K16
0x5C240A00, // 0091 MOVE R9 R5 0x5C240A00, // 0091 MOVE R9 R5
0x58280023, // 0092 LDCONST R10 K35 0x58280023, // 0092 LDCONST R10 K35
0x7C1C0600, // 0093 CALL R7 3 0x7C1C0600, // 0093 CALL R7 3
0x8C20073D, // 0094 GETMET R8 R3 K61 0x8C20073E, // 0094 GETMET R8 R3 K62
0x8828093B, // 0095 GETMBR R10 R4 K59 0x8828093C, // 0095 GETMBR R10 R4 K60
0x5C2C0E00, // 0096 MOVE R11 R7 0x5C2C0E00, // 0096 MOVE R11 R7
0x7C200600, // 0097 CALL R8 3 0x7C200600, // 0097 CALL R8 3
0x80041000, // 0098 RET 1 R8 0x80041000, // 0098 RET 1 R8
@ -1296,13 +1301,13 @@ be_local_closure(class_Matter_Plugin_read_attribute, /* name */
0x541EFFFC, // 009A LDINT R7 65533 0x541EFFFC, // 009A LDINT R7 65533
0x1C1C0C07, // 009B EQ R7 R6 R7 0x1C1C0C07, // 009B EQ R7 R6 R7
0x781E0009, // 009C JMPF R7 #00A7 0x781E0009, // 009C JMPF R7 #00A7
0x881C0140, // 009D GETMBR R7 R0 K64 0x881C0141, // 009D GETMBR R7 R0 K65
0x8C1C0F10, // 009E GETMET R7 R7 K16 0x8C1C0F10, // 009E GETMET R7 R7 K16
0x5C240A00, // 009F MOVE R9 R5 0x5C240A00, // 009F MOVE R9 R5
0x58280026, // 00A0 LDCONST R10 K38 0x58280026, // 00A0 LDCONST R10 K38
0x7C1C0600, // 00A1 CALL R7 3 0x7C1C0600, // 00A1 CALL R7 3
0x8C20073D, // 00A2 GETMET R8 R3 K61 0x8C20073E, // 00A2 GETMET R8 R3 K62
0x8828093B, // 00A3 GETMBR R10 R4 K59 0x8828093C, // 00A3 GETMBR R10 R4 K60
0x5C2C0E00, // 00A4 MOVE R11 R7 0x5C2C0E00, // 00A4 MOVE R11 R7
0x7C200600, // 00A5 CALL R8 3 0x7C200600, // 00A5 CALL R8 3
0x80041000, // 00A6 RET 1 R8 0x80041000, // 00A6 RET 1 R8

View File

@ -3,8 +3,8 @@
* Generated code, don't edit * * Generated code, don't edit *
\********************************************************************/ \********************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
// compact class 'Matter_Autoconf' ktab size: 73, total: 90 (saved 136 bytes) // compact class 'Matter_Autoconf' ktab size: 74, total: 91 (saved 136 bytes)
static const bvalue be_ktab_class_Matter_Autoconf[73] = { static const bvalue be_ktab_class_Matter_Autoconf[74] = {
/* K0 */ be_nested_str_weak(device), /* K0 */ be_nested_str_weak(device),
/* K1 */ be_nested_str_weak(k2l_num), /* K1 */ be_nested_str_weak(k2l_num),
/* K2 */ be_nested_str_weak(plugins), /* K2 */ be_nested_str_weak(plugins),
@ -12,72 +12,73 @@ static const bvalue be_ktab_class_Matter_Autoconf[73] = {
/* K4 */ be_nested_str_weak(matter), /* K4 */ be_nested_str_weak(matter),
/* K5 */ be_nested_str_weak(Plugin_Root), /* K5 */ be_nested_str_weak(Plugin_Root),
/* K6 */ be_const_int(0), /* K6 */ be_const_int(0),
/* K7 */ be_nested_str_weak(log), /* K7 */ be_nested_str_weak(find),
/* K8 */ be_nested_str_weak(MTR_X3A_X20Configuring_X20endpoints), /* K8 */ be_nested_str_weak(0),
/* K9 */ be_const_int(2), /* K9 */ be_nested_str_weak(log),
/* K10 */ be_nested_str_weak(MTR_X3A_X20_X20_X20endpoint_X20_X3D_X20_X255i_X20type_X3A_X25s_X25s), /* K10 */ be_nested_str_weak(MTR_X3A_X20Configuring_X20endpoints),
/* K11 */ be_nested_str_weak(root), /* K11 */ be_const_int(2),
/* K12 */ be_nested_str_weak(), /* K12 */ be_nested_str_weak(MTR_X3A_X20_X20_X20endpoint_X20_X3D_X20_X255i_X20type_X3A_X25s_X25s),
/* K13 */ be_nested_str_weak(Plugin_Aggregator), /* K13 */ be_nested_str_weak(root),
/* K14 */ be_nested_str_weak(AGGREGATOR_ENDPOINT), /* K14 */ be_nested_str_weak(),
/* K15 */ be_nested_str_weak(aggregator), /* K15 */ be_nested_str_weak(Plugin_Aggregator),
/* K16 */ be_nested_str_weak(find), /* K16 */ be_nested_str_weak(AGGREGATOR_ENDPOINT),
/* K17 */ be_nested_str_weak(type), /* K17 */ be_nested_str_weak(aggregator),
/* K18 */ be_nested_str_weak(MTR_X3A_X20no_X20class_X20name_X2C_X20skipping), /* K18 */ be_nested_str_weak(type),
/* K19 */ be_const_int(3), /* K19 */ be_nested_str_weak(MTR_X3A_X20no_X20class_X20name_X2C_X20skipping),
/* K20 */ be_nested_str_weak(MTR_X3A_X20only_X20one_X20root_X20node_X20allowed), /* K20 */ be_const_int(3),
/* K21 */ be_nested_str_weak(plugins_classes), /* K21 */ be_nested_str_weak(MTR_X3A_X20only_X20one_X20root_X20node_X20allowed),
/* K22 */ be_nested_str_weak(MTR_X3A_X20unknown_X20class_X20name_X20_X27), /* K22 */ be_nested_str_weak(plugins_classes),
/* K23 */ be_nested_str_weak(_X27_X20skipping), /* K23 */ be_nested_str_weak(MTR_X3A_X20unknown_X20class_X20name_X20_X27),
/* K24 */ be_nested_str_weak(conf_to_log), /* K24 */ be_nested_str_weak(_X27_X20skipping),
/* K25 */ be_nested_str_weak(MTR_X3A_X20Exception), /* K25 */ be_nested_str_weak(conf_to_log),
/* K26 */ be_nested_str_weak(_X7C), /* K26 */ be_nested_str_weak(MTR_X3A_X20Exception),
/* K27 */ be_nested_str_weak(stop_iteration), /* K27 */ be_nested_str_weak(_X7C),
/* K28 */ be_nested_str_weak(tasmota), /* K28 */ be_nested_str_weak(stop_iteration),
/* K29 */ be_nested_str_weak(publish_result), /* K29 */ be_nested_str_weak(tasmota),
/* K30 */ be_nested_str_weak(_X7B_X22Matter_X22_X3A_X7B_X22Initialized_X22_X3A1_X7D_X7D), /* K30 */ be_nested_str_weak(publish_result),
/* K31 */ be_nested_str_weak(Matter), /* K31 */ be_nested_str_weak(_X7B_X22Matter_X22_X3A_X7B_X22Initialized_X22_X3A1_X7D_X7D),
/* K32 */ be_nested_str_weak(json), /* K32 */ be_nested_str_weak(Matter),
/* K33 */ be_nested_str_weak(START_ENDPOINT), /* K33 */ be_nested_str_weak(json),
/* K34 */ be_nested_str_weak(light), /* K34 */ be_nested_str_weak(START_ENDPOINT),
/* K35 */ be_nested_str_weak(get), /* K35 */ be_nested_str_weak(light),
/* K36 */ be_nested_str_weak(channels), /* K36 */ be_nested_str_weak(get),
/* K37 */ be_const_int(1), /* K37 */ be_nested_str_weak(channels),
/* K38 */ be_nested_str_weak(light1), /* K38 */ be_const_int(1),
/* K39 */ be_nested_str_weak(light2), /* K39 */ be_nested_str_weak(light1),
/* K40 */ be_nested_str_weak(light3), /* K40 */ be_nested_str_weak(light2),
/* K41 */ be_nested_str_weak(cmd), /* K41 */ be_nested_str_weak(light3),
/* K42 */ be_nested_str_weak(Status_X2013), /* K42 */ be_nested_str_weak(cmd),
/* K43 */ be_nested_str_weak(MTR_X3A_X20Status_X2013_X20_X3D_X20), /* K43 */ be_nested_str_weak(Status_X2013),
/* K44 */ be_nested_str_weak(contains), /* K44 */ be_nested_str_weak(MTR_X3A_X20Status_X2013_X20_X3D_X20),
/* K45 */ be_nested_str_weak(StatusSHT), /* K45 */ be_nested_str_weak(contains),
/* K46 */ be_nested_str_weak(SHT), /* K46 */ be_nested_str_weak(StatusSHT),
/* K47 */ be_nested_str_weak(MTR_X3A_X20_X27_X25s_X27_X20_X3D_X20_X25s), /* K47 */ be_nested_str_weak(SHT),
/* K48 */ be_nested_str_weak(Relay1), /* K48 */ be_nested_str_weak(MTR_X3A_X20_X27_X25s_X27_X20_X3D_X20_X25s),
/* K49 */ be_nested_str_weak(Relay2), /* K49 */ be_nested_str_weak(Relay1),
/* K50 */ be_nested_str_weak(MTR_X3A_X20relay1_X3D_X25s_X20relay2_X3D_X25s), /* K50 */ be_nested_str_weak(Relay2),
/* K51 */ be_nested_str_weak(TiltConfig), /* K51 */ be_nested_str_weak(MTR_X3A_X20relay1_X3D_X25s_X20relay2_X3D_X25s),
/* K52 */ be_nested_str_weak(shutter_X2Btilt), /* K52 */ be_nested_str_weak(TiltConfig),
/* K53 */ be_nested_str_weak(shutter), /* K53 */ be_nested_str_weak(shutter_X2Btilt),
/* K54 */ be_nested_str_weak(get_power), /* K54 */ be_nested_str_weak(shutter),
/* K55 */ be_nested_str_weak(relay), /* K55 */ be_nested_str_weak(get_power),
/* K56 */ be_nested_str_weak(load), /* K56 */ be_nested_str_weak(relay),
/* K57 */ be_nested_str_weak(read_sensors), /* K57 */ be_nested_str_weak(load),
/* K58 */ be_nested_str_weak(autoconf_sensors_list), /* K58 */ be_nested_str_weak(read_sensors),
/* K59 */ be_nested_str_weak(k2l), /* K59 */ be_nested_str_weak(autoconf_sensors_list),
/* K60 */ be_nested_str_weak(Temperature), /* K60 */ be_nested_str_weak(k2l),
/* K61 */ be_nested_str_weak(_X23Temperature), /* K61 */ be_nested_str_weak(Temperature),
/* K62 */ be_nested_str_weak(temperature), /* K62 */ be_nested_str_weak(_X23Temperature),
/* K63 */ be_nested_str_weak(filter), /* K63 */ be_nested_str_weak(temperature),
/* K64 */ be_nested_str_weak(Pressure), /* K64 */ be_nested_str_weak(filter),
/* K65 */ be_nested_str_weak(_X23Pressure), /* K65 */ be_nested_str_weak(Pressure),
/* K66 */ be_nested_str_weak(pressure), /* K66 */ be_nested_str_weak(_X23Pressure),
/* K67 */ be_nested_str_weak(Illuminance), /* K67 */ be_nested_str_weak(pressure),
/* K68 */ be_nested_str_weak(_X23Illuminance), /* K68 */ be_nested_str_weak(Illuminance),
/* K69 */ be_nested_str_weak(illuminance), /* K69 */ be_nested_str_weak(_X23Illuminance),
/* K70 */ be_nested_str_weak(Humidity), /* K70 */ be_nested_str_weak(illuminance),
/* K71 */ be_nested_str_weak(_X23Humidity), /* K71 */ be_nested_str_weak(Humidity),
/* K72 */ be_nested_str_weak(humidity), /* K72 */ be_nested_str_weak(_X23Humidity),
/* K73 */ be_nested_str_weak(humidity),
}; };
@ -99,7 +100,7 @@ be_local_closure(class_Matter_Autoconf_instantiate_plugins_from_config, /* nam
&be_ktab_class_Matter_Autoconf, /* shared constants */ &be_ktab_class_Matter_Autoconf, /* shared constants */
be_str_weak(instantiate_plugins_from_config), be_str_weak(instantiate_plugins_from_config),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[148]) { /* code */ ( &(const binstruction[151]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0 0x88080100, // 0000 GETMBR R2 R0 K0
0x8C080501, // 0001 GETMET R2 R2 K1 0x8C080501, // 0001 GETMET R2 R2 K1
0x5C100200, // 0002 MOVE R4 R1 0x5C100200, // 0002 MOVE R4 R1
@ -111,143 +112,146 @@ be_local_closure(class_Matter_Autoconf_instantiate_plugins_from_config, /* nam
0x8C180D05, // 0008 GETMET R6 R6 K5 0x8C180D05, // 0008 GETMET R6 R6 K5
0x88200100, // 0009 GETMBR R8 R0 K0 0x88200100, // 0009 GETMBR R8 R0 K0
0x58240006, // 000A LDCONST R9 K6 0x58240006, // 000A LDCONST R9 K6
0x60280013, // 000B GETGBL R10 G19 0x8C280307, // 000B GETMET R10 R1 K7
0x7C280000, // 000C CALL R10 0 0x58300008, // 000C LDCONST R12 K8
0x7C180800, // 000D CALL R6 4 0x60340013, // 000D GETGBL R13 G19
0x7C100400, // 000E CALL R4 2 0x7C340000, // 000E CALL R13 0
0xB8120E00, // 000F GETNGBL R4 K7 0x7C280600, // 000F CALL R10 3
0x58140008, // 0010 LDCONST R5 K8 0x7C180800, // 0010 CALL R6 4
0x58180009, // 0011 LDCONST R6 K9 0x7C100400, // 0011 CALL R4 2
0x7C100400, // 0012 CALL R4 2 0xB8121200, // 0012 GETNGBL R4 K9
0xB8120E00, // 0013 GETNGBL R4 K7 0x5814000A, // 0013 LDCONST R5 K10
0x60140018, // 0014 GETGBL R5 G24 0x5818000B, // 0014 LDCONST R6 K11
0x5818000A, // 0015 LDCONST R6 K10 0x7C100400, // 0015 CALL R4 2
0x581C0006, // 0016 LDCONST R7 K6 0xB8121200, // 0016 GETNGBL R4 K9
0x5820000B, // 0017 LDCONST R8 K11 0x60140018, // 0017 GETGBL R5 G24
0x5824000C, // 0018 LDCONST R9 K12 0x5818000C, // 0018 LDCONST R6 K12
0x7C140800, // 0019 CALL R5 4 0x581C0006, // 0019 LDCONST R7 K6
0x58180009, // 001A LDCONST R6 K9 0x5820000D, // 001A LDCONST R8 K13
0x7C100400, // 001B CALL R4 2 0x5824000E, // 001B LDCONST R9 K14
0x8C100703, // 001C GETMET R4 R3 K3 0x7C140800, // 001C CALL R5 4
0xB81A0800, // 001D GETNGBL R6 K4 0x5818000B, // 001D LDCONST R6 K11
0x8C180D0D, // 001E GETMET R6 R6 K13 0x7C100400, // 001E CALL R4 2
0x88200100, // 001F GETMBR R8 R0 K0 0x8C100703, // 001F GETMET R4 R3 K3
0xB8260800, // 0020 GETNGBL R9 K4 0xB81A0800, // 0020 GETNGBL R6 K4
0x8824130E, // 0021 GETMBR R9 R9 K14 0x8C180D0F, // 0021 GETMET R6 R6 K15
0x60280013, // 0022 GETGBL R10 G19 0x88200100, // 0022 GETMBR R8 R0 K0
0x7C280000, // 0023 CALL R10 0 0xB8260800, // 0023 GETNGBL R9 K4
0x7C180800, // 0024 CALL R6 4 0x88241310, // 0024 GETMBR R9 R9 K16
0x7C100400, // 0025 CALL R4 2 0x60280013, // 0025 GETGBL R10 G19
0xB8120E00, // 0026 GETNGBL R4 K7 0x7C280000, // 0026 CALL R10 0
0x60140018, // 0027 GETGBL R5 G24 0x7C180800, // 0027 CALL R6 4
0x5818000A, // 0028 LDCONST R6 K10 0x7C100400, // 0028 CALL R4 2
0xB81E0800, // 0029 GETNGBL R7 K4 0xB8121200, // 0029 GETNGBL R4 K9
0x881C0F0E, // 002A GETMBR R7 R7 K14 0x60140018, // 002A GETGBL R5 G24
0x5820000F, // 002B LDCONST R8 K15 0x5818000C, // 002B LDCONST R6 K12
0x5824000C, // 002C LDCONST R9 K12 0xB81E0800, // 002C GETNGBL R7 K4
0x7C140800, // 002D CALL R5 4 0x881C0F10, // 002D GETMBR R7 R7 K16
0x58180009, // 002E LDCONST R6 K9 0x58200011, // 002E LDCONST R8 K17
0x7C100400, // 002F CALL R4 2 0x5824000E, // 002F LDCONST R9 K14
0x60100010, // 0030 GETGBL R4 G16 0x7C140800, // 0030 CALL R5 4
0x5C140400, // 0031 MOVE R5 R2 0x5818000B, // 0031 LDCONST R6 K11
0x7C100200, // 0032 CALL R4 1 0x7C100400, // 0032 CALL R4 2
0xA8020056, // 0033 EXBLK 0 #008B 0x60100010, // 0033 GETGBL R4 G16
0x5C140800, // 0034 MOVE R5 R4 0x5C140400, // 0034 MOVE R5 R2
0x7C140000, // 0035 CALL R5 0 0x7C100200, // 0035 CALL R4 1
0x1C180B06, // 0036 EQ R6 R5 K6 0xA8020056, // 0036 EXBLK 0 #008E
0x781A0000, // 0037 JMPF R6 #0039 0x5C140800, // 0037 MOVE R5 R4
0x7001FFFA, // 0038 JMP #0034 0x7C140000, // 0038 CALL R5 0
0xA802003F, // 0039 EXBLK 0 #007A 0x1C180B06, // 0039 EQ R6 R5 K6
0x60180008, // 003A GETGBL R6 G8 0x781A0000, // 003A JMPF R6 #003C
0x5C1C0A00, // 003B MOVE R7 R5 0x7001FFFA, // 003B JMP #0037
0x7C180200, // 003C CALL R6 1 0xA802003F, // 003C EXBLK 0 #007D
0x94180206, // 003D GETIDX R6 R1 R6 0x60180008, // 003D GETGBL R6 G8
0x8C1C0D10, // 003E GETMET R7 R6 K16 0x5C1C0A00, // 003E MOVE R7 R5
0x58240011, // 003F LDCONST R9 K17 0x7C180200, // 003F CALL R6 1
0x7C1C0400, // 0040 CALL R7 2 0x94180206, // 0040 GETIDX R6 R1 R6
0x4C200000, // 0041 LDNIL R8 0x8C1C0D07, // 0041 GETMET R7 R6 K7
0x1C200E08, // 0042 EQ R8 R7 R8 0x58240012, // 0042 LDCONST R9 K18
0x78220005, // 0043 JMPF R8 #004A 0x7C1C0400, // 0043 CALL R7 2
0xB8220E00, // 0044 GETNGBL R8 K7 0x4C200000, // 0044 LDNIL R8
0x58240012, // 0045 LDCONST R9 K18 0x1C200E08, // 0045 EQ R8 R7 R8
0x58280013, // 0046 LDCONST R10 K19 0x78220005, // 0046 JMPF R8 #004D
0x7C200400, // 0047 CALL R8 2 0xB8221200, // 0047 GETNGBL R8 K9
0xA8040001, // 0048 EXBLK 1 1 0x58240013, // 0048 LDCONST R9 K19
0x7001FFE9, // 0049 JMP #0034 0x58280014, // 0049 LDCONST R10 K20
0x1C200F0B, // 004A EQ R8 R7 K11 0x7C200400, // 004A CALL R8 2
0x78220005, // 004B JMPF R8 #0052 0xA8040001, // 004B EXBLK 1 1
0xB8220E00, // 004C GETNGBL R8 K7 0x7001FFE9, // 004C JMP #0037
0x58240014, // 004D LDCONST R9 K20 0x1C200F0D, // 004D EQ R8 R7 K13
0x58280013, // 004E LDCONST R10 K19 0x78220005, // 004E JMPF R8 #0055
0x7C200400, // 004F CALL R8 2 0xB8221200, // 004F GETNGBL R8 K9
0xA8040001, // 0050 EXBLK 1 1 0x58240015, // 0050 LDCONST R9 K21
0x7001FFE1, // 0051 JMP #0034 0x58280014, // 0051 LDCONST R10 K20
0x88200100, // 0052 GETMBR R8 R0 K0 0x7C200400, // 0052 CALL R8 2
0x88201115, // 0053 GETMBR R8 R8 K21 0xA8040001, // 0053 EXBLK 1 1
0x8C201110, // 0054 GETMET R8 R8 K16 0x7001FFE1, // 0054 JMP #0037
0x5C280E00, // 0055 MOVE R10 R7 0x88200100, // 0055 GETMBR R8 R0 K0
0x7C200400, // 0056 CALL R8 2 0x88201116, // 0056 GETMBR R8 R8 K22
0x4C240000, // 0057 LDNIL R9 0x8C201107, // 0057 GETMET R8 R8 K7
0x1C241009, // 0058 EQ R9 R8 R9 0x5C280E00, // 0058 MOVE R10 R7
0x78260009, // 0059 JMPF R9 #0064 0x7C200400, // 0059 CALL R8 2
0xB8260E00, // 005A GETNGBL R9 K7 0x4C240000, // 005A LDNIL R9
0x60280008, // 005B GETGBL R10 G8 0x1C241009, // 005B EQ R9 R8 R9
0x5C2C0E00, // 005C MOVE R11 R7 0x78260009, // 005C JMPF R9 #0067
0x7C280200, // 005D CALL R10 1 0xB8261200, // 005D GETNGBL R9 K9
0x002A2C0A, // 005E ADD R10 K22 R10 0x60280008, // 005E GETGBL R10 G8
0x00281517, // 005F ADD R10 R10 K23 0x5C2C0E00, // 005F MOVE R11 R7
0x582C0009, // 0060 LDCONST R11 K9 0x7C280200, // 0060 CALL R10 1
0x7C240400, // 0061 CALL R9 2 0x002A2E0A, // 0061 ADD R10 K23 R10
0xA8040001, // 0062 EXBLK 1 1 0x00281518, // 0062 ADD R10 R10 K24
0x7001FFCF, // 0063 JMP #0034 0x582C000B, // 0063 LDCONST R11 K11
0x5C241000, // 0064 MOVE R9 R8 0x7C240400, // 0064 CALL R9 2
0x88280100, // 0065 GETMBR R10 R0 K0 0xA8040001, // 0065 EXBLK 1 1
0x5C2C0A00, // 0066 MOVE R11 R5 0x7001FFCF, // 0066 JMP #0037
0x5C300C00, // 0067 MOVE R12 R6 0x5C241000, // 0067 MOVE R9 R8
0x7C240600, // 0068 CALL R9 3 0x88280100, // 0068 GETMBR R10 R0 K0
0x8C280703, // 0069 GETMET R10 R3 K3 0x5C2C0A00, // 0069 MOVE R11 R5
0x5C301200, // 006A MOVE R12 R9 0x5C300C00, // 006A MOVE R12 R6
0x7C280400, // 006B CALL R10 2 0x7C240600, // 006B CALL R9 3
0xB82A0E00, // 006C GETNGBL R10 K7 0x8C280703, // 006C GETMET R10 R3 K3
0x602C0018, // 006D GETGBL R11 G24 0x5C301200, // 006D MOVE R12 R9
0x5830000A, // 006E LDCONST R12 K10 0x7C280400, // 006E CALL R10 2
0x5C340A00, // 006F MOVE R13 R5 0xB82A1200, // 006F GETNGBL R10 K9
0x5C380E00, // 0070 MOVE R14 R7 0x602C0018, // 0070 GETGBL R11 G24
0x883C0100, // 0071 GETMBR R15 R0 K0 0x5830000C, // 0071 LDCONST R12 K12
0x8C3C1F18, // 0072 GETMET R15 R15 K24 0x5C340A00, // 0072 MOVE R13 R5
0x5C440C00, // 0073 MOVE R17 R6 0x5C380E00, // 0073 MOVE R14 R7
0x7C3C0400, // 0074 CALL R15 2 0x883C0100, // 0074 GETMBR R15 R0 K0
0x7C2C0800, // 0075 CALL R11 4 0x8C3C1F19, // 0075 GETMET R15 R15 K25
0x58300009, // 0076 LDCONST R12 K9 0x5C440C00, // 0076 MOVE R17 R6
0x7C280400, // 0077 CALL R10 2 0x7C3C0400, // 0077 CALL R15 2
0xA8040001, // 0078 EXBLK 1 1 0x7C2C0800, // 0078 CALL R11 4
0x7002000F, // 0079 JMP #008A 0x5830000B, // 0079 LDCONST R12 K11
0xAC180002, // 007A CATCH R6 0 2 0x7C280400, // 007A CALL R10 2
0x7002000C, // 007B JMP #0089 0xA8040001, // 007B EXBLK 1 1
0xB8220E00, // 007C GETNGBL R8 K7 0x7002000F, // 007C JMP #008D
0x60240008, // 007D GETGBL R9 G8 0xAC180002, // 007D CATCH R6 0 2
0x5C280C00, // 007E MOVE R10 R6 0x7002000C, // 007E JMP #008C
0x7C240200, // 007F CALL R9 1 0xB8221200, // 007F GETNGBL R8 K9
0x00263209, // 0080 ADD R9 K25 R9 0x60240008, // 0080 GETGBL R9 G8
0x0024131A, // 0081 ADD R9 R9 K26 0x5C280C00, // 0081 MOVE R10 R6
0x60280008, // 0082 GETGBL R10 G8 0x7C240200, // 0082 CALL R9 1
0x5C2C0E00, // 0083 MOVE R11 R7 0x00263409, // 0083 ADD R9 K26 R9
0x7C280200, // 0084 CALL R10 1 0x0024131B, // 0084 ADD R9 R9 K27
0x0024120A, // 0085 ADD R9 R9 R10 0x60280008, // 0085 GETGBL R10 G8
0x58280009, // 0086 LDCONST R10 K9 0x5C2C0E00, // 0086 MOVE R11 R7
0x7C200400, // 0087 CALL R8 2 0x7C280200, // 0087 CALL R10 1
0x70020000, // 0088 JMP #008A 0x0024120A, // 0088 ADD R9 R9 R10
0xB0080000, // 0089 RAISE 2 R0 R0 0x5828000B, // 0089 LDCONST R10 K11
0x7001FFA8, // 008A JMP #0034 0x7C200400, // 008A CALL R8 2
0x5810001B, // 008B LDCONST R4 K27 0x70020000, // 008B JMP #008D
0xAC100200, // 008C CATCH R4 1 0 0xB0080000, // 008C RAISE 2 R0 R0
0xB0080000, // 008D RAISE 2 R0 R0 0x7001FFA8, // 008D JMP #0037
0xB8123800, // 008E GETNGBL R4 K28 0x5810001C, // 008E LDCONST R4 K28
0x8C10091D, // 008F GETMET R4 R4 K29 0xAC100200, // 008F CATCH R4 1 0
0x5818001E, // 0090 LDCONST R6 K30 0xB0080000, // 0090 RAISE 2 R0 R0
0x581C001F, // 0091 LDCONST R7 K31 0xB8123A00, // 0091 GETNGBL R4 K29
0x7C100600, // 0092 CALL R4 3 0x8C10091E, // 0092 GETMET R4 R4 K30
0x80000000, // 0093 RET 0 0x5818001F, // 0093 LDCONST R6 K31
0x581C0020, // 0094 LDCONST R7 K32
0x7C100600, // 0095 CALL R4 3
0x80000000, // 0096 RET 0
}) })
) )
); );
@ -271,41 +275,41 @@ be_local_closure(class_Matter_Autoconf_autoconf_device_map, /* name */
be_str_weak(autoconf_device_map), be_str_weak(autoconf_device_map),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[262]) { /* code */ ( &(const binstruction[262]) { /* code */
0xA4064000, // 0000 IMPORT R1 K32 0xA4064200, // 0000 IMPORT R1 K33
0x60080013, // 0001 GETGBL R2 G19 0x60080013, // 0001 GETGBL R2 G19
0x7C080000, // 0002 CALL R2 0 0x7C080000, // 0002 CALL R2 0
0xB80E0800, // 0003 GETNGBL R3 K4 0xB80E0800, // 0003 GETNGBL R3 K4
0x880C0721, // 0004 GETMBR R3 R3 K33 0x880C0722, // 0004 GETMBR R3 R3 K34
0x58100006, // 0005 LDCONST R4 K6 0x58100006, // 0005 LDCONST R4 K6
0xA4164400, // 0006 IMPORT R5 K34 0xA4164600, // 0006 IMPORT R5 K35
0x8C180B23, // 0007 GETMET R6 R5 K35 0x8C180B24, // 0007 GETMET R6 R5 K36
0x58200006, // 0008 LDCONST R8 K6 0x58200006, // 0008 LDCONST R8 K6
0x7C180400, // 0009 CALL R6 2 0x7C180400, // 0009 CALL R6 2
0x4C1C0000, // 000A LDNIL R7 0x4C1C0000, // 000A LDNIL R7
0x201C0C07, // 000B NE R7 R6 R7 0x201C0C07, // 000B NE R7 R6 R7
0x781E0066, // 000C JMPF R7 #0074 0x781E0066, // 000C JMPF R7 #0074
0x601C000C, // 000D GETGBL R7 G12 0x601C000C, // 000D GETGBL R7 G12
0x8C200D10, // 000E GETMET R8 R6 K16 0x8C200D07, // 000E GETMET R8 R6 K7
0x58280024, // 000F LDCONST R10 K36 0x58280025, // 000F LDCONST R10 K37
0x582C000C, // 0010 LDCONST R11 K12 0x582C000E, // 0010 LDCONST R11 K14
0x7C200600, // 0011 CALL R8 3 0x7C200600, // 0011 CALL R8 3
0x7C1C0200, // 0012 CALL R7 1 0x7C1C0200, // 0012 CALL R7 1
0x58100025, // 0013 LDCONST R4 K37 0x58100026, // 0013 LDCONST R4 K38
0x24200F06, // 0014 GT R8 R7 K6 0x24200F06, // 0014 GT R8 R7 K6
0x7822005D, // 0015 JMPF R8 #0074 0x7822005D, // 0015 JMPF R8 #0074
0x1C200F25, // 0016 EQ R8 R7 K37 0x1C200F26, // 0016 EQ R8 R7 K38
0x7822001E, // 0017 JMPF R8 #0037 0x7822001E, // 0017 JMPF R8 #0037
0x60200008, // 0018 GETGBL R8 G8 0x60200008, // 0018 GETGBL R8 G8
0x5C240600, // 0019 MOVE R9 R3 0x5C240600, // 0019 MOVE R9 R3
0x7C200200, // 001A CALL R8 1 0x7C200200, // 001A CALL R8 1
0x60240013, // 001B GETGBL R9 G19 0x60240013, // 001B GETGBL R9 G19
0x7C240000, // 001C CALL R9 0 0x7C240000, // 001C CALL R9 0
0x98262326, // 001D SETIDX R9 K17 K38 0x98262527, // 001D SETIDX R9 K18 K39
0x98081009, // 001E SETIDX R2 R8 R9 0x98081009, // 001E SETIDX R2 R8 R9
0x000C0725, // 001F ADD R3 R3 K37 0x000C0726, // 001F ADD R3 R3 K38
0x58200025, // 0020 LDCONST R8 K37 0x58200026, // 0020 LDCONST R8 K38
0x4C240000, // 0021 LDNIL R9 0x4C240000, // 0021 LDNIL R9
0x8C280B23, // 0022 GETMET R10 R5 K35 0x8C280B24, // 0022 GETMET R10 R5 K36
0x5C301000, // 0023 MOVE R12 R8 0x5C301000, // 0023 MOVE R12 R8
0x7C280400, // 0024 CALL R10 2 0x7C280400, // 0024 CALL R10 2
0x5C241400, // 0025 MOVE R9 R10 0x5C241400, // 0025 MOVE R9 R10
@ -317,152 +321,152 @@ be_local_closure(class_Matter_Autoconf_autoconf_device_map, /* name */
0x7C280200, // 002B CALL R10 1 0x7C280200, // 002B CALL R10 1
0x602C0013, // 002C GETGBL R11 G19 0x602C0013, // 002C GETGBL R11 G19
0x7C2C0000, // 002D CALL R11 0 0x7C2C0000, // 002D CALL R11 0
0x982E2326, // 002E SETIDX R11 K17 K38 0x982E2527, // 002E SETIDX R11 K18 K39
0x00301125, // 002F ADD R12 R8 K37 0x00301126, // 002F ADD R12 R8 K38
0x982E440C, // 0030 SETIDX R11 K34 R12 0x982E460C, // 0030 SETIDX R11 K35 R12
0x9808140B, // 0031 SETIDX R2 R10 R11 0x9808140B, // 0031 SETIDX R2 R10 R11
0x000C0725, // 0032 ADD R3 R3 K37 0x000C0726, // 0032 ADD R3 R3 K38
0x00100925, // 0033 ADD R4 R4 K37 0x00100926, // 0033 ADD R4 R4 K38
0x00201125, // 0034 ADD R8 R8 K37 0x00201126, // 0034 ADD R8 R8 K38
0x7001FFEB, // 0035 JMP #0022 0x7001FFEB, // 0035 JMP #0022
0x7002003C, // 0036 JMP #0074 0x7002003C, // 0036 JMP #0074
0x1C200F09, // 0037 EQ R8 R7 K9 0x1C200F0B, // 0037 EQ R8 R7 K11
0x78220008, // 0038 JMPF R8 #0042 0x78220008, // 0038 JMPF R8 #0042
0x60200008, // 0039 GETGBL R8 G8 0x60200008, // 0039 GETGBL R8 G8
0x5C240600, // 003A MOVE R9 R3 0x5C240600, // 003A MOVE R9 R3
0x7C200200, // 003B CALL R8 1 0x7C200200, // 003B CALL R8 1
0x60240013, // 003C GETGBL R9 G19 0x60240013, // 003C GETGBL R9 G19
0x7C240000, // 003D CALL R9 0 0x7C240000, // 003D CALL R9 0
0x98262327, // 003E SETIDX R9 K17 K39 0x98262528, // 003E SETIDX R9 K18 K40
0x98081009, // 003F SETIDX R2 R8 R9 0x98081009, // 003F SETIDX R2 R8 R9
0x000C0725, // 0040 ADD R3 R3 K37 0x000C0726, // 0040 ADD R3 R3 K38
0x70020031, // 0041 JMP #0074 0x70020031, // 0041 JMP #0074
0x1C200F13, // 0042 EQ R8 R7 K19 0x1C200F14, // 0042 EQ R8 R7 K20
0x7822002B, // 0043 JMPF R8 #0070 0x7822002B, // 0043 JMPF R8 #0070
0x60200008, // 0044 GETGBL R8 G8 0x60200008, // 0044 GETGBL R8 G8
0x5C240600, // 0045 MOVE R9 R3 0x5C240600, // 0045 MOVE R9 R3
0x7C200200, // 0046 CALL R8 1 0x7C200200, // 0046 CALL R8 1
0x60240013, // 0047 GETGBL R9 G19 0x60240013, // 0047 GETGBL R9 G19
0x7C240000, // 0048 CALL R9 0 0x7C240000, // 0048 CALL R9 0
0x98262328, // 0049 SETIDX R9 K17 K40 0x98262529, // 0049 SETIDX R9 K18 K41
0x98081009, // 004A SETIDX R2 R8 R9 0x98081009, // 004A SETIDX R2 R8 R9
0x000C0725, // 004B ADD R3 R3 K37 0x000C0726, // 004B ADD R3 R3 K38
0x8C200B23, // 004C GETMET R8 R5 K35 0x8C200B24, // 004C GETMET R8 R5 K36
0x58280025, // 004D LDCONST R10 K37 0x58280026, // 004D LDCONST R10 K38
0x7C200400, // 004E CALL R8 2 0x7C200400, // 004E CALL R8 2
0x4C240000, // 004F LDNIL R9 0x4C240000, // 004F LDNIL R9
0x20241009, // 0050 NE R9 R8 R9 0x20241009, // 0050 NE R9 R8 R9
0x7826001C, // 0051 JMPF R9 #006F 0x7826001C, // 0051 JMPF R9 #006F
0x6024000C, // 0052 GETGBL R9 G12 0x6024000C, // 0052 GETGBL R9 G12
0x8C281110, // 0053 GETMET R10 R8 K16 0x8C281107, // 0053 GETMET R10 R8 K7
0x58300024, // 0054 LDCONST R12 K36 0x58300025, // 0054 LDCONST R12 K37
0x5834000C, // 0055 LDCONST R13 K12 0x5834000E, // 0055 LDCONST R13 K14
0x7C280600, // 0056 CALL R10 3 0x7C280600, // 0056 CALL R10 3
0x7C240200, // 0057 CALL R9 1 0x7C240200, // 0057 CALL R9 1
0x1C281325, // 0058 EQ R10 R9 K37 0x1C281326, // 0058 EQ R10 R9 K38
0x782A0009, // 0059 JMPF R10 #0064 0x782A0009, // 0059 JMPF R10 #0064
0x60280008, // 005A GETGBL R10 G8 0x60280008, // 005A GETGBL R10 G8
0x5C2C0600, // 005B MOVE R11 R3 0x5C2C0600, // 005B MOVE R11 R3
0x7C280200, // 005C CALL R10 1 0x7C280200, // 005C CALL R10 1
0x602C0013, // 005D GETGBL R11 G19 0x602C0013, // 005D GETGBL R11 G19
0x7C2C0000, // 005E CALL R11 0 0x7C2C0000, // 005E CALL R11 0
0x982E2326, // 005F SETIDX R11 K17 K38 0x982E2527, // 005F SETIDX R11 K18 K39
0x9808140B, // 0060 SETIDX R2 R10 R11 0x9808140B, // 0060 SETIDX R2 R10 R11
0x000C0725, // 0061 ADD R3 R3 K37 0x000C0726, // 0061 ADD R3 R3 K38
0x00100925, // 0062 ADD R4 R4 K37 0x00100926, // 0062 ADD R4 R4 K38
0x7002000A, // 0063 JMP #006F 0x7002000A, // 0063 JMP #006F
0x1C281309, // 0064 EQ R10 R9 K9 0x1C28130B, // 0064 EQ R10 R9 K11
0x782A0008, // 0065 JMPF R10 #006F 0x782A0008, // 0065 JMPF R10 #006F
0x60280008, // 0066 GETGBL R10 G8 0x60280008, // 0066 GETGBL R10 G8
0x5C2C0600, // 0067 MOVE R11 R3 0x5C2C0600, // 0067 MOVE R11 R3
0x7C280200, // 0068 CALL R10 1 0x7C280200, // 0068 CALL R10 1
0x602C0013, // 0069 GETGBL R11 G19 0x602C0013, // 0069 GETGBL R11 G19
0x7C2C0000, // 006A CALL R11 0 0x7C2C0000, // 006A CALL R11 0
0x982E2327, // 006B SETIDX R11 K17 K39 0x982E2528, // 006B SETIDX R11 K18 K40
0x9808140B, // 006C SETIDX R2 R10 R11 0x9808140B, // 006C SETIDX R2 R10 R11
0x000C0725, // 006D ADD R3 R3 K37 0x000C0726, // 006D ADD R3 R3 K38
0x00100925, // 006E ADD R4 R4 K37 0x00100926, // 006E ADD R4 R4 K38
0x70020003, // 006F JMP #0074 0x70020003, // 006F JMP #0074
0x54220003, // 0070 LDINT R8 4 0x54220003, // 0070 LDINT R8 4
0x1C200E08, // 0071 EQ R8 R7 R8 0x1C200E08, // 0071 EQ R8 R7 R8
0x78220000, // 0072 JMPF R8 #0074 0x78220000, // 0072 JMPF R8 #0074
0x7001FFFF, // 0073 JMP #0074 0x7001FFFF, // 0073 JMP #0074
0xB81E3800, // 0074 GETNGBL R7 K28 0xB81E3A00, // 0074 GETNGBL R7 K29
0x8C1C0F29, // 0075 GETMET R7 R7 K41 0x8C1C0F2A, // 0075 GETMET R7 R7 K42
0x5824002A, // 0076 LDCONST R9 K42 0x5824002B, // 0076 LDCONST R9 K43
0x50280200, // 0077 LDBOOL R10 1 0 0x50280200, // 0077 LDBOOL R10 1 0
0x7C1C0600, // 0078 CALL R7 3 0x7C1C0600, // 0078 CALL R7 3
0x60200012, // 0079 GETGBL R8 G18 0x60200012, // 0079 GETGBL R8 G18
0x7C200000, // 007A CALL R8 0 0x7C200000, // 007A CALL R8 0
0xB8260E00, // 007B GETNGBL R9 K7 0xB8261200, // 007B GETNGBL R9 K9
0x60280008, // 007C GETGBL R10 G8 0x60280008, // 007C GETGBL R10 G8
0x5C2C0E00, // 007D MOVE R11 R7 0x5C2C0E00, // 007D MOVE R11 R7
0x7C280200, // 007E CALL R10 1 0x7C280200, // 007E CALL R10 1
0x002A560A, // 007F ADD R10 K43 R10 0x002A580A, // 007F ADD R10 K44 R10
0x582C0013, // 0080 LDCONST R11 K19 0x582C0014, // 0080 LDCONST R11 K20
0x7C240400, // 0081 CALL R9 2 0x7C240400, // 0081 CALL R9 2
0x4C240000, // 0082 LDNIL R9 0x4C240000, // 0082 LDNIL R9
0x20240E09, // 0083 NE R9 R7 R9 0x20240E09, // 0083 NE R9 R7 R9
0x7826004D, // 0084 JMPF R9 #00D3 0x7826004D, // 0084 JMPF R9 #00D3
0x8C240F2C, // 0085 GETMET R9 R7 K44 0x8C240F2D, // 0085 GETMET R9 R7 K45
0x582C002D, // 0086 LDCONST R11 K45 0x582C002E, // 0086 LDCONST R11 K46
0x7C240400, // 0087 CALL R9 2 0x7C240400, // 0087 CALL R9 2
0x78260049, // 0088 JMPF R9 #00D3 0x78260049, // 0088 JMPF R9 #00D3
0x941C0F2D, // 0089 GETIDX R7 R7 K45 0x941C0F2E, // 0089 GETIDX R7 R7 K46
0x58240006, // 008A LDCONST R9 K6 0x58240006, // 008A LDCONST R9 K6
0x50280200, // 008B LDBOOL R10 1 0 0x50280200, // 008B LDBOOL R10 1 0
0x782A0045, // 008C JMPF R10 #00D3 0x782A0045, // 008C JMPF R10 #00D3
0x60280008, // 008D GETGBL R10 G8 0x60280008, // 008D GETGBL R10 G8
0x5C2C1200, // 008E MOVE R11 R9 0x5C2C1200, // 008E MOVE R11 R9
0x7C280200, // 008F CALL R10 1 0x7C280200, // 008F CALL R10 1
0x002A5C0A, // 0090 ADD R10 K46 R10 0x002A5E0A, // 0090 ADD R10 K47 R10
0x8C2C0F2C, // 0091 GETMET R11 R7 K44 0x8C2C0F2D, // 0091 GETMET R11 R7 K45
0x5C341400, // 0092 MOVE R13 R10 0x5C341400, // 0092 MOVE R13 R10
0x7C2C0400, // 0093 CALL R11 2 0x7C2C0400, // 0093 CALL R11 2
0x742E0000, // 0094 JMPT R11 #0096 0x742E0000, // 0094 JMPT R11 #0096
0x7002003C, // 0095 JMP #00D3 0x7002003C, // 0095 JMP #00D3
0x942C0E0A, // 0096 GETIDX R11 R7 R10 0x942C0E0A, // 0096 GETIDX R11 R7 R10
0xB8320E00, // 0097 GETNGBL R12 K7 0xB8321200, // 0097 GETNGBL R12 K9
0x60340018, // 0098 GETGBL R13 G24 0x60340018, // 0098 GETGBL R13 G24
0x5838002F, // 0099 LDCONST R14 K47 0x58380030, // 0099 LDCONST R14 K48
0x5C3C1400, // 009A MOVE R15 R10 0x5C3C1400, // 009A MOVE R15 R10
0x60400008, // 009B GETGBL R16 G8 0x60400008, // 009B GETGBL R16 G8
0x5C441600, // 009C MOVE R17 R11 0x5C441600, // 009C MOVE R17 R11
0x7C400200, // 009D CALL R16 1 0x7C400200, // 009D CALL R16 1
0x7C340600, // 009E CALL R13 3 0x7C340600, // 009E CALL R13 3
0x58380013, // 009F LDCONST R14 K19 0x58380014, // 009F LDCONST R14 K20
0x7C300400, // 00A0 CALL R12 2 0x7C300400, // 00A0 CALL R12 2
0x8C301710, // 00A1 GETMET R12 R11 K16 0x8C301707, // 00A1 GETMET R12 R11 K7
0x58380030, // 00A2 LDCONST R14 K48 0x58380031, // 00A2 LDCONST R14 K49
0x543DFFFE, // 00A3 LDINT R15 -1 0x543DFFFE, // 00A3 LDINT R15 -1
0x7C300600, // 00A4 CALL R12 3 0x7C300600, // 00A4 CALL R12 3
0x8C341710, // 00A5 GETMET R13 R11 K16 0x8C341707, // 00A5 GETMET R13 R11 K7
0x583C0031, // 00A6 LDCONST R15 K49 0x583C0032, // 00A6 LDCONST R15 K50
0x5441FFFE, // 00A7 LDINT R16 -1 0x5441FFFE, // 00A7 LDINT R16 -1
0x7C340600, // 00A8 CALL R13 3 0x7C340600, // 00A8 CALL R13 3
0x24381906, // 00A9 GT R14 R12 K6 0x24381906, // 00A9 GT R14 R12 K6
0x783A0002, // 00AA JMPF R14 #00AE 0x783A0002, // 00AA JMPF R14 #00AE
0x8C381103, // 00AB GETMET R14 R8 K3 0x8C381103, // 00AB GETMET R14 R8 K3
0x04401925, // 00AC SUB R16 R12 K37 0x04401926, // 00AC SUB R16 R12 K38
0x7C380400, // 00AD CALL R14 2 0x7C380400, // 00AD CALL R14 2
0x24381B06, // 00AE GT R14 R13 K6 0x24381B06, // 00AE GT R14 R13 K6
0x783A0002, // 00AF JMPF R14 #00B3 0x783A0002, // 00AF JMPF R14 #00B3
0x8C381103, // 00B0 GETMET R14 R8 K3 0x8C381103, // 00B0 GETMET R14 R8 K3
0x04401B25, // 00B1 SUB R16 R13 K37 0x04401B26, // 00B1 SUB R16 R13 K38
0x7C380400, // 00B2 CALL R14 2 0x7C380400, // 00B2 CALL R14 2
0xB83A0E00, // 00B3 GETNGBL R14 K7 0xB83A1200, // 00B3 GETNGBL R14 K9
0x603C0018, // 00B4 GETGBL R15 G24 0x603C0018, // 00B4 GETGBL R15 G24
0x58400032, // 00B5 LDCONST R16 K50 0x58400033, // 00B5 LDCONST R16 K51
0x5C441800, // 00B6 MOVE R17 R12 0x5C441800, // 00B6 MOVE R17 R12
0x5C481A00, // 00B7 MOVE R18 R13 0x5C481A00, // 00B7 MOVE R18 R13
0x7C3C0600, // 00B8 CALL R15 3 0x7C3C0600, // 00B8 CALL R15 3
0x58400013, // 00B9 LDCONST R16 K19 0x58400014, // 00B9 LDCONST R16 K20
0x7C380400, // 00BA CALL R14 2 0x7C380400, // 00BA CALL R14 2
0x8C381710, // 00BB GETMET R14 R11 K16 0x8C381707, // 00BB GETMET R14 R11 K7
0x58400033, // 00BC LDCONST R16 K51 0x58400034, // 00BC LDCONST R16 K52
0x7C380400, // 00BD CALL R14 2 0x7C380400, // 00BD CALL R14 2
0x783A0002, // 00BE JMPF R14 #00C2 0x783A0002, // 00BE JMPF R14 #00C2
0x943C1D09, // 00BF GETIDX R15 R14 K9 0x943C1D0B, // 00BF GETIDX R15 R14 K11
0x243C1F06, // 00C0 GT R15 R15 K6 0x243C1F06, // 00C0 GT R15 R15 K6
0x743E0000, // 00C1 JMPT R15 #00C3 0x743E0000, // 00C1 JMPT R15 #00C3
0x503C0001, // 00C2 LDBOOL R15 0 1 0x503C0001, // 00C2 LDBOOL R15 0 1
@ -473,25 +477,25 @@ be_local_closure(class_Matter_Autoconf_autoconf_device_map, /* name */
0x60440013, // 00C7 GETGBL R17 G19 0x60440013, // 00C7 GETGBL R17 G19
0x7C440000, // 00C8 CALL R17 0 0x7C440000, // 00C8 CALL R17 0
0x783E0001, // 00C9 JMPF R15 #00CC 0x783E0001, // 00C9 JMPF R15 #00CC
0x58480034, // 00CA LDCONST R18 K52 0x58480035, // 00CA LDCONST R18 K53
0x70020000, // 00CB JMP #00CD 0x70020000, // 00CB JMP #00CD
0x58480035, // 00CC LDCONST R18 K53 0x58480036, // 00CC LDCONST R18 K54
0x98462212, // 00CD SETIDX R17 K17 R18 0x98462412, // 00CD SETIDX R17 K18 R18
0x98466A09, // 00CE SETIDX R17 K53 R9 0x98466C09, // 00CE SETIDX R17 K54 R9
0x98082011, // 00CF SETIDX R2 R16 R17 0x98082011, // 00CF SETIDX R2 R16 R17
0x000C0725, // 00D0 ADD R3 R3 K37 0x000C0726, // 00D0 ADD R3 R3 K38
0x00241325, // 00D1 ADD R9 R9 K37 0x00241326, // 00D1 ADD R9 R9 K38
0x7001FFB7, // 00D2 JMP #008B 0x7001FFB7, // 00D2 JMP #008B
0x6024000C, // 00D3 GETGBL R9 G12 0x6024000C, // 00D3 GETGBL R9 G12
0xB82A3800, // 00D4 GETNGBL R10 K28 0xB82A3A00, // 00D4 GETNGBL R10 K29
0x8C281536, // 00D5 GETMET R10 R10 K54 0x8C281537, // 00D5 GETMET R10 R10 K55
0x7C280200, // 00D6 CALL R10 1 0x7C280200, // 00D6 CALL R10 1
0x7C240200, // 00D7 CALL R9 1 0x7C240200, // 00D7 CALL R9 1
0x58280006, // 00D8 LDCONST R10 K6 0x58280006, // 00D8 LDCONST R10 K6
0x04241204, // 00D9 SUB R9 R9 R4 0x04241204, // 00D9 SUB R9 R9 R4
0x142C1409, // 00DA LT R11 R10 R9 0x142C1409, // 00DA LT R11 R10 R9
0x782E0011, // 00DB JMPF R11 #00EE 0x782E0011, // 00DB JMPF R11 #00EE
0x8C2C1110, // 00DC GETMET R11 R8 K16 0x8C2C1107, // 00DC GETMET R11 R8 K7
0x5C341400, // 00DD MOVE R13 R10 0x5C341400, // 00DD MOVE R13 R10
0x7C2C0400, // 00DE CALL R11 2 0x7C2C0400, // 00DE CALL R11 2
0x4C300000, // 00DF LDNIL R12 0x4C300000, // 00DF LDNIL R12
@ -502,19 +506,19 @@ be_local_closure(class_Matter_Autoconf_autoconf_device_map, /* name */
0x7C2C0200, // 00E4 CALL R11 1 0x7C2C0200, // 00E4 CALL R11 1
0x60300013, // 00E5 GETGBL R12 G19 0x60300013, // 00E5 GETGBL R12 G19
0x7C300000, // 00E6 CALL R12 0 0x7C300000, // 00E6 CALL R12 0
0x98322337, // 00E7 SETIDX R12 K17 K55 0x98322538, // 00E7 SETIDX R12 K18 K56
0x00341525, // 00E8 ADD R13 R10 K37 0x00341526, // 00E8 ADD R13 R10 K38
0x98326E0D, // 00E9 SETIDX R12 K55 R13 0x9832700D, // 00E9 SETIDX R12 K56 R13
0x9808160C, // 00EA SETIDX R2 R11 R12 0x9808160C, // 00EA SETIDX R2 R11 R12
0x000C0725, // 00EB ADD R3 R3 K37 0x000C0726, // 00EB ADD R3 R3 K38
0x00281525, // 00EC ADD R10 R10 K37 0x00281526, // 00EC ADD R10 R10 K38
0x7001FFEB, // 00ED JMP #00DA 0x7001FFEB, // 00ED JMP #00DA
0x8C2C0338, // 00EE GETMET R11 R1 K56 0x8C2C0339, // 00EE GETMET R11 R1 K57
0xB8363800, // 00EF GETNGBL R13 K28 0xB8363A00, // 00EF GETNGBL R13 K29
0x8C341B39, // 00F0 GETMET R13 R13 K57 0x8C341B3A, // 00F0 GETMET R13 R13 K58
0x7C340200, // 00F1 CALL R13 1 0x7C340200, // 00F1 CALL R13 1
0x7C2C0400, // 00F2 CALL R11 2 0x7C2C0400, // 00F2 CALL R11 2
0x8C30013A, // 00F3 GETMET R12 R0 K58 0x8C30013B, // 00F3 GETMET R12 R0 K59
0x5C381600, // 00F4 MOVE R14 R11 0x5C381600, // 00F4 MOVE R14 R11
0x7C300400, // 00F5 CALL R12 2 0x7C300400, // 00F5 CALL R12 2
0x60340010, // 00F6 GETGBL R13 G16 0x60340010, // 00F6 GETGBL R13 G16
@ -527,9 +531,9 @@ be_local_closure(class_Matter_Autoconf_autoconf_device_map, /* name */
0x5C400600, // 00FD MOVE R16 R3 0x5C400600, // 00FD MOVE R16 R3
0x7C3C0200, // 00FE CALL R15 1 0x7C3C0200, // 00FE CALL R15 1
0x98081E0E, // 00FF SETIDX R2 R15 R14 0x98081E0E, // 00FF SETIDX R2 R15 R14
0x000C0725, // 0100 ADD R3 R3 K37 0x000C0726, // 0100 ADD R3 R3 K38
0x7001FFF7, // 0101 JMP #00FA 0x7001FFF7, // 0101 JMP #00FA
0x5834001B, // 0102 LDCONST R13 K27 0x5834001C, // 0102 LDCONST R13 K28
0xAC340200, // 0103 CATCH R13 1 0 0xAC340200, // 0103 CATCH R13 1 0
0xB0080000, // 0104 RAISE 2 R0 R0 0xB0080000, // 0104 RAISE 2 R0 R0
0x80040400, // 0105 RET 1 R2 0x80040400, // 0105 RET 1 R2
@ -582,7 +586,7 @@ be_local_closure(class_Matter_Autoconf_autoconf_sensors_list, /* name */
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[121]) { /* code */ ( &(const binstruction[121]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0 0x88080100, // 0000 GETMBR R2 R0 K0
0x8808053B, // 0001 GETMBR R2 R2 K59 0x8808053C, // 0001 GETMBR R2 R2 K60
0x600C0012, // 0002 GETGBL R3 G18 0x600C0012, // 0002 GETGBL R3 G18
0x7C0C0000, // 0003 CALL R3 0 0x7C0C0000, // 0003 CALL R3 0
0x60100010, // 0004 GETGBL R4 G16 0x60100010, // 0004 GETGBL R4 G16
@ -599,19 +603,19 @@ be_local_closure(class_Matter_Autoconf_autoconf_sensors_list, /* name */
0x60240013, // 000F GETGBL R9 G19 0x60240013, // 000F GETGBL R9 G19
0x7C1C0400, // 0010 CALL R7 2 0x7C1C0400, // 0010 CALL R7 2
0x781E000A, // 0011 JMPF R7 #001D 0x781E000A, // 0011 JMPF R7 #001D
0x8C1C0D2C, // 0012 GETMET R7 R6 K44 0x8C1C0D2D, // 0012 GETMET R7 R6 K45
0x5824003C, // 0013 LDCONST R9 K60 0x5824003D, // 0013 LDCONST R9 K61
0x7C1C0400, // 0014 CALL R7 2 0x7C1C0400, // 0014 CALL R7 2
0x781E0006, // 0015 JMPF R7 #001D 0x781E0006, // 0015 JMPF R7 #001D
0x001C0B3D, // 0016 ADD R7 R5 K61 0x001C0B3E, // 0016 ADD R7 R5 K62
0x8C200703, // 0017 GETMET R8 R3 K3 0x8C200703, // 0017 GETMET R8 R3 K3
0x60280013, // 0018 GETGBL R10 G19 0x60280013, // 0018 GETGBL R10 G19
0x7C280000, // 0019 CALL R10 0 0x7C280000, // 0019 CALL R10 0
0x982A233E, // 001A SETIDX R10 K17 K62 0x982A253F, // 001A SETIDX R10 K18 K63
0x982A7E07, // 001B SETIDX R10 K63 R7 0x982A8007, // 001B SETIDX R10 K64 R7
0x7C200400, // 001C CALL R8 2 0x7C200400, // 001C CALL R8 2
0x7001FFEB, // 001D JMP #000A 0x7001FFEB, // 001D JMP #000A
0x5810001B, // 001E LDCONST R4 K27 0x5810001C, // 001E LDCONST R4 K28
0xAC100200, // 001F CATCH R4 1 0 0xAC100200, // 001F CATCH R4 1 0
0xB0080000, // 0020 RAISE 2 R0 R0 0xB0080000, // 0020 RAISE 2 R0 R0
0x60100010, // 0021 GETGBL R4 G16 0x60100010, // 0021 GETGBL R4 G16
@ -628,19 +632,19 @@ be_local_closure(class_Matter_Autoconf_autoconf_sensors_list, /* name */
0x60240013, // 002C GETGBL R9 G19 0x60240013, // 002C GETGBL R9 G19
0x7C1C0400, // 002D CALL R7 2 0x7C1C0400, // 002D CALL R7 2
0x781E000A, // 002E JMPF R7 #003A 0x781E000A, // 002E JMPF R7 #003A
0x8C1C0D2C, // 002F GETMET R7 R6 K44 0x8C1C0D2D, // 002F GETMET R7 R6 K45
0x58240040, // 0030 LDCONST R9 K64 0x58240041, // 0030 LDCONST R9 K65
0x7C1C0400, // 0031 CALL R7 2 0x7C1C0400, // 0031 CALL R7 2
0x781E0006, // 0032 JMPF R7 #003A 0x781E0006, // 0032 JMPF R7 #003A
0x001C0B41, // 0033 ADD R7 R5 K65 0x001C0B42, // 0033 ADD R7 R5 K66
0x8C200703, // 0034 GETMET R8 R3 K3 0x8C200703, // 0034 GETMET R8 R3 K3
0x60280013, // 0035 GETGBL R10 G19 0x60280013, // 0035 GETGBL R10 G19
0x7C280000, // 0036 CALL R10 0 0x7C280000, // 0036 CALL R10 0
0x982A2342, // 0037 SETIDX R10 K17 K66 0x982A2543, // 0037 SETIDX R10 K18 K67
0x982A7E07, // 0038 SETIDX R10 K63 R7 0x982A8007, // 0038 SETIDX R10 K64 R7
0x7C200400, // 0039 CALL R8 2 0x7C200400, // 0039 CALL R8 2
0x7001FFEB, // 003A JMP #0027 0x7001FFEB, // 003A JMP #0027
0x5810001B, // 003B LDCONST R4 K27 0x5810001C, // 003B LDCONST R4 K28
0xAC100200, // 003C CATCH R4 1 0 0xAC100200, // 003C CATCH R4 1 0
0xB0080000, // 003D RAISE 2 R0 R0 0xB0080000, // 003D RAISE 2 R0 R0
0x60100010, // 003E GETGBL R4 G16 0x60100010, // 003E GETGBL R4 G16
@ -657,19 +661,19 @@ be_local_closure(class_Matter_Autoconf_autoconf_sensors_list, /* name */
0x60240013, // 0049 GETGBL R9 G19 0x60240013, // 0049 GETGBL R9 G19
0x7C1C0400, // 004A CALL R7 2 0x7C1C0400, // 004A CALL R7 2
0x781E000A, // 004B JMPF R7 #0057 0x781E000A, // 004B JMPF R7 #0057
0x8C1C0D2C, // 004C GETMET R7 R6 K44 0x8C1C0D2D, // 004C GETMET R7 R6 K45
0x58240043, // 004D LDCONST R9 K67 0x58240044, // 004D LDCONST R9 K68
0x7C1C0400, // 004E CALL R7 2 0x7C1C0400, // 004E CALL R7 2
0x781E0006, // 004F JMPF R7 #0057 0x781E0006, // 004F JMPF R7 #0057
0x001C0B44, // 0050 ADD R7 R5 K68 0x001C0B45, // 0050 ADD R7 R5 K69
0x8C200703, // 0051 GETMET R8 R3 K3 0x8C200703, // 0051 GETMET R8 R3 K3
0x60280013, // 0052 GETGBL R10 G19 0x60280013, // 0052 GETGBL R10 G19
0x7C280000, // 0053 CALL R10 0 0x7C280000, // 0053 CALL R10 0
0x982A2345, // 0054 SETIDX R10 K17 K69 0x982A2546, // 0054 SETIDX R10 K18 K70
0x982A7E07, // 0055 SETIDX R10 K63 R7 0x982A8007, // 0055 SETIDX R10 K64 R7
0x7C200400, // 0056 CALL R8 2 0x7C200400, // 0056 CALL R8 2
0x7001FFEB, // 0057 JMP #0044 0x7001FFEB, // 0057 JMP #0044
0x5810001B, // 0058 LDCONST R4 K27 0x5810001C, // 0058 LDCONST R4 K28
0xAC100200, // 0059 CATCH R4 1 0 0xAC100200, // 0059 CATCH R4 1 0
0xB0080000, // 005A RAISE 2 R0 R0 0xB0080000, // 005A RAISE 2 R0 R0
0x60100010, // 005B GETGBL R4 G16 0x60100010, // 005B GETGBL R4 G16
@ -686,19 +690,19 @@ be_local_closure(class_Matter_Autoconf_autoconf_sensors_list, /* name */
0x60240013, // 0066 GETGBL R9 G19 0x60240013, // 0066 GETGBL R9 G19
0x7C1C0400, // 0067 CALL R7 2 0x7C1C0400, // 0067 CALL R7 2
0x781E000A, // 0068 JMPF R7 #0074 0x781E000A, // 0068 JMPF R7 #0074
0x8C1C0D2C, // 0069 GETMET R7 R6 K44 0x8C1C0D2D, // 0069 GETMET R7 R6 K45
0x58240046, // 006A LDCONST R9 K70 0x58240047, // 006A LDCONST R9 K71
0x7C1C0400, // 006B CALL R7 2 0x7C1C0400, // 006B CALL R7 2
0x781E0006, // 006C JMPF R7 #0074 0x781E0006, // 006C JMPF R7 #0074
0x001C0B47, // 006D ADD R7 R5 K71 0x001C0B48, // 006D ADD R7 R5 K72
0x8C200703, // 006E GETMET R8 R3 K3 0x8C200703, // 006E GETMET R8 R3 K3
0x60280013, // 006F GETGBL R10 G19 0x60280013, // 006F GETGBL R10 G19
0x7C280000, // 0070 CALL R10 0 0x7C280000, // 0070 CALL R10 0
0x982A2348, // 0071 SETIDX R10 K17 K72 0x982A2549, // 0071 SETIDX R10 K18 K73
0x982A7E07, // 0072 SETIDX R10 K63 R7 0x982A8007, // 0072 SETIDX R10 K64 R7
0x7C200400, // 0073 CALL R8 2 0x7C200400, // 0073 CALL R8 2
0x7001FFEB, // 0074 JMP #0061 0x7001FFEB, // 0074 JMP #0061
0x5810001B, // 0075 LDCONST R4 K27 0x5810001C, // 0075 LDCONST R4 K28
0xAC100200, // 0076 CATCH R4 1 0 0xAC100200, // 0076 CATCH R4 1 0
0xB0080000, // 0077 RAISE 2 R0 R0 0xB0080000, // 0077 RAISE 2 R0 R0
0x80040600, // 0078 RET 1 R3 0x80040600, // 0078 RET 1 R3

View File

@ -3,8 +3,8 @@
* Generated code, don't edit * * Generated code, don't edit *
\********************************************************************/ \********************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
// compact class 'Matter_Commissioning' ktab size: 132, total: 272 (saved 1120 bytes) // compact class 'Matter_Commissioning' ktab size: 127, total: 259 (saved 1056 bytes)
static const bvalue be_ktab_class_Matter_Commissioning[132] = { static const bvalue be_ktab_class_Matter_Commissioning[127] = {
/* K0 */ be_nested_str_weak(device), /* K0 */ be_nested_str_weak(device),
/* K1 */ be_nested_str_weak(sessions), /* K1 */ be_nested_str_weak(sessions),
/* K2 */ be_nested_str_weak(active_fabrics), /* K2 */ be_nested_str_weak(active_fabrics),
@ -128,15 +128,10 @@ static const bvalue be_ktab_class_Matter_Commissioning[132] = {
/* K120 */ be_nested_str_weak(_CM1), /* K120 */ be_nested_str_weak(_CM1),
/* K121 */ be_nested_str_weak(MTR_X3A_X20starting_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27_X20ptr_X20to_X20_X60_X25s_X2Elocal_X60), /* K121 */ be_nested_str_weak(MTR_X3A_X20starting_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27_X20ptr_X20to_X20_X60_X25s_X2Elocal_X60),
/* K122 */ be_nested_str_weak(millis), /* K122 */ be_nested_str_weak(millis),
/* K123 */ be_nested_str_weak(mdns_announce_PASE), /* K123 */ be_nested_str_weak(when_network_up),
/* K124 */ be_nested_str_weak(add_rule), /* K124 */ be_nested_str_weak(get_fabric),
/* K125 */ be_nested_str_weak(Wifi_X23Connected), /* K125 */ be_nested_str_weak(get_admin_vendor_name),
/* K126 */ be_nested_str_weak(Eth_X23Connected), /* K126 */ 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),
/* K127 */ be_nested_str_weak(_mdns_announce_hostname),
/* K128 */ be_nested_str_weak(matter_mdns_host),
/* K129 */ be_nested_str_weak(get_fabric),
/* K130 */ be_nested_str_weak(get_admin_vendor_name),
/* K131 */ 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),
}; };
@ -1551,15 +1546,15 @@ be_local_closure(class_Matter_Commissioning_mdns_announce_PASE, /* name */
********************************************************************/ ********************************************************************/
be_local_closure(class_Matter_Commissioning_start_basic_commissioning, /* name */ be_local_closure(class_Matter_Commissioning_start_basic_commissioning, /* name */
be_nested_proto( be_nested_proto(
13, /* nstack */ 11, /* nstack */
8, /* argc */ 8, /* argc */
10, /* varg */ 10, /* varg */
0, /* has upvals */ 0, /* has upvals */
NULL, /* no upvals */ NULL, /* no upvals */
1, /* has sup protos */ 1, /* has sup protos */
( &(const struct bproto*[ 2]) { ( &(const struct bproto*[ 1]) {
be_nested_proto( be_nested_proto(
4, /* nstack */ 2, /* nstack */
0, /* argc */ 0, /* argc */
0, /* varg */ 0, /* varg */
1, /* has upvals */ 1, /* has upvals */
@ -1569,55 +1564,16 @@ be_local_closure(class_Matter_Commissioning_start_basic_commissioning, /* name
0, /* has sup protos */ 0, /* has sup protos */
NULL, /* no sub protos */ NULL, /* no sub protos */
1, /* has constants */ 1, /* has constants */
( &(const bvalue[ 4]) { /* constants */ ( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str_weak(mdns_announce_PASE), /* 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_str_weak(_anonymous_),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[ 9]) { /* code */ ( &(const binstruction[ 4]) { /* code */
0x68000000, // 0000 GETUPV R0 U0 0x68000000, // 0000 GETUPV R0 U0
0x8C000100, // 0001 GETMET R0 R0 K0 0x8C000100, // 0001 GETMET R0 R0 K0
0x7C000200, // 0002 CALL R0 1 0x7C000200, // 0002 CALL R0 1
0xB8020200, // 0003 GETNGBL R0 K1 0x80000000, // 0003 RET 0
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
}) })
), ),
}), }),
@ -1625,7 +1581,7 @@ be_local_closure(class_Matter_Commissioning_start_basic_commissioning, /* name
&be_ktab_class_Matter_Commissioning, /* shared constants */ &be_ktab_class_Matter_Commissioning, /* shared constants */
be_str_weak(start_basic_commissioning), be_str_weak(start_basic_commissioning),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[40]) { /* code */ ( &(const binstruction[19]) { /* code */
0xB8221000, // 0000 GETNGBL R8 K8 0xB8221000, // 0000 GETNGBL R8 K8
0x8C20117A, // 0001 GETMET R8 R8 K122 0x8C20117A, // 0001 GETMET R8 R8 K122
0x7C200200, // 0002 CALL R8 1 0x7C200200, // 0002 CALL R8 1
@ -1640,32 +1596,11 @@ be_local_closure(class_Matter_Commissioning_start_basic_commissioning, /* name
0x90022406, // 000B SETMBR R0 K18 R6 0x90022406, // 000B SETMBR R0 K18 R6
0x90022607, // 000C SETMBR R0 K19 R7 0x90022607, // 000C SETMBR R0 K19 R7
0xB8221000, // 000D GETNGBL R8 K8 0xB8221000, // 000D GETNGBL R8 K8
0x8C201131, // 000E GETMET R8 R8 K49 0x8C20117B, // 000E GETMET R8 R8 K123
0x7C200200, // 000F CALL R8 1 0x84280000, // 000F CLOSURE R10 P0
0x9420113E, // 0010 GETIDX R8 R8 K62 0x7C200400, // 0010 CALL R8 2
0x74220004, // 0011 JMPT R8 #0017 0xA0000000, // 0011 CLOSE R0
0xB8221000, // 0012 GETNGBL R8 K8 0x80000000, // 0012 RET 0
0x8C20112C, // 0013 GETMET R8 R8 K44
0x7C200200, // 0014 CALL R8 1
0x9420113E, // 0015 GETIDX R8 R8 K62
0x78220002, // 0016 JMPF R8 #001A
0x8C20017B, // 0017 GETMET R8 R0 K123
0x7C200200, // 0018 CALL R8 1
0x7002000B, // 0019 JMP #0026
0xB8221000, // 001A GETNGBL R8 K8
0x8C20117C, // 001B GETMET R8 R8 K124
0x5828007D, // 001C LDCONST R10 K125
0x842C0000, // 001D CLOSURE R11 P0
0x5830007B, // 001E LDCONST R12 K123
0x7C200800, // 001F CALL R8 4
0xB8221000, // 0020 GETNGBL R8 K8
0x8C20117C, // 0021 GETMET R8 R8 K124
0x5828007E, // 0022 LDCONST R10 K126
0x842C0001, // 0023 CLOSURE R11 P1
0x5830007B, // 0024 LDCONST R12 K123
0x7C200800, // 0025 CALL R8 4
0xA0000000, // 0026 CLOSE R0
0x80000000, // 0027 RET 0
}) })
) )
); );
@ -1677,15 +1612,15 @@ be_local_closure(class_Matter_Commissioning_start_basic_commissioning, /* name
********************************************************************/ ********************************************************************/
be_local_closure(class_Matter_Commissioning_start_mdns_announce_hostnames, /* name */ be_local_closure(class_Matter_Commissioning_start_mdns_announce_hostnames, /* name */
be_nested_proto( be_nested_proto(
6, /* nstack */ 4, /* nstack */
1, /* argc */ 1, /* argc */
10, /* varg */ 10, /* varg */
0, /* has upvals */ 0, /* has upvals */
NULL, /* no upvals */ NULL, /* no upvals */
1, /* has sup protos */ 1, /* has sup protos */
( &(const struct bproto*[ 2]) { ( &(const struct bproto*[ 1]) {
be_nested_proto( be_nested_proto(
4, /* nstack */ 3, /* nstack */
0, /* argc */ 0, /* argc */
0, /* varg */ 0, /* varg */
1, /* has upvals */ 1, /* has upvals */
@ -1696,58 +1631,34 @@ be_local_closure(class_Matter_Commissioning_start_mdns_announce_hostnames, /*
NULL, /* no sub protos */ NULL, /* no sub protos */
1, /* has constants */ 1, /* has constants */
( &(const bvalue[ 5]) { /* constants */ ( &(const bvalue[ 5]) { /* constants */
/* K0 */ be_nested_str_weak(_mdns_announce_hostname), /* K0 */ be_nested_str_weak(tasmota),
/* K1 */ be_nested_str_weak(tasmota), /* K1 */ be_nested_str_weak(wifi),
/* K2 */ be_nested_str_weak(remove_rule), /* K2 */ be_nested_str_weak(up),
/* K3 */ be_nested_str_weak(Wifi_X23Connected), /* K3 */ be_nested_str_weak(_mdns_announce_hostname),
/* K4 */ be_nested_str_weak(matter_mdns_host), /* K4 */ be_nested_str_weak(eth),
}), }),
be_str_weak(_anonymous_), be_str_weak(_anonymous_),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[10]) { /* code */ ( &(const binstruction[19]) { /* code */
0x68000000, // 0000 GETUPV R0 U0 0xB8020000, // 0000 GETNGBL R0 K0
0x8C000100, // 0001 GETMET R0 R0 K0 0x8C000101, // 0001 GETMET R0 R0 K1
0x50080000, // 0002 LDBOOL R2 0 0 0x58080002, // 0002 LDCONST R2 K2
0x7C000400, // 0003 CALL R0 2 0x7C000400, // 0003 CALL R0 2
0xB8020200, // 0004 GETNGBL R0 K1 0x78020003, // 0004 JMPF R0 #0009
0x8C000102, // 0005 GETMET R0 R0 K2 0x68000000, // 0005 GETUPV R0 U0
0x58080003, // 0006 LDCONST R2 K3 0x8C000103, // 0006 GETMET R0 R0 K3
0x580C0004, // 0007 LDCONST R3 K4 0x50080000, // 0007 LDBOOL R2 0 0
0x7C000600, // 0008 CALL R0 3 0x7C000400, // 0008 CALL R0 2
0x80000000, // 0009 RET 0 0xB8020000, // 0009 GETNGBL R0 K0
}) 0x8C000104, // 000A GETMET R0 R0 K4
), 0x58080002, // 000B LDCONST R2 K2
be_nested_proto( 0x7C000400, // 000C CALL R0 2
4, /* nstack */ 0x78020003, // 000D JMPF R0 #0012
0, /* argc */ 0x68000000, // 000E GETUPV R0 U0
0, /* varg */ 0x8C000103, // 000F GETMET R0 R0 K3
1, /* has upvals */ 0x50080200, // 0010 LDBOOL R2 1 0
( &(const bupvaldesc[ 1]) { /* upvals */ 0x7C000400, // 0011 CALL R0 2
be_local_const_upval(1, 0), 0x80000000, // 0012 RET 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
}) })
), ),
}), }),
@ -1755,39 +1666,13 @@ be_local_closure(class_Matter_Commissioning_start_mdns_announce_hostnames, /*
&be_ktab_class_Matter_Commissioning, /* shared constants */ &be_ktab_class_Matter_Commissioning, /* shared constants */
be_str_weak(start_mdns_announce_hostnames), be_str_weak(start_mdns_announce_hostnames),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[32]) { /* code */ ( &(const binstruction[ 6]) { /* code */
0xB8061000, // 0000 GETNGBL R1 K8 0xB8061000, // 0000 GETNGBL R1 K8
0x8C040331, // 0001 GETMET R1 R1 K49 0x8C04037B, // 0001 GETMET R1 R1 K123
0x7C040200, // 0002 CALL R1 1 0x840C0000, // 0002 CLOSURE R3 P0
0x9404033E, // 0003 GETIDX R1 R1 K62 0x7C040400, // 0003 CALL R1 2
0x78060003, // 0004 JMPF R1 #0009 0xA0000000, // 0004 CLOSE R0
0x8C04017F, // 0005 GETMET R1 R0 K127 0x80000000, // 0005 RET 0
0x500C0000, // 0006 LDBOOL R3 0 0
0x7C040400, // 0007 CALL R1 2
0x70020005, // 0008 JMP #000F
0xB8061000, // 0009 GETNGBL R1 K8
0x8C04037C, // 000A GETMET R1 R1 K124
0x580C007D, // 000B LDCONST R3 K125
0x84100000, // 000C CLOSURE R4 P0
0x58140080, // 000D LDCONST R5 K128
0x7C040800, // 000E CALL R1 4
0xB8061000, // 000F GETNGBL R1 K8
0x8C04032C, // 0010 GETMET R1 R1 K44
0x7C040200, // 0011 CALL R1 1
0x9404033E, // 0012 GETIDX R1 R1 K62
0x78060003, // 0013 JMPF R1 #0018
0x8C04017F, // 0014 GETMET R1 R0 K127
0x500C0200, // 0015 LDBOOL R3 1 0
0x7C040400, // 0016 CALL R1 2
0x70020005, // 0017 JMP #001E
0xB8061000, // 0018 GETNGBL R1 K8
0x8C04037C, // 0019 GETMET R1 R1 K124
0x580C007E, // 001A LDCONST R3 K126
0x84100001, // 001B CLOSURE R4 P1
0x58140080, // 001C LDCONST R5 K128
0x7C040800, // 001D CALL R1 4
0xA0000000, // 001E CLOSE R0
0x80000000, // 001F RET 0
}) })
) )
); );
@ -1872,7 +1757,7 @@ be_local_closure(class_Matter_Commissioning_start_commissioning_complete, /* n
be_str_weak(start_commissioning_complete), be_str_weak(start_commissioning_complete),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[23]) { /* code */ ( &(const binstruction[23]) { /* code */
0x8C080381, // 0000 GETMET R2 R1 K129 0x8C08037C, // 0000 GETMET R2 R1 K124
0x7C080200, // 0001 CALL R2 1 0x7C080200, // 0001 CALL R2 1
0x8C0C0504, // 0002 GETMET R3 R2 K4 0x8C0C0504, // 0002 GETMET R3 R2 K4
0x7C0C0200, // 0003 CALL R3 1 0x7C0C0200, // 0003 CALL R3 1
@ -1882,11 +1767,11 @@ be_local_closure(class_Matter_Commissioning_start_commissioning_complete, /* n
0x7C0C0200, // 0007 CALL R3 1 0x7C0C0200, // 0007 CALL R3 1
0x8C0C073B, // 0008 GETMET R3 R3 K59 0x8C0C073B, // 0008 GETMET R3 R3 K59
0x7C0C0200, // 0009 CALL R3 1 0x7C0C0200, // 0009 CALL R3 1
0x8C100582, // 000A GETMET R4 R2 K130 0x8C10057D, // 000A GETMET R4 R2 K125
0x7C100200, // 000B CALL R4 1 0x7C100200, // 000B CALL R4 1
0xB8164A00, // 000C GETNGBL R5 K37 0xB8164A00, // 000C GETNGBL R5 K37
0x60180018, // 000D GETGBL R6 G24 0x60180018, // 000D GETGBL R6 G24
0x581C0083, // 000E LDCONST R7 K131 0x581C007E, // 000E LDCONST R7 K126
0x5C200600, // 000F MOVE R8 R3 0x5C200600, // 000F MOVE R8 R3
0x5C240800, // 0010 MOVE R9 R4 0x5C240800, // 0010 MOVE R9 R4
0x7C180600, // 0011 CALL R6 3 0x7C180600, // 0011 CALL R6 3

View File

@ -0,0 +1,897 @@
/*
be_httpserver_lib.c - HTTP server support for Berry using ESP-IDF HTTP server
Copyright (C) 2025 Jonathan E. Peace
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 <http://www.gnu.org/licenses/>.
*/
#ifdef USE_BERRY_HTTPSERVER
#include <stddef.h> // For NULL, size_t
#include <stdbool.h> // For bool, true, false
#include <string.h> // For string functions
#include <stdlib.h> // For malloc/free
// ESP-IDF includes
#define LOG_LOCAL_LEVEL ESP_LOG_INFO
#include "esp_log.h"
#include "esp_http_server.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
// Berry includes
#include "be_mapping.h"
#include "be_exec.h"
#include "be_vm.h"
#include "be_gc.h"
// External function declarations
httpd_handle_t be_httpserver_get_handle(void);
void be_httpserver_set_disconnect_handler(httpd_close_func_t handler);
bool httpserver_has_queue(void);
// Message types for queue
typedef enum {
HTTP_MSG_WEBSOCKET = 1,
HTTP_MSG_FILE = 2,
HTTP_MSG_WEB = 3
} http_msg_type_t;
// Message structure for queue
typedef struct {
http_msg_type_t type;
int client_id;
void *data;
size_t data_len;
void *user_data;
bvalue func; // Berry function value for web handlers
httpd_req_t *req; // HTTP request handle for async processing
} http_queue_msg_t;
// Forward declarations for internal functions
void be_httpserver_process_websocket_msg(bvm *vm, int client_id, const char *data, size_t len);
bool httpserver_queue_message(http_msg_type_t type, int client_id, const void *data, size_t data_len, void *user_data);
bool httpserver_queue_web_request(int handler_id, httpd_req_t *req, bvalue func);
// Logger tag
static const char *TAG = "HTTPSERVER";
// Global queue for handling messages in the main task context
static QueueHandle_t http_msg_queue = NULL;
static SemaphoreHandle_t http_queue_mutex = NULL;
static bool http_queue_initialized = false;
// Maximum number of HTTP handlers
#define HTTP_HANDLER_MAX 5
// Handler storage
typedef struct {
bool active; // Whether this handler is in use
bvm *vm; // Berry VM instance
bvalue func; // Berry function to call for requests
} http_handler_t;
static http_handler_t http_handlers[HTTP_HANDLER_MAX];
// Maximum concurrent HTTP server connections
#define HTTPD_MAX_CONNECTIONS 8
// Handle to HTTP server
static httpd_handle_t http_server = NULL;
// Disconnect handler for WebSocket connections
static httpd_close_func_t http_server_disconn_handler = NULL;
// Current HTTP request being processed (for Berry access)
static httpd_req_t *current_request = NULL;
// Connection tracking
static struct {
int count;
SemaphoreHandle_t mutex;
} connection_tracking = {0, NULL};
// Connection cleanup function
// CONTEXT: ESP-IDF HTTP Server Task
// Called automatically by ESP-IDF when a client disconnects
static void http_connection_cleanup(void *arg) {
if (xSemaphoreTake(connection_tracking.mutex, pdMS_TO_TICKS(100)) == pdTRUE) {
connection_tracking.count--;
xSemaphoreGive(connection_tracking.mutex);
// Call WebSocket disconnect handler if registered
if (http_server_disconn_handler) {
// arg is the socket file descriptor in this context
http_server_disconn_handler(NULL, (int)(intptr_t)arg);
}
}
}
// WebSocket message processing function
// CONTEXT: Main Tasmota Task (Berry VM Context)
// This function runs in the main task when processing queued WebSocket messages
void be_httpserver_process_websocket_msg(bvm *vm, int client_id, const char *data, size_t data_len) {
// Log message details safely (handling NULL data for connect events)
if (data) {
ESP_LOGD(TAG, "Processing WebSocket message in main task context: client=%d, data='%s', len=%d",
client_id, data, (int)data_len);
} else {
ESP_LOGD(TAG, "Processing WebSocket event in main task context: client=%d", client_id);
}
// Forward to the WebSocket handler in be_wsserver_lib.c
be_wsserver_handle_message(vm, client_id, data, data_len);
}
// File request processing function
static void be_httpserver_process_file_request(bvm *vm, void *user_data) {
ESP_LOGI(TAG, "Processing file request (placeholder)");
// Placeholder for file handling - to be extended as needed
}
// Initialize the message queue
static bool init_http_queue() {
if (!http_queue_initialized) {
http_msg_queue = xQueueCreate(10, sizeof(http_queue_msg_t));
http_queue_mutex = xSemaphoreCreateMutex();
if (http_msg_queue != NULL && http_queue_mutex != NULL) {
http_queue_initialized = true;
ESP_LOGI(TAG, "HTTP queue initialized");
return true;
} else {
ESP_LOGE(TAG, "Failed to create HTTP queue");
return false;
}
}
return true;
}
// Queue a message for processing in the main task
// CONTEXT: Any Task (typically ESP-IDF HTTP Server Task)
// This function is called to queue messages for processing in the main task
// TRANSITION: Current Task → Main Tasmota Task
bool httpserver_queue_message(http_msg_type_t type, int client_id, const void *data, size_t data_len, void *user_data) {
if (!http_queue_initialized) {
ESP_LOGE(TAG, "Queue not initialized");
return false;
}
if (!data && data_len > 0) {
ESP_LOGE(TAG, "Invalid data pointer with non-zero length");
return false;
}
// Take mutex to protect queue
if (xSemaphoreTake(http_queue_mutex, pdMS_TO_TICKS(100)) != pdTRUE) {
ESP_LOGE(TAG, "Failed to take mutex");
return false;
}
// Create a message to queue
http_queue_msg_t msg = {0};;
msg.type = type;
msg.client_id = client_id;
msg.user_data = user_data;
// Special case for HTTP_MSG_WEB is handled by httpserver_queue_web_request
if (type == HTTP_MSG_WEB) {
ESP_LOGE(TAG, "HTTP_MSG_WEB must use httpserver_queue_web_request");
xSemaphoreGive(http_queue_mutex);
return false;
}
// For other message types, copy the data if needed
if (data_len > 0) {
char *data_copy = malloc(data_len + 1);
if (!data_copy) {
ESP_LOGE(TAG, "Failed to allocate memory for data copy");
xSemaphoreGive(http_queue_mutex);
return false;
}
memcpy(data_copy, data, data_len);
data_copy[data_len] = '\0'; // Ensure null termination
msg.data = data_copy;
msg.data_len = data_len;
}
// Queue the message
if (xQueueSend(http_msg_queue, &msg, 0) != pdTRUE) {
// Queue is full, free the data if we allocated it
if (msg.data) {
free(msg.data);
}
ESP_LOGE(TAG, "Failed to queue message - queue is full");
xSemaphoreGive(http_queue_mutex);
return false;
}
// Message successfully queued
ESP_LOGD(TAG, "Message queued successfully (type %d, client %d)", type, client_id);
ESP_LOGD(TAG, "DIAGNOSTIC: Queue has %d messages waiting", uxQueueMessagesWaiting(http_msg_queue));
if (msg.data) {
ESP_LOGD(TAG, "QUEUE ITEM: type=%d, client=%d, data_len=%d, data_ptr=%p, user_data=%p",
msg.type, msg.client_id, (int)msg.data_len, msg.data, msg.user_data);
ESP_LOGD(TAG, "QUEUE DATA: '%s'", msg.data);
}
xSemaphoreGive(http_queue_mutex);
return true;
}
// Specialized function for queuing HTTP web requests with a Berry function
bool httpserver_queue_web_request(int handler_id, httpd_req_t *req, bvalue func) {
if (!http_queue_initialized) {
ESP_LOGE(TAG, "Queue not initialized");
return false;
}
if (!req) {
ESP_LOGE(TAG, "NULL request for web request");
return false;
}
// Create a copy of the request that we can process asynchronously
httpd_req_t *req_copy = NULL;
esp_err_t err = httpd_req_async_handler_begin(req, &req_copy);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to create async request: %d", err);
return false;
}
// Take mutex to protect queue
if (xSemaphoreTake(http_queue_mutex, pdMS_TO_TICKS(100)) != pdTRUE) {
ESP_LOGE(TAG, "Failed to take mutex");
// Release the request copy since we won't be using it
httpd_req_async_handler_complete(req_copy);
return false;
}
// Create a message to queue
http_queue_msg_t msg = {0};
msg.type = HTTP_MSG_WEB;
msg.client_id = handler_id;
msg.user_data = NULL;
msg.func = func; // Store the function reference
msg.req = req_copy; // Store the COPY of the request handle
// Queue the message
if (xQueueSend(http_msg_queue, &msg, 0) != pdTRUE) {
// Queue is full
ESP_LOGE(TAG, "Failed to queue web request - queue is full");
// Release the request copy since we won't be using it
httpd_req_async_handler_complete(req_copy);
xSemaphoreGive(http_queue_mutex);
return false;
}
// Message successfully queued
ESP_LOGD(TAG, "HTTP request queued successfully (type %d, handler %d)", msg.type, msg.client_id);
ESP_LOGD(TAG, "DIAGNOSTIC: Queue has %d messages waiting", uxQueueMessagesWaiting(http_msg_queue));
ESP_LOGD(TAG, "QUEUE ITEM: type=%d, client=%d, data_len=%d, data_ptr=%p, user_data=%p, req=%p",
msg.type, msg.client_id, (int)msg.data_len, msg.data, msg.user_data, msg.req);
xSemaphoreGive(http_queue_mutex);
return true;
}
// ------------------------------------------------------------------------
// Web request processing function
// CONTEXT: Main Tasmota Task (Berry VM Context)
// This function processes queued web requests in the main task context
// ------------------------------------------------------------------------
void be_httpserver_process_web_request(bvm *vm, http_queue_msg_t *msg) {
ESP_LOGD(TAG, "Processing web request: msg=%p", msg);
if (!msg) {
ESP_LOGE(TAG, "Web request has NULL message handle");
return;
}
ESP_LOGD(TAG, "Request details: req=%p, client_id=%d", msg->req, msg->client_id);
if (!msg->req) {
ESP_LOGE(TAG, "Web request has NULL request handle");
return;
}
// Get handler ID (passed in client_id field)
int handler_id = msg->client_id;
if (handler_id < 0 || handler_id >= HTTP_HANDLER_MAX || !http_handlers[handler_id].active) {
ESP_LOGE(TAG, "Invalid handler ID from queue: %d", handler_id);
httpd_resp_set_status(msg->req, "500 Internal Server Error");
httpd_resp_sendstr(msg->req, "Invalid handler ID");
httpd_req_async_handler_complete(msg->req);
return;
}
ESP_LOGI(TAG, "Processing web request for URI: %s with handler %d", msg->req->uri, handler_id);
// Get the Berry VM and handler function
bvm *handler_vm = http_handlers[handler_id].vm;
if (handler_vm == NULL) {
ESP_LOGE(TAG, "Berry VM is NULL for handler %d", handler_id);
httpd_resp_set_status(msg->req, "500 Internal Server Error");
httpd_resp_sendstr(msg->req, "VM error");
httpd_req_async_handler_complete(msg->req);
return;
}
ESP_LOGI(TAG, "STACK: Before pushing function, stack top = %d", be_top(handler_vm));
// Push the function stored in the message
be_pushnil(handler_vm);
bvalue *top = be_indexof(handler_vm, -1);
*top = msg->func;
current_request = msg->req;
// Push URI as argument
be_pushstring(handler_vm, current_request->uri);
// Check if this is a POST request and handle POST data
int arg_count = 1; // Start with 1 for the URI
if (current_request->method == HTTP_POST) {
ESP_LOGI(TAG, "Processing POST request data");
// Get content length
int content_len = current_request->content_len;
ESP_LOGI(TAG, "POST content length: %d", content_len);
if (content_len > 0) {
// Allocate buffer for POST data
char *post_data = malloc(content_len + 1);
if (post_data) {
// Read POST data
int received = httpd_req_recv(current_request, post_data, content_len);
if (received > 0) {
// Null-terminate the data
post_data[received] = '\0';
ESP_LOGI(TAG, "Received POST data: %s", post_data);
// Push POST data as second argument
be_pushstring(handler_vm, post_data);
arg_count = 2; // Now we have 2 arguments
} else {
ESP_LOGW(TAG, "Failed to read POST data, received: %d", received);
// Push nil as second argument
be_pushnil(handler_vm);
arg_count = 2;
}
free(post_data);
} else {
ESP_LOGE(TAG, "Failed to allocate memory for POST data");
// Push nil as second argument
be_pushnil(handler_vm);
arg_count = 2;
}
} else {
// No content, push empty string as second argument
be_pushstring(handler_vm, "");
arg_count = 2;
}
}
// Call the Berry function
int result = be_pcall(handler_vm, arg_count);
// Log stack state after call
ESP_LOGI(TAG, "STACK: After be_pcall, stack top = %d, result = %d", be_top(handler_vm), result);
// Check for errors
if (result != 0) {
const char *err_msg = be_tostring(handler_vm, -1);
ESP_LOGE(TAG, "Berry handler error: %s", err_msg);
// Send error response
httpd_resp_set_status(msg->req, "500 Internal Server Error");
httpd_resp_sendstr(msg->req, (char*)err_msg);
be_error_pop_all(handler_vm); // Clear entire stack on error
} else {
// Get return value
const char *response = be_tostring(handler_vm, -1);
ESP_LOGI(TAG, "Request processed. Response: %s", response ? response : "(null)");
// Send success response if httpserver.send() wasn't used
if (response != NULL) {
httpd_resp_set_type(msg->req, "text/html");
httpd_resp_sendstr(msg->req, response);
}
// Pop the argument (which has been replaced by the return value)
be_pop(handler_vm, 1);
}
// Clear current_request AFTER all processing is done
current_request = NULL;
// Complete the async request - ALWAYS call this to release the request
httpd_req_async_handler_complete(msg->req);
// Pop the function if we didn't encounter an error
if (result == 0) {
// Pop the function
be_pop(handler_vm, 1); // Pop the function reference
} else {
ESP_LOGE(TAG, "Function parsing error: %d", result);
}
// Log final stack state
ESP_LOGI(TAG, "STACK: Final state, stack top = %d", be_top(handler_vm));
}
// ------------------------------------------------------------------------
// Berry mapped C function to process queued messages
// CONTEXT: Main Tasmota Task (Berry VM Context)
// This function is registered to fast_loop() by the Berry app and is called
// periodically to process queued HTTP/WebSocket messages from the ESP-IDF HTTP server
// ------------------------------------------------------------------------
static int w_httpserver_process_queue(bvm *vm) {
if (!http_msg_queue) {
be_pushnil(vm);
be_return(vm);
}
// Count of messages processed in this call
int processed = 0;
// Process up to 5 messages in a single call to avoid blocking
for (int i = 0; i < 5; i++) {
// Take mutex before accessing queue
if (xSemaphoreTake(http_queue_mutex, 0) != pdTRUE) {
ESP_LOGW(TAG, "Failed to take mutex, will retry");
break;
}
// Process one message from the queue
http_queue_msg_t msg;
if (xQueueReceive(http_msg_queue, &msg, 0) == pdTRUE) {
// Release mutex while processing message
xSemaphoreGive(http_queue_mutex);
// Count this message
processed++;
// Diagnostic logging for queue state
ESP_LOGD(TAG, "QUEUE ITEM: type=%d, client=%d, data_len=%d, data_ptr=%p, user_data=%p, req=%p",
msg.type, msg.client_id, msg.data_len, msg.data, msg.user_data, msg.req);
// Process message based on type
switch (msg.type) {
case HTTP_MSG_WEBSOCKET:
if (msg.data) {
ESP_LOGD(TAG, "QUEUE DATA: '%.*s'", msg.data_len, (char*)msg.data);
} else {
ESP_LOGD(TAG, "QUEUE DATA: '' (connect/disconnect event)");
}
be_httpserver_process_websocket_msg(vm, msg.client_id, msg.data, msg.data_len);
// Free the data buffer we allocated
if (msg.data) {
free(msg.data);
}
break;
case HTTP_MSG_FILE:
ESP_LOGI(TAG, "Processing file request");
be_httpserver_process_file_request(vm, msg.user_data);
// user_data is not allocated by us, so don't free it
break;
case HTTP_MSG_WEB:
ESP_LOGD(TAG, "Processing web request from queue");
if (msg.req == NULL) {
ESP_LOGE(TAG, "CRITICAL ERROR: HTTP request pointer is NULL, skipping processing");
break;
}
be_httpserver_process_web_request(vm, &msg);
break;
default:
ESP_LOGW(TAG, "Unknown message type: %d", msg.type);
// Free data if it was allocated
if (msg.data) {
free(msg.data);
}
// If it's a request that wasn't processed, complete it
if (msg.req) {
httpd_req_async_handler_complete(msg.req);
}
break;
}
} else {
// No messages in queue
xSemaphoreGive(http_queue_mutex);
break;
}
}
// Return the number of messages processed
be_pushint(vm, processed);
be_return(vm);
}
// ------------------------------------------------------------------------
// HTTP Handler implementation
// ------------------------------------------------------------------------
// Forward declaration for handler implementation
static esp_err_t berry_http_handler_impl(httpd_req_t *req, int handler_id);
// Macro to create handler functions for each supported endpoint
#define HTTP_HANDLER_FUNC(n) \
static esp_err_t berry_http_handler_##n(httpd_req_t *req) { \
return berry_http_handler_impl(req, n); \
}
// Generate handler functions
HTTP_HANDLER_FUNC(0)
HTTP_HANDLER_FUNC(1)
HTTP_HANDLER_FUNC(2)
HTTP_HANDLER_FUNC(3)
HTTP_HANDLER_FUNC(4)
// Array of handler function pointers
typedef esp_err_t (*http_handler_func_t)(httpd_req_t *req);
static const http_handler_func_t berry_handlers[HTTP_HANDLER_MAX] = {
berry_http_handler_0,
berry_http_handler_1,
berry_http_handler_2,
berry_http_handler_3,
berry_http_handler_4
};
// Implementation of HTTP handler dispatched by each numbered handler
static esp_err_t berry_http_handler_impl(httpd_req_t *req, int handler_id) {
if (handler_id < 0 || handler_id >= HTTP_HANDLER_MAX || !http_handlers[handler_id].active) {
ESP_LOGE(TAG, "Invalid or inactive handler ID: %d", handler_id);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Invalid handler");
httpd_req_async_handler_complete(req);
return ESP_FAIL;
}
// Store current request for access in Berry functions
current_request = req;
// Get the Berry VM and handler function
bvm *vm = http_handlers[handler_id].vm;
if (vm == NULL) {
ESP_LOGE(TAG, "Berry VM is NULL for handler %d", handler_id);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "VM error");
current_request = NULL;
httpd_req_async_handler_complete(req);
return ESP_FAIL;
}
// Log initial stack state
ESP_LOGI(TAG, "HANDLER: Initial stack top = %d", be_top(vm));
// Queue message for processing in main task if available
if (httpserver_has_queue()) {
ESP_LOGI(TAG, "Queueing request for %s", req->uri);
// Queue the request with the stored function value
if (!httpserver_queue_web_request(handler_id, req, http_handlers[handler_id].func)) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to queue message");
current_request = NULL;
httpd_req_async_handler_complete(req);
return ESP_FAIL;
}
// Note: We don't send a response here - that will be done asynchronously
current_request = NULL;
// Log final stack state
ESP_LOGI(TAG, "HANDLER: Final stack top = %d", be_top(vm));
return ESP_OK;
}
// If no queue, we'll process directly with caution
ESP_LOGW(TAG, "Processing request directly - this may be unsafe!");
// Start the async handler
httpd_req_t *async_req = NULL;
esp_err_t ret = httpd_req_async_handler_begin(req, &async_req);
if (ret != ESP_OK || async_req == NULL) {
ESP_LOGE(TAG, "Failed to start async handler");
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to start async handler");
current_request = NULL;
httpd_req_async_handler_complete(req);
return ESP_FAIL;
}
// Get the initial stack size
int top = be_top(vm);
// Push the handler function directly onto the stack (copy from stored value)
be_pushnil(vm); // Push a temporary placeholder
bvalue *top_ptr = be_indexof(vm, -1);
*top_ptr = http_handlers[handler_id].func; // Replace placeholder with stored function
// Push the URI string (argument) onto the stack
be_pushstring(vm, req->uri);
// Call the handler function with the URI as single argument
if (be_pcall(vm, 1) != 0) {
const char *err_msg = be_tostring(vm, -1);
ESP_LOGE(TAG, "Berry error: %s", err_msg ? err_msg : "unknown error");
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Handler call failed");
be_error_pop_all(vm); // Special case - clears entire stack on error
current_request = NULL;
httpd_req_async_handler_complete(req);
return ESP_FAIL;
}
// Get the response string
const char *response = be_tostring(vm, -1);
if (response == NULL) {
ESP_LOGE(TAG, "Handler returned nil response");
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Handler returned nil response");
be_error_pop_all(vm); // Special case - clears entire stack on error
current_request = NULL;
httpd_req_async_handler_complete(req);
return ESP_FAIL;
}
// Send the response
httpd_resp_set_type(req, "text/html");
httpd_resp_sendstr(req, response);
// Clean up
be_pop(vm, 1); // Pop return value
be_pop(vm, 1); // Pop function
current_request = NULL;
// Complete the async handler
httpd_req_async_handler_complete(async_req);
return ESP_OK;
}
// ------------------------------------------------------------------------
// Berry API Implementation
// ------------------------------------------------------------------------
// Start the HTTP server
static int w_httpserver_start(bvm *vm) {
int top = be_top(vm);
if (http_server != NULL) {
be_pushbool(vm, true); // Server already running
be_return (vm);
}
// Initialize connection tracking
connection_tracking.mutex = xSemaphoreCreateMutex();
if (!connection_tracking.mutex) {
ESP_LOGE(TAG, "Failed to create connection tracking mutex");
be_pushbool(vm, false);
be_return (vm);
}
// Configure the server
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.stack_size = 8192;
config.max_uri_handlers = HTTP_HANDLER_MAX;
config.max_open_sockets = HTTPD_MAX_CONNECTIONS;
config.lru_purge_enable = true; // Enable LRU purging of connections
config.uri_match_fn = httpd_uri_match_wildcard; // Enable wildcard URI matching
// Handle port parameter if provided
if (top > 0 && be_isint(vm, 1)) {
config.server_port = be_toint(vm, 1);
}
ESP_LOGI(TAG, "Starting HTTP server on port %d", config.server_port);
esp_err_t ret = httpd_start(&http_server, &config);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to start HTTP server: %d", ret);
vSemaphoreDelete(connection_tracking.mutex);
be_pushbool(vm, false);
be_return (vm);
}
ESP_LOGI(TAG, "HTTP server started successfully");
// Initialize the queue for thread-safe message passing
init_http_queue();
be_pushbool(vm, true);
be_return (vm);
}
// Register a URI handler
static int w_httpserver_on(bvm *vm) {
int top = be_top(vm);
httpd_method_t http_method = HTTP_GET; // Default method
if (top < 2 || http_server == NULL) {
be_raise(vm, "value_error", top < 2 ? "Missing arguments" : "Server not started");
be_return(vm);
}
if (!be_isstring(vm, 1) || !be_isfunction(vm, 2)) {
be_raise(vm, "type_error", "String and function required");
be_return(vm);
}
// Check for optional method argument
if (top >= 3) {
if (!be_isstring(vm, 3)) {
be_raise(vm, "type_error", "Method must be a string");
be_return(vm);
}
const char *method_str = be_tostring(vm, 3);
if (strcasecmp(method_str, "POST") == 0) {
http_method = HTTP_POST;
} else if (strcasecmp(method_str, "GET") != 0) {
be_raise(vm, "value_error", "Method must be 'GET' or 'POST'");
be_return(vm);
}
}
const char *uri = be_tostring(vm, 1);
ESP_LOGI(TAG, "Registering handler for URI: %s, Method: %s", uri,
http_method == HTTP_GET ? "GET" : "POST");
// Find a free handler slot
int slot = -1;
for (int i = 0; i < HTTP_HANDLER_MAX; i++) {
if (!http_handlers[i].active) {
slot = i;
break;
}
}
if (slot < 0) {
be_raise(vm, "runtime_error", "No more handler slots available");
be_return(vm);
}
// Store handler info
http_handlers[slot].vm = vm;
http_handlers[slot].active = true;
// Store the function reference
be_pushvalue(vm, 2);
bvalue *v = be_indexof(vm, -1);
http_handlers[slot].func = *v;
be_pop(vm, 1);
// Register the handler with ESP-IDF HTTP server
httpd_uri_t http_uri = {
.uri = uri,
.method = http_method,
.handler = berry_handlers[slot],
.user_ctx = NULL
};
esp_err_t ret = httpd_register_uri_handler(http_server, &http_uri);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to register URI handler: %d", ret);
http_handlers[slot].active = false;
be_pushbool(vm, false);
be_return (vm);
}
// Return the handler slot
be_pushint(vm, slot);
be_return (vm);
}
// Stop the HTTP server
static int w_httpserver_stop(bvm *vm) {
if (http_server == NULL) {
be_pushbool(vm, false); // Server not running
be_return (vm);
}
// Clean up handler registrations
for (int i = 0; i < HTTP_HANDLER_MAX; i++) {
if (http_handlers[i].active) {
http_handlers[i].active = false;
// Potentially unregister URI handlers here if needed
}
}
// Stop the server
esp_err_t ret = httpd_stop(http_server);
http_server = NULL;
// Clean up connection tracking
if (connection_tracking.mutex) {
vSemaphoreDelete(connection_tracking.mutex);
connection_tracking.mutex = NULL;
}
be_pushbool(vm, ret == ESP_OK);
be_return (vm);
}
// Simple wrapper around httpd_resp_sendstr
static int w_httpserver_send(bvm *vm) {
int argc = be_top(vm);
if (argc >= 1 && be_isstring(vm, 1)) {
const char* content = be_tostring(vm, 1);
// Get the current request from the async message
httpd_req_t* req = current_request;
if (!req) {
be_raisef(vm, "request_error", "No active request");
// Note: Don't call httpd_req_async_handler_complete here as there's no valid request
return 0;
}
// Send the response
esp_err_t ret = httpd_resp_sendstr(req, content);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to send response: %d", ret);
// Don't complete the handler here - let the main handler do it
be_pushbool(vm, false);
be_return (vm);
}
be_pushbool(vm, true);
be_return (vm);
}
be_return_nil(vm);
}
// Set WebSocket disconnect handler
void be_httpserver_set_disconnect_handler(httpd_close_func_t handler) {
http_server_disconn_handler = handler;
}
// Get HTTP server handle
httpd_handle_t be_httpserver_get_handle(void) {
return http_server;
}
// Function to check if message queue is available (referenced by wsserver)
bool httpserver_has_queue() {
return http_queue_initialized;
}
/* @const_object_info_begin
module httpserver (scope: global, strings: weak) {
start, func(w_httpserver_start)
on, func(w_httpserver_on)
send, func(w_httpserver_send)
stop, func(w_httpserver_stop)
process_queue, func(w_httpserver_process_queue)
}
@const_object_info_end */
#include "be_fixed_httpserver.h"
#endif // USE_BERRY_HTTPSERVER

View File

@ -315,11 +315,11 @@ char* be_fgets(void *hfile, void *buffer, int size)
uint8_t * buf = (uint8_t*) buffer; uint8_t * buf = (uint8_t*) buffer;
if (hfile != nullptr && buffer != nullptr && size > 0) { if (hfile != nullptr && buffer != nullptr && size > 0) {
File * f_ptr = (File*) hfile; File * f_ptr = (File*) hfile;
int ret = f_ptr->readBytesUntil('\n', buf, size - 2); int ret = f_ptr->readBytesUntil('\n', buf, size - 1);
// Serial.printf("be_fgets ret=%d\n", ret); // Serial.printf("be_fgets size=%d ret=%d\n", size, ret);
if (ret >= 0) { if (ret >= 0) {
buf[ret] = 0; // add string terminator buf[ret] = 0; // add string terminator
if (ret > 0 && ret < size - 2) { if (ret < size - 1) {
buf[ret] = '\n'; buf[ret] = '\n';
buf[ret+1] = 0; buf[ret+1] = 0;
} }

View File

@ -90,6 +90,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
_crons, var // list of active crons _crons, var // list of active crons
_ccmd, var // list of active Tasmota commands implemented in Berry _ccmd, var // list of active Tasmota commands implemented in Berry
_drivers, var // list of active drivers _drivers, var // list of active drivers
_wnu, var // list of closures to call when network is connected
wire1, var // Tasmota I2C Wire1 wire1, var // Tasmota I2C Wire1
wire2, var // Tasmota I2C Wire2 wire2, var // Tasmota I2C Wire2
cmd_res, var // store the command result, nil if disables, true if capture enabled, contains return value cmd_res, var // store the command result, nil if disables, true if capture enabled, contains return value
@ -106,7 +107,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
init, closure(class_Tasmota_init_closure) init, closure(class_Tasmota_init_closure)
get_free_heap, func(l_getFreeHeap) get_free_heap, func(l_getFreeHeap)
arch, func(l_arch) arch, static_func(l_arch)
publish, func(be_mqtt_publish) publish, func(be_mqtt_publish)
publish_result, func(l_publish_result) publish_result, func(l_publish_result)
publish_rule, func(l_publish_rule) publish_rule, func(l_publish_rule)
@ -183,6 +184,8 @@ class be_class_tasmota (scope: global, name: Tasmota) {
exec_cmd, closure(class_Tasmota_exec_cmd_closure) exec_cmd, closure(class_Tasmota_exec_cmd_closure)
gc, closure(class_Tasmota_gc_closure) gc, closure(class_Tasmota_gc_closure)
event, closure(class_Tasmota_event_closure) event, closure(class_Tasmota_event_closure)
when_network_up, closure(class_Tasmota_when_network_up_closure)
run_network_up, closure(class_Tasmota_run_network_up_closure)
add_driver, closure(class_Tasmota_add_driver_closure) add_driver, closure(class_Tasmota_add_driver_closure)
remove_driver, closure(class_Tasmota_remove_driver_closure) remove_driver, closure(class_Tasmota_remove_driver_closure)
load, closure(class_Tasmota_load_closure) load, closure(class_Tasmota_load_closure)

View File

@ -6,8 +6,6 @@
*******************************************************************/ *******************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
#ifdef USE_WEBCLIENT
extern int wc_tcp_init(bvm *vm); extern int wc_tcp_init(bvm *vm);
extern int wc_tcp_deinit(bvm *vm); extern int wc_tcp_deinit(bvm *vm);
@ -44,5 +42,3 @@ class be_class_tcpclient (scope: global, name: tcpclient) {
readbytes, func(wc_tcp_readbytes) readbytes, func(wc_tcp_readbytes)
} }
@const_object_info_end */ @const_object_info_end */
#endif // USE_WEBCLIENT

View File

@ -5,8 +5,6 @@
*******************************************************************/ *******************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
#ifdef USE_WEBCLIENT
extern int wc_tcpasync_init(bvm *vm); extern int wc_tcpasync_init(bvm *vm);
extern int wc_tcpasync_deinit(bvm *vm); extern int wc_tcpasync_deinit(bvm *vm);
@ -42,5 +40,3 @@ class be_class_tcpclientasync (scope: global, name: tcpclientasync) {
readbytes, func(wc_tcpasync_readbytes) readbytes, func(wc_tcpasync_readbytes)
} }
@const_object_info_end */ @const_object_info_end */
#endif // USE_WEBCLIENT

View File

@ -7,8 +7,6 @@
#include "be_constobj.h" #include "be_constobj.h"
#include "be_mapping.h" #include "be_mapping.h"
#ifdef USE_WEBCLIENT
extern int be_udp_read(struct bvm *vm); extern int be_udp_read(struct bvm *vm);
extern void *be_udp_init_ntv(void); extern void *be_udp_init_ntv(void);
@ -53,5 +51,3 @@ class be_class_udp (scope: global, name: udp) {
close, ctype_func(be_udp_stop_ntv) close, ctype_func(be_udp_stop_ntv)
} }
@const_object_info_end */ @const_object_info_end */
#endif // USE_WEBCLIENT

View File

@ -6,8 +6,6 @@
*******************************************************************/ *******************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
#ifdef USE_WEBCLIENT
extern int wc_init(bvm *vm); extern int wc_init(bvm *vm);
extern int wc_deinit(bvm *vm); extern int wc_deinit(bvm *vm);
extern int wc_urlencode(bvm *vm); extern int wc_urlencode(bvm *vm);
@ -72,5 +70,3 @@ class be_class_webclient (scope: global, name: webclient) {
get_bytes, func(wc_getbytes) get_bytes, func(wc_getbytes)
} }
@const_object_info_end */ @const_object_info_end */
#endif // USE_WEBCLIENT

View File

@ -0,0 +1,400 @@
/*
be_webfiles_lib.c - Static file server for Berry using ESP-IDF HTTP server
Copyright (C) 2025 Jonathan E. Peace
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 <http://www.gnu.org/licenses/>.
*/
#ifdef USE_BERRY_WEBFILES
#ifndef LOG_LOCAL_LEVEL
#define LOG_LOCAL_LEVEL ESP_LOG_INFO
#endif
#include "be_constobj.h"
#include "be_mapping.h"
// ESP-IDF includes
#include "esp_log.h"
#include "esp_http_server.h"
#include "esp_vfs.h"
// External Berry/Tasmota includes
extern httpd_handle_t be_httpserver_get_handle(void);
extern bool httpserver_queue_message(int type, int client_id,
const char* data, size_t len, void* user_data);
// Tag for logging
static const char *TAG = "WEBFILES";
// Default base path for files
static char base_path[64] = "/files";
// URI prefix for the file server
static char uri_prefix[32] = "/";
// Maximum file path length
#define FILE_PATH_MAX 128
// Scratch buffer size for file transfer
#define SCRATCH_BUFSIZE 4096 // 4KB scratch buffer for chunks
// Static buffer for file sending - fixed allocation
static char scratch_buffer[SCRATCH_BUFSIZE];
// MIME Type Mapping
static const struct {
const char *extension;
const char *mimetype;
} mime_types[] = {
{".html", "text/html"},
{".htm", "text/html"},
{".js", "application/javascript"},
{".mjs", "application/javascript"}, // ES modules
{".css", "text/css"},
{".png", "image/png"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".gif", "image/gif"},
{".ico", "image/x-icon"},
{".svg", "image/svg+xml"},
{".json", "application/json"},
{".txt", "text/plain"},
{".md", "text/markdown"},
{".wasm", "application/wasm"}, // WebAssembly
{".map", "application/json"}, // Source maps
{".woff", "font/woff"},
{".woff2", "font/woff2"},
{".ttf", "font/ttf"},
{".otf", "font/otf"},
{".bin", "application/octet-stream"},
{NULL, NULL}
};
// Get MIME type based on file extension
static const char* get_mime_type(const char *path) {
const char *ext = strrchr(path, '.');
if (!ext) return "text/plain";
for (int i = 0; mime_types[i].extension; i++) {
if (strcasecmp(mime_types[i].extension, ext) == 0) {
return mime_types[i].mimetype;
}
}
return "text/plain";
}
// Build full path including base path
static const char* get_full_path(char *dest, const char *uri, size_t destsize) {
size_t base_len = strlen(base_path);
size_t prefix_len = strlen(uri_prefix);
size_t uri_len = strlen(uri);
// Handle query parameters and fragments in URI
const char *query = strchr(uri, '?');
if (query) {
uri_len = query - uri;
}
const char *fragment = strchr(uri, '#');
if (fragment && (!query || fragment < query)) {
uri_len = fragment - uri;
}
// Skip the URI prefix to get the relative path
const char *relative_path = uri;
if (prefix_len > 1 && strncmp(uri, uri_prefix, prefix_len) == 0) {
relative_path = uri + prefix_len - 1; // -1 because we want to keep the leading slash
uri_len -= (prefix_len - 1);
}
// Check if path will fit in destination buffer
if (base_len + uri_len + 1 > destsize) {
ESP_LOGE(TAG, "Path too long");
return NULL;
}
// Construct full path
strcpy(dest, base_path);
if (base_len > 0 && base_path[base_len-1] == '/' && relative_path[0] == '/') {
// Avoid double slash
strlcpy(dest + base_len, relative_path + 1, uri_len);
} else {
strlcpy(dest + base_len, relative_path, uri_len + 1);
}
return dest;
}
// Set content type based on file extension
static void set_content_type_from_file(httpd_req_t *req, const char *filepath) {
const char* mime_type = get_mime_type(filepath);
httpd_resp_set_type(req, mime_type);
// Set Cache-Control header for static assets
// Don't cache HTML, but cache other static assets
if (strstr(mime_type, "text/html") == NULL) {
// Cache for 1 hour (3600 seconds)
httpd_resp_set_hdr(req, "Cache-Control", "max-age=3600");
} else {
// Don't cache HTML content
httpd_resp_set_hdr(req, "Cache-Control", "no-cache");
}
// Add CORS headers for development convenience
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
}
//checks if a .html, .css, or .js file exists with a .br suffix and serve that Brotli-compressed version instead
static esp_err_t webfiles_handler(httpd_req_t *req) {
char filepath[FILE_PATH_MAX];
char compressed_filepath[FILE_PATH_MAX];
FILE *file = NULL;
struct stat file_stat;
bool use_compression = false;
const char* compression_type = NULL; // Only Gzip for now
// Process any URL query parameters if needed
char *query = strchr(req->uri, '?');
if (query) {
ESP_LOGI(TAG, "Request has query params: %s", query);
*query = '\0'; // Temporarily terminate URI at the query string for path resolution
}
// Get the full file path from the URI
if (get_full_path(filepath, req->uri, sizeof(filepath)) == NULL) {
ESP_LOGE(TAG, "Failed to get file path for URI: %s", req->uri);
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File not found");
return ESP_FAIL;
}
// Restore query string if we modified it
if (query) *query = '?';
ESP_LOGI(TAG, "Requested file: %s", filepath);
// Check if file is .html, .css, .js, or .svg and if a compressed version exists
const char *ext = strrchr(filepath, '.');
if (ext && (strcasecmp(ext, ".html") == 0 || strcasecmp(ext, ".css") == 0 ||
strcasecmp(ext, ".js") == 0 || strcasecmp(ext, ".svg") == 0)) {
// Check what compression formats the client supports
char accept_encoding[64] = {0};
if (httpd_req_get_hdr_value_str(req, "Accept-Encoding", accept_encoding, sizeof(accept_encoding)) == ESP_OK) {
ESP_LOGI(TAG, "Client supports compression: %s", accept_encoding);
if (!use_compression && strstr(accept_encoding, "gzip") != NULL) {
// Construct Gzip filepath
snprintf(compressed_filepath, sizeof(compressed_filepath), "%s.gz", filepath);
if (stat(compressed_filepath, &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
use_compression = true;
compression_type = "gzip";
strcpy(filepath, compressed_filepath); // Use the .gz file
ESP_LOGI(TAG, "Found Gzip version: %s", filepath);
}
}
}
}
// Check if file exists
if (stat(filepath, &file_stat) != 0) {
ESP_LOGE(TAG, "File does not exist: %s", filepath);
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File not found");
return ESP_FAIL;
}
// Check if it's a regular file
if (!S_ISREG(file_stat.st_mode)) {
ESP_LOGE(TAG, "Not a regular file: %s", filepath);
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Not a file");
return ESP_FAIL;
}
// Open the file for reading
file = fopen(filepath, "r");
if (!file) {
ESP_LOGE(TAG, "Failed to open file: %s", filepath);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to open file");
return ESP_FAIL;
}
// Set content type based on file extension (use original path for MIME type if compressed)
char original_filepath[FILE_PATH_MAX];
if (use_compression) {
// Strip compression extension for MIME type detection
strcpy(original_filepath, filepath);
char* dot_pos = strrchr(original_filepath, '.');
if (dot_pos) {
*dot_pos = '\0'; // Remove compression extension
}
set_content_type_from_file(req, original_filepath);
} else {
set_content_type_from_file(req, filepath);
}
// Set compression headers if applicable
if (use_compression) {
httpd_resp_set_hdr(req, "Content-Encoding", compression_type);
httpd_resp_set_hdr(req, "Vary", "Accept-Encoding");
}
// Send file in chunks for efficiency
size_t chunk_size;
size_t total_sent = 0;
while ((chunk_size = fread(scratch_buffer, 1, SCRATCH_BUFSIZE, file)) > 0) {
if (httpd_resp_send_chunk(req, scratch_buffer, chunk_size) != ESP_OK) {
ESP_LOGE(TAG, "File send failed");
fclose(file);
httpd_resp_send_chunk(req, NULL, 0);
return ESP_FAIL;
}
total_sent += chunk_size;
}
// Close file
fclose(file);
// Finish the HTTP response
httpd_resp_send_chunk(req, NULL, 0);
ESP_LOGI(TAG, "File sent successfully (%d bytes, %s)", (int)total_sent, use_compression ? compression_type : "uncompressed");
return ESP_OK;
}
/****************************************************************
* Berry Interface Functions
****************************************************************/
// webfiles.serve(base_path, uri_prefix) -> bool
// Serve files from base_path at uri_prefix
static int w_webfiles_serve(bvm *vm) {
int initial_top = be_top(vm);
if (be_top(vm) >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) {
const char* path = be_tostring(vm, 1);
const char* prefix = be_tostring(vm, 2);
ESP_LOGI(TAG, "Setting up file server with base path: %s, uri prefix: %s", path, prefix);
struct stat st;
if (stat(path, &st) != 0 || !S_ISDIR(st.st_mode)) {
ESP_LOGE(TAG, "Input path is not a valid directory: %s", path);
be_pushbool(vm, false);
// Clean up stack before returning
while (be_top(vm) > initial_top) {
be_pop(vm, 1);
}
be_return (vm); // Return directly
}
httpd_handle_t server = be_httpserver_get_handle();
if (!server) {
ESP_LOGE(TAG, "HTTP server not running");
be_pushbool(vm, false);
while (be_top(vm) > initial_top) {
be_pop(vm, 1);
}
be_return (vm);
}
strlcpy(base_path, path, sizeof(base_path));
strlcpy(uri_prefix, prefix, sizeof(uri_prefix));
// Use a static buffer for the URI pattern
static char registered_uri_pattern[64]; // ADD static keyword
// Ensure it's null-terminated even if snprintf truncates
registered_uri_pattern[sizeof(registered_uri_pattern) - 1] = '\0';
snprintf(registered_uri_pattern, sizeof(registered_uri_pattern), "%s*", prefix);
ESP_LOGI(TAG, "Registering URI handler with pattern: %s", registered_uri_pattern);
httpd_uri_t uri_handler = {
// Point to the static buffer
.uri = registered_uri_pattern, // Use the static buffer
.method = HTTP_GET,
.handler = webfiles_handler,
.is_websocket = false,
.user_ctx = NULL
};
esp_err_t ret = httpd_register_uri_handler(server, &uri_handler);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to register URI handler: %d", ret);
be_pushbool(vm, false);
be_pop(vm, be_top(vm) - initial_top);
be_return (vm);
}
be_pushbool(vm, true);
be_pop(vm, be_top(vm) - initial_top);
be_return (vm);
}
be_pushbool(vm, false);
be_pop(vm, be_top(vm) - initial_top);
be_return (vm);
}
// webfiles.serve_file(file_path, uri) -> bool
// Serve a specific file at a specific URI
static int w_webfiles_serve_file(bvm *vm) {
int initial_top = be_top(vm);
if (be_top(vm) >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) {
const char* file_path = be_tostring(vm, 1);
const char* uri = be_tostring(vm, 2);
// Check if file exists
struct stat file_stat;
if (stat(file_path, &file_stat) == -1) {
ESP_LOGE(TAG, "File not found: %s", file_path);
be_pushbool(vm, false);
be_pop(vm, be_top(vm) - initial_top);
be_return (vm);
}
// TODO: Implement custom handler for specific files
// This would require keeping track of file mappings
ESP_LOGW(TAG, "serve_file not yet implemented");
be_pushbool(vm, false);
be_pop(vm, be_top(vm) - initial_top);
be_return (vm);
}
be_pushbool(vm, false);
be_pop(vm, be_top(vm) - initial_top);
be_return (vm);
}
// Module definition
/* @const_object_info_begin
module webfiles (scope: global, strings: weak) {
serve, func(w_webfiles_serve)
serve_file, func(w_webfiles_serve_file)
// MIME type constants
MIME_HTML, str("text/html")
MIME_JS, str("application/javascript")
MIME_CSS, str("text/css")
MIME_JSON, str("application/json")
MIME_TEXT, str("text/plain")
MIME_BINARY, str("application/octet-stream")
}
@const_object_info_end */
#include "be_fixed_webfiles.h"
#endif // USE_BERRY_WEBFILES

File diff suppressed because it is too large Load Diff

View File

@ -158,18 +158,6 @@ class Leds : Leds_ntv
def get_gamma() def get_gamma()
return self.gamma return self.gamma
end end
# def rotate_left(rot, first, last)
# self.call_native(20, rot, first, last)
# end
# def rotate_right(rot, first, last)
# self.call_native(21, rot, first, last)
# end
# def shift_left(rot, first, last)
# self.call_native(22, rot, first, last)
# end
# def shift_right(rot, first, last)
# self.call_native(22, rot, first, last)
# end
# apply gamma and bri # apply gamma and bri
def to_gamma(rgb, bri) def to_gamma(rgb, bri)
@ -252,217 +240,6 @@ class Leds : Leds_ntv
end end
def create_matrix(w, h, offset)
offset = int(offset)
w = int(w)
h = int(h)
if offset == nil offset = 0 end
if w * h + offset > self.leds || h < 0 || w < 0 || offset < 0
raise "value_error", "out of range"
end
# inner class
class Leds_matrix
var strip
var offset
var h, w
var alternate # are rows in alternate mode (even/odd are reversed)
var pix_buffer
var pix_size
def init(strip, w, h, offset)
self.strip = strip
self.offset = offset
self.h = h
self.w = w
self.alternate = false
self.pix_buffer = self.strip.pixels_buffer()
self.pix_size = self.strip.pixel_size()
end
def clear()
self.clear_to(0x000000)
self.show()
end
def begin()
# do nothing, already being handled by physical strip
end
def show(force)
# don't trigger on segment, you will need to trigger on full strip instead
if bool(force) || (self.offset == 0 && self.w * self.h == self.strip.leds)
self.strip.show()
self.pix_buffer = self.strip.pixels_buffer(self.pix_buffer) # update buffer after show()
end
end
def can_show()
return self.strip.can_show()
end
def is_dirty() ## DEPRECATED
return self.strip.is_dirty()
end
def dirty() ## DEPRECATED
self.strip.dirty()
end
def pixels_buffer()
return self.strip.pixels_buffer()
end
def pixel_size()
return self.pix_size
end
def pixel_count()
return self.w * self.h
end
def pixel_offset()
return self.offset
end
def clear_to(col, bri)
if (bri == nil) bri = self.strip.bri end
self.strip.call_native(9, self.strip.to_gamma(col, bri), self.offset, self.w * self.h)
end
def set_pixel_color(idx, col, bri)
if (bri == nil) bri = self.strip.bri end
self.strip.set_pixel_color(idx + self.offset, col, bri)
end
def get_pixel_color(idx)
return self.strip.get_pixel_color(idx + self.offseta)
end
# setbytes(row, bytes)
# sets the raw bytes for `row`, copying at most 3 or 4 x col bytes
def set_bytes(row, buf, offset, len)
var h_bytes = self.h * self.pix_size
if (len > h_bytes) len = h_bytes end
var offset_in_matrix = (self.offset + row) * h_bytes
self.pix_buffer.setbytes(offset_in_matrix, buf, offset, len)
end
# Leds_matrix specific
def set_alternate(alt)
self.alternate = alt
end
def get_alternate()
return self.alternate
end
def set_matrix_pixel_color(x, y, col, bri)
if (bri == nil) bri = self.strip.bri end
if self.alternate && (y & 0x1)
# reversed line
self.strip.set_pixel_color(x * self.w + self.h - y - 1 + self.offset, col, bri)
else
self.strip.set_pixel_color(x * self.w + y + self.offset, col, bri)
end
end
def scroll(direction, outshift, inshift) # 0 - up, 1 - left, 2 - down, 3 - right ; outshift mandatory, inshift optional
var buf = self.pix_buffer
var h = self.h
var sz = self.w * 3 # row size in bytes
var pos
if direction%2 == 0 #up/down
if direction == 0 #up
outshift.setbytes(0,(buf[0..sz-1]).reverse(0,nil,3))
var line = 0
while line < (h-1)
pos = 0
var offset_dst = line * sz
var offset_src = ((line+2) * sz) - 3
while pos < sz
var dst = pos + offset_dst
var src = offset_src - pos
buf[dst] = buf[src]
buf[dst+1] = buf[src+1]
buf[dst+2] = buf[src+2]
pos += 3
end
line += 1
end
var lastline = inshift ? inshift : outshift
if h%2 == 1
lastline.reverse(0,nil,3)
end
buf.setbytes((h-1) * sz, lastline)
else # down
outshift.setbytes(0,(buf[size(buf)-sz..]).reverse(0,nil,3))
var line = h - 1
while line > 0
buf.setbytes(line * sz,(buf[(line-1) * sz..line * sz-1]).reverse(0,nil,3))
line -= 1
end
var lastline = inshift ? inshift : outshift
if h%2 == 1
lastline.reverse(0,nil,3)
end
buf.setbytes(0, lastline)
end
else # left/right
var line = 0
var step = 3
if direction == 3 # right
step *= -1
end
while line < h
pos = line * sz
if step > 0
var line_end = pos + sz - step
outshift[(line * 3)] = buf[pos]
outshift[(line * 3) + 1] = buf[pos+1]
outshift[(line * 3) + 2] = buf[pos+2]
while pos < line_end
buf[pos] = buf[pos+3]
buf[pos+1] = buf[pos+4]
buf[pos+2] = buf[pos+5]
pos += step
end
if inshift == nil
buf[line_end] = outshift[(line * 3)]
buf[line_end+1] = outshift[(line * 3) + 1]
buf[line_end+2] = outshift[(line * 3) + 2]
else
buf[line_end] = inshift[(line * 3)]
buf[line_end+1] = inshift[(line * 3) + 1]
buf[line_end+2] = inshift[(line * 3) + 2]
end
else
var line_end = pos
pos = pos + sz + step
outshift[(line * 3)] = buf[pos]
outshift[(line * 3) + 1] = buf[pos+1]
outshift[(line * 3) + 2] = buf[pos+2]
while pos > line_end
buf[pos] = buf[pos-3]
buf[pos+1] = buf[pos-2]
buf[pos+2] = buf[pos-1]
pos += step
end
if inshift == nil
buf[line_end] = outshift[(line * 3)]
buf[line_end+1] = outshift[(line * 3) + 1]
buf[line_end+2] = outshift[(line * 3) + 2]
else
buf[line_end] = inshift[(line * 3)]
buf[line_end+1] = inshift[(line * 3) + 1]
buf[line_end+2] = inshift[(line * 3) + 2]
end
end
step *= -1
line += 1
end
end
end
end
return Leds_matrix(self, w, h, offset)
end
static def matrix(w, h, gpio, rmt)
var strip = Leds(w * h, gpio, rmt)
var matrix = strip.create_matrix(w, h, 0)
return matrix
end
end end
@ -483,26 +260,3 @@ end
anim() anim()
-# -#
#-
var s = Leds(25, gpio.pin(gpio.WS2812, 1)).create_matrix(5, 5)
s.set_alternate(true)
s.clear_to(0x400000)
s.show()
x = 0
y = 0
def anim()
s.clear_to(0x400000)
s.set_matrix_pixel_color(x, y, 0x004000)
s.show()
y = (y + 1) % 5
if y == 0
x = (x + 1) % 5
end
tasmota.set_timer(200, anim)
end
anim()
-#

View File

@ -8,29 +8,34 @@ tapp_module.init = def (m)
class Tapp class Tapp
# we make sure the instance is registered as a driver to receive the "autoexec" event
def init() def init()
tasmota.add_driver(self) tasmota.add_driver(self)
end end
def autoexec() # Takes a list of files, and run any tapp file's autoexec.be
static def autoexec_dir(dir_name)
import path import path
import string import string
for d: path.listdir(dir_name)
var dir = path.listdir("/") if string.endswith(d, ".tapp")
log(f"TAP: Loaded Tasmota App '{dir_name}{d}'", 2)
for d: dir tasmota.load(dir_name + d + "#autoexec.be")
if string.find(d, ".tapp") > 0
tasmota.log(format("TAP: Loaded Tasmota App '%s'", d), 2)
tasmota.load(d + "#autoexec.be")
end end
end end
end end
# react to the "autoexec" event that is triggered at first tick when Berry starts
# Note: this is alled before the file "/autoexec.be" is loaded
#
# We run all `*.tapp` that are located in "/.extensions/" and in "/" in this order
def autoexec()
self.autoexec_dir("/.extensions/")
self.autoexec_dir("/")
end
end end
return Tapp() # return an instance of this class return Tapp() # return an instance of this class
end end
# aa = autoconf_module.init(autoconf_module)
# import webserver
# webserver.on('/ac2', / -> aa.page_autoconf_mgr(), webserver.HTTP_GET)
return tapp_module return tapp_module

View File

@ -13,6 +13,7 @@ class Tasmota
var _crons var _crons
var _ccmd var _ccmd
var _drivers var _drivers
var _wnu # when_connected: list of closures to call when network is connected, or nil
var wire1 var wire1
var wire2 var wire2
var cmd_res # store the command result, nil if disables, true if capture enabled, contains return value var cmd_res # store the command result, nil if disables, true if capture enabled, contains return value
@ -723,9 +724,45 @@ class Tasmota
end end
end end
# add a closure to the list to be called when network is connected
# or call immediately if network is already up
def when_network_up(cl)
self.check_not_method(cl)
var is_connected = tasmota.wifi()['up'] || tasmota.eth()['up']
if is_connected
cl() # call closure
else
if (self._wnu == nil)
self._wnu = [ cl ] # create list
else
self._wnu.push(cl) # append to list
end
end
end
# run all pending closures when network is up
def run_network_up()
if (self._wnu == nil) return end
var is_connected = tasmota.wifi()['up'] || tasmota.eth()['up']
if is_connected
# run all closures in a safe loop
while (size(self._wnu) > 0)
var cl = self._wnu[0]
self._wnu.remove(0) # failsafe, remove first to avoid an infinite loop if call fails
try
cl()
except .. as e,m
print(format("BRY: Exception> run_network_up '%s' - %s", e, m))
end
end
self._wnu = nil # all done, clear list
end
end
def event(event_type, cmd, idx, payload, raw) def event(event_type, cmd, idx, payload, raw)
import introspect import introspect
if event_type=='every_50ms' if event_type=='every_50ms'
if (self._wnu) self.run_network_up() end # capture when network becomes connected
self.run_timers() self.run_timers()
end #- first run deferred events -# end #- first run deferred events -#

View File

@ -238,7 +238,10 @@ class webserver_async
# pre: self.buf_in is not empty # pre: self.buf_in is not empty
# post: self.buf_in has made progress (smaller or '') # post: self.buf_in has made progress (smaller or '')
def parse_http_req_line() def parse_http_req_line()
var m = global._re_http_srv.match2(self.buf_in, self.buf_in_offset) import re
# print("parse_http_req_line", "self.buf_in=", self.buf_in)
var m = re.match2(self.server.re_http_srv, self.buf_in, self.buf_in_offset)
# print(f"{m=}")
# Ex: "GET / HTTP/1.1\r\n" # Ex: "GET / HTTP/1.1\r\n"
if m if m
var offset = m[0] var offset = m[0]
@ -261,16 +264,18 @@ class webserver_async
############################################################# #############################################################
# parse incoming headers # parse incoming headers
def parse_http_headers() def parse_http_headers()
import re
while true while true
# print("parse_http_headers", "self.buf_in_offset=", self.buf_in_offset) # print("parse_http_headers", "self.buf_in_offset=", self.buf_in_offset)
var m = global._re_http_srv_header.match2(self.buf_in, self.buf_in_offset) var m = re.match2(self.server.re_http_srv_header, self.buf_in, self.buf_in_offset)
# print("m=", m) # print(f"{m=}")
# Ex: [32, 'Content-Type', 'application/json'] # Ex: [32, 'Content-Type', 'application/json']
if m if m
self.event_http_header(m[1], m[2]) self.event_http_header(m[1], m[2])
self.buf_in_offset += m[0] self.buf_in_offset += m[0]
else # no more headers else # no more headers
var m2 = global._re_http_srv_body.match2(self.buf_in, self.buf_in_offset) var m2 = re.match2(self.server.re_http_srv_body, self.buf_in, self.buf_in_offset)
# print(f"{m2=}")
if m2 if m2
# end of headers # end of headers
# we keep \r\n which is used by pattern # we keep \r\n which is used by pattern
@ -519,9 +524,16 @@ class webserver_async
var p1 # temporary object bytes() to avoid reallocation var p1 # temporary object bytes() to avoid reallocation
# static var TIMEOUT = 1000 # default timeout: 1000ms # static var TIMEOUT = 1000 # default timeout: 1000ms
#############################################################
# pre-compile REGEX
#
# static var HTTP_REQ = "^(\\w+) (\\S+) HTTP\\/(\\d\\.\\d)\r\n" # static var HTTP_REQ = "^(\\w+) (\\S+) HTTP\\/(\\d\\.\\d)\r\n"
# static var HTTP_HEADER_REGEX = "([A-Za-z0-9-]+): (.*?)\r\n" # extract a header with its 2 parts # 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_BODY_REGEX = "\r\n" # end of headers
static var re_http_srv = re.compilebytes("^(\\w+) (\\S+) HTTP\\/(\\d\\.\\d)\r\n")
static var re_http_srv_header = re.compilebytes("([A-Za-z0-9-]+): (.*?)\r\n")
static var re_http_srv_body = re.compilebytes("\r\n")
############################################################# #############################################################
# init # init
@ -535,27 +547,12 @@ class webserver_async
self.cors = false self.cors = false
self.p1 = bytes(100) # reserve 100 bytes by default self.p1 = bytes(100) # reserve 100 bytes by default
# TODO what about max_clients ? # TODO what about max_clients ?
self.compile_re()
# register cb # register cb
tasmota.add_driver(self) tasmota.add_driver(self)
self.fastloop_cb = def () self.loop() end self.fastloop_cb = def () self.loop() end
tasmota.add_fast_loop(self.fastloop_cb) tasmota.add_fast_loop(self.fastloop_cb)
end end
#############################################################
# compile once for all the regex
def compile_re()
import re
if !global.contains("_re_http_srv")
# global._re_http_srv = re.compile(self.HTTP_REQ)
# global._re_http_srv_header = re.compile(self.HTTP_HEADER_REGEX)
# global._re_http_srv_body = re.compile(self.HTTP_BODY_REGEX)
global._re_http_srv = re.compile("^(\\w+) (\\S+) HTTP\\/(\\d\\.\\d)\r\n")
global._re_http_srv_header = re.compile("([A-Za-z0-9-]+): (.*?)\r\n")
global._re_http_srv_body = re.compile("\r\n")
end
end
############################################################# #############################################################
# enable or disable chunked mode (enabled by default) # enable or disable chunked mode (enabled by default)
def set_chunked(chunked) def set_chunked(chunked)

File diff suppressed because it is too large Load Diff

View File

@ -3,23 +3,26 @@
* Generated code, don't edit * * Generated code, don't edit *
\********************************************************************/ \********************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
// compact class 'Tapp' ktab size: 15, total: 16 (saved 8 bytes) extern const bclass be_class_Tapp;
static const bvalue be_ktab_class_Tapp[15] = { // compact class 'Tapp' ktab size: 17, total: 18 (saved 8 bytes)
static const bvalue be_ktab_class_Tapp[17] = {
/* K0 */ be_nested_str(tasmota), /* K0 */ be_nested_str(tasmota),
/* K1 */ be_nested_str(add_driver), /* K1 */ be_nested_str(add_driver),
/* K2 */ be_nested_str(path), /* K2 */ be_nested_str(autoexec_dir),
/* K3 */ be_nested_str(string), /* K3 */ be_nested_str(_X2F_X2Eextensions_X2F),
/* K4 */ be_nested_str(listdir), /* K4 */ be_nested_str(_X2F),
/* K5 */ be_nested_str(_X2F), /* K5 */ be_const_class(be_class_Tapp),
/* K6 */ be_nested_str(find), /* K6 */ be_nested_str(path),
/* K7 */ be_nested_str(_X2Etapp), /* K7 */ be_nested_str(string),
/* K8 */ be_const_int(0), /* K8 */ be_nested_str(listdir),
/* K9 */ be_nested_str(log), /* K9 */ be_nested_str(endswith),
/* K10 */ be_nested_str(TAP_X3A_X20Loaded_X20Tasmota_X20App_X20_X27_X25s_X27), /* K10 */ be_nested_str(_X2Etapp),
/* K11 */ be_const_int(2), /* K11 */ be_nested_str(log),
/* K12 */ be_nested_str(load), /* K12 */ be_nested_str(TAP_X3A_X20Loaded_X20Tasmota_X20App_X20_X27_X25s_X25s_X27),
/* K13 */ be_nested_str(_X23autoexec_X2Ebe), /* K13 */ be_const_int(2),
/* K14 */ be_nested_str(stop_iteration), /* K14 */ be_nested_str(load),
/* K15 */ be_nested_str(_X23autoexec_X2Ebe),
/* K16 */ be_nested_str(stop_iteration),
}; };
@ -58,7 +61,7 @@ be_local_closure(class_Tapp_init, /* name */
********************************************************************/ ********************************************************************/
be_local_closure(class_Tapp_autoexec, /* name */ be_local_closure(class_Tapp_autoexec, /* name */
be_nested_proto( be_nested_proto(
11, /* nstack */ 4, /* nstack */
1, /* argc */ 1, /* argc */
10, /* varg */ 10, /* varg */
0, /* has upvals */ 0, /* has upvals */
@ -69,38 +72,68 @@ be_local_closure(class_Tapp_autoexec, /* name */
&be_ktab_class_Tapp, /* shared constants */ &be_ktab_class_Tapp, /* shared constants */
&be_const_str_autoexec, &be_const_str_autoexec,
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[ 7]) { /* code */
0x8C040102, // 0000 GETMET R1 R0 K2
0x580C0003, // 0001 LDCONST R3 K3
0x7C040400, // 0002 CALL R1 2
0x8C040102, // 0003 GETMET R1 R0 K2
0x580C0004, // 0004 LDCONST R3 K4
0x7C040400, // 0005 CALL R1 2
0x80000000, // 0006 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: autoexec_dir
********************************************************************/
be_local_closure(class_Tapp_autoexec_dir, /* name */
be_nested_proto(
11, /* nstack */
1, /* argc */
12, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
&be_ktab_class_Tapp, /* shared constants */
&be_const_str_autoexec_dir,
&be_const_str_solidified,
( &(const binstruction[34]) { /* code */ ( &(const binstruction[34]) { /* code */
0xA4060400, // 0000 IMPORT R1 K2 0x58040005, // 0000 LDCONST R1 K5
0xA40A0600, // 0001 IMPORT R2 K3 0xA40A0C00, // 0001 IMPORT R2 K6
0x8C0C0304, // 0002 GETMET R3 R1 K4 0xA40E0E00, // 0002 IMPORT R3 K7
0x58140005, // 0003 LDCONST R5 K5 0x60100010, // 0003 GETGBL R4 G16
0x7C0C0400, // 0004 CALL R3 2 0x8C140508, // 0004 GETMET R5 R2 K8
0x60100010, // 0005 GETGBL R4 G16 0x5C1C0000, // 0005 MOVE R7 R0
0x5C140600, // 0006 MOVE R5 R3 0x7C140400, // 0006 CALL R5 2
0x7C100200, // 0007 CALL R4 1 0x7C100200, // 0007 CALL R4 1
0xA8020014, // 0008 EXBLK 0 #001E 0xA8020014, // 0008 EXBLK 0 #001E
0x5C140800, // 0009 MOVE R5 R4 0x5C140800, // 0009 MOVE R5 R4
0x7C140000, // 000A CALL R5 0 0x7C140000, // 000A CALL R5 0
0x8C180506, // 000B GETMET R6 R2 K6 0x8C180709, // 000B GETMET R6 R3 K9
0x5C200A00, // 000C MOVE R8 R5 0x5C200A00, // 000C MOVE R8 R5
0x58240007, // 000D LDCONST R9 K7 0x5824000A, // 000D LDCONST R9 K10
0x7C180600, // 000E CALL R6 3 0x7C180600, // 000E CALL R6 3
0x24180D08, // 000F GT R6 R6 K8 0x781A000C, // 000F JMPF R6 #001D
0x781A000B, // 0010 JMPF R6 #001D 0xB81A1600, // 0010 GETNGBL R6 K11
0xB81A0000, // 0011 GETNGBL R6 K0 0x601C0018, // 0011 GETGBL R7 G24
0x8C180D09, // 0012 GETMET R6 R6 K9 0x5820000C, // 0012 LDCONST R8 K12
0x60200018, // 0013 GETGBL R8 G24 0x5C240000, // 0013 MOVE R9 R0
0x5824000A, // 0014 LDCONST R9 K10 0x5C280A00, // 0014 MOVE R10 R5
0x5C280A00, // 0015 MOVE R10 R5 0x7C1C0600, // 0015 CALL R7 3
0x7C200400, // 0016 CALL R8 2 0x5820000D, // 0016 LDCONST R8 K13
0x5824000B, // 0017 LDCONST R9 K11 0x7C180400, // 0017 CALL R6 2
0x7C180600, // 0018 CALL R6 3 0xB81A0000, // 0018 GETNGBL R6 K0
0xB81A0000, // 0019 GETNGBL R6 K0 0x8C180D0E, // 0019 GETMET R6 R6 K14
0x8C180D0C, // 001A GETMET R6 R6 K12 0x00200005, // 001A ADD R8 R0 R5
0x00200B0D, // 001B ADD R8 R5 K13 0x0020110F, // 001B ADD R8 R8 K15
0x7C180400, // 001C CALL R6 2 0x7C180400, // 001C CALL R6 2
0x7001FFEA, // 001D JMP #0009 0x7001FFEA, // 001D JMP #0009
0x5810000E, // 001E LDCONST R4 K14 0x58100010, // 001E LDCONST R4 K16
0xAC100200, // 001F CATCH R4 1 0 0xAC100200, // 001F CATCH R4 1 0
0xB0080000, // 0020 RAISE 2 R0 R0 0xB0080000, // 0020 RAISE 2 R0 R0
0x80000000, // 0021 RET 0 0x80000000, // 0021 RET 0
@ -116,10 +149,11 @@ be_local_closure(class_Tapp_autoexec, /* name */
be_local_class(Tapp, be_local_class(Tapp,
0, 0,
NULL, NULL,
be_nested_map(2, be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) { ( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key(init, -1), be_const_closure(class_Tapp_init_closure) },
{ be_const_key(autoexec, -1), be_const_closure(class_Tapp_autoexec_closure) }, { be_const_key(autoexec, -1), be_const_closure(class_Tapp_autoexec_closure) },
{ be_const_key(init, 0), be_const_closure(class_Tapp_init_closure) }, { be_const_key(autoexec_dir, -1), be_const_static_closure(class_Tapp_autoexec_dir_closure) },
})), })),
(bstring*) &be_const_str_Tapp (bstring*) &be_const_str_Tapp
); );

View File

@ -4,62 +4,82 @@
#include "re1.5.h" #include "re1.5.h"
// TASMOTA SPECIFIC
#ifndef INST_BUF_SIZE
#define INST_BUF_SIZE 96
#endif
void be_writebuffer(const char *buffer, size_t length);
#define be_writestring(s) be_writebuffer((s), strlen(s))
#define logbuf(...) snprintf(__lbuf, sizeof(__lbuf), __VA_ARGS__)
#define logfmt(...) \
do { \
char __lbuf[INST_BUF_SIZE]; \
logbuf(__VA_ARGS__); \
be_writestring(__lbuf); \
} while (0)
// all `printf` replaced with `logfmt`
void re1_5_dumpcode(ByteProg *prog) void re1_5_dumpcode(ByteProg *prog)
{ {
int pc = 0; int pc = 0;
char *code = prog->insts; char *code = prog->insts;
while (pc < prog->bytelen) { while (pc < prog->bytelen) {
printf("%2d: ", pc); logfmt("%2d: ", pc);
switch(code[pc++]) { switch(code[pc++]) {
default: default:
assert(0); assert(0);
// re1_5_fatal("printprog"); // re1_5_fatal("printprog");
case Split: case Split:
printf("split %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]); logfmt("split %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]);
pc++; pc++;
break; break;
case RSplit: case RSplit:
printf("rsplit %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]); logfmt("rsplit %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]);
pc++; pc++;
break; break;
case Jmp: case Jmp:
printf("jmp %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]); logfmt("jmp %d (%d)\n", pc + (signed char)code[pc] + 1, (signed char)code[pc]);
pc++; pc++;
break; break;
case Char: case Char:
printf("char %c\n", code[pc++]); logfmt("char %c\n", code[pc++]);
break; break;
case Any: case Any:
printf("any\n"); logfmt("any\n");
break; break;
case Class: case Class:
case ClassNot: { case ClassNot: {
int num = code[pc]; int num = code[pc];
printf("class%s %d", (code[pc - 1] == ClassNot ? "not" : ""), num); logfmt("class%s %d", (code[pc - 1] == ClassNot ? "not" : ""), num);
pc++; pc++;
while (num--) { while (num--) {
printf(" 0x%02x-0x%02x", code[pc], code[pc + 1]); logfmt(" 0x%02x-0x%02x", code[pc], code[pc + 1]);
pc += 2; pc += 2;
} }
printf("\n"); logfmt("\n");
break; break;
} }
case NamedClass: case NamedClass:
printf("namedclass %c\n", code[pc++]); logfmt("namedclass %c\n", code[pc++]);
break; break;
case Match: case Match:
printf("match\n"); logfmt("match\n");
break; break;
case Save: case Save:
printf("save %d\n", (unsigned char)code[pc++]); logfmt("save %d\n", (unsigned char)code[pc++]);
break; break;
case Bol: case Bol:
printf("assert bol\n"); logfmt("assert bol\n");
break; break;
case Eol: case Eol:
printf("assert eol\n"); logfmt("assert eol\n");
break; break;
} }
} }
printf("Bytes: %d, insts: %d\n", prog->bytelen, prog->len); logfmt("Bytes: %d, insts: %d\n", prog->bytelen, prog->len);
} }

File diff suppressed because it is too large Load Diff

View File

@ -40,8 +40,7 @@ typedef enum {
* @param font pointer to a font to use. * @param font pointer to a font to use.
* @return a pointer to reference this theme later * @return a pointer to reference this theme later
*/ */
lv_theme_t * lv_theme_haspmota_init(lv_display_t * disp, lv_color_t color_primary, lv_color_t color_secondary, bool dark, const lv_font_t * font); lv_theme_t * lv_theme_haspmota_init(lv_display_t * disp, lv_color_t * colors, const lv_font_t * font_small, const lv_font_t * font_normal, const lv_font_t * font_large);
bool lv_theme_haspmota_is_inited(void); bool lv_theme_haspmota_is_inited(void);
/********************** /**********************

View File

@ -152,7 +152,7 @@ theme_get_font_large|lv.obj|lv.font|[lv_theme_get_font_large](https://docs.lvgl.
theme_get_font_normal|lv.obj|lv.font|[lv_theme_get_font_normal](https://docs.lvgl.io/9.0/search.html?q=lv_theme_get_font_normal) theme_get_font_normal|lv.obj|lv.font|[lv_theme_get_font_normal](https://docs.lvgl.io/9.0/search.html?q=lv_theme_get_font_normal)
theme_get_font_small|lv.obj|lv.font|[lv_theme_get_font_small](https://docs.lvgl.io/9.0/search.html?q=lv_theme_get_font_small) theme_get_font_small|lv.obj|lv.font|[lv_theme_get_font_small](https://docs.lvgl.io/9.0/search.html?q=lv_theme_get_font_small)
theme_get_from_obj|lv.obj|lv.theme|[lv_theme_get_from_obj](https://docs.lvgl.io/9.0/search.html?q=lv_theme_get_from_obj) theme_get_from_obj|lv.obj|lv.theme|[lv_theme_get_from_obj](https://docs.lvgl.io/9.0/search.html?q=lv_theme_get_from_obj)
theme_haspmota_init|lv.display, lv.color, lv.color, bool, lv.font|lv.theme|[lv_theme_haspmota_init](https://docs.lvgl.io/9.0/search.html?q=lv_theme_haspmota_init) theme_haspmota_init|lv.display, lv.color_arr, lv.font, lv.font, lv.font|lv.theme|[lv_theme_haspmota_init](https://docs.lvgl.io/9.0/search.html?q=lv_theme_haspmota_init)
theme_haspmota_is_inited||bool|[lv_theme_haspmota_is_inited](https://docs.lvgl.io/9.0/search.html?q=lv_theme_haspmota_is_inited) theme_haspmota_is_inited||bool|[lv_theme_haspmota_is_inited](https://docs.lvgl.io/9.0/search.html?q=lv_theme_haspmota_is_inited)
theme_set_parent|lv.theme, lv.theme||[lv_theme_set_parent](https://docs.lvgl.io/9.0/search.html?q=lv_theme_set_parent) theme_set_parent|lv.theme, lv.theme||[lv_theme_set_parent](https://docs.lvgl.io/9.0/search.html?q=lv_theme_set_parent)
timer_create|\<closure\>, int, \<any\>|lv.timer|[lv_timer_create](https://docs.lvgl.io/9.0/search.html?q=lv_timer_create) timer_create|\<closure\>, int, \<any\>|lv.timer|[lv_timer_create](https://docs.lvgl.io/9.0/search.html?q=lv_timer_create)

View File

@ -174,7 +174,7 @@ const be_ntv_func_def_t lv_func[] = {
{ "theme_get_font_normal", { (const void*) &lv_theme_get_font_normal, "lv.font", "(lv.obj)" } }, { "theme_get_font_normal", { (const void*) &lv_theme_get_font_normal, "lv.font", "(lv.obj)" } },
{ "theme_get_font_small", { (const void*) &lv_theme_get_font_small, "lv.font", "(lv.obj)" } }, { "theme_get_font_small", { (const void*) &lv_theme_get_font_small, "lv.font", "(lv.obj)" } },
{ "theme_get_from_obj", { (const void*) &lv_theme_get_from_obj, "lv.theme", "(lv.obj)" } }, { "theme_get_from_obj", { (const void*) &lv_theme_get_from_obj, "lv.theme", "(lv.obj)" } },
{ "theme_haspmota_init", { (const void*) &lv_theme_haspmota_init, "lv.theme", "(lv.display)(lv.color)(lv.color)b(lv.font)" } }, { "theme_haspmota_init", { (const void*) &lv_theme_haspmota_init, "lv.theme", "(lv.display)(lv.color_arr)(lv.font)(lv.font)(lv.font)" } },
{ "theme_haspmota_is_inited", { (const void*) &lv_theme_haspmota_is_inited, "b", "" } }, { "theme_haspmota_is_inited", { (const void*) &lv_theme_haspmota_is_inited, "b", "" } },
{ "theme_set_parent", { (const void*) &lv_theme_set_parent, "", "(lv.theme)(lv.theme)" } }, { "theme_set_parent", { (const void*) &lv_theme_set_parent, "", "(lv.theme)(lv.theme)" } },
{ "timer_create", { (const void*) &lv_timer_create, "lv.timer", "^lv_timer_cb^i." } }, { "timer_create", { (const void*) &lv_timer_create, "lv.timer", "^lv_timer_cb^i." } },

View File

@ -1491,7 +1491,7 @@ lv_obj_t * lv_tileview_get_tile_active(lv_obj_t * obj)
// ../../lvgl/src/widgets/win/lv_win.h // ../../lvgl/src/widgets/win/lv_win.h
// ../../LVGL_assets/src/lv_theme_haspmota.h // ../../LVGL_assets/src/lv_theme_haspmota.h
lv_theme_t * lv_theme_haspmota_init(lv_display_t * disp, lv_color_t color_primary, lv_color_t color_secondary, bool dark, const lv_font_t * font) lv_theme_t * lv_theme_haspmota_init(lv_display_t * disp, lv_color_t * colors, const lv_font_t * font_small, const lv_font_t * font_normal, const lv_font_t * font_large)
bool lv_theme_haspmota_is_inited(void) bool lv_theme_haspmota_is_inited(void)
// ../src/lv_berry.h // ../src/lv_berry.h

View File

@ -112,14 +112,32 @@ end
class lv_style_prop_arr : bytes class lv_style_prop_arr : bytes
def init(l) def init(l)
if type(l) != 'instance' || !isinstance(l, list) raise "value_error", "argument must be a list" end if type(l) != 'instance' || !isinstance(l, list) raise "value_error", "argument must be a list" end
super(self).init(size(l) * 4) super(self).init(size(l))
for e: l for e: l
self.add(int(e), 4) self.add(int(e))
end end
end end
end end
class lv_color_arr : bytes
def init(l)
if type(l) != 'instance' || !isinstance(l, list) raise "value_error", "argument must be a list" end
super(self).init(size(l) * 3)
for e: l
self.add(int(e), 3)
end
end
def item(n)
return lv.color(self.get(n * 3, 3))
end
def setitem(n, v)
self.set(n * 3, int(v), 3)
end
end
class lv_str_arr : bytes class lv_str_arr : bytes
var l # keep a copy of the list because we want the pointer to strings to remain valid var l # keep a copy of the list because we want the pointer to strings to remain valid
def init(l) def init(l)
@ -138,6 +156,7 @@ lv_extra.lv_int_arr = lv_int_arr
lv_extra.lv_point_arr = lv_point_arr lv_extra.lv_point_arr = lv_point_arr
lv_extra.lv_style_prop_arr = lv_style_prop_arr lv_extra.lv_style_prop_arr = lv_style_prop_arr
lv_extra.lv_str_arr = lv_str_arr lv_extra.lv_str_arr = lv_str_arr
lv_extra.lv_color_arr = lv_color_arr
lv_extra.init = def (m) lv_extra.init = def (m)
import global import global
@ -151,6 +170,7 @@ lv_extra.init = def (m)
lv.point_arr = m.lv_point_arr lv.point_arr = m.lv_point_arr
lv.style_prop_arr = m.lv_style_prop_arr lv.style_prop_arr = m.lv_style_prop_arr
lv.str_arr = m.lv_str_arr lv.str_arr = m.lv_str_arr
lv.color_arr = m.lv_color_arr
return m return m
end end

View File

@ -4,84 +4,6 @@
\********************************************************************/ \********************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
extern const bclass be_class_lv_str_arr;
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(class_lv_str_arr_init, /* 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[ 6]) { /* constants */
/* K0 */ be_nested_str_weak(l),
/* K1 */ be_nested_str_weak(init),
/* K2 */ be_nested_str_weak(introspect),
/* K3 */ be_nested_str_weak(add),
/* K4 */ be_nested_str_weak(toptr),
/* K5 */ be_nested_str_weak(stop_iteration),
}),
be_str_weak(init),
&be_const_str_solidified,
( &(const binstruction[31]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x60080003, // 0001 GETGBL R2 G3
0x5C0C0000, // 0002 MOVE R3 R0
0x7C080200, // 0003 CALL R2 1
0x8C080501, // 0004 GETMET R2 R2 K1
0x6010000C, // 0005 GETGBL R4 G12
0x5C140200, // 0006 MOVE R5 R1
0x7C100200, // 0007 CALL R4 1
0x54160003, // 0008 LDINT R5 4
0x08100805, // 0009 MUL R4 R4 R5
0x7C080400, // 000A CALL R2 2
0xA40A0400, // 000B IMPORT R2 K2
0x600C0010, // 000C GETGBL R3 G16
0x5C100200, // 000D MOVE R4 R1
0x7C0C0200, // 000E CALL R3 1
0xA802000A, // 000F EXBLK 0 #001B
0x5C100600, // 0010 MOVE R4 R3
0x7C100000, // 0011 CALL R4 0
0x8C140103, // 0012 GETMET R5 R0 K3
0x601C0009, // 0013 GETGBL R7 G9
0x8C200504, // 0014 GETMET R8 R2 K4
0x5C280800, // 0015 MOVE R10 R4
0x7C200400, // 0016 CALL R8 2
0x7C1C0200, // 0017 CALL R7 1
0x54220003, // 0018 LDINT R8 4
0x7C140600, // 0019 CALL R5 3
0x7001FFF4, // 001A JMP #0010
0x580C0005, // 001B LDCONST R3 K5
0xAC0C0200, // 001C CATCH R3 1 0
0xB0080000, // 001D RAISE 2 R0 R0
0x80000000, // 001E RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: lv_str_arr
********************************************************************/
extern const bclass be_class_bytes;
be_local_class(lv_str_arr,
1,
&be_class_bytes,
be_nested_map(2,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(init, -1), be_const_closure(class_lv_str_arr_init_closure) },
{ be_const_key_weak(l, 0), be_const_var(0) },
})),
be_str_weak(lv_str_arr)
);
extern const bclass be_class_lv_int_arr; extern const bclass be_class_lv_int_arr;
/******************************************************************** /********************************************************************
@ -355,88 +277,41 @@ be_local_class(lv_point_arr,
})), })),
be_str_weak(lv_point_arr) be_str_weak(lv_point_arr)
); );
// compact class 'lv_color_arr' ktab size: 11, total: 13 (saved 16 bytes)
/******************************************************************** static const bvalue be_ktab_class_lv_color_arr[11] = {
** Solidified function: _anonymous_
********************************************************************/
be_local_closure(_anonymous_, /* name */
be_nested_proto(
4, /* nstack */
1, /* argc */
0, /* 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(lv),
/* K2 */ be_nested_str_weak(lv_coord_arr),
/* K3 */ be_nested_str_weak(lv_int_arr),
/* K4 */ be_nested_str_weak(lv_point_arr),
/* K5 */ be_nested_str_weak(coord_arr),
/* K6 */ be_nested_str_weak(int_arr),
/* K7 */ be_nested_str_weak(point_arr),
/* K8 */ be_nested_str_weak(style_prop_arr),
/* K9 */ be_nested_str_weak(lv_style_prop_arr),
/* K10 */ be_nested_str_weak(str_arr),
/* K11 */ be_nested_str_weak(lv_str_arr),
}),
be_str_weak(_anonymous_),
&be_const_str_solidified,
( &(const binstruction[19]) { /* code */
0xA4060000, // 0000 IMPORT R1 K0
0x88080301, // 0001 GETMBR R2 R1 K1
0x880C0102, // 0002 GETMBR R3 R0 K2
0x900A0403, // 0003 SETMBR R2 K2 R3
0x880C0103, // 0004 GETMBR R3 R0 K3
0x900A0603, // 0005 SETMBR R2 K3 R3
0x880C0104, // 0006 GETMBR R3 R0 K4
0x900A0803, // 0007 SETMBR R2 K4 R3
0x880C0102, // 0008 GETMBR R3 R0 K2
0x900A0A03, // 0009 SETMBR R2 K5 R3
0x880C0103, // 000A GETMBR R3 R0 K3
0x900A0C03, // 000B SETMBR R2 K6 R3
0x880C0104, // 000C GETMBR R3 R0 K4
0x900A0E03, // 000D SETMBR R2 K7 R3
0x880C0109, // 000E GETMBR R3 R0 K9
0x900A1003, // 000F SETMBR R2 K8 R3
0x880C010B, // 0010 GETMBR R3 R0 K11
0x900A1403, // 0011 SETMBR R2 K10 R3
0x80040000, // 0012 RET 1 R0
})
)
);
/*******************************************************************/
extern const bclass be_class_lv_style_prop_arr;
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(class_lv_style_prop_arr_init, /* 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[ 6]) { /* constants */
/* K0 */ be_nested_str_weak(instance), /* K0 */ be_nested_str_weak(instance),
/* K1 */ be_nested_str_weak(value_error), /* K1 */ be_nested_str_weak(value_error),
/* K2 */ be_nested_str_weak(argument_X20must_X20be_X20a_X20list), /* K2 */ be_nested_str_weak(argument_X20must_X20be_X20a_X20list),
/* K3 */ be_nested_str_weak(init), /* K3 */ be_nested_str_weak(init),
/* K4 */ be_nested_str_weak(add), /* K4 */ be_const_int(3),
/* K5 */ be_nested_str_weak(stop_iteration), /* K5 */ be_nested_str_weak(add),
}), /* K6 */ be_nested_str_weak(stop_iteration),
/* K7 */ be_nested_str_weak(lv),
/* K8 */ be_nested_str_weak(color),
/* K9 */ be_nested_str_weak(get),
/* K10 */ be_nested_str_weak(set),
};
extern const bclass be_class_lv_color_arr;
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(class_lv_color_arr_init, /* name */
be_nested_proto(
8, /* nstack */
2, /* argc */
10, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
&be_ktab_class_lv_color_arr, /* shared constants */
be_str_weak(init), be_str_weak(init),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[38]) { /* code */ ( &(const binstruction[37]) { /* code */
0x60080004, // 0000 GETGBL R2 G4 0x60080004, // 0000 GETGBL R2 G4
0x5C0C0200, // 0001 MOVE R3 R1 0x5C0C0200, // 0001 MOVE R3 R1
0x7C080200, // 0002 CALL R2 1 0x7C080200, // 0002 CALL R2 1
@ -455,26 +330,25 @@ be_local_closure(class_lv_style_prop_arr_init, /* name */
0x6010000C, // 000F GETGBL R4 G12 0x6010000C, // 000F GETGBL R4 G12
0x5C140200, // 0010 MOVE R5 R1 0x5C140200, // 0010 MOVE R5 R1
0x7C100200, // 0011 CALL R4 1 0x7C100200, // 0011 CALL R4 1
0x54160003, // 0012 LDINT R5 4 0x08100904, // 0012 MUL R4 R4 K4
0x08100805, // 0013 MUL R4 R4 R5 0x7C080400, // 0013 CALL R2 2
0x7C080400, // 0014 CALL R2 2 0x60080010, // 0014 GETGBL R2 G16
0x60080010, // 0015 GETGBL R2 G16 0x5C0C0200, // 0015 MOVE R3 R1
0x5C0C0200, // 0016 MOVE R3 R1 0x7C080200, // 0016 CALL R2 1
0x7C080200, // 0017 CALL R2 1 0xA8020008, // 0017 EXBLK 0 #0021
0xA8020008, // 0018 EXBLK 0 #0022 0x5C0C0400, // 0018 MOVE R3 R2
0x5C0C0400, // 0019 MOVE R3 R2 0x7C0C0000, // 0019 CALL R3 0
0x7C0C0000, // 001A CALL R3 0 0x8C100105, // 001A GETMET R4 R0 K5
0x8C100104, // 001B GETMET R4 R0 K4 0x60180009, // 001B GETGBL R6 G9
0x60180009, // 001C GETGBL R6 G9 0x5C1C0600, // 001C MOVE R7 R3
0x5C1C0600, // 001D MOVE R7 R3 0x7C180200, // 001D CALL R6 1
0x7C180200, // 001E CALL R6 1 0x581C0004, // 001E LDCONST R7 K4
0x541E0003, // 001F LDINT R7 4 0x7C100600, // 001F CALL R4 3
0x7C100600, // 0020 CALL R4 3 0x7001FFF6, // 0020 JMP #0018
0x7001FFF6, // 0021 JMP #0019 0x58080006, // 0021 LDCONST R2 K6
0x58080005, // 0022 LDCONST R2 K5 0xAC080200, // 0022 CATCH R2 1 0
0xAC080200, // 0023 CATCH R2 1 0 0xB0080000, // 0023 RAISE 2 R0 R0
0xB0080000, // 0024 RAISE 2 R0 R0 0x80000000, // 0024 RET 0
0x80000000, // 0025 RET 0
}) })
) )
); );
@ -482,19 +356,142 @@ be_local_closure(class_lv_style_prop_arr_init, /* name */
/******************************************************************** /********************************************************************
** Solidified class: lv_style_prop_arr ** Solidified function: item
********************************************************************/
be_local_closure(class_lv_color_arr_item, /* name */
be_nested_proto(
8, /* nstack */
2, /* argc */
10, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
&be_ktab_class_lv_color_arr, /* shared constants */
be_str_weak(item),
&be_const_str_solidified,
( &(const binstruction[ 8]) { /* code */
0xB80A0E00, // 0000 GETNGBL R2 K7
0x8C080508, // 0001 GETMET R2 R2 K8
0x8C100109, // 0002 GETMET R4 R0 K9
0x08180304, // 0003 MUL R6 R1 K4
0x581C0004, // 0004 LDCONST R7 K4
0x7C100600, // 0005 CALL R4 3
0x7C080400, // 0006 CALL R2 2
0x80040400, // 0007 RET 1 R2
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: setitem
********************************************************************/
be_local_closure(class_lv_color_arr_setitem, /* name */
be_nested_proto(
8, /* nstack */
3, /* argc */
10, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
&be_ktab_class_lv_color_arr, /* shared constants */
be_str_weak(setitem),
&be_const_str_solidified,
( &(const binstruction[ 8]) { /* code */
0x8C0C010A, // 0000 GETMET R3 R0 K10
0x08140304, // 0001 MUL R5 R1 K4
0x60180009, // 0002 GETGBL R6 G9
0x5C1C0400, // 0003 MOVE R7 R2
0x7C180200, // 0004 CALL R6 1
0x581C0004, // 0005 LDCONST R7 K4
0x7C0C0800, // 0006 CALL R3 4
0x80000000, // 0007 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: lv_color_arr
********************************************************************/ ********************************************************************/
extern const bclass be_class_bytes; extern const bclass be_class_bytes;
be_local_class(lv_style_prop_arr, be_local_class(lv_color_arr,
0, 0,
&be_class_bytes, &be_class_bytes,
be_nested_map(1, be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) { ( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(init, -1), be_const_closure(class_lv_style_prop_arr_init_closure) }, { be_const_key_weak(init, -1), be_const_closure(class_lv_color_arr_init_closure) },
{ be_const_key_weak(item, -1), be_const_closure(class_lv_color_arr_item_closure) },
{ be_const_key_weak(setitem, -1), be_const_closure(class_lv_color_arr_setitem_closure) },
})), })),
be_str_weak(lv_style_prop_arr) be_str_weak(lv_color_arr)
); );
/********************************************************************
** Solidified function: _anonymous_
********************************************************************/
be_local_closure(_anonymous_, /* name */
be_nested_proto(
4, /* nstack */
1, /* argc */
0, /* 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(global),
/* K1 */ be_nested_str_weak(lv),
/* K2 */ be_nested_str_weak(lv_coord_arr),
/* K3 */ be_nested_str_weak(lv_int_arr),
/* K4 */ be_nested_str_weak(lv_point_arr),
/* K5 */ be_nested_str_weak(coord_arr),
/* K6 */ be_nested_str_weak(int_arr),
/* K7 */ be_nested_str_weak(point_arr),
/* K8 */ be_nested_str_weak(style_prop_arr),
/* K9 */ be_nested_str_weak(lv_style_prop_arr),
/* K10 */ be_nested_str_weak(str_arr),
/* K11 */ be_nested_str_weak(lv_str_arr),
/* K12 */ be_nested_str_weak(color_arr),
/* K13 */ be_nested_str_weak(lv_color_arr),
}),
be_str_weak(_anonymous_),
&be_const_str_solidified,
( &(const binstruction[21]) { /* code */
0xA4060000, // 0000 IMPORT R1 K0
0x88080301, // 0001 GETMBR R2 R1 K1
0x880C0102, // 0002 GETMBR R3 R0 K2
0x900A0403, // 0003 SETMBR R2 K2 R3
0x880C0103, // 0004 GETMBR R3 R0 K3
0x900A0603, // 0005 SETMBR R2 K3 R3
0x880C0104, // 0006 GETMBR R3 R0 K4
0x900A0803, // 0007 SETMBR R2 K4 R3
0x880C0102, // 0008 GETMBR R3 R0 K2
0x900A0A03, // 0009 SETMBR R2 K5 R3
0x880C0103, // 000A GETMBR R3 R0 K3
0x900A0C03, // 000B SETMBR R2 K6 R3
0x880C0104, // 000C GETMBR R3 R0 K4
0x900A0E03, // 000D SETMBR R2 K7 R3
0x880C0109, // 000E GETMBR R3 R0 K9
0x900A1003, // 000F SETMBR R2 K8 R3
0x880C010B, // 0010 GETMBR R3 R0 K11
0x900A1403, // 0011 SETMBR R2 K10 R3
0x880C010D, // 0012 GETMBR R3 R0 K13
0x900A1803, // 0013 SETMBR R2 K12 R3
0x80040000, // 0014 RET 1 R0
})
)
);
/*******************************************************************/
extern const bclass be_class_lv_coord_arr; extern const bclass be_class_lv_coord_arr;
/******************************************************************** /********************************************************************
@ -666,19 +663,179 @@ be_local_class(lv_coord_arr,
be_str_weak(lv_coord_arr) be_str_weak(lv_coord_arr)
); );
extern const bclass be_class_lv_style_prop_arr;
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(class_lv_style_prop_arr_init, /* 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[ 6]) { /* constants */
/* K0 */ be_nested_str_weak(instance),
/* K1 */ be_nested_str_weak(value_error),
/* K2 */ be_nested_str_weak(argument_X20must_X20be_X20a_X20list),
/* K3 */ be_nested_str_weak(init),
/* K4 */ be_nested_str_weak(add),
/* K5 */ be_nested_str_weak(stop_iteration),
}),
be_str_weak(init),
&be_const_str_solidified,
( &(const binstruction[35]) { /* code */
0x60080004, // 0000 GETGBL R2 G4
0x5C0C0200, // 0001 MOVE R3 R1
0x7C080200, // 0002 CALL R2 1
0x20080500, // 0003 NE R2 R2 K0
0x740A0004, // 0004 JMPT R2 #000A
0x6008000F, // 0005 GETGBL R2 G15
0x5C0C0200, // 0006 MOVE R3 R1
0x60100012, // 0007 GETGBL R4 G18
0x7C080400, // 0008 CALL R2 2
0x740A0000, // 0009 JMPT R2 #000B
0xB0060302, // 000A RAISE 1 K1 K2
0x60080003, // 000B GETGBL R2 G3
0x5C0C0000, // 000C MOVE R3 R0
0x7C080200, // 000D CALL R2 1
0x8C080503, // 000E GETMET R2 R2 K3
0x6010000C, // 000F GETGBL R4 G12
0x5C140200, // 0010 MOVE R5 R1
0x7C100200, // 0011 CALL R4 1
0x7C080400, // 0012 CALL R2 2
0x60080010, // 0013 GETGBL R2 G16
0x5C0C0200, // 0014 MOVE R3 R1
0x7C080200, // 0015 CALL R2 1
0xA8020007, // 0016 EXBLK 0 #001F
0x5C0C0400, // 0017 MOVE R3 R2
0x7C0C0000, // 0018 CALL R3 0
0x8C100104, // 0019 GETMET R4 R0 K4
0x60180009, // 001A GETGBL R6 G9
0x5C1C0600, // 001B MOVE R7 R3
0x7C180200, // 001C CALL R6 1
0x7C100400, // 001D CALL R4 2
0x7001FFF7, // 001E JMP #0017
0x58080005, // 001F LDCONST R2 K5
0xAC080200, // 0020 CATCH R2 1 0
0xB0080000, // 0021 RAISE 2 R0 R0
0x80000000, // 0022 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: lv_style_prop_arr
********************************************************************/
extern const bclass be_class_bytes;
be_local_class(lv_style_prop_arr,
0,
&be_class_bytes,
be_nested_map(1,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(init, -1), be_const_closure(class_lv_style_prop_arr_init_closure) },
})),
be_str_weak(lv_style_prop_arr)
);
extern const bclass be_class_lv_str_arr;
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(class_lv_str_arr_init, /* 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[ 6]) { /* constants */
/* K0 */ be_nested_str_weak(l),
/* K1 */ be_nested_str_weak(init),
/* K2 */ be_nested_str_weak(introspect),
/* K3 */ be_nested_str_weak(add),
/* K4 */ be_nested_str_weak(toptr),
/* K5 */ be_nested_str_weak(stop_iteration),
}),
be_str_weak(init),
&be_const_str_solidified,
( &(const binstruction[31]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x60080003, // 0001 GETGBL R2 G3
0x5C0C0000, // 0002 MOVE R3 R0
0x7C080200, // 0003 CALL R2 1
0x8C080501, // 0004 GETMET R2 R2 K1
0x6010000C, // 0005 GETGBL R4 G12
0x5C140200, // 0006 MOVE R5 R1
0x7C100200, // 0007 CALL R4 1
0x54160003, // 0008 LDINT R5 4
0x08100805, // 0009 MUL R4 R4 R5
0x7C080400, // 000A CALL R2 2
0xA40A0400, // 000B IMPORT R2 K2
0x600C0010, // 000C GETGBL R3 G16
0x5C100200, // 000D MOVE R4 R1
0x7C0C0200, // 000E CALL R3 1
0xA802000A, // 000F EXBLK 0 #001B
0x5C100600, // 0010 MOVE R4 R3
0x7C100000, // 0011 CALL R4 0
0x8C140103, // 0012 GETMET R5 R0 K3
0x601C0009, // 0013 GETGBL R7 G9
0x8C200504, // 0014 GETMET R8 R2 K4
0x5C280800, // 0015 MOVE R10 R4
0x7C200400, // 0016 CALL R8 2
0x7C1C0200, // 0017 CALL R7 1
0x54220003, // 0018 LDINT R8 4
0x7C140600, // 0019 CALL R5 3
0x7001FFF4, // 001A JMP #0010
0x580C0005, // 001B LDCONST R3 K5
0xAC0C0200, // 001C CATCH R3 1 0
0xB0080000, // 001D RAISE 2 R0 R0
0x80000000, // 001E RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: lv_str_arr
********************************************************************/
extern const bclass be_class_bytes;
be_local_class(lv_str_arr,
1,
&be_class_bytes,
be_nested_map(2,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(init, -1), be_const_closure(class_lv_str_arr_init_closure) },
{ be_const_key_weak(l, 0), be_const_var(0) },
})),
be_str_weak(lv_str_arr)
);
/******************************************************************** /********************************************************************
** Solidified module: lv_extra ** Solidified module: lv_extra
********************************************************************/ ********************************************************************/
be_local_module(lv_extra, be_local_module(lv_extra,
"lv_extra", "lv_extra",
be_nested_map(6, be_nested_map(7,
( (struct bmapnode*) &(const bmapnode[]) { ( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(lv_coord_arr, 4), be_const_class(be_class_lv_coord_arr) }, { be_const_key_weak(lv_style_prop_arr, 4), be_const_class(be_class_lv_style_prop_arr) },
{ be_const_key_weak(lv_int_arr, -1), be_const_class(be_class_lv_int_arr) }, { be_const_key_weak(lv_str_arr, -1), be_const_class(be_class_lv_str_arr) },
{ be_const_key_weak(lv_coord_arr, -1), be_const_class(be_class_lv_coord_arr) },
{ be_const_key_weak(lv_int_arr, 0), be_const_class(be_class_lv_int_arr) },
{ be_const_key_weak(lv_point_arr, -1), be_const_class(be_class_lv_point_arr) }, { be_const_key_weak(lv_point_arr, -1), be_const_class(be_class_lv_point_arr) },
{ be_const_key_weak(init, -1), be_const_closure(_anonymous__closure) }, { be_const_key_weak(init, -1), be_const_closure(_anonymous__closure) },
{ be_const_key_weak(lv_style_prop_arr, -1), be_const_class(be_class_lv_style_prop_arr) }, { be_const_key_weak(lv_color_arr, 2), be_const_class(be_class_lv_color_arr) },
{ be_const_key_weak(lv_str_arr, 0), be_const_class(be_class_lv_str_arr) },
})) }))
); );
BE_EXPORT_VARIABLE be_define_const_native_module(lv_extra); BE_EXPORT_VARIABLE be_define_const_native_module(lv_extra);

View File

@ -383,6 +383,7 @@ class type_mapper_class:
"int32_t *": "lv_int_arr", "int32_t *": "lv_int_arr",
"int32_t []": "lv_int_arr", "int32_t []": "lv_int_arr",
"uint32_t *": "lv_int_arr", "uint32_t *": "lv_int_arr",
"lv_color_t *": "lv_color_arr",
# "float *": "lv_float_arr", # "float *": "lv_float_arr",
# layouts # layouts
"lv_flex_align_t": "i", "lv_flex_align_t": "i",

View File

@ -2360,6 +2360,7 @@ class lvh_chart : lvh_obj
var _ser1, _ser2 var _ser1, _ser2
# y_min/y_max contain the main range for y. Since LVGL does not have getters, we need to memorize on our side the lates tvalues # y_min/y_max contain the main range for y. Since LVGL does not have getters, we need to memorize on our side the lates tvalues
var _y_min, _y_max var _y_min, _y_max
var _y2_min, _y2_max
# h_div/v_div contain the horizontal and vertical divisions, we need to memorize values because both are set from same API # h_div/v_div contain the horizontal and vertical divisions, we need to memorize values because both are set from same API
var _h_div, _v_div var _h_div, _v_div
@ -2367,6 +2368,8 @@ class lvh_chart : lvh_obj
# default values from LVGL are 0..100 # default values from LVGL are 0..100
self._y_min = 0 self._y_min = 0
self._y_max = 100 self._y_max = 100
self._y2_min = 0
self._y2_max = 100
# default values # default values
#define LV_CHART_HDIV_DEF 3 #define LV_CHART_HDIV_DEF 3
#define LV_CHART_VDIV_DEF 5 #define LV_CHART_VDIV_DEF 5
@ -2376,7 +2379,7 @@ class lvh_chart : lvh_obj
self._lv_obj.set_update_mode(lv.CHART_UPDATE_MODE_SHIFT) self._lv_obj.set_update_mode(lv.CHART_UPDATE_MODE_SHIFT)
self._ser1 = self._lv_obj.add_series(lv.color(0xEE4444), lv.CHART_AXIS_PRIMARY_Y) self._ser1 = self._lv_obj.add_series(lv.color(0xEE4444), lv.CHART_AXIS_PRIMARY_Y)
self._ser2 = self._lv_obj.add_series(lv.color(0x44EE44), lv.CHART_AXIS_PRIMARY_Y) self._ser2 = self._lv_obj.add_series(lv.color(0x44EE44), lv.CHART_AXIS_SECONDARY_Y)
end end
def add_point(v) def add_point(v)
@ -2399,6 +2402,12 @@ class lvh_chart : lvh_obj
def get_y_max() def get_y_max()
return self._y_max return self._y_max
end end
def get_y2_min()
return self._y2_min
end
def get_y2_max()
return self._y2_max
end
def set_y_min(_y_min) def set_y_min(_y_min)
self._y_min = _y_min self._y_min = _y_min
self._lv_obj.set_range(lv.CHART_AXIS_PRIMARY_Y, self._y_min, self._y_max) self._lv_obj.set_range(lv.CHART_AXIS_PRIMARY_Y, self._y_min, self._y_max)
@ -2407,6 +2416,14 @@ class lvh_chart : lvh_obj
self._y_max = _y_max self._y_max = _y_max
self._lv_obj.set_range(lv.CHART_AXIS_PRIMARY_Y, self._y_min, self._y_max) self._lv_obj.set_range(lv.CHART_AXIS_PRIMARY_Y, self._y_min, self._y_max)
end end
def set_y2_min(_y2_min)
self._y2_min = _y2_min
self._lv_obj.set_range(lv.CHART_AXIS_SECONDARY_Y, self._y2_min, self._y2_max)
end
def set_y2_max(_y2_max)
self._y2_max = _y2_max
self._lv_obj.set_range(lv.CHART_AXIS_SECONDARY_Y, self._y2_min, self._y2_max)
end
def set_series1_color(color) def set_series1_color(color)
self._lv_obj.set_series_color(self._ser1, self.parse_color(color)) self._lv_obj.set_series_color(self._ser1, self.parse_color(color))
@ -2601,8 +2618,6 @@ class lvh_page
self._lv_scr = lv.layer_top() # top layer, visible over all screens self._lv_scr = lv.layer_top() # top layer, visible over all screens
else else
self._lv_scr = lv.obj(0) # allocate a new screen self._lv_scr = lv.obj(0) # allocate a new screen
var bg_color = lv.scr_act().get_style_bg_color(0 #- lv.PART_MAIN | lv.STATE_DEFAULT -#) # bg_color of default screen
self._lv_scr.set_style_bg_color(bg_color, 0 #- lv.PART_MAIN | lv.STATE_DEFAULT -#) # set white background
end end
# page object is also stored in the object map at id `0` as instance of `lvg_scr` # page object is also stored in the object map at id `0` as instance of `lvg_scr`
@ -2784,10 +2799,10 @@ end
# main class controller, meant to be a singleton and the only externally used class # main class controller, meant to be a singleton and the only externally used class
class HASPmota class HASPmota
var dark # (bool) use dark theme? var started # (bool) is HASPmota already started?
var hres, vres # (int) resolution var hres, vres # (int) resolution
var scr # (lv_obj) default LVGL screen var scr # (lv_obj) default LVGL screen
var r16 # (lv_font) robotocondensed fonts size 16 var r12, r16, r24 # (lv_font) robotocondensed fonts size 12, 16 and 24
# haspmota objects # haspmota objects
var lvh_pages # (list of lvg_page) list of pages var lvh_pages # (list of lvg_page) list of pages
var lvh_page_cur_idx # (int) current page index number var lvh_page_cur_idx # (int) current page index number
@ -2840,12 +2855,12 @@ class HASPmota
# special cases # special cases
static lvh_chart = lvh_chart static lvh_chart = lvh_chart
static def_templ_name = "pages.jsonl" # default template name static var PAGES_JSONL = "pages.jsonl" # default template name
def init() def init()
self.fix_lv_version() self.fix_lv_version()
import re import re
self.re_page_target = re.compile("p\\d+") self.re_page_target = re.compilebytes("p\\d+")
# nothing to put here up to now # nothing to put here up to now
end end
@ -2860,35 +2875,72 @@ class HASPmota
#==================================================================== #====================================================================
# init # init
# #
# arg1: (bool) use dark theme if `true` # Opt1: no arguments
# load "pages.jsonl"
# Opt2:
# arg1: (string) use it as template name
#
# Opt3:
# arg1: (bool) set dark mode (deprecated)
# arg2: (string) use it as template name
# #
# implicitly loads `pages.jsonl` from file-system // TODO allow to specicify file name
#==================================================================== #====================================================================
def start(dark, templ_name) def start(arg1, arg2)
if (self.started) return end
var templ_name
if type(arg1) == 'string'
templ_name = arg1
elif type(arg2) == 'string'
templ_name = arg2
else
templ_name = self.PAGES_JSONL # use default PAGES.JSONL
end
import path import path
if templ_name == nil templ_name = self.def_templ_name end
if !path.exists(templ_name) if !path.exists(templ_name)
raise "io_erorr", "file '" + templ_name + "' not found" raise "io_erorr", "file '" + templ_name + "' not found"
end end
# start lv if not already started. It does no harm to call lv.start() if LVGL was already started # start lv if not already started. It does no harm to call lv.start() if LVGL was already started
lv.start() lv.start()
self.dark = bool(dark)
self.hres = lv.get_hor_res() # ex: 320 self.hres = lv.get_hor_res() # ex: 320
self.vres = lv.get_ver_res() # ex: 240 self.vres = lv.get_ver_res() # ex: 240
self.scr = lv.scr_act() # LVGL default screean object self.scr = lv.scr_act() # LVGL default screean object
try
self.r12 = lv.font_embedded("robotocondensed", 12) # TODO what if does not exist
except ..
self.r12 = lv.font_embedded("montserrat", 10) # TODO what if does not exist
end
try try
self.r16 = lv.font_embedded("robotocondensed", 16) # TODO what if does not exist self.r16 = lv.font_embedded("robotocondensed", 16) # TODO what if does not exist
except .. except ..
self.r16 = lv.font_embedded("montserrat", 14) # TODO what if does not exist self.r16 = lv.font_embedded("montserrat", 14) # TODO what if does not exist
end end
try
self.r24 = lv.font_embedded("robotocondensed", 24) # TODO what if does not exist
except ..
self.r24 = lv.font_embedded("montserrat", 20) # TODO what if does not exist
end
# set the theme for HASPmota # set the theme for HASPmota
var th2 = lv.theme_haspmota_init(0, lv.color(0xFF00FF), lv.color(0x303030), self.dark, self.r16) var primary_color = self.lvh_root.parse_color(tasmota.webcolor(10 #-COL_BUTTON-#))
var secondary_color = self.lvh_root.parse_color(tasmota.webcolor(11 #-COL_BUTTON_HOVER-#))
var color_scr = self.lvh_root.parse_color(tasmota.webcolor(1 #-COL_BACKGROUND-#))
var color_text = self.lvh_root.parse_color(tasmota.webcolor(9 #-COL_BUTTON_TEXT-#))
var color_card = self.lvh_root.parse_color(tasmota.webcolor(2 #-COL_FORM-#))
var color_grey = self.lvh_root.parse_color(tasmota.webcolor(2 #-COL_FORM-#))
var color_reset = self.lvh_root.parse_color(tasmota.webcolor(12 #-COL_BUTTON_RESET-#))
var color_reset_hover = self.lvh_root.parse_color(tasmota.webcolor(13 #-COL_BUTTON_RESET_HOVER-#))
var color_save = self.lvh_root.parse_color(tasmota.webcolor(14 #-COL_BUTTON_SAVE-#))
var color_save_hover = self.lvh_root.parse_color(tasmota.webcolor(15 #-COL_BUTTON_SAVE_HOVER-#))
var colors = lv.color_arr([primary_color, secondary_color, color_scr, color_text, color_card, color_grey,
color_reset, color_reset_hover, color_save, color_save_hover])
var th2 = lv.theme_haspmota_init(0, colors,
self.r12, self.r16, self.r24)
self.scr.get_disp().set_theme(th2) self.scr.get_disp().set_theme(th2)
self.scr.set_style_bg_color(self.dark ? lv.color(0x000000) : lv.color(0xFFFFFF),0) # set background to white
# apply theme to layer_top, but keep it transparent # apply theme to layer_top, but keep it transparent
lv.theme_apply(lv.layer_top()) lv.theme_apply(lv.layer_top())
lv.layer_top().set_style_bg_opa(0,0) lv.layer_top().set_style_bg_opa(0,0)
@ -2896,6 +2948,7 @@ class HASPmota
self.lvh_pages = {} self.lvh_pages = {}
# load from JSONL # load from JSONL
self._load(templ_name) self._load(templ_name)
self.started = true
end end
################################################################################# #################################################################################
@ -2948,21 +3001,20 @@ class HASPmota
import string import string
import json import json
var f = open(templ_name,"r") var f = open(templ_name)
var f_content = f.read()
f.close()
var jsonl = string.split(f_content, "\n")
f = nil # allow deallocation
f_content = nil
# parse each line # parse each line
while size(jsonl) > 0 while f.tell() < f.size() # while we're not at the end of the file
var jline = json.load(jsonl[0]) var line = f.readline()
# if size is '1', the line is considered as empty because it's a '\n' character
if (size(line) <= 1) || (line[0] == '#') # skip empty lines and lines starting with '#'
continue
end
var jline = json.load(line)
if type(jline) == 'instance' if type(jline) == 'instance'
if tasmota.loglevel(4) if tasmota.loglevel(4)
tasmota.log(f"HSP: parsing line '{jsonl[0]}'", 4) tasmota.log(f"HSP: parsing line '{line}'", 4)
end end
self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx_parsing self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx_parsing
# objects are created in the current page # objects are created in the current page
@ -2972,14 +3024,13 @@ class HASPmota
self.parse_obj(jline, self.lvh_pages[self.lvh_page_cur_idx_parsing]) # then parse object within this page self.parse_obj(jline, self.lvh_pages[self.lvh_page_cur_idx_parsing]) # then parse object within this page
else else
# check if it's invalid json # check if it's invalid json
if size(string.tr(jsonl[0], " \t", "")) > 0 if size(string.tr(line, " \t", "")) > 0
tasmota.log(f"HSP: invalid JSON line '{jsonl[0]}'", 2) tasmota.log(f"HSP: invalid JSON line '{line}'", 2)
end end
end end
jline = nil jline = nil
jsonl.remove(0)
end end
jsonl = nil # make all of it freeable f.close()
# current page is always 1 when we start # current page is always 1 when we start
var pages_sorted = self.pages_list_sorted(nil) # nil for full list var pages_sorted = self.pages_list_sorted(nil) # nil for full list
@ -3094,6 +3145,7 @@ class HASPmota
# Returns: the target page object if changed, or `nil` if still on same page # Returns: the target page object if changed, or `nil` if still on same page
#==================================================================== #====================================================================
def page_show(action, anim, duration) def page_show(action, anim, duration)
import re
# resolve between page numbers # resolve between page numbers
# p1 is either a number or nil (stored value) # p1 is either a number or nil (stored value)
# p2 is the default value # p2 is the default value
@ -3129,7 +3181,7 @@ class HASPmota
if (to_page == cur_page.id()) if (to_page == cur_page.id())
to_page = to_page_resolve(int(cur_page.next), sorted_pages_list[1], sorted_pages_list) to_page = to_page_resolve(int(cur_page.next), sorted_pages_list[1], sorted_pages_list)
end end
elif self.re_page_target.match(action) elif re.match(self.re_page_target, action)
# action is supposed to be `p<number>` format # action is supposed to be `p<number>` format
to_page = to_page_resolve(int(action[1..-1]), nil #-default to nil-#, sorted_pages_list) to_page = to_page_resolve(int(action[1..-1]), nil #-default to nil-#, sorted_pages_list)
end end

View File

@ -26,7 +26,7 @@ platform = env.PioPlatform()
from genericpath import exists from genericpath import exists
import os import os
import sys import sys
from os.path import join from os.path import join, getsize
import csv import csv
import requests import requests
import shutil import shutil
@ -272,6 +272,13 @@ def esp32_create_combined_bin(source, target, env):
"--flash_size", "--flash_size",
flash_size, flash_size,
] ]
# platformio estimates the flash space used to store the firmware.
# the estimation is inaccurate. perform a final check on the firmware
# size by comparing it against the partition size.
max_size = env.BoardConfig().get("upload.maximum_size", 1)
fw_size = getsize(firmware_name)
if (fw_size > max_size):
raise Exception(Fore.RED + "firmware binary too large: %d > %d" % (fw_size, max_size))
print(" Offset | File") print(" Offset | File")
for section in sections: for section in sections:

View File

@ -81,7 +81,7 @@ lib_ignore = ${esp32_defaults.lib_ignore}
ccronexpr ccronexpr
[core32] [core32]
platform = https://github.com/tasmota/platform-espressif32/releases/download/2025.02.30/platform-espressif32.zip platform = https://github.com/tasmota/platform-espressif32/releases/download/2025.04.30/platform-espressif32.zip
platform_packages = platform_packages =
build_unflags = ${esp32_defaults.build_unflags} build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags} build_flags = ${esp32_defaults.build_flags}

View File

@ -67,6 +67,88 @@ build_flags = ${env:tasmota32_base.build_flags}
-DUSE_LVGL_OPENHASP -DUSE_LVGL_OPENHASP
-DOTA_URL='""' -DOTA_URL='""'
[env:tasmota32-WPA3_SAE]
; Arduino libs with WiFi Enterprise support
extends = env:tasmota32_base
build_flags = ${env:tasmota32_base.build_flags}
-DFIRMWARE_TASMOTA32
-DOTA_URL='""'
lib_ignore = Micro-RTSP
custom_sdkconfig = CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y
CONFIG_WIFI_AUTH_WPA2_ENTERPRISE=y
CONFIG_WIFI_AUTH_WPA3_ENTERPRISE=y
CONFIG_WIFI_AUTH_WPA2_WPA3_ENTERPRISE=y
CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y
CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y
[env:tasmota32s3-qio_opi_per]
; device needs >= 8MB Flash!! Hybrid compile for max. performance when using Displays
extends = env:tasmota32_base
board = esp32s3-qio_opi_120
board_build.partitions = partitions/esp32_partition_app3904k_fs3392k.csv
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
build_unflags = ${env:tasmota32_base.build_unflags}
-Os
-ffunction-sections
build_flags = ${env:tasmota32_base.build_flags}
-Ofast
-mtext-section-literals
-DUSE_BERRY_ULP
-DFIRMWARE_LVGL
-DUSE_LVGL_OPENHASP
-DOTA_URL='""'
custom_sdkconfig = '# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set'
CONFIG_COMPILER_OPTIMIZATION_PERF=y
'# CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS is not set'
'# CONFIG_LWIP_PPP_SUPPORT is not set'
'# SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE is not set'
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_SPEED_120M=y
CONFIG_SPIRAM_IGNORE_NOTFOUND=y
'# CONFIG_SPIRAM_MEMTEST is not set'
CONFIG_LCD_RGB_ISR_IRAM_SAFE=y
CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y
CONFIG_I2S_ISR_IRAM_SAFE=y
CONFIG_GDMA_ISR_IRAM_SAFE=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
CONFIG_SPIRAM_RODATA=y
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
CONFIG_ESP32S3_DATA_CACHE_64KB=y
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
[env:tasmota32c2-no-NAPT]
; Hybrid compile: No IDF BT support, disabled PPP, Ethernet and NAPT
extends = env:tasmota32_base
board = esp32c2
build_flags = ${env:tasmota32_base.build_flags}
-DFIRMWARE_TASMOTA32
-DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c2.bin"'
lib_ignore = ${env:tasmota32_base.lib_ignore}
Micro-RTSP
custom_sdkconfig =
'# CONFIG_BT_ENABLED is not set'
'# CONFIG_BT_NIMBLE_ENABLED is not set'
'# CONFIG_BT_CONTROLLER_ENABLED is not set'
CONFIG_BT_CONTROLLER_DISABLED=y
'# CONFIG_LWIP_IP_FORWARD is not set'
'# CONFIG_LWIP_IPV4_NAPT is not set'
'# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set'
'# CONFIG_ETH_ENABLED is not set'
'# CONFIG_ETH_USE_SPI_ETHERNET is not set'
'# CONFIG_ETH_TRANSMIT_MUTEX is not set'
'# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set'
'# CONFIG_ETH_SPI_ETHERNET_W5500 is not set'
'# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set'
'# CONFIG_LWIP_PPP_SUPPORT is not set'
; disable not needed IDF managed components for Arduino libs compile
custom_component_remove = espressif/esp_hosted
espressif/esp_wifi_remote
espressif/esp_modem
; add IDF component from espressif registry for Arduino libs compile
custom_component_add = espressif/esp-dsp @ ^1.5.2
[env:tasmota32s3-opi_opi] [env:tasmota32s3-opi_opi]
extends = env:tasmota32_base extends = env:tasmota32_base
board = esp32s3-opi_opi board = esp32s3-opi_opi

View File

@ -0,0 +1,64 @@
#-------------------------------------------------------------
- Specialized driver for AXP2102 of M5Core2v1_1
-------------------------------------------------------------#
class AXP2102_M5Core2v1_1 : AXP2102
def init()
super(self).init()
if self.wire
# From https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/Power_Class.cpp#L351-L360
# for Core2 v1.1
# static constexpr std::uint8_t reg_data_array[] =
# { 0x27, 0x00 // PowerKey Hold=1sec / PowerOff=4sec
# , 0x10, 0x30 // PMU common config (internal off-discharge enable)
# , 0x12, 0x00 // BATFET disable
# , 0x68, 0x01 // Battery detection enabled.
# , 0x69, 0x13 // CHGLED setting
# , 0x99, 0x00 // DLDO1 set 0.5v (vibration motor)
# , 0x30, 0x0F // ADC enabled (for voltage measurement)
# // , 0x18, 0x0E
# };
self.write8(0x90, 0xBE) # LDOS ON/OFF control 0
self.write8(0x92, 0x00) # ALDO1 off
self.write8(0x93, 33 -5) # ALDO2 on, set to 3.3v // AXP_ILI9342C_RTS
self.write8(0x94, 0x00) # ALDO3 on, set to 0.5V // AXP_SPK_EN off
self.write8(0x95, 33 -5) # ALDO4 on, set to 3.3v // AXP_ILI9342C_POWER
self.write8(0x96, 0x00) # BLDO1 on, set to 0.5V // AXP_ILI9342C_BL off
self.write8(0x99, 0x00) # DLDO1 on, set to 0.5V // AXP_VIB off
self.write8(0x27, 0x00) # PowerKey Hold=1sec // PowerOff=4sec
self.write8(0x22, 0x06) # PWROFF_EN behavior
self.write8(0x10, 0x30) # PMU common config
self.write8(0x12, 0x00) # BATFET disabled
self.write8(0x68, 0x01) # Battery detection enabled
self.write8(0x69, 0x13) # CHGLED setting
self.write8(0x30, 0x0F) # ADC enabled (for voltage measurement)
tasmota.add_driver(self)
end
end
# set LCD backlight voltage on BLDO1
def set_lcd_voltage(voltage)
if (voltage < 2500) voltage = 2500 end
if (voltage > 3300) voltage = 3300 end
self.set_ldo_voltage(4, voltage) # 4=BLD01
end
# Speaker enable
def set_speaker_enable(state)
self.set_ldo_voltage(2, state ? 3300 : 0) # 2 = ALDO3
end
# Dimmer in percentage
def set_displaydimmer(x)
var v = tasmota.scale_uint(x, 0, 100, 2500, 3300)
self.set_lcd_voltage(v)
end
# respond to display events
def display(cmd, idx, payload, raw)
if cmd == "dim" || cmd == "power"
self.set_displaydimmer(idx)
end
end
end
return AXP2102_M5Core2v1_1()

View File

@ -333,6 +333,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "TUYA_TX", (int32_t) GPIO_TUYA_TX }, { "TUYA_TX", (int32_t) GPIO_TUYA_TX },
{ "TX2X_TXD_BLACK", (int32_t) GPIO_TX2X_TXD_BLACK }, { "TX2X_TXD_BLACK", (int32_t) GPIO_TX2X_TXD_BLACK },
{ "TXD", (int32_t) GPIO_TXD }, { "TXD", (int32_t) GPIO_TXD },
{ "V9240_RX", (int32_t) GPIO_V9240_RX },
{ "V9240_TX", (int32_t) GPIO_V9240_TX },
{ "VINDRIKTNING_RX", (int32_t) GPIO_VINDRIKTNING_RX }, { "VINDRIKTNING_RX", (int32_t) GPIO_VINDRIKTNING_RX },
{ "VL53LXX_XSHUT1", (int32_t) GPIO_VL53LXX_XSHUT1 }, { "VL53LXX_XSHUT1", (int32_t) GPIO_VL53LXX_XSHUT1 },
{ "WE517_RX", (int32_t) GPIO_WE517_RX }, { "WE517_RX", (int32_t) GPIO_WE517_RX },

View File

@ -707,6 +707,7 @@ class leds_panel
static var SAMPLING = 100 static var SAMPLING = 100
static var PORT = 8886 # default port 8886 static var PORT = 8886 # default port 8886
static var HTML_WIDTH = 290
static var HTML_HEAD1 = static var HTML_HEAD1 =
"<!DOCTYPE HTML><html><head>" "<!DOCTYPE HTML><html><head>"
static var HTML_URL_F = static var HTML_URL_F =
@ -797,7 +798,7 @@ class leds_panel
'<table style="width:100%;border:0px;margin:0px;">' '<table style="width:100%;border:0px;margin:0px;">'
'<tbody>' '<tbody>'
'<tr><td>' '<tr><td>'
'<canvas id="canvas" width="330" height="10" style="display:block;margin-left:auto;margin-right:auto;"></canvas>' '<canvas id="canvas" width="290" height="10" style="display:block;margin-left:auto;margin-right:auto;"></canvas>'
'</td></tr>' '</td></tr>'
'</tbody>' '</tbody>'
'</table>' '</table>'
@ -837,7 +838,7 @@ class leds_panel
self.p_leds = self.strip.pixels_buffer(self.p_leds) # update buffer self.p_leds = self.strip.pixels_buffer(self.p_leds) # update buffer
self.h = tasmota.settings.light_pixels_height_1 + 1 self.h = tasmota.settings.light_pixels_height_1 + 1
self.w = self.strip.pixel_count() / (tasmota.settings.light_pixels_height_1 + 1) self.w = self.strip.pixel_count() / (tasmota.settings.light_pixels_height_1 + 1)
self.cell_size = tasmota.int(330 / self.w, 4, 25) self.cell_size = tasmota.int(self.HTML_WIDTH / self.w, 4, 25)
self.cell_space = (self.cell_size <= 6) ? 1 : 2 self.cell_space = (self.cell_size <= 6) ? 1 : 2
end end
@ -946,14 +947,46 @@ class leds_panel
webserver.content_send( webserver.content_send(
f'<table style="width:100%;">' f'<table style="width:100%;">'
'<tbody>' '<tbody>'
'<fieldset style="background-color:{tasmota.webcolor(1)};"><legend style="text-align:left;">&nbsp;Leds mirroring&nbsp;</legend>' '<tr>'
'<iframe src="http://{ip}:{self.port}/leds" ' '<td>'
'style="color:#eaeaea; border:0px none;height:{height}px;width:340px;margin:0px 8px 0px 8px;padding:0px 0px;">' '<fieldset style="background-color:{tasmota.webcolor(1)};">'
'<legend style="text-align:left;">'
'<label>'
'<input type="checkbox" id="ledchk">&nbsp;Leds mirroring&nbsp;'
'</label>'
'</legend>'
'<iframe id="led_iframe" src="about:blank" hidden="true" '
'style="color:#eaeaea;border:0px none;height:{height}px;width:300px;margin:0px 8px 0px 8px;padding:0px 0px;">'
'</iframe>' '</iframe>'
'</fieldset>' '</fieldset>'
'</td>' '</td>'
'</tr>' '</tr>'
'</tbody></table>' '</tbody>'
'</table>'
'<script>'
'const leduri="http://{ip}:{self.port}/leds";'
'</script>'
)
webserver.content_send(
'<script>'
'function ledm(){'
'ledchk=eb("ledchk");'
# checkbox event
'ledchk.addEventListener("change",(event)=>{'
'const iframe=document.getElementById("led_iframe");'
'if(ledchk.checked){'
# When checked, reload the original content
'iframe.src=leduri;'
'iframe.hidden=false;'
'}else{'
# When unchecked, replace iframe with itself to unload it
'iframe.src="about:blank";'
'iframe.hidden=true;'
'}'
'});'
'}'
'wl(ledm);'
'</script>'
) )
end end
end end

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -107,7 +107,6 @@ class cc2652_flasher
# restart the MCU in BSL mode and establish communication # restart the MCU in BSL mode and establish communication
def start(debug) def start(debug)
if debug == nil debug = false end
self.debug = bool(debug) self.debug = bool(debug)
self.reset_bsl() self.reset_bsl()
# #
@ -134,9 +133,9 @@ class cc2652_flasher
self.ser.write(bytes("5555")) # trigger auto baudrate detector self.ser.write(bytes("5555")) # trigger auto baudrate detector
var ret = self.recv_raw(100) var ret = self.recv_raw(100)
if self.debug print("ret=", ret) end if self.debug print(f"reset_bsl ret='{ret}'") end
if ret != bytes('CC') if ret[-1] != 0xCC
raise "protocol_error" raise "protocol_error", f"received '{ret}'"
end end
end end
@ -218,7 +217,7 @@ class cc2652_flasher
if self.debug print("sending:", payload) end if self.debug print("sending:", payload) end
self.ser.write(payload) self.ser.write(payload)
var ret = self.recv_raw(500) var ret = self.recv_raw(500)
if self.debug print("ret=", ret) end if self.debug print(f"ret={ret}") end
if no_response == true if no_response == true
#ignore #ignore
self.decode_ack(ret) self.decode_ack(ret)

View File

@ -70,7 +70,7 @@ class sonoff_zb_pro_flasher
except .. as e, m except .. as e, m
self.file_checked = false self.file_checked = false
self.file_validated = false self.file_validated = false
raise e, m print(f"FLH: Exception raised '{e}' - '{m}'")
end end
end end

725
tasmota/include/alpinejs.h Normal file
View File

@ -0,0 +1,725 @@
/*
alpinejs.h - support for alpinejs 2.8.2
SPDX-FileCopyrightText: 2025 Stephan Hadinger
SPDX-License-Identifier: GPL-3.0-only
*/
#ifdef USE_WEBSERVER
#ifdef USE_ALPINEJS
// `xxd -i alpine.min.js.gz > tas_alpine.h`
static const char PROGMEM alpine_min_js_gz[] = {
0x1f, 0x8b, 0x08, 0x08, 0xe8, 0x91, 0xd9, 0x67, 0x02, 0x03, 0x61, 0x6c,
0x70, 0x69, 0x6e, 0x65, 0x2e, 0x6d, 0x69, 0x6e, 0x2e, 0x6a, 0x73, 0x00,
0xd5, 0x3d, 0x6b, 0x77, 0xdb, 0xb6, 0x92, 0xdf, 0xf7, 0x57, 0x48, 0x5c,
0xaf, 0x0e, 0xd9, 0xc0, 0xb2, 0x9d, 0xdd, 0x7b, 0xce, 0x5e, 0xaa, 0x8c,
0x6e, 0x9a, 0x47, 0xdb, 0xdb, 0x3c, 0xba, 0x4d, 0x7a, 0x7b, 0xb7, 0x8a,
0x9a, 0xd0, 0x12, 0x64, 0xa3, 0xa1, 0x40, 0x5d, 0x12, 0x8c, 0xed, 0x4a,
0xfc, 0xef, 0x3b, 0x33, 0x00, 0x08, 0x90, 0xa2, 0xec, 0x24, 0x9b, 0x7b,
0xf6, 0xec, 0x97, 0x58, 0xc4, 0x73, 0x30, 0x98, 0x17, 0x66, 0x06, 0xc8,
0x70, 0x55, 0xc9, 0x85, 0x12, 0xb9, 0x0c, 0x39, 0x53, 0xd1, 0x36, 0xc8,
0xcf, 0x7f, 0xe7, 0x0b, 0x15, 0x24, 0x89, 0xba, 0xd9, 0xf0, 0x7c, 0x35,
0xe0, 0xd7, 0x9b, 0xbc, 0x50, 0xe5, 0x68, 0x14, 0x54, 0x72, 0xc9, 0x57,
0x42, 0xf2, 0x65, 0x30, 0xb4, 0x95, 0xeb, 0x7c, 0x59, 0x65, 0x7c, 0xaa,
0xff, 0x8c, 0x4d, 0xd3, 0x44, 0x85, 0x51, 0x1c, 0xd8, 0x61, 0xdd, 0x48,
0xba, 0xf7, 0x68, 0xa4, 0xff, 0x8e, 0xd3, 0xf5, 0x72, 0xaa, 0x7f, 0x86,
0x2a, 0x8a, 0x43, 0x9e, 0xf0, 0xdd, 0xae, 0xe4, 0xd9, 0x2a, 0x1a, 0x3f,
0xcc, 0x36, 0x50, 0x8a, 0xc3, 0xd4, 0xa1, 0xba, 0x14, 0x25, 0x0b, 0x1b,
0x18, 0x01, 0xc0, 0xaa, 0xe4, 0x83, 0x52, 0x15, 0x02, 0x80, 0x9c, 0xd8,
0xf2, 0x01, 0x47, 0xe8, 0x99, 0x8c, 0xb6, 0x05, 0x57, 0x55, 0x21, 0x07,
0x6a, 0x20, 0xa0, 0x70, 0xfa, 0x92, 0x16, 0x33, 0xd6, 0xd3, 0xfc, 0x58,
0xe4, 0x1b, 0x5e, 0xa8, 0x1b, 0x6a, 0xba, 0xfd, 0x90, 0x66, 0x15, 0x8f,
0x25, 0xe3, 0xb2, 0x5a, 0xf3, 0x22, 0x3d, 0xcf, 0x78, 0x3c, 0x3c, 0x65,
0x8b, 0x5c, 0xae, 0xc4, 0x45, 0xd5, 0x7c, 0x5f, 0x15, 0x42, 0x99, 0xdf,
0x75, 0x14, 0xf3, 0x99, 0x9a, 0x27, 0xd0, 0xa5, 0x6e, 0xe6, 0x55, 0x1a,
0x6b, 0x1f, 0xd2, 0x62, 0x20, 0x13, 0x33, 0xdb, 0x7b, 0x7e, 0x53, 0x86,
0x3c, 0x9a, 0x88, 0x55, 0x68, 0x4a, 0x2e, 0xb8, 0x7a, 0x79, 0x25, 0xed,
0xfc, 0xaf, 0x6e, 0xd6, 0xe7, 0x79, 0x56, 0xea, 0x5e, 0x22, 0xb9, 0xad,
0x0d, 0x0e, 0xa3, 0x46, 0xa3, 0x50, 0x24, 0x62, 0xbc, 0x12, 0x99, 0xe2,
0x45, 0xe8, 0x70, 0xa1, 0x9a, 0xd5, 0xf6, 0x0e, 0xf1, 0x98, 0x97, 0x8b,
0x42, 0x6c, 0x54, 0x5e, 0x10, 0x8c, 0x63, 0xb7, 0xd0, 0x3a, 0x8a, 0x22,
0x26, 0xc7, 0x9b, 0xaa, 0xbc, 0x1c, 0xa7, 0x9b, 0x4d, 0x76, 0x13, 0x4a,
0x26, 0xa2, 0xda, 0x0c, 0x26, 0xdd, 0xea, 0x64, 0x08, 0x18, 0x5d, 0xc1,
0x00, 0x1a, 0xd2, 0xb3, 0x89, 0xf8, 0x3a, 0x2d, 0x2e, 0x60, 0x18, 0xa9,
0xca, 0x71, 0xc6, 0xe5, 0x85, 0xba, 0x9c, 0x88, 0x7b, 0xf7, 0xf4, 0x4a,
0x8a, 0x44, 0x56, 0x59, 0x36, 0x4c, 0x9a, 0x16, 0x33, 0x31, 0x9f, 0xfa,
0x1f, 0xf1, 0xb6, 0x9e, 0x88, 0x7f, 0xbb, 0x3f, 0x55, 0x06, 0x2d, 0x61,
0x11, 0xb1, 0xe1, 0x69, 0x34, 0x86, 0x09, 0x9e, 0xa4, 0x8b, 0xcb, 0xf6,
0xca, 0x38, 0xc0, 0xa4, 0x58, 0x01, 0x08, 0x8f, 0x00, 0xdc, 0xf8, 0x8e,
0x15, 0x96, 0xbd, 0x3b, 0x2d, 0x78, 0x09, 0xa3, 0xdc, 0xd5, 0x15, 0xc0,
0x88, 0x62, 0x0f, 0xa6, 0x3e, 0x80, 0x78, 0xb4, 0xed, 0x27, 0x25, 0x20,
0x86, 0xbb, 0x26, 0x08, 0x0b, 0xc6, 0x23, 0x5c, 0x44, 0x0f, 0x82, 0x05,
0x8e, 0x6c, 0x8a, 0x1f, 0x16, 0x45, 0x7a, 0x33, 0x5e, 0x15, 0xf9, 0x3a,
0x94, 0xfc, 0x6a, 0xf0, 0x8a, 0x03, 0x6d, 0x41, 0xa7, 0xa6, 0x6d, 0x11,
0x36, 0x4d, 0x65, 0xfa, 0x41, 0x5c, 0xa4, 0x30, 0xf6, 0x18, 0x98, 0xa1,
0x78, 0x78, 0x01, 0x08, 0x1e, 0x0b, 0xb9, 0xc8, 0xaa, 0x25, 0xac, 0x38,
0x78, 0x91, 0x2f, 0xf9, 0xf8, 0xf7, 0x32, 0x88, 0x76, 0xbb, 0xdb, 0x1b,
0xfe, 0x5e, 0x2e, 0xf3, 0x75, 0xe0, 0x4d, 0x51, 0x6a, 0x6a, 0x36, 0xb3,
0x70, 0xe0, 0x5c, 0x57, 0x97, 0x1b, 0xf9, 0xa0, 0xf8, 0x7a, 0x93, 0xa5,
0x8a, 0x83, 0x10, 0x48, 0xf8, 0x58, 0xa5, 0x17, 0x2f, 0xd2, 0x35, 0xfc,
0xcd, 0x9f, 0xe5, 0x57, 0xbc, 0x78, 0x94, 0x96, 0x3c, 0x8c, 0xa6, 0xc0,
0x45, 0x65, 0x0e, 0x02, 0xe1, 0x2a, 0x2d, 0x64, 0xf8, 0x4e, 0xb3, 0x73,
0x3c, 0x98, 0x1d, 0x6d, 0x55, 0x3d, 0x1f, 0x2c, 0x45, 0x01, 0xe8, 0x12,
0x1f, 0x80, 0x8b, 0x2f, 0xf3, 0x2a, 0x5b, 0x0e, 0x72, 0x99, 0xdd, 0x0c,
0xce, 0xf9, 0x20, 0x5d, 0x2e, 0xf9, 0x72, 0xa0, 0xf2, 0xc1, 0xd7, 0x76,
0x8e, 0x07, 0x03, 0x18, 0xbf, 0x1c, 0x03, 0x2e, 0xf8, 0xe0, 0x52, 0xa9,
0x4d, 0x19, 0x9f, 0x9c, 0x5c, 0x08, 0x75, 0x59, 0x9d, 0x8f, 0x17, 0xf9,
0xfa, 0x24, 0xa5, 0x81, 0x7f, 0x2f, 0xcd, 0x8f, 0x7f, 0xc5, 0xf1, 0xdf,
0x45, 0xf1, 0x19, 0x41, 0x06, 0x30, 0x28, 0x5c, 0xee, 0xe2, 0x52, 0x64,
0xcb, 0x27, 0x19, 0x47, 0x2a, 0x7c, 0x94, 0x57, 0x12, 0xd8, 0xa9, 0x1f,
0xbc, 0xf6, 0xac, 0x83, 0x2b, 0x98, 0xc7, 0x82, 0xcc, 0xe5, 0x02, 0x7b,
0xf2, 0x02, 0xe0, 0xa3, 0xf2, 0x54, 0x0e, 0x2a, 0x09, 0xe2, 0x0e, 0x16,
0x02, 0x45, 0xc0, 0x58, 0xe7, 0xbc, 0x18, 0x80, 0x88, 0x2b, 0xf2, 0x5c,
0x0d, 0xb8, 0x9e, 0x0c, 0xe0, 0x7e, 0x9e, 0xbe, 0x87, 0x55, 0x56, 0x05,
0xf7, 0x07, 0xbf, 0x4c, 0xcb, 0x41, 0x3a, 0x28, 0x85, 0xbc, 0xc8, 0x78,
0xab, 0xc3, 0x78, 0xf0, 0xce, 0xdb, 0x8b, 0xd4, 0x23, 0x8d, 0x0e, 0x7e,
0xc7, 0x05, 0x87, 0xb1, 0x16, 0x3c, 0x3c, 0x39, 0x0e, 0xdf, 0x5c, 0x45,
0x27, 0x17, 0x2c, 0xa4, 0xcd, 0x49, 0x1e, 0x28, 0x68, 0xf8, 0xf3, 0x66,
0x63, 0x1b, 0xfa, 0xe4, 0x93, 0xe9, 0xfd, 0x03, 0xa1, 0x34, 0x3c, 0x4b,
0x60, 0x67, 0x91, 0xb8, 0xf4, 0xf0, 0x93, 0x8c, 0x2b, 0x90, 0x5e, 0x1c,
0x24, 0x4c, 0x51, 0x2a, 0x8b, 0x2a, 0x44, 0xdb, 0x04, 0x79, 0x7f, 0x22,
0x27, 0x51, 0x86, 0xdc, 0x08, 0x32, 0x23, 0x91, 0x63, 0x58, 0xb6, 0x6d,
0xf3, 0x4a, 0x9c, 0x67, 0xb0, 0x0c, 0x37, 0xc7, 0xc2, 0x93, 0x86, 0x13,
0x03, 0xbb, 0x27, 0xba, 0xb5, 0x14, 0x21, 0x89, 0x5e, 0x38, 0x31, 0x31,
0x59, 0x64, 0x3c, 0x2d, 0x5e, 0x8b, 0x35, 0xcf, 0x2b, 0x05, 0x02, 0x07,
0x66, 0x29, 0xb9, 0xb2, 0xdf, 0xbe, 0xe8, 0x97, 0x24, 0x61, 0x18, 0x37,
0x42, 0x4b, 0xb0, 0x02, 0xd8, 0x0a, 0x26, 0xac, 0x6b, 0xdc, 0x51, 0x35,
0xa8, 0x12, 0xa3, 0x05, 0x92, 0x07, 0xb8, 0xce, 0xbe, 0x6d, 0x1e, 0x3c,
0x29, 0x8a, 0xbc, 0x88, 0x07, 0xc1, 0xd1, 0x56, 0xd6, 0xc1, 0x1b, 0xf9,
0x46, 0x3e, 0xb9, 0xde, 0x14, 0xbc, 0x2c, 0x61, 0x06, 0x2a, 0x55, 0x58,
0x6a, 0xd6, 0x17, 0xbf, 0x03, 0xce, 0x65, 0x43, 0x60, 0xbc, 0x48, 0x5d,
0x16, 0xf9, 0x95, 0x95, 0xb3, 0x29, 0x34, 0xbf, 0x00, 0xd9, 0xc8, 0xb6,
0x3c, 0x8b, 0x39, 0xe3, 0x6e, 0x04, 0x05, 0xf0, 0xc8, 0xda, 0xa9, 0xa5,
0x25, 0x00, 0x84, 0x8d, 0x94, 0xdf, 0x48, 0xd6, 0xd1, 0x56, 0x15, 0x37,
0x5b, 0x0d, 0xb4, 0x48, 0x60, 0xa3, 0x2c, 0xb2, 0x04, 0xa8, 0xad, 0x52,
0xa5, 0x72, 0x81, 0xfa, 0x12, 0x44, 0xc9, 0x5a, 0x94, 0x7c, 0x2a, 0xc6,
0x8b, 0x54, 0xa1, 0x38, 0xe2, 0xc9, 0x83, 0x2a, 0x84, 0xf5, 0xa1, 0x3c,
0x89, 0x62, 0x51, 0xeb, 0x62, 0x20, 0x13, 0x5b, 0x5a, 0xbb, 0xad, 0x58,
0x69, 0x54, 0x30, 0x91, 0x6c, 0xeb, 0x86, 0x8e, 0x96, 0x61, 0x18, 0x02,
0x72, 0x7a, 0x74, 0xb3, 0x9a, 0x02, 0xa7, 0xa4, 0x19, 0xec, 0x73, 0x14,
0xa3, 0xf4, 0x79, 0x6a, 0xb1, 0x3e, 0x0b, 0x8e, 0x96, 0xa9, 0x4a, 0x03,
0x36, 0x1e, 0x8f, 0x7d, 0xfd, 0x26, 0xa2, 0x39, 0x7b, 0x87, 0x1b, 0xfa,
0xf6, 0xad, 0xe6, 0xbe, 0xb7, 0xb0, 0xbc, 0x2a, 0x53, 0x13, 0x62, 0x90,
0x90, 0x3a, 0x45, 0x83, 0x6d, 0xb7, 0x7a, 0x90, 0x0c, 0x10, 0xc7, 0x83,
0x7a, 0x32, 0x30, 0x30, 0x75, 0x1a, 0xbc, 0x8b, 0x00, 0xaf, 0x6e, 0x2e,
0xd2, 0xd2, 0x38, 0x1b, 0x68, 0xac, 0x3e, 0x6c, 0x9b, 0x9d, 0x5f, 0x27,
0x27, 0xbf, 0x5d, 0x1f, 0x87, 0xb9, 0xdc, 0x9d, 0x0b, 0xb9, 0xdc, 0xe1,
0xe4, 0x3b, 0x05, 0x84, 0xba, 0xbb, 0x54, 0xeb, 0x6c, 0x07, 0xe6, 0x09,
0xcf, 0x76, 0x62, 0xb5, 0x03, 0x72, 0xde, 0x81, 0xd0, 0xb9, 0xda, 0x2d,
0xb2, 0x3c, 0x7d, 0xbf, 0x53, 0x45, 0x2a, 0x4b, 0x81, 0xcb, 0xdc, 0x15,
0x7c, 0xb5, 0x2b, 0x61, 0xe0, 0x74, 0x19, 0xbd, 0x39, 0x3f, 0x71, 0x1b,
0xb8, 0x41, 0xf4, 0xea, 0x39, 0x54, 0x02, 0x96, 0xc3, 0x58, 0x82, 0xb4,
0x6b, 0xb6, 0x6b, 0x3d, 0x56, 0xbc, 0x54, 0xa0, 0xae, 0x1c, 0xde, 0x2f,
0xad, 0x21, 0x82, 0x4c, 0x25, 0x12, 0x4f, 0xa8, 0x03, 0xd9, 0x2a, 0x30,
0x5b, 0xce, 0x2b, 0xe8, 0x13, 0x59, 0x6d, 0xbe, 0x89, 0xc6, 0xeb, 0x74,
0x13, 0x7e, 0x88, 0x80, 0x23, 0x9c, 0x8a, 0x87, 0x8d, 0x0e, 0x34, 0x34,
0xb0, 0x43, 0x28, 0x65, 0x61, 0x93, 0xa2, 0x68, 0x76, 0x3a, 0x47, 0x9b,
0xa2, 0xd0, 0x63, 0xcb, 0x04, 0xb7, 0xb8, 0x18, 0x3b, 0x7c, 0x30, 0x35,
0xd6, 0x68, 0x9f, 0xa0, 0xb9, 0x00, 0x40, 0x03, 0x7d, 0x58, 0x0b, 0x04,
0xa8, 0xb9, 0x20, 0x75, 0xa8, 0xe7, 0x0b, 0xc3, 0x19, 0x80, 0x39, 0x07,
0x5a, 0xf8, 0x10, 0x6e, 0x71, 0x49, 0x80, 0x58, 0x6d, 0x10, 0x29, 0x34,
0x0e, 0x9c, 0xaa, 0x9a, 0xb6, 0x80, 0xd2, 0x90, 0x00, 0x48, 0x12, 0xe8,
0xcf, 0x57, 0x8e, 0x08, 0x90, 0x4a, 0x66, 0x01, 0x62, 0x3f, 0x60, 0x01,
0x21, 0x1c, 0xfe, 0x22, 0xae, 0xe1, 0x0f, 0xd1, 0xe9, 0x31, 0x50, 0x57,
0x30, 0x9f, 0x34, 0x12, 0xad, 0x04, 0x53, 0x31, 0x44, 0xb9, 0x45, 0xec,
0xaa, 0xb1, 0x75, 0x4c, 0x92, 0x09, 0x34, 0xd4, 0x92, 0x5f, 0xbf, 0x84,
0xe5, 0xe9, 0x85, 0x4f, 0xbd, 0x01, 0x62, 0x5d, 0x06, 0xd8, 0xea, 0xb4,
0x95, 0x3d, 0x6d, 0x75, 0x99, 0x9d, 0xd2, 0xb5, 0x15, 0xd1, 0xb1, 0xfb,
0x28, 0x48, 0x35, 0x43, 0x99, 0xdb, 0xc3, 0x1e, 0x9c, 0x18, 0x1a, 0x90,
0x48, 0x03, 0x11, 0x30, 0x95, 0x04, 0x34, 0x22, 0xf3, 0xad, 0x71, 0xe3,
0xec, 0xc7, 0x49, 0x1c, 0xce, 0xd2, 0xe3, 0x3f, 0x1e, 0x1e, 0xff, 0x7a,
0x7a, 0xfc, 0xe7, 0x37, 0xc7, 0xf1, 0xfc, 0x5e, 0x74, 0x12, 0xb1, 0xd2,
0xd5, 0xbf, 0x19, 0xcf, 0x7e, 0x1b, 0xbf, 0x99, 0xcf, 0xef, 0x85, 0xd3,
0x64, 0xf6, 0x1b, 0xfc, 0xf8, 0xea, 0x08, 0xa4, 0x37, 0xe8, 0xe9, 0x99,
0x45, 0xcc, 0x16, 0x21, 0x8e, 0xc5, 0x54, 0xcc, 0xce, 0xe6, 0x31, 0x49,
0x3b, 0x0d, 0x42, 0x31, 0x2d, 0x9a, 0x12, 0xc0, 0xae, 0x58, 0x09, 0x5e,
0x94, 0x71, 0xa9, 0x37, 0x93, 0x76, 0xc6, 0xea, 0x84, 0x60, 0x0c, 0x18,
0x0f, 0x90, 0x5f, 0x5a, 0x9c, 0xe2, 0x56, 0x77, 0xd3, 0x52, 0x2c, 0x20,
0x6d, 0xc0, 0x64, 0xff, 0x05, 0x79, 0x36, 0xf8, 0x4b, 0x10, 0x4d, 0xbd,
0x81, 0xfe, 0x02, 0x03, 0x5d, 0x1f, 0x43, 0xef, 0x00, 0x2c, 0xdf, 0x56,
0xc3, 0xb8, 0xdd, 0x30, 0xa6, 0x86, 0xb8, 0xf7, 0xd4, 0xd4, 0x4d, 0x75,
0x8e, 0xcc, 0x90, 0x7c, 0x93, 0x83, 0x14, 0x4e, 0xa5, 0x3f, 0xe9, 0x26,
0x13, 0x2a, 0x0c, 0x06, 0x41, 0xc3, 0x07, 0xca, 0x72, 0xf2, 0x45, 0x12,
0x08, 0x19, 0xb0, 0xeb, 0x24, 0x00, 0xe9, 0x1f, 0xb0, 0xb7, 0x09, 0x6c,
0x28, 0x88, 0xc3, 0x2c, 0x83, 0x63, 0x87, 0x63, 0xcb, 0x2b, 0x2b, 0xdd,
0x00, 0xfb, 0xc3, 0x33, 0xd2, 0x6a, 0x45, 0x64, 0xf7, 0x39, 0x24, 0xd3,
0x9b, 0x8f, 0xdf, 0xbe, 0xbd, 0x7e, 0xeb, 0x58, 0x7c, 0x34, 0xea, 0x96,
0x58, 0x62, 0xbe, 0xb0, 0x7a, 0x50, 0x43, 0x50, 0x26, 0xc8, 0xc3, 0x82,
0x05, 0xae, 0x65, 0x10, 0xb1, 0xdc, 0x96, 0x12, 0x4d, 0x5b, 0x5e, 0xcc,
0x47, 0xa3, 0x7c, 0xdc, 0xec, 0x87, 0x67, 0x5a, 0xf9, 0x7d, 0xad, 0x2c,
0xf0, 0x5a, 0x62, 0x5f, 0xe1, 0x35, 0xc7, 0xb5, 0x46, 0xa3, 0xd1, 0xd0,
0x2f, 0x13, 0xd8, 0xd5, 0x5b, 0x93, 0x86, 0x0e, 0xc5, 0x44, 0xbb, 0xcd,
0x68, 0xb4, 0x37, 0x12, 0x08, 0x80, 0xc2, 0xe3, 0x5c, 0x6b, 0x1c, 0x7c,
0x2d, 0x1a, 0xaa, 0xd7, 0xed, 0x50, 0x8b, 0x30, 0xff, 0xfc, 0x87, 0x28,
0xb5, 0xb4, 0x5e, 0x24, 0xdb, 0x25, 0x1c, 0x84, 0xb0, 0x2a, 0x7e, 0x09,
0x0a, 0x26, 0xb0, 0x5f, 0x01, 0x3b, 0xfb, 0xd3, 0x29, 0x60, 0xa4, 0x10,
0x17, 0xc2, 0x54, 0xe9, 0xdf, 0xc8, 0xea, 0x1c, 0xcd, 0x24, 0xc0, 0x17,
0xd9, 0x12, 0xf1, 0x36, 0xdf, 0xa4, 0x0b, 0xa1, 0x6e, 0xe2, 0x53, 0x56,
0x82, 0x7a, 0xe1, 0xba, 0x35, 0xfd, 0x0c, 0xd8, 0x9f, 0xff, 0x14, 0xd5,
0xac, 0xe4, 0x30, 0xdb, 0xd2, 0x35, 0x3c, 0x33, 0x0d, 0xcf, 0x4e, 0x4f,
0xeb, 0x7a, 0xf2, 0xde, 0x00, 0x45, 0x6a, 0x0b, 0x14, 0x19, 0x6e, 0x38,
0xbb, 0x00, 0x76, 0xc5, 0xad, 0x40, 0x31, 0x5b, 0xf3, 0x0c, 0x8f, 0x83,
0x20, 0x4d, 0xd6, 0x9c, 0x18, 0x61, 0x16, 0x68, 0x08, 0x98, 0xfe, 0x7b,
0x4c, 0x64, 0xdb, 0x7c, 0x71, 0x10, 0x4f, 0x73, 0x87, 0x2d, 0xae, 0xf5,
0x0b, 0xe0, 0x61, 0xda, 0xc5, 0x02, 0xd8, 0x16, 0x5b, 0x4b, 0x0f, 0xe7,
0xe1, 0xc3, 0x10, 0x04, 0x0c, 0x18, 0xfe, 0x4b, 0x2d, 0x9b, 0xf5, 0x14,
0x24, 0x9a, 0xcd, 0x00, 0xbb, 0xdd, 0xd6, 0x63, 0xb7, 0x20, 0xa8, 0x23,
0x5f, 0x30, 0x23, 0xfe, 0x91, 0x84, 0xfa, 0x07, 0x32, 0x30, 0x7e, 0xea,
0x70, 0xe9, 0xa1, 0xe1, 0x70, 0x91, 0x9f, 0x38, 0xd8, 0xe4, 0x15, 0xac,
0xbb, 0x64, 0x39, 0x4b, 0x61, 0xe5, 0x0d, 0xb2, 0x2f, 0xd0, 0xc0, 0x22,
0x54, 0x97, 0x84, 0xec, 0x18, 0x4f, 0xe4, 0x0d, 0x0f, 0x3e, 0xf9, 0x92,
0x3c, 0x78, 0xfd, 0x7f, 0xcf, 0x83, 0x9a, 0x97, 0x86, 0x7b, 0xcc, 0xf4,
0x65, 0x79, 0xf0, 0xc1, 0x47, 0xf1, 0xa0, 0x4f, 0x7d, 0x72, 0xda, 0xc3,
0x7d, 0x7d, 0x1c, 0x79, 0x72, 0x1f, 0x30, 0xe4, 0x78, 0xb6, 0xfc, 0x34,
0x0e, 0xf5, 0x19, 0x6f, 0x8f, 0x2b, 0x0f, 0xb1, 0xaf, 0xe5, 0xd0, 0x16,
0x7f, 0xe6, 0xec, 0xda, 0x90, 0x4d, 0x71, 0x88, 0x47, 0x41, 0x1f, 0x7c,
0x80, 0x21, 0xf4, 0xdf, 0x86, 0x47, 0xf5, 0xd7, 0x17, 0xe2, 0x51, 0x3d,
0xc5, 0x17, 0xe0, 0x51, 0x1f, 0xc6, 0x2f, 0xc0, 0xa3, 0x6e, 0x91, 0x9f,
0xcf, 0xa3, 0x1e, 0xba, 0xaf, 0x6f, 0xe5, 0xd1, 0x97, 0xd6, 0x1a, 0x05,
0x5a, 0x27, 0x83, 0x89, 0x37, 0xd4, 0xa7, 0x1a, 0xc2, 0xb6, 0x4c, 0x07,
0x27, 0x91, 0x99, 0x5f, 0x7f, 0xef, 0x8c, 0xf8, 0x6b, 0x28, 0x5c, 0x43,
0xf8, 0x34, 0xdb, 0x8f, 0xc6, 0x17, 0x70, 0xcb, 0x8f, 0x68, 0x9a, 0xb7,
0xaa, 0x1b, 0x9a, 0xc4, 0x16, 0x9a, 0xed, 0x38, 0xf0, 0x8b, 0xb1, 0x80,
0xc2, 0x19, 0x98, 0x46, 0x60, 0x17, 0xad, 0xcb, 0x13, 0x2d, 0x21, 0x6c,
0x67, 0x0e, 0xe6, 0x8d, 0xb1, 0x3a, 0x2d, 0xad, 0xea, 0x29, 0x66, 0x81,
0xca, 0x37, 0x40, 0x1c, 0x50, 0x76, 0xa9, 0x89, 0x64, 0xa5, 0x1c, 0x19,
0xb3, 0xe0, 0x3c, 0x57, 0x2a, 0x5f, 0xb7, 0x28, 0xa6, 0xbd, 0x8a, 0xfb,
0xf3, 0x68, 0x3a, 0x13, 0x6c, 0xaf, 0x74, 0x3e, 0xfe, 0x3d, 0x17, 0x92,
0xac, 0x10, 0x38, 0x4b, 0x35, 0x28, 0x7b, 0xef, 0xa8, 0x0b, 0xb1, 0x1d,
0x6d, 0x3f, 0x42, 0x88, 0x69, 0x13, 0xe5, 0x60, 0x45, 0x23, 0x38, 0xd2,
0x04, 0xed, 0xa8, 0x1b, 0x38, 0x93, 0x1a, 0xc6, 0x62, 0x59, 0x53, 0x42,
0xbd, 0xe0, 0x80, 0xb2, 0x66, 0x8b, 0xfd, 0xb2, 0x97, 0x84, 0x11, 0x56,
0x25, 0x43, 0xdf, 0x7f, 0x63, 0x06, 0x21, 0xb1, 0xe5, 0x97, 0xeb, 0x1d,
0x8a, 0xd8, 0x32, 0xa9, 0x76, 0xbb, 0xde, 0x0e, 0x6c, 0xd5, 0xad, 0xb2,
0x7d, 0xd6, 0xc9, 0x96, 0x48, 0x1d, 0x8e, 0xdb, 0xcb, 0xd1, 0x28, 0xec,
0xc0, 0x9b, 0x94, 0xda, 0x49, 0x60, 0xbf, 0x61, 0x20, 0xaf, 0x51, 0x03,
0x6e, 0xf2, 0x8e, 0x86, 0x0b, 0x8f, 0xb6, 0xb6, 0x3d, 0x7d, 0x9f, 0xa0,
0x6c, 0x89, 0xde, 0x81, 0xd6, 0x07, 0x22, 0x11, 0xf2, 0x02, 0xe6, 0xe8,
0xed, 0xae, 0x57, 0x0b, 0x73, 0x69, 0x42, 0x00, 0x4b, 0xd6, 0x6f, 0x41,
0x98, 0xb5, 0x6e, 0xb6, 0x64, 0xb6, 0x9c, 0x36, 0xcb, 0x02, 0xbe, 0x61,
0xab, 0x69, 0xd0, 0x8c, 0x83, 0x05, 0xde, 0x2e, 0x43, 0x77, 0xb1, 0x0e,
0xfb, 0x46, 0x7b, 0x6c, 0x68, 0x16, 0xa6, 0xb4, 0xe4, 0x7b, 0x72, 0xc6,
0xff, 0xfd, 0x5e, 0x50, 0x06, 0x3d, 0xad, 0x5f, 0x8b, 0x35, 0x00, 0x6f,
0x4f, 0xc8, 0x60, 0xa0, 0x56, 0xe7, 0x62, 0x71, 0x7c, 0xce, 0xff, 0x00,
0xad, 0x12, 0x9e, 0x8e, 0xff, 0x83, 0x0d, 0x4e, 0xc7, 0xa7, 0xf8, 0xcf,
0x7d, 0x36, 0x38, 0x8b, 0x02, 0x90, 0xa6, 0xa0, 0xae, 0xd0, 0x7d, 0x01,
0x9c, 0xc9, 0x80, 0xf1, 0x0f, 0xa2, 0x56, 0x4b, 0xdd, 0x4f, 0xc0, 0xad,
0xe9, 0xd0, 0x41, 0xee, 0xa5, 0x58, 0x72, 0x98, 0x43, 0xe0, 0x74, 0xe8,
0x5b, 0x91, 0xd5, 0xe6, 0xc0, 0x94, 0xe9, 0xa1, 0x39, 0xb2, 0x03, 0x15,
0x66, 0x67, 0x16, 0xb7, 0x6e, 0x89, 0x71, 0xd2, 0x1c, 0x44, 0xf2, 0x81,
0xfa, 0x0e, 0x5a, 0xb1, 0x15, 0xe8, 0x97, 0x23, 0x60, 0xc7, 0x35, 0x08,
0xbd, 0xc2, 0x1e, 0x10, 0x1e, 0x3a, 0x27, 0x4f, 0x8f, 0x1f, 0x83, 0x4f,
0xe5, 0x98, 0xa3, 0x4c, 0x4d, 0x15, 0xff, 0x89, 0xa4, 0x89, 0xf3, 0xef,
0x80, 0xee, 0xe2, 0x70, 0x3c, 0x71, 0xa7, 0x88, 0x57, 0x6d, 0x56, 0x67,
0xe9, 0x17, 0x65, 0x76, 0x64, 0x6d, 0x6c, 0xa1, 0x89, 0x38, 0xcd, 0xde,
0x2e, 0xb2, 0xb4, 0x2c, 0x79, 0x89, 0xa7, 0x3d, 0xe0, 0xf1, 0x86, 0xcd,
0xf8, 0x98, 0x2a, 0x9e, 0x09, 0x60, 0x93, 0x74, 0xb9, 0x0c, 0xc7, 0xe3,
0xb1, 0xf4, 0x59, 0xa4, 0xa7, 0x5e, 0x45, 0x0d, 0x51, 0x15, 0x8e, 0xa8,
0xfc, 0x86, 0x05, 0x5f, 0xe7, 0x1f, 0x38, 0x8d, 0xe5, 0x1f, 0xe0, 0x87,
0x99, 0x27, 0x26, 0x23, 0x3a, 0x24, 0xee, 0x8f, 0x2e, 0x1c, 0x0d, 0x95,
0x6d, 0x1a, 0xea, 0x9f, 0x41, 0x7d, 0xfc, 0x0c, 0xae, 0x93, 0xb8, 0xb5,
0x93, 0xd9, 0xf8, 0x05, 0x6d, 0x8a, 0x93, 0xcd, 0x47, 0xfb, 0x67, 0x94,
0x47, 0xda, 0xa5, 0xb5, 0x55, 0x63, 0x0d, 0x32, 0x4c, 0x27, 0xca, 0x47,
0xb9, 0x94, 0xe4, 0x9a, 0x1d, 0x8d, 0xd4, 0xb8, 0x01, 0x9f, 0x2d, 0x39,
0x68, 0x23, 0x3e, 0xe8, 0x6e, 0x1c, 0x9c, 0xff, 0x27, 0xdd, 0xb2, 0x44,
0x1f, 0xc4, 0x25, 0xd3, 0x9b, 0x1a, 0xdb, 0x69, 0x44, 0xf8, 0x16, 0x4e,
0xfc, 0x21, 0xfa, 0x0c, 0xc0, 0x80, 0x92, 0xa2, 0xbc, 0x8c, 0x0b, 0x86,
0x2e, 0xd1, 0xa7, 0x05, 0x7a, 0x0c, 0x88, 0x68, 0x99, 0x1a, 0x9b, 0xbd,
0x85, 0x5f, 0x76, 0x1b, 0xd9, 0x1e, 0xb9, 0x34, 0xbd, 0x92, 0x82, 0xff,
0xa3, 0xe2, 0xa5, 0x7a, 0x28, 0xc5, 0x9a, 0x38, 0x84, 0x4a, 0xcd, 0x84,
0xda, 0xd5, 0x03, 0xc2, 0xe8, 0xab, 0x17, 0xe4, 0x65, 0x0e, 0x2f, 0xb8,
0x7a, 0x94, 0xaf, 0x37, 0x15, 0xac, 0xee, 0x15, 0x72, 0x10, 0x20, 0xac,
0x87, 0xc9, 0x9c, 0x8b, 0x98, 0x8d, 0xbf, 0x3a, 0x41, 0x87, 0x80, 0x3b,
0xae, 0x97, 0xda, 0x41, 0x30, 0x39, 0x45, 0x47, 0x0e, 0x70, 0xf9, 0x9d,
0xc3, 0xa7, 0x16, 0xb0, 0xbd, 0xd1, 0xed, 0x58, 0xb8, 0x52, 0x4d, 0x90,
0x9f, 0xbb, 0x4e, 0x74, 0x51, 0x01, 0x11, 0x33, 0xcf, 0xf5, 0xbb, 0x37,
0x92, 0x46, 0x38, 0x5a, 0x94, 0x3a, 0x9e, 0xd2, 0xd0, 0xc5, 0x8f, 0xce,
0xa5, 0x31, 0xd4, 0x1e, 0x37, 0x51, 0xd2, 0x5f, 0x28, 0x47, 0x93, 0xbe,
0x7c, 0x91, 0xbe, 0x80, 0x9f, 0xae, 0xc3, 0x23, 0xe7, 0xb4, 0x1a, 0x9e,
0xf5, 0x78, 0xaa, 0xd5, 0x6e, 0x17, 0x42, 0xd5, 0x69, 0xe3, 0x6b, 0x26,
0xa7, 0x75, 0xe3, 0xb2, 0x8e, 0x7c, 0x4f, 0xeb, 0xef, 0x44, 0x94, 0x24,
0x43, 0xa2, 0x6d, 0x8e, 0x06, 0xf2, 0xf5, 0x31, 0xc8, 0x4a, 0x38, 0x01,
0xe0, 0x04, 0x69, 0xf2, 0x38, 0xec, 0x91, 0x53, 0x62, 0xca, 0x6f, 0x93,
0x53, 0x02, 0x4c, 0x92, 0x08, 0x8c, 0x83, 0xfd, 0xb3, 0x39, 0x8e, 0x59,
0xc0, 0x39, 0x08, 0x64, 0x19, 0x0b, 0xc4, 0xaa, 0x39, 0x05, 0x15, 0xb0,
0xce, 0x5b, 0x87, 0xf4, 0x3d, 0x85, 0xd6, 0x64, 0x9b, 0xcd, 0x09, 0xc6,
0x32, 0xb9, 0xb5, 0xa7, 0x1c, 0x0b, 0xc5, 0xd7, 0x25, 0xcc, 0x3e, 0xf9,
0x31, 0x2c, 0x01, 0xa1, 0xe5, 0x83, 0xe4, 0x14, 0xe8, 0xa6, 0xf4, 0xbd,
0x9b, 0x1a, 0xdd, 0x65, 0xa4, 0xbd, 0xc3, 0x11, 0x23, 0xa7, 0xd4, 0xbd,
0x33, 0x20, 0x0d, 0x8b, 0xde, 0xb2, 0xa6, 0x55, 0xa4, 0x80, 0x26, 0x10,
0x7f, 0x6a, 0x92, 0xb9, 0x38, 0x5b, 0x28, 0xc0, 0xd0, 0x32, 0xc4, 0x5e,
0xb5, 0x17, 0x6d, 0xf0, 0x8a, 0x35, 0x79, 0x52, 0x4e, 0x65, 0xb8, 0x05,
0xd1, 0x17, 0x61, 0x28, 0x31, 0x47, 0x83, 0x0e, 0x00, 0x9b, 0x27, 0x8a,
0x19, 0xd3, 0x0e, 0x80, 0xca, 0xad, 0x99, 0x37, 0x4f, 0x04, 0xb2, 0xf5,
0x22, 0xcf, 0x32, 0xbe, 0xd0, 0xa2, 0x9c, 0x2a, 0x5d, 0xc1, 0x3c, 0x29,
0x1a, 0xe0, 0xf2, 0x3a, 0xc4, 0xa3, 0x6f, 0xce, 0x32, 0x06, 0xd0, 0xa3,
0xe9, 0x74, 0x07, 0xea, 0xc9, 0xd3, 0x19, 0xb5, 0x3c, 0xb6, 0xb0, 0xf2,
0x96, 0x4d, 0x8f, 0x3b, 0x63, 0x86, 0x2f, 0xa6, 0x1f, 0xbd, 0x37, 0xda,
0xb8, 0x07, 0xab, 0x3a, 0x96, 0x1a, 0x61, 0x39, 0xab, 0xd0, 0x5e, 0x6b,
0x87, 0xe9, 0xd1, 0x2e, 0xb7, 0xb6, 0x33, 0x6e, 0xff, 0x87, 0x5c, 0x2c,
0x07, 0xa7, 0x34, 0x3b, 0x32, 0x0d, 0x60, 0xf6, 0x2d, 0x80, 0xe3, 0x35,
0x68, 0x95, 0x93, 0x69, 0x6e, 0x0d, 0x6f, 0x1b, 0xfe, 0x69, 0x82, 0x3d,
0x38, 0xb8, 0x3c, 0xd4, 0x5c, 0x8e, 0x37, 0x69, 0x01, 0x3c, 0x60, 0x42,
0x24, 0x80, 0xeb, 0x12, 0x94, 0xfe, 0x37, 0x1c, 0x9a, 0x62, 0xc8, 0x96,
0x47, 0x13, 0x99, 0x0c, 0xc3, 0x61, 0x5f, 0x9c, 0x68, 0xb7, 0x6b, 0xa0,
0xec, 0xab, 0x6e, 0x01, 0x3e, 0x1a, 0xf5, 0x46, 0x9a, 0xea, 0x70, 0xd1,
0x53, 0xcc, 0x96, 0xd1, 0x64, 0x35, 0x0d, 0x8d, 0x78, 0x5f, 0xf9, 0x03,
0xb1, 0xe6, 0x2b, 0xa9, 0x80, 0x4a, 0xaa, 0xcd, 0x12, 0x76, 0xc0, 0xf4,
0x2e, 0xc3, 0x95, 0x46, 0x76, 0xd3, 0x06, 0x0f, 0xe3, 0x61, 0x17, 0xd5,
0x1a, 0x3d, 0xcb, 0x7c, 0x51, 0xe9, 0x05, 0xaf, 0x31, 0xc9, 0x01, 0x63,
0xac, 0x61, 0x13, 0x64, 0xc4, 0x30, 0xb6, 0x73, 0x33, 0xdf, 0x8a, 0x20,
0xd5, 0x03, 0x7f, 0xd4, 0x5b, 0x5a, 0x03, 0x61, 0x80, 0xa1, 0x75, 0x65,
0xa1, 0xc4, 0xf3, 0x5e, 0xf3, 0x83, 0x83, 0x41, 0xd4, 0x59, 0x1b, 0x08,
0x47, 0x25, 0xd2, 0x4c, 0xfc, 0x71, 0xeb, 0xfa, 0x80, 0xf5, 0x56, 0x6c,
0xd1, 0xda, 0xdd, 0x25, 0x29, 0xb3, 0xd6, 0x9a, 0x75, 0x3e, 0x03, 0xec,
0x23, 0xbf, 0x7d, 0x1f, 0xf9, 0xdd, 0xfb, 0xd8, 0xd7, 0xc4, 0x91, 0x9a,
0x3e, 0x1e, 0x4a, 0xf2, 0xa8, 0xf7, 0xb4, 0x7b, 0x12, 0x5a, 0xdf, 0x1f,
0xb7, 0xb6, 0x43, 0xe4, 0xa3, 0x81, 0x62, 0x92, 0x00, 0xa6, 0xf0, 0x60,
0x12, 0x1d, 0x00, 0x04, 0x52, 0x0d, 0xf3, 0xa5, 0xff, 0x63, 0x27, 0xfd,
0x4f, 0x58, 0x38, 0xfb, 0x8d, 0xbd, 0xa9, 0xd1, 0x17, 0x1f, 0x85, 0xd3,
0xd8, 0xff, 0x8c, 0xa6, 0x47, 0x27, 0x30, 0xfc, 0x2b, 0x45, 0x1a, 0x9c,
0x47, 0xee, 0x0c, 0xfb, 0xa6, 0x7c, 0xf3, 0x6a, 0xfe, 0xd5, 0x34, 0x7a,
0x53, 0xde, 0x83, 0x3e, 0x42, 0xee, 0xf2, 0x15, 0xfd, 0x36, 0x15, 0x91,
0x3e, 0xdb, 0x0e, 0xa5, 0x1f, 0x60, 0xc5, 0x40, 0xdc, 0x44, 0x68, 0x51,
0x9a, 0xc8, 0xd9, 0xfd, 0xb9, 0x39, 0x8e, 0x4c, 0xb4, 0x58, 0x91, 0x70,
0xfe, 0x35, 0x25, 0x4e, 0x77, 0xff, 0xf6, 0x26, 0xdc, 0xbd, 0x89, 0x8e,
0x4e, 0x2e, 0x50, 0xc9, 0xb2, 0x32, 0x29, 0x0c, 0x08, 0xca, 0x09, 0xd5,
0x69, 0xa8, 0xc7, 0x84, 0x3a, 0xdb, 0x4d, 0x91, 0xba, 0x37, 0x87, 0x1d,
0xe3, 0x6e, 0x4a, 0x4a, 0x37, 0x3e, 0x2b, 0x61, 0x76, 0x4c, 0x2a, 0xf1,
0x64, 0x61, 0x52, 0x3a, 0x88, 0xd0, 0x23, 0x65, 0xc6, 0x64, 0xde, 0xc1,
0xf8, 0xb5, 0x91, 0x84, 0x05, 0x49, 0xc9, 0x85, 0x26, 0x92, 0xea, 0x76,
0xd5, 0x01, 0x6d, 0x09, 0x15, 0x01, 0x89, 0xc4, 0x80, 0x22, 0x47, 0x28,
0x5e, 0x2e, 0x80, 0x5c, 0x2f, 0x24, 0x70, 0xc4, 0x53, 0x60, 0xab, 0x92,
0x2f, 0x9f, 0xe6, 0xc5, 0xdf, 0xb0, 0xc5, 0x37, 0x00, 0x2c, 0x20, 0x7b,
0x34, 0x6a, 0xd8, 0x2d, 0xa5, 0x54, 0x81, 0x86, 0x99, 0xca, 0x57, 0x60,
0x32, 0x10, 0xf3, 0x35, 0xfe, 0x8b, 0x96, 0xf8, 0xab, 0x46, 0x23, 0xb3,
0x5f, 0x45, 0xe4, 0xa2, 0x2e, 0x27, 0x40, 0x06, 0x61, 0x95, 0x20, 0x12,
0x83, 0x22, 0x5d, 0x8a, 0x9c, 0x7c, 0x0b, 0x3a, 0x62, 0xd4, 0x74, 0x55,
0x5e, 0x7c, 0x4e, 0x8b, 0xf0, 0xd1, 0x48, 0x8b, 0x79, 0xa8, 0xcc, 0xa6,
0x26, 0x16, 0x99, 0x54, 0xb1, 0x2e, 0x1c, 0x42, 0x21, 0x8c, 0x8a, 0x09,
0x06, 0x7c, 0xf1, 0x9e, 0x2f, 0x93, 0x32, 0x34, 0x4d, 0x40, 0x5e, 0x83,
0xe6, 0x41, 0x9f, 0x17, 0xae, 0x9c, 0xaa, 0xcf, 0xf3, 0x6b, 0x6f, 0xca,
0xe0, 0x5c, 0x47, 0x44, 0x9c, 0x39, 0x00, 0x87, 0xf1, 0x99, 0x8e, 0xf6,
0x10, 0x34, 0x9e, 0x33, 0xa3, 0x8a, 0x76, 0x3b, 0x37, 0xe1, 0xb4, 0x35,
0x77, 0xdb, 0xd4, 0xa9, 0xa2, 0xa9, 0x03, 0xa6, 0x72, 0xde, 0x36, 0x4a,
0xea, 0x68, 0x9c, 0x68, 0xb1, 0x6b, 0x33, 0x1c, 0x56, 0xf8, 0xa9, 0x97,
0x65, 0xb0, 0x56, 0x79, 0x90, 0xbf, 0x7a, 0xf2, 0xec, 0xc9, 0xa3, 0xd7,
0x06, 0x6e, 0x9d, 0xe7, 0x11, 0x0d, 0xdb, 0x72, 0xc2, 0x46, 0xc5, 0x66,
0x73, 0x1b, 0x6f, 0x54, 0x91, 0x8b, 0x49, 0xdd, 0x23, 0x33, 0xb3, 0x15,
0x02, 0xcd, 0x37, 0xd8, 0xb9, 0xf4, 0x72, 0x6c, 0x38, 0x31, 0x77, 0xc9,
0x33, 0x32, 0xd8, 0x41, 0x0c, 0x74, 0x3d, 0x7f, 0xbb, 0x1d, 0x9c, 0x12,
0x41, 0x34, 0xe8, 0x38, 0x9d, 0x62, 0x06, 0x44, 0x24, 0x23, 0x0b, 0x3c,
0xec, 0xbb, 0x25, 0x86, 0x66, 0x9b, 0xea, 0xda, 0x6d, 0x01, 0x9e, 0x3f,
0x34, 0xf1, 0xc1, 0x67, 0x17, 0x6b, 0x76, 0x15, 0x1c, 0x96, 0x79, 0xe8,
0xbc, 0x06, 0xc3, 0x82, 0x61, 0xfa, 0xd0, 0xd2, 0x87, 0x1d, 0x92, 0x09,
0xad, 0x03, 0x70, 0xe1, 0x30, 0x90, 0x73, 0x35, 0x44, 0x6e, 0xf2, 0x6e,
0x3e, 0x5d, 0xd5, 0xa4, 0x12, 0x91, 0xa5, 0x54, 0x45, 0x2e, 0x12, 0x8a,
0x0e, 0xe2, 0x6a, 0xc6, 0xe7, 0xc7, 0x15, 0xa6, 0x3d, 0x75, 0x70, 0x84,
0x15, 0xd3, 0x73, 0x14, 0x43, 0x7e, 0xb1, 0xea, 0x1c, 0xdf, 0x68, 0x8b,
0x6f, 0x6d, 0x65, 0xc4, 0x28, 0x36, 0xac, 0x0d, 0x9c, 0x1f, 0x81, 0x00,
0x90, 0x83, 0x15, 0xcc, 0x0e, 0x04, 0xf3, 0x51, 0xc8, 0x90, 0x3d, 0xc8,
0x90, 0xc9, 0xc2, 0xf3, 0x37, 0x2d, 0x80, 0x9a, 0xb2, 0x20, 0x9a, 0xa6,
0x94, 0x71, 0xc0, 0x7c, 0xea, 0x67, 0xc3, 0xb3, 0x16, 0x03, 0x4c, 0x2d,
0xd0, 0x6e, 0x4a, 0xe8, 0x33, 0xf4, 0xe3, 0xcf, 0xc6, 0x9c, 0x0d, 0x96,
0xa2, 0xc4, 0x04, 0x37, 0x8c, 0x41, 0x1b, 0x2a, 0x47, 0xcf, 0x21, 0x1c,
0x3b, 0x44, 0x61, 0x7e, 0xa6, 0x4b, 0x4c, 0x37, 0x82, 0x9f, 0x70, 0x5c,
0x5c, 0x72, 0x74, 0x88, 0xe7, 0x1b, 0xfa, 0x63, 0x29, 0x10, 0x7e, 0xa6,
0x95, 0xca, 0x57, 0x28, 0x98, 0xe0, 0x37, 0xc9, 0xeb, 0x05, 0xb4, 0xc1,
0xb0, 0x76, 0x95, 0x29, 0xb1, 0x41, 0xdf, 0x77, 0x20, 0x73, 0x20, 0x33,
0x81, 0xc6, 0x04, 0xb6, 0xcf, 0xb2, 0xfc, 0x6a, 0x05, 0x0b, 0x28, 0x17,
0x05, 0xa7, 0xc1, 0xa8, 0x64, 0x93, 0xde, 0xa0, 0xd0, 0x32, 0xa7, 0x1e,
0x28, 0x45, 0x0f, 0x4a, 0xbb, 0x23, 0x4c, 0x04, 0x32, 0x1b, 0xc1, 0x41,
0x4b, 0xa2, 0xc8, 0x33, 0x9c, 0x32, 0xcb, 0xc9, 0xe1, 0xb9, 0xae, 0x34,
0x34, 0xd8, 0xa0, 0x14, 0x12, 0xf4, 0x21, 0x76, 0x59, 0xf2, 0x55, 0x0a,
0x60, 0x20, 0x64, 0x25, 0x30, 0x1a, 0xad, 0xe9, 0x03, 0x2f, 0x4a, 0x0d,
0x78, 0x79, 0x23, 0x17, 0xba, 0x11, 0xf9, 0x46, 0x65, 0xae, 0x33, 0x33,
0x5b, 0xde, 0x51, 0x60, 0x22, 0x19, 0x4d, 0x9f, 0x51, 0xca, 0x08, 0xec,
0xa7, 0xfe, 0x21, 0x3d, 0xf5, 0xf8, 0xcc, 0x3a, 0x8d, 0x39, 0xe6, 0xb4,
0x39, 0xa4, 0xab, 0x68, 0x98, 0x90, 0x43, 0xa4, 0xb5, 0xfb, 0xaa, 0xd5,
0xf7, 0x85, 0xef, 0x52, 0xa1, 0xd4, 0x13, 0x4d, 0x5b, 0x79, 0xb2, 0xdd,
0x60, 0xda, 0xcc, 0x07, 0x1e, 0xfb, 0x91, 0x12, 0x53, 0x16, 0x44, 0x35,
0xa9, 0xc1, 0x8c, 0x55, 0xdd, 0xa8, 0x8c, 0xa1, 0x13, 0x3a, 0xa6, 0x22,
0xad, 0x68, 0x8d, 0x66, 0x6b, 0xd3, 0x2b, 0x40, 0x5e, 0x34, 0x05, 0xd9,
0x6e, 0x15, 0x06, 0x1c, 0x9a, 0x52, 0x3a, 0x4e, 0x22, 0x42, 0x53, 0x30,
0xbe, 0xc2, 0x14, 0x84, 0x57, 0x01, 0x0b, 0x89, 0xd0, 0xe1, 0x99, 0xaf,
0x56, 0x00, 0xfd, 0x2f, 0x62, 0xa9, 0x2e, 0xbf, 0x3e, 0x43, 0xef, 0x80,
0x2e, 0xf8, 0x8e, 0xa3, 0x77, 0xf9, 0xeb, 0x33, 0x38, 0xf6, 0xfd, 0x81,
0x59, 0x15, 0xfa, 0x94, 0xd2, 0x8a, 0xe9, 0xc8, 0x05, 0x47, 0x30, 0x1a,
0xc5, 0xa4, 0x49, 0xf2, 0xc9, 0x07, 0xf8, 0x8d, 0x7c, 0xc5, 0x25, 0x1c,
0x03, 0x24, 0x28, 0xc6, 0x1c, 0xf9, 0x2a, 0x06, 0x88, 0xfc, 0xde, 0x57,
0x20, 0xb5, 0x31, 0x64, 0x35, 0xd5, 0x3f, 0x5a, 0x38, 0xb0, 0x23, 0x42,
0xad, 0xfd, 0x19, 0xdb, 0x65, 0x00, 0x32, 0x2a, 0x10, 0xf6, 0xba, 0xd7,
0x68, 0x84, 0xbf, 0x6d, 0x9b, 0xdd, 0xae, 0x01, 0xe5, 0x3c, 0x5f, 0xde,
0xb8, 0xf5, 0x82, 0x62, 0xa4, 0xe3, 0x41, 0xd8, 0xc7, 0x20, 0x20, 0x73,
0x60, 0x24, 0x24, 0x51, 0xf8, 0x55, 0x6d, 0xf6, 0x09, 0x63, 0x34, 0xea,
0xb3, 0x7e, 0xdb, 0x2e, 0x9e, 0x99, 0x5d, 0x0f, 0x73, 0xc0, 0x03, 0x9d,
0x22, 0x21, 0xd2, 0xaf, 0x12, 0x3d, 0xf6, 0xf3, 0xb6, 0x4b, 0x67, 0x42,
0x87, 0x0a, 0x6f, 0xd5, 0xfc, 0x3c, 0xaf, 0x08, 0xa7, 0x8d, 0x11, 0xe8,
0x02, 0x63, 0xae, 0x72, 0x22, 0x29, 0x59, 0x60, 0x81, 0xf9, 0xbd, 0x3f,
0x86, 0xa1, 0x9c, 0xc1, 0x99, 0x72, 0x0e, 0x1a, 0x51, 0x48, 0x62, 0xa3,
0xe3, 0xab, 0x54, 0x00, 0xe2, 0x6c, 0x42, 0xc1, 0xba, 0xa4, 0xf3, 0x70,
0x34, 0xbd, 0x1f, 0x9f, 0x45, 0x35, 0xcc, 0xa8, 0xcf, 0x1a, 0x3a, 0x53,
0xd5, 0x68, 0x08, 0x38, 0xef, 0x43, 0xc5, 0x99, 0x57, 0x01, 0x67, 0x0d,
0xe8, 0x04, 0x05, 0x3f, 0x81, 0x00, 0x43, 0x9b, 0xd1, 0xb5, 0xb4, 0x81,
0x91, 0x59, 0xb0, 0x50, 0x85, 0xce, 0x68, 0x11, 0x14, 0x7e, 0x48, 0x89,
0x05, 0xd7, 0x1c, 0x33, 0xa3, 0x82, 0xc5, 0x1a, 0x99, 0xaf, 0xac, 0x36,
0xc0, 0x74, 0x73, 0x1f, 0x53, 0xb2, 0x07, 0x07, 0x49, 0xdb, 0x21, 0x27,
0xda, 0x4d, 0x80, 0xe6, 0x34, 0x50, 0x0f, 0x4e, 0x69, 0x17, 0x9d, 0x9b,
0x4c, 0x25, 0x0f, 0x42, 0x9a, 0x69, 0x48, 0x61, 0x11, 0x33, 0x1d, 0x7e,
0x90, 0xaf, 0x42, 0xc3, 0x02, 0x07, 0x83, 0xd9, 0x3b, 0x4c, 0xb0, 0xfa,
0x81, 0xdf, 0xbc, 0x03, 0x15, 0x12, 0x99, 0xd1, 0xc8, 0x2c, 0xbe, 0x6b,
0xb5, 0x26, 0xfc, 0x32, 0x3c, 0xa5, 0xb3, 0x30, 0xb0, 0x4b, 0x8b, 0x11,
0xed, 0xf6, 0x02, 0x85, 0xa4, 0x63, 0xf3, 0xf1, 0x58, 0x0b, 0xa3, 0xb0,
0xcd, 0x2a, 0xb4, 0xfd, 0xd4, 0x0c, 0x7f, 0xa1, 0x5b, 0x38, 0xbd, 0x48,
0xb5, 0x63, 0xa5, 0xdd, 0x8e, 0x67, 0x2b, 0xdd, 0x4e, 0x33, 0x28, 0xae,
0x05, 0x40, 0xde, 0x3a, 0x0e, 0x1c, 0xab, 0x4b, 0x2e, 0xb5, 0xfa, 0xa3,
0xa4, 0x45, 0x3e, 0xdd, 0x9f, 0x3a, 0xee, 0xe3, 0xd2, 0xea, 0x16, 0xf6,
0x44, 0xad, 0xa7, 0x35, 0xd2, 0xed, 0xad, 0x5a, 0xb0, 0xee, 0x93, 0xab,
0x98, 0x89, 0x3e, 0x82, 0xed, 0x21, 0x4f, 0xa6, 0x92, 0x1f, 0x43, 0xbe,
0x47, 0xa3, 0xc6, 0xe1, 0xb6, 0x57, 0x11, 0xdf, 0xff, 0xd3, 0xe9, 0x24,
0x4b, 0x16, 0x61, 0x86, 0xa9, 0x8d, 0x15, 0xaa, 0xf5, 0x5e, 0x00, 0x1b,
0x99, 0xfb, 0x87, 0x75, 0x94, 0x78, 0x19, 0x36, 0xd6, 0x26, 0x7f, 0x94,
0xaf, 0xd7, 0xa9, 0x5c, 0x7a, 0x46, 0xb9, 0x30, 0xd8, 0xb6, 0x51, 0x5b,
0x19, 0x92, 0x4f, 0x05, 0x93, 0x1c, 0x19, 0xfc, 0xdd, 0x1e, 0x11, 0x7a,
0x63, 0x51, 0xb7, 0xb2, 0x47, 0x7f, 0x42, 0x21, 0x52, 0x5e, 0x09, 0x93,
0x70, 0xb8, 0x48, 0x4b, 0x1e, 0x9c, 0x04, 0xb1, 0x09, 0xd8, 0x95, 0x60,
0x00, 0x5c, 0x06, 0x13, 0x2a, 0x1d, 0x04, 0x31, 0xfd, 0x7d, 0xb5, 0x81,
0xb3, 0xc8, 0x79, 0x5a, 0xb8, 0x46, 0x58, 0x10, 0x4c, 0x8c, 0x02, 0x8b,
0x2d, 0xa8, 0xa8, 0x50, 0x9a, 0x03, 0x0f, 0xe5, 0x4f, 0xcd, 0xa3, 0x70,
0xf6, 0xf0, 0xf8, 0xd7, 0x39, 0x26, 0xb6, 0x06, 0x47, 0x67, 0xc7, 0x47,
0xf7, 0x3d, 0xef, 0xe5, 0xc9, 0xec, 0xed, 0x9b, 0x72, 0x7e, 0xc2, 0x82,
0x63, 0x3c, 0xe3, 0xf8, 0x59, 0xb1, 0x9e, 0x4b, 0xee, 0x69, 0xfb, 0x36,
0x80, 0xb3, 0xf9, 0x75, 0xf6, 0x18, 0x45, 0x36, 0x2e, 0xd3, 0xd2, 0x33,
0x61, 0x30, 0xdf, 0x0b, 0x13, 0xa6, 0x3b, 0xca, 0x4d, 0x97, 0x33, 0x54,
0x3b, 0x94, 0x23, 0xaf, 0x45, 0xb2, 0xf4, 0xb3, 0x34, 0x1f, 0x55, 0x40,
0xe5, 0x6b, 0xda, 0x21, 0x74, 0x5a, 0x2c, 0x81, 0x0d, 0x45, 0xe6, 0xbc,
0x25, 0xfa, 0x7b, 0xd2, 0x3d, 0x09, 0x98, 0xd4, 0xb6, 0xed, 0x9e, 0x3d,
0x2a, 0x5a, 0xf6, 0xa8, 0x23, 0x40, 0x9d, 0x63, 0x0c, 0x3a, 0xe2, 0x7b,
0x4c, 0x75, 0xa3, 0x1d, 0x34, 0x36, 0x7d, 0xdc, 0xfe, 0x9e, 0x34, 0x53,
0x9b, 0x52, 0x63, 0x08, 0x4d, 0x9b, 0x94, 0x40, 0x30, 0x24, 0x91, 0x6b,
0x3c, 0xc1, 0x32, 0x2c, 0x29, 0x36, 0xe2, 0xe5, 0xfd, 0x75, 0x3a, 0xd7,
0x14, 0xf8, 0x25, 0x0b, 0xc9, 0x40, 0xdf, 0x97, 0xf7, 0x8d, 0x5b, 0x69,
0x6d, 0xa4, 0xc8, 0xcb, 0xba, 0xdb, 0x5b, 0x83, 0x9f, 0xea, 0x6e, 0x67,
0xb2, 0xf6, 0xd7, 0x4b, 0x7b, 0x42, 0xb0, 0xc7, 0x88, 0xef, 0xf7, 0x0e,
0x02, 0x60, 0xe2, 0x7e, 0xd2, 0x08, 0x7b, 0xfd, 0x27, 0x0d, 0x8a, 0xfb,
0x71, 0x77, 0x00, 0xf1, 0x1c, 0x8f, 0x4b, 0x7e, 0x7e, 0x89, 0x58, 0x53,
0x22, 0x9c, 0x3e, 0x36, 0xc7, 0xbc, 0xf6, 0x48, 0xf0, 0x7b, 0x3f, 0x71,
0x94, 0x4f, 0x37, 0x29, 0x98, 0x68, 0x4f, 0xb3, 0x3c, 0xc5, 0xbc, 0x6b,
0x0a, 0x13, 0xd8, 0xb9, 0x7e, 0x04, 0x85, 0x3d, 0x55, 0xd0, 0x99, 0x1a,
0x6f, 0x0d, 0x1d, 0xc4, 0xcf, 0x6b, 0xed, 0x5d, 0x65, 0x5b, 0x80, 0x0e,
0x64, 0xa8, 0xca, 0x91, 0x60, 0x5e, 0xae, 0xe2, 0x6f, 0x18, 0x18, 0x99,
0xc0, 0xd9, 0xf1, 0x3f, 0x58, 0xfb, 0x2e, 0x42, 0xfc, 0x33, 0xeb, 0xde,
0x7e, 0x88, 0x7f, 0x61, 0xa2, 0x7c, 0x72, 0x0d, 0x62, 0xa3, 0x14, 0x78,
0x89, 0xe5, 0x07, 0x76, 0xe8, 0x92, 0x42, 0xfc, 0x6d, 0xa7, 0x0a, 0x77,
0xb7, 0x8c, 0xbf, 0x63, 0xbd, 0xd7, 0x52, 0xe2, 0xbf, 0x31, 0x23, 0x86,
0xcd, 0xe0, 0x00, 0x7a, 0xfc, 0x2b, 0x03, 0x96, 0xf2, 0xda, 0xc6, 0x7f,
0xad, 0xcd, 0xdd, 0x16, 0xb6, 0xc5, 0xab, 0x26, 0xf1, 0x7f, 0x31, 0x4d,
0x80, 0xf1, 0xdf, 0x19, 0xec, 0x4c, 0xfc, 0xdf, 0x66, 0x85, 0x20, 0xd1,
0xcd, 0xea, 0xbc, 0xeb, 0x3c, 0xdc, 0x4b, 0x52, 0x74, 0xde, 0x26, 0xef,
0xde, 0x8d, 0xd7, 0xa0, 0x2f, 0x0c, 0x68, 0x82, 0x85, 0x12, 0x76, 0x98,
0x5f, 0x0d, 0x7e, 0xe1, 0xe9, 0xfb, 0xe7, 0xe9, 0xc6, 0x8d, 0x2f, 0xb8,
0xb6, 0x6e, 0x24, 0xf1, 0x3b, 0xfd, 0x36, 0x3d, 0x0a, 0x9e, 0xa0, 0xe2,
0x26, 0xd3, 0x17, 0xa6, 0x00, 0x9a, 0x71, 0xbd, 0x4a, 0xde, 0xbe, 0x1f,
0xa1, 0x89, 0xe6, 0xfb, 0xf2, 0xe5, 0x79, 0xc9, 0x8b, 0x0f, 0x78, 0xf0,
0xc0, 0xbd, 0xa4, 0xae, 0x80, 0x84, 0xeb, 0x1b, 0xbc, 0xd7, 0xe4, 0xdf,
0xa0, 0x68, 0x2e, 0x29, 0xfd, 0x5d, 0xe7, 0x5a, 0x7f, 0x87, 0xd9, 0xee,
0x7f, 0xa3, 0xc3, 0x52, 0x73, 0x5a, 0x13, 0xc6, 0x0d, 0x5e, 0x24, 0xdf,
0x92, 0xc4, 0x99, 0x14, 0x63, 0xff, 0x4e, 0x12, 0x28, 0xe5, 0x22, 0xc1,
0xe3, 0x1b, 0xda, 0xd7, 0xc0, 0xb1, 0xec, 0xe7, 0x50, 0x8b, 0x7e, 0xf4,
0xe1, 0xfd, 0x4a, 0x69, 0x94, 0x78, 0x18, 0x1b, 0xa4, 0xe6, 0x50, 0x57,
0x54, 0x0b, 0x7b, 0x01, 0x68, 0x8b, 0x31, 0x8c, 0xb1, 0x3d, 0xdc, 0xbd,
0x26, 0xb2, 0x4f, 0x40, 0x0d, 0x60, 0xe9, 0x9a, 0xaf, 0xcf, 0x8b, 0x14,
0xb0, 0xc5, 0xeb, 0x0b, 0x83, 0x0f, 0xdd, 0x7f, 0xdb, 0x6e, 0x0f, 0x27,
0x35, 0xdb, 0x14, 0x34, 0x84, 0x4d, 0xe5, 0x97, 0x70, 0x5c, 0x35, 0x17,
0xaa, 0x34, 0x2a, 0xf8, 0x32, 0x2e, 0xeb, 0x44, 0x34, 0x4e, 0x2a, 0x7d,
0x7b, 0x40, 0x38, 0xc4, 0x00, 0xbc, 0x06, 0xef, 0x88, 0x8e, 0xde, 0x99,
0x84, 0x9b, 0x49, 0x0f, 0xfd, 0xbc, 0x52, 0x40, 0xf6, 0xcb, 0xb8, 0xa8,
0xf5, 0xc4, 0x4d, 0xce, 0x3c, 0xcc, 0x0e, 0xa6, 0x83, 0x9c, 0x86, 0x42,
0x5f, 0xcf, 0x2a, 0x42, 0x81, 0xf9, 0x32, 0x71, 0xa0, 0x0d, 0x1e, 0x93,
0x47, 0xf2, 0x1c, 0x44, 0xeb, 0x68, 0xa4, 0xeb, 0x18, 0xd8, 0x38, 0xda,
0x5b, 0xec, 0xdf, 0x09, 0xbb, 0x7b, 0xc9, 0x6d, 0x40, 0x44, 0x07, 0x10,
0xe3, 0x7f, 0x26, 0x6c, 0x08, 0xbd, 0x64, 0x98, 0x47, 0xc7, 0x8f, 0xcc,
0x4a, 0xeb, 0x66, 0x53, 0x9a, 0x12, 0x60, 0x9a, 0x4f, 0x99, 0xbc, 0x41,
0x70, 0x77, 0x76, 0x33, 0x23, 0x5d, 0x7c, 0x93, 0x35, 0xd8, 0xf8, 0x3f,
0xe8, 0x6b, 0x68, 0xfd, 0xe3, 0xaa, 0x76, 0xe7, 0x86, 0x20, 0x15, 0x12,
0x24, 0x20, 0xaf, 0xf6, 0xe5, 0x86, 0x2f, 0xca, 0x7e, 0x30, 0x37, 0xdb,
0x86, 0x4d, 0x44, 0x40, 0x4d, 0x3e, 0x9e, 0x52, 0x7e, 0x00, 0x62, 0x6f,
0x62, 0x22, 0xbb, 0x1d, 0x70, 0x84, 0x60, 0x98, 0x01, 0xce, 0x0a, 0xa4,
0x07, 0x4f, 0xcc, 0x69, 0x94, 0xd4, 0x17, 0x9d, 0xc2, 0x8f, 0x5b, 0xcd,
0x37, 0xc8, 0x07, 0xb7, 0x5e, 0x86, 0xfb, 0x68, 0xe2, 0xee, 0x20, 0xbd,
0xd0, 0xc5, 0x0d, 0xbf, 0x4c, 0x0a, 0xc2, 0xba, 0x89, 0xa2, 0x7d, 0xab,
0x3f, 0x30, 0xda, 0xc2, 0xc3, 0xb2, 0xc9, 0x8b, 0x2a, 0x27, 0xf6, 0x0c,
0xfc, 0x2d, 0x4d, 0xde, 0xe4, 0xc0, 0xf3, 0x30, 0x87, 0xb3, 0x6b, 0x89,
0xfc, 0x8c, 0xe9, 0x5b, 0xc0, 0xcf, 0xac, 0xec, 0x70, 0xfb, 0xcf, 0x44,
0x27, 0x70, 0x16, 0x2d, 0xa3, 0x38, 0xaf, 0xf7, 0x84, 0xee, 0x61, 0x8c,
0xb8, 0xa5, 0xc8, 0x36, 0x72, 0x72, 0x0a, 0xd3, 0x20, 0xa9, 0xa0, 0xb8,
0xd0, 0x9c, 0xb0, 0x77, 0x3b, 0xf2, 0x23, 0x98, 0xb2, 0x68, 0x61, 0xc8,
0xf2, 0x04, 0xb0, 0x7d, 0xc1, 0xb6, 0xad, 0x5b, 0x94, 0x79, 0x9d, 0x90,
0x8f, 0xf6, 0xaf, 0xe6, 0x82, 0x09, 0x0b, 0xec, 0xa5, 0x4a, 0x4a, 0x5c,
0x72, 0xc5, 0xda, 0x47, 0xec, 0xd9, 0x3f, 0xdf, 0x12, 0xb3, 0xc2, 0x11,
0x50, 0xbb, 0xf4, 0x8c, 0xbc, 0xb5, 0x36, 0xca, 0xcf, 0x58, 0xcb, 0xf6,
0x0f, 0xb9, 0x03, 0x33, 0x22, 0x6f, 0x46, 0x24, 0x7b, 0x4f, 0x8f, 0x51,
0x70, 0x97, 0x50, 0xc8, 0x78, 0x4d, 0x0e, 0x05, 0x3a, 0x5a, 0xe4, 0xa3,
0x91, 0xc6, 0x35, 0x6c, 0x46, 0xc1, 0xa4, 0x16, 0xae, 0x65, 0x23, 0x2d,
0xbc, 0x7b, 0x54, 0x1f, 0xaf, 0x04, 0x7e, 0xe2, 0xe9, 0xf2, 0xa5, 0xcc,
0x6e, 0x3c, 0x65, 0xa0, 0xa5, 0xf3, 0xe2, 0x4b, 0x49, 0x67, 0xb7, 0xc9,
0xac, 0xbb, 0x53, 0x0d, 0xcf, 0x89, 0x7e, 0xe9, 0x2c, 0x9d, 0x74, 0xa6,
0x45, 0xca, 0x7d, 0x88, 0xdb, 0x52, 0xba, 0x39, 0x26, 0xf6, 0x49, 0xce,
0xa6, 0xf2, 0xff, 0xa9, 0xb8, 0x3b, 0x24, 0x7d, 0xfe, 0x29, 0x22, 0x44,
0x7c, 0x51, 0xb1, 0x01, 0xb6, 0x36, 0x33, 0x24, 0x5f, 0xa2, 0x1b, 0x93,
0x8e, 0xe8, 0x21, 0x26, 0x87, 0xa9, 0x44, 0x9b, 0x4e, 0x9f, 0x25, 0x56,
0xbc, 0xed, 0xee, 0x13, 0x0f, 0x4d, 0xb5, 0xe3, 0x8c, 0x8a, 0x37, 0x71,
0x35, 0x0b, 0xeb, 0x73, 0x28, 0x99, 0xaa, 0x64, 0x36, 0x8f, 0xf7, 0xef,
0x95, 0x63, 0xf0, 0x24, 0xa1, 0x20, 0x9e, 0x31, 0xbd, 0x96, 0xdc, 0xde,
0x85, 0xee, 0xb1, 0x08, 0x57, 0x34, 0x38, 0x1e, 0xbe, 0xc0, 0x76, 0x46,
0x5b, 0xb0, 0xe5, 0xce, 0xb1, 0xa3, 0x37, 0x17, 0xd3, 0xdb, 0xd5, 0xcf,
0xdd, 0x65, 0xc7, 0xe1, 0xe9, 0xc4, 0xaa, 0xb2, 0x6f, 0x42, 0x77, 0x93,
0x4b, 0xc1, 0x90, 0x4b, 0x40, 0x8c, 0x19, 0x5d, 0x35, 0xbf, 0xbe, 0x71,
0x57, 0x53, 0xd6, 0x3c, 0x31, 0x4e, 0x7a, 0x38, 0x27, 0x6f, 0xfc, 0x8f,
0x4b, 0x32, 0x1a, 0x3d, 0x68, 0x3f, 0xf0, 0xb6, 0x18, 0x2d, 0x49, 0x76,
0x22, 0x81, 0xa0, 0xd8, 0x9c, 0xb4, 0x05, 0x95, 0x6a, 0x04, 0x55, 0x13,
0x64, 0x92, 0x5e, 0xcc, 0x26, 0x46, 0xb2, 0x28, 0xd0, 0x1d, 0x43, 0x77,
0x8c, 0x13, 0x2f, 0x4d, 0xc5, 0x9e, 0xd6, 0xe8, 0x22, 0x18, 0x8d, 0x05,
0xf2, 0x0d, 0x89, 0x8e, 0x9c, 0xfb, 0x0c, 0xfa, 0x09, 0xdd, 0xaf, 0xf4,
0xfb, 0x61, 0xfa, 0x40, 0xbb, 0x35, 0x46, 0xc6, 0xe5, 0x55, 0x91, 0x6e,
0xac, 0xa4, 0x22, 0x73, 0xd2, 0x4a, 0xab, 0x9b, 0x8e, 0xb4, 0xa2, 0x6d,
0x20, 0xc1, 0x44, 0x00, 0x3e, 0x16, 0x70, 0x00, 0x2e, 0x28, 0x88, 0x78,
0xc9, 0x99, 0x2b, 0x37, 0x2a, 0x21, 0xd9, 0xf8, 0x85, 0x96, 0x0d, 0x92,
0xb5, 0x5f, 0xea, 0x4b, 0xcf, 0x64, 0x65, 0x6a, 0xf4, 0x96, 0x7e, 0x0b,
0x50, 0x5d, 0xfa, 0x46, 0x3c, 0x1b, 0xd2, 0xe1, 0xc0, 0x62, 0xb6, 0x03,
0x02, 0x28, 0xbe, 0x96, 0x3e, 0x92, 0xac, 0x23, 0x46, 0xd8, 0xde, 0x84,
0xb8, 0x25, 0x7c, 0xd2, 0xbb, 0x1e, 0x72, 0x7a, 0xc3, 0xe1, 0xac, 0x77,
0x5d, 0x14, 0x86, 0x98, 0xca, 0xb8, 0x7f, 0x7d, 0x0a, 0x71, 0x3f, 0x15,
0xf1, 0xe1, 0x75, 0x2a, 0xdc, 0xd5, 0x69, 0x11, 0xaf, 0xe0, 0xdc, 0xd8,
0x18, 0xc6, 0x9e, 0xa5, 0x85, 0xaa, 0x0a, 0xc3, 0xdb, 0x7d, 0x90, 0x85,
0x5a, 0x5e, 0xf4, 0x8f, 0x8c, 0x4a, 0xad, 0xb9, 0x5c, 0x4a, 0x4d, 0xb4,
0x64, 0xa7, 0x48, 0xea, 0x2b, 0x04, 0x9e, 0x9c, 0xf6, 0x8d, 0x24, 0x1d,
0x17, 0x46, 0xea, 0x93, 0x87, 0x0d, 0x1d, 0xf4, 0x85, 0x69, 0xec, 0x6e,
0xac, 0xef, 0xe9, 0x06, 0x00, 0x54, 0x6b, 0xd3, 0xa8, 0xe1, 0xa7, 0x5e,
0x40, 0x3d, 0x16, 0xeb, 0x07, 0x16, 0x11, 0xdc, 0x0b, 0x23, 0x3d, 0x5a,
0x60, 0x41, 0x03, 0x09, 0xee, 0x53, 0xa8, 0x53, 0xf6, 0x04, 0x42, 0xdd,
0xdb, 0xd9, 0x4a, 0x68, 0x47, 0x47, 0x8d, 0x2d, 0xa4, 0x03, 0xf2, 0xa4,
0xf2, 0x0c, 0x2a, 0x9b, 0x24, 0x77, 0xd1, 0x5c, 0xf2, 0x68, 0xa9, 0x9b,
0x04, 0xcf, 0xe1, 0x03, 0x8b, 0x98, 0xd0, 0x85, 0x3e, 0x91, 0x34, 0x53,
0xb4, 0x19, 0x14, 0xdd, 0x0b, 0x84, 0x2f, 0x0d, 0x62, 0x85, 0x4b, 0xf3,
0xd1, 0x4c, 0xb6, 0x2e, 0x1d, 0xd8, 0x50, 0x2b, 0x04, 0x76, 0xa8, 0xc0,
0x3e, 0x45, 0x21, 0xd0, 0xe5, 0x58, 0x33, 0x33, 0x0d, 0xad, 0xba, 0x33,
0xcd, 0xe2, 0xf3, 0xa6, 0xa1, 0xa1, 0x3a, 0xd3, 0xd4, 0xa0, 0xef, 0x51,
0xb7, 0x63, 0xaa, 0x19, 0x7e, 0x6a, 0x4e, 0x3f, 0xdf, 0xb3, 0x4b, 0x28,
0x0d, 0xd7, 0x18, 0x27, 0x47, 0x3c, 0x03, 0x46, 0xb1, 0x00, 0xd9, 0xa2,
0x76, 0x8c, 0x28, 0xb8, 0x3e, 0xa6, 0xeb, 0xc2, 0x08, 0x64, 0x40, 0x21,
0xd7, 0x69, 0xb0, 0xad, 0x03, 0xe0, 0xc3, 0xe2, 0x70, 0x0f, 0xcc, 0x5c,
0x09, 0xac, 0x36, 0xdc, 0x1e, 0xe1, 0x7d, 0x69, 0xd3, 0xb4, 0x66, 0x79,
0x82, 0x57, 0x93, 0xfd, 0xb2, 0x49, 0xe7, 0x4a, 0xeb, 0x05, 0x1f, 0xaf,
0xd3, 0x0b, 0xb1, 0x70, 0x6e, 0x0f, 0xef, 0x38, 0xdd, 0xdc, 0x73, 0x3d,
0xf0, 0x7e, 0x43, 0xc9, 0xde, 0x1d, 0x1d, 0x6d, 0x79, 0xfd, 0x8e, 0xfc,
0x2c, 0xf1, 0xbe, 0x6c, 0x55, 0xa0, 0x6c, 0xeb, 0x5a, 0xcb, 0x43, 0x04,
0xa0, 0x92, 0xb9, 0x61, 0xf1, 0xc7, 0xb0, 0x4e, 0x02, 0x0e, 0x3a, 0xfe,
0xdc, 0x2a, 0x0d, 0xa3, 0x78, 0xa5, 0xaf, 0x64, 0xd0, 0xa2, 0x9c, 0x95,
0x96, 0x32, 0x44, 0x4e, 0x9c, 0x99, 0x53, 0x04, 0xd2, 0x33, 0xb6, 0xff,
0x5e, 0xfa, 0xfc, 0xb0, 0x3f, 0x4b, 0x34, 0xc1, 0x54, 0x8b, 0x85, 0x96,
0x51, 0x74, 0xc5, 0x37, 0xc9, 0x3a, 0x96, 0x61, 0xda, 0x07, 0x1d, 0xed,
0x98, 0x45, 0x5b, 0x7f, 0x83, 0x82, 0xaf, 0x4a, 0x4f, 0x46, 0xac, 0x4a,
0x4d, 0x55, 0x66, 0xb1, 0x98, 0x91, 0xf3, 0x5a, 0x2c, 0xde, 0x03, 0x4f,
0x2d, 0xde, 0x83, 0x16, 0xef, 0x1f, 0xc3, 0xb6, 0x42, 0x1d, 0xb8, 0xdd,
0xef, 0x47, 0xef, 0x8c, 0x20, 0x93, 0xea, 0xde, 0x57, 0x98, 0x94, 0xc1,
0x0b, 0x0c, 0x0e, 0xf6, 0x0f, 0x47, 0x0d, 0x1a, 0xe5, 0xda, 0xea, 0x33,
0xe3, 0x73, 0x54, 0x67, 0x9d, 0x22, 0x00, 0x2c, 0x62, 0xdd, 0x42, 0x3d,
0x2b, 0x26, 0x4a, 0x7f, 0x49, 0x72, 0xe9, 0x01, 0xf8, 0x23, 0x08, 0x88,
0xd9, 0x3d, 0x68, 0x51, 0x12, 0xe6, 0xcb, 0x3e, 0xb6, 0x6f, 0x61, 0xb4,
0x31, 0xdc, 0xaa, 0x7a, 0x96, 0x36, 0x8f, 0x32, 0x30, 0xb0, 0x4b, 0x00,
0xfe, 0x5c, 0xea, 0x74, 0x32, 0x4c, 0xd4, 0xcd, 0x25, 0x94, 0x7f, 0xdf,
0xa4, 0x7e, 0x2d, 0xcb, 0x56, 0xe0, 0xbf, 0xb1, 0x06, 0x18, 0xe6, 0x87,
0xe2, 0x4b, 0x32, 0x34, 0xfe, 0x26, 0xad, 0x4a, 0x6e, 0x04, 0x26, 0xde,
0x03, 0xc0, 0x87, 0x6f, 0x34, 0x15, 0x1c, 0xce, 0xe5, 0xb1, 0x64, 0x54,
0x18, 0xf0, 0xf7, 0xc6, 0x38, 0x33, 0x15, 0x3d, 0x79, 0x68, 0x4d, 0x67,
0x3f, 0x71, 0x8b, 0x0a, 0x33, 0x0a, 0x6a, 0x3c, 0xcd, 0x8b, 0x17, 0xfc,
0xca, 0x36, 0x7f, 0x9d, 0xbb, 0xf5, 0x00, 0x25, 0xf6, 0xb8, 0xf7, 0x16,
0xa3, 0xd1, 0xc2, 0xd8, 0x4e, 0x0d, 0x4b, 0x44, 0x88, 0x1c, 0xff, 0xe1,
0x08, 0x9a, 0x8a, 0xb0, 0xf5, 0x09, 0x78, 0x02, 0xd0, 0x4e, 0x49, 0x9d,
0x74, 0x39, 0x7a, 0xdb, 0x4d, 0x12, 0xf6, 0xa2, 0xa3, 0x5d, 0xeb, 0x89,
0x1e, 0x5d, 0x98, 0xb4, 0xdf, 0xe6, 0xa1, 0x64, 0x0f, 0xd9, 0xc9, 0xe9,
0x98, 0x05, 0x47, 0x74, 0x4f, 0x9e, 0xd8, 0x10, 0xff, 0x5a, 0xc6, 0xc1,
0xdf, 0x44, 0xcc, 0xed, 0x30, 0x2a, 0x86, 0xe4, 0x90, 0xe0, 0x25, 0xba,
0xf0, 0x91, 0x90, 0x84, 0x7e, 0x20, 0xa9, 0x91, 0x03, 0xcc, 0xc3, 0x47,
0xdd, 0x2b, 0x5e, 0xb8, 0xce, 0xdb, 0x52, 0x4e, 0x0f, 0xca, 0x64, 0xd1,
0x7a, 0x65, 0x43, 0x75, 0xb3, 0x24, 0x95, 0x26, 0x5d, 0xc4, 0xcc, 0xe4,
0x16, 0x2c, 0xa0, 0x4e, 0xba, 0xe1, 0x61, 0xcb, 0x1f, 0x40, 0xd7, 0xfb,
0xb7, 0x8a, 0xfe, 0x00, 0xed, 0xdb, 0x4b, 0xee, 0x24, 0x05, 0xe5, 0xd8,
0xb3, 0x7a, 0x7c, 0x77, 0x05, 0xa6, 0xbd, 0x62, 0x3a, 0x8c, 0xd0, 0x79,
0xe1, 0x0d, 0x53, 0x8b, 0xf9, 0xb4, 0xf5, 0xe5, 0x70, 0xa9, 0x92, 0x07,
0x30, 0x07, 0x14, 0xb9, 0xd0, 0x80, 0x4b, 0x00, 0x9f, 0xfa, 0x3b, 0xe0,
0x06, 0xf0, 0xb6, 0x42, 0x36, 0x3e, 0x57, 0x69, 0x83, 0x71, 0x63, 0xd0,
0x47, 0xd6, 0x7f, 0x38, 0x4c, 0x12, 0x31, 0x1a, 0x61, 0x7e, 0xdd, 0xb2,
0x5a, 0x70, 0xca, 0x56, 0x2e, 0x00, 0x34, 0xfb, 0xb4, 0x82, 0xc0, 0x03,
0xad, 0x98, 0x15, 0xf3, 0x08, 0xf3, 0x09, 0x1a, 0xf8, 0xe4, 0x1e, 0x7c,
0x14, 0xde, 0xc5, 0x76, 0x98, 0xef, 0xd9, 0x91, 0xf0, 0xde, 0x1b, 0x47,
0xfb, 0x70, 0xfa, 0x0f, 0x30, 0xb8, 0xf0, 0xc3, 0x18, 0xf3, 0xee, 0xef,
0x5c, 0x84, 0x00, 0x1d, 0x5c, 0xcc, 0x0a, 0x13, 0xfc, 0x3d, 0x3e, 0x9b,
0xb7, 0x56, 0x82, 0xb9, 0xd5, 0x9d, 0x95, 0x14, 0x77, 0x2d, 0x43, 0xa3,
0x99, 0x15, 0xb3, 0xf2, 0xd0, 0x4a, 0x98, 0xea, 0x4a, 0x07, 0x38, 0x4e,
0xd1, 0x9d, 0x89, 0xfa, 0x2a, 0xcd, 0xde, 0x3f, 0x94, 0xcb, 0x57, 0xef,
0xc5, 0xe6, 0x05, 0x07, 0xd6, 0x5f, 0x36, 0xbc, 0x59, 0xea, 0x13, 0x53,
0x62, 0x45, 0x04, 0x90, 0x15, 0xd2, 0x01, 0x2d, 0xba, 0x1d, 0xab, 0xb3,
0x26, 0x06, 0x65, 0xbc, 0xfb, 0x19, 0x81, 0x56, 0xca, 0x4e, 0x75, 0xb6,
0x33, 0x4e, 0x8a, 0xef, 0xb7, 0x9c, 0xe1, 0xa5, 0x48, 0x8a, 0x6e, 0xf5,
0x88, 0x26, 0xb4, 0x71, 0x1a, 0xa9, 0x24, 0xe9, 0x22, 0xb3, 0x51, 0x25,
0xb7, 0x01, 0x8a, 0x60, 0xf5, 0xa7, 0x5c, 0x83, 0x88, 0xed, 0x54, 0xe8,
0x04, 0x60, 0xbe, 0x7c, 0xbb, 0x86, 0x23, 0x2f, 0xd5, 0xf5, 0x8b, 0x49,
0x5a, 0xff, 0x50, 0x22, 0x6e, 0x49, 0x38, 0x48, 0xe0, 0x76, 0x1a, 0x81,
0x38, 0xeb, 0x9c, 0x0e, 0x3d, 0x8d, 0xf2, 0xe0, 0xd7, 0x7c, 0x01, 0xc8,
0x00, 0x08, 0x1f, 0xe1, 0xeb, 0x39, 0x3f, 0xf1, 0x75, 0x0a, 0x03, 0xca,
0x8b, 0x57, 0x7b, 0x4a, 0x25, 0xec, 0xef, 0xf1, 0xc2, 0x57, 0xd1, 0xa8,
0x9d, 0xfb, 0xe1, 0x01, 0x8c, 0x9c, 0x62, 0x22, 0x50, 0x7b, 0x07, 0x74,
0xc2, 0x17, 0x6c, 0x00, 0xbd, 0x76, 0x82, 0x92, 0xb3, 0xc9, 0x5a, 0x20,
0x5f, 0x5b, 0x5f, 0x16, 0x59, 0x72, 0x1e, 0x76, 0xf2, 0x89, 0xec, 0x30,
0xf8, 0x18, 0x19, 0xd0, 0x1c, 0x02, 0x59, 0xf0, 0x0b, 0x54, 0x08, 0x85,
0x8d, 0x75, 0x6b, 0x5f, 0x11, 0x33, 0x75, 0x65, 0x9e, 0x7d, 0xe0, 0xdf,
0xe4, 0x95, 0x5c, 0x36, 0x83, 0x60, 0x03, 0xd0, 0x5e, 0x18, 0x28, 0x6f,
0x0b, 0x2d, 0x7f, 0x5f, 0x3f, 0x7a, 0x4b, 0xb7, 0x4d, 0x2a, 0xe9, 0x70,
0x6f, 0x5b, 0x0f, 0xd0, 0x9a, 0xf3, 0x33, 0x68, 0xdb, 0xc0, 0x87, 0x42,
0xc7, 0x95, 0xcc, 0x76, 0x76, 0xb6, 0xf2, 0x9f, 0xb8, 0x93, 0x77, 0xd4,
0x6f, 0x31, 0x5f, 0xd2, 0xc2, 0x6f, 0xf0, 0xde, 0x36, 0xd8, 0xdc, 0x5e,
0xde, 0x76, 0x63, 0x87, 0x72, 0xb8, 0x6f, 0xe9, 0x3d, 0x89, 0x7a, 0x2a,
0x29, 0x7f, 0x26, 0x8c, 0xb4, 0x30, 0xf8, 0x94, 0xa5, 0x6f, 0x0f, 0xd8,
0x4c, 0x63, 0x93, 0xfe, 0x16, 0xba, 0x70, 0xaf, 0x39, 0x1c, 0xe1, 0xdb,
0x49, 0x00, 0xaa, 0x79, 0x0f, 0xca, 0x24, 0xaa, 0xe1, 0xe5, 0x32, 0x27,
0xfe, 0xb4, 0x8d, 0xc9, 0x4d, 0x9a, 0x49, 0xa8, 0x1f, 0xd0, 0x6a, 0x52,
0x4e, 0x28, 0xd7, 0x9c, 0xae, 0xb0, 0x99, 0xd1, 0x2c, 0x09, 0x86, 0x0d,
0x61, 0x45, 0xde, 0xd3, 0x4c, 0x48, 0x3c, 0x1c, 0xe8, 0xe6, 0xad, 0x79,
0x2c, 0x8a, 0xff, 0x6f, 0x2c, 0x3d, 0xe3, 0xb9, 0xab, 0xf7, 0xe9, 0x69,
0x7b, 0x07, 0x33, 0x9c, 0x21, 0xcd, 0xf5, 0xf3, 0xd1, 0xd6, 0xb1, 0xab,
0xb3, 0x78, 0xcd, 0x8b, 0x33, 0xf6, 0x9d, 0x19, 0xff, 0x75, 0x19, 0xff,
0x05, 0x99, 0xbc, 0xc6, 0x25, 0x9b, 0x0c, 0x10, 0x61, 0x32, 0x40, 0xc0,
0x26, 0x8b, 0x5f, 0xe8, 0x83, 0x26, 0x37, 0x77, 0x28, 0xe1, 0x34, 0x7d,
0x0e, 0x67, 0xce, 0xf7, 0x3a, 0x19, 0x44, 0x3f, 0x04, 0x14, 0x0f, 0xfb,
0xae, 0xf4, 0xa0, 0x19, 0x92, 0x27, 0x5e, 0x56, 0x81, 0xea, 0xcf, 0x2a,
0xd8, 0xed, 0x66, 0x2e, 0x75, 0xc2, 0xe6, 0x6f, 0x7b, 0x66, 0x91, 0x49,
0xaa, 0xde, 0xed, 0xfc, 0x7c, 0x9d, 0x2c, 0xfd, 0x03, 0x13, 0x03, 0xa1,
0x63, 0x2a, 0x2f, 0x78, 0x10, 0x07, 0x42, 0x6e, 0x2a, 0x15, 0x4c, 0x5e,
0x98, 0x2b, 0x35, 0x02, 0xcc, 0xf6, 0x6d, 0x51, 0x0f, 0x92, 0x01, 0xdd,
0x2b, 0x7f, 0x25, 0x96, 0xfc, 0xe5, 0xca, 0x33, 0x77, 0x75, 0x16, 0x0c,
0x1b, 0x60, 0xa3, 0xe8, 0x5d, 0x2b, 0x53, 0xa6, 0xb4, 0x99, 0x32, 0xbd,
0x3d, 0xe3, 0xa7, 0x2e, 0x20, 0x6b, 0x9f, 0xaf, 0xe4, 0x06, 0x33, 0xb5,
0x7e, 0x04, 0xf0, 0xc0, 0xce, 0xe1, 0x55, 0x34, 0xf7, 0x70, 0x54, 0xb3,
0x55, 0x13, 0xb1, 0xb7, 0x59, 0x85, 0xd9, 0xac, 0xd2, 0xdb, 0xac, 0xd4,
0xdf, 0xac, 0xcc, 0xdf, 0xac, 0xc2, 0x6c, 0x96, 0xd9, 0x8b, 0xd7, 0x16,
0x26, 0xe3, 0x74, 0x64, 0x19, 0xe5, 0xf4, 0xa7, 0xad, 0x7d, 0xa3, 0x2c,
0xf3, 0x18, 0x1d, 0xab, 0xcd, 0x73, 0x7f, 0xb7, 0xa5, 0x7d, 0xd8, 0xab,
0x4f, 0xa5, 0xcd, 0xc2, 0x7e, 0xed, 0x16, 0xde, 0x37, 0x3c, 0x66, 0x61,
0x04, 0x31, 0x1d, 0x6a, 0xef, 0x38, 0x76, 0x70, 0xec, 0x1f, 0x4d, 0xda,
0x04, 0x04, 0x48, 0x72, 0x59, 0xfb, 0x4d, 0xc2, 0xbf, 0xec, 0x26, 0xfc,
0x2b, 0x4a, 0xf8, 0xd7, 0x39, 0x1f, 0x8f, 0xf4, 0x45, 0x9d, 0x44, 0xd5,
0x74, 0xad, 0x34, 0x6b, 0x81, 0x83, 0x8f, 0x84, 0x75, 0x89, 0x94, 0x6e,
0x7c, 0x61, 0xb6, 0x07, 0x70, 0xcf, 0x77, 0xaf, 0x9f, 0x3f, 0xbb, 0xe3,
0x8a, 0x1c, 0xbe, 0x9f, 0x69, 0xd7, 0x4c, 0x10, 0x7b, 0xc3, 0xd3, 0x6b,
0x25, 0xf1, 0xe7, 0xad, 0xb4, 0x79, 0x5d, 0xc5, 0xbe, 0x73, 0x61, 0x2e,
0x4b, 0xea, 0xcb, 0xd3, 0x4b, 0x51, 0x62, 0x76, 0x70, 0x12, 0xc8, 0x1c,
0x93, 0x83, 0x75, 0xfa, 0xb6, 0x28, 0xdf, 0xe2, 0x8c, 0x68, 0xcb, 0xa0,
0xfb, 0x84, 0x3a, 0xe8, 0xb7, 0xb2, 0x74, 0x27, 0x9b, 0x06, 0xa8, 0x3b,
0x79, 0x15, 0x66, 0xb4, 0x9e, 0x74, 0xeb, 0x80, 0x1a, 0x04, 0x98, 0xfe,
0xa2, 0x9b, 0xea, 0x06, 0xcd, 0xb1, 0x38, 0x30, 0x5d, 0x83, 0x68, 0x0f,
0x86, 0xd3, 0x9a, 0xa2, 0xc5, 0xb8, 0x55, 0xcd, 0xeb, 0x30, 0xb8, 0x79,
0xa1, 0x9c, 0xe6, 0x61, 0x14, 0x23, 0x33, 0x35, 0x8f, 0x23, 0x18, 0xc3,
0x7a, 0x2b, 0xa7, 0x61, 0x78, 0x08, 0x3a, 0x4c, 0xe2, 0x6d, 0x5f, 0x0b,
0x85, 0xad, 0xbe, 0x0a, 0xed, 0x13, 0x24, 0x39, 0xdd, 0x0f, 0xc2, 0x17,
0x37, 0x99, 0xf0, 0xc4, 0x74, 0xac, 0x87, 0x1b, 0xee, 0x2f, 0xf6, 0x49,
0xd3, 0xd5, 0xb6, 0x2f, 0xb5, 0x72, 0xd2, 0xa3, 0xc4, 0xde, 0x28, 0x74,
0x7d, 0xc7, 0x3d, 0xfb, 0xb2, 0x5e, 0xf3, 0xa5, 0x40, 0xce, 0xc0, 0x24,
0x76, 0x7d, 0x88, 0x8c, 0xdc, 0xd5, 0x24, 0x74, 0xdb, 0x1f, 0x94, 0xee,
0x64, 0x4d, 0x1c, 0xaa, 0xf4, 0x33, 0x79, 0x31, 0xa3, 0xea, 0x93, 0x0c,
0x04, 0xde, 0xa7, 0x22, 0xc9, 0x15, 0x92, 0xee, 0x55, 0xfa, 0xea, 0x46,
0x39, 0xf2, 0x5d, 0xb0, 0xb4, 0x23, 0xc5, 0xc5, 0x8a, 0x64, 0x81, 0x70,
0x77, 0x4a, 0x30, 0x95, 0xdd, 0x7f, 0x9a, 0xae, 0x79, 0xbd, 0xe7, 0xb3,
0x89, 0xbc, 0xb9, 0x3a, 0x8b, 0x77, 0x5a, 0x9b, 0x57, 0x80, 0xfa, 0xee,
0xc5, 0x01, 0xf2, 0xf4, 0x75, 0x9d, 0x03, 0x57, 0xcf, 0x3c, 0x7b, 0x5b,
0xdf, 0xc2, 0xda, 0xed, 0x4a, 0x7a, 0x20, 0xa3, 0x43, 0x36, 0x43, 0x30,
0x3a, 0xa1, 0x02, 0x08, 0xa0, 0xef, 0x4a, 0xa1, 0xbd, 0x95, 0xdc, 0x33,
0x49, 0xdf, 0x45, 0x34, 0x3c, 0xad, 0x4e, 0xbc, 0xbb, 0x14, 0xfd, 0x17,
0x06, 0x55, 0xeb, 0xc2, 0xe0, 0x67, 0xdd, 0x14, 0xbc, 0xba, 0x0d, 0xdc,
0x2e, 0x44, 0xfd, 0xb7, 0x02, 0x7b, 0x07, 0x28, 0xfa, 0x2f, 0x21, 0x76,
0x31, 0x8a, 0x0c, 0xed, 0x51, 0x8a, 0xea, 0x88, 0x3a, 0x24, 0x8b, 0xf8,
0x77, 0x27, 0x08, 0xbb, 0xf5, 0xf4, 0xee, 0x22, 0x3e, 0xe2, 0xb7, 0x27,
0x61, 0xae, 0x8f, 0x75, 0x9d, 0x56, 0x92, 0xb7, 0x10, 0x10, 0x68, 0x57,
0xcf, 0xb0, 0xb7, 0xfe, 0x08, 0xaa, 0x70, 0xce, 0x0f, 0x66, 0x74, 0xb5,
0x68, 0xb2, 0x5a, 0x91, 0xdf, 0x51, 0x3b, 0xc4, 0xd6, 0xd9, 0xf9, 0xd8,
0x14, 0x3c, 0x75, 0x09, 0x04, 0xfe, 0xcc, 0xfb, 0x89, 0xb3, 0x87, 0xa6,
0xee, 0x90, 0x72, 0xcf, 0x7b, 0x9b, 0x68, 0x19, 0xf6, 0xbd, 0xb9, 0x69,
0xe5, 0x61, 0xd7, 0xbc, 0xb4, 0x4f, 0x71, 0x32, 0x31, 0xd6, 0x76, 0x48,
0xa4, 0x9d, 0xe3, 0x3c, 0xb1, 0xc0, 0x52, 0xb0, 0xd8, 0x7b, 0x39, 0xda,
0x8f, 0x5d, 0x87, 0x74, 0x0b, 0xc4, 0xbf, 0xcd, 0x5e, 0xa3, 0x9d, 0xea,
0xfc, 0xfa, 0xac, 0xe3, 0x92, 0x72, 0x96, 0x94, 0xcb, 0xc5, 0x6f, 0x3f,
0x01, 0x8a, 0x28, 0x25, 0x0d, 0x0a, 0x6a, 0xbb, 0xf7, 0x21, 0x50, 0x7a,
0xf3, 0xd3, 0x6b, 0x85, 0x2f, 0x7f, 0x9a, 0xc5, 0xe9, 0xe7, 0x3e, 0x0f,
0x3e, 0xeb, 0x39, 0x39, 0x9c, 0xc3, 0x37, 0xed, 0xe2, 0x85, 0xef, 0xe3,
0x25, 0xee, 0xb6, 0x69, 0x52, 0x58, 0xbb, 0x15, 0xb8, 0x24, 0xfe, 0xb9,
0x6b, 0xb9, 0x63, 0x11, 0x28, 0x0a, 0x7a, 0x5f, 0x27, 0xfd, 0x62, 0x64,
0xd9, 0x5f, 0x63, 0xe8, 0x0c, 0x0d, 0x10, 0x24, 0x3b, 0x3a, 0x65, 0xda,
0x11, 0x29, 0x23, 0x99, 0x56, 0xed, 0x65, 0x28, 0x43, 0xcb, 0xad, 0xce,
0x48, 0x8e, 0x25, 0x3b, 0xaf, 0xce, 0xcf, 0x33, 0x5e, 0xd2, 0xd3, 0xe6,
0xc0, 0x76, 0x77, 0xbb, 0x62, 0x5d, 0x62, 0xb2, 0x0d, 0xc5, 0xe0, 0xf0,
0xe4, 0xea, 0x03, 0x78, 0x4c, 0xe8, 0x53, 0x3b, 0xaa, 0xe8, 0x74, 0xa8,
0xaf, 0xd8, 0x9e, 0x4e, 0xd4, 0xd7, 0xd6, 0xea, 0x98, 0x28, 0x7c, 0x2d,
0xdc, 0x8a, 0x48, 0x7c, 0x4e, 0xbd, 0x49, 0x34, 0xce, 0xf2, 0x12, 0xdf,
0x52, 0x0d, 0x66, 0xda, 0xbd, 0x33, 0x0f, 0xf4, 0x75, 0x09, 0xcc, 0xa9,
0xee, 0x3d, 0x77, 0x13, 0x53, 0xb9, 0x1b, 0x9b, 0xa4, 0x8d, 0x68, 0x3c,
0x4a, 0xf0, 0xb6, 0x4e, 0x22, 0x5b, 0xda, 0x34, 0xa4, 0x5b, 0x8c, 0xbd,
0x10, 0xf4, 0xc7, 0xb1, 0x76, 0x3b, 0x8c, 0x5f, 0x01, 0x5b, 0xaf, 0x9c,
0x17, 0x5b, 0xb2, 0x76, 0x90, 0x2a, 0x9a, 0xb4, 0x89, 0xa8, 0xed, 0xe4,
0x75, 0xdb, 0x3f, 0xe3, 0x98, 0xa8, 0x88, 0x1e, 0x5c, 0xeb, 0x88, 0xb7,
0xc5, 0x54, 0xa8, 0xe5, 0x0f, 0x41, 0x8b, 0x2f, 0x61, 0xe3, 0x7a, 0x4b,
0xef, 0x2c, 0xde, 0xad, 0x69, 0x4d, 0xa2, 0xdf, 0xbc, 0x96, 0x50, 0xf1,
0x1a, 0xd6, 0x8f, 0x99, 0xce, 0x1d, 0xc1, 0xbd, 0xdb, 0xe1, 0x65, 0x6e,
0x32, 0x90, 0xd1, 0x7a, 0x71, 0x58, 0x36, 0x6d, 0xa7, 0x87, 0x7c, 0xf7,
0xf8, 0x64, 0xce, 0xbe, 0x17, 0xaa, 0x46, 0x31, 0x3d, 0x36, 0x8e, 0x3f,
0x7c, 0xe4, 0x98, 0x9e, 0xd9, 0xc6, 0xe3, 0x26, 0xbe, 0x9a, 0xef, 0xb6,
0x05, 0xbf, 0xca, 0xea, 0x5c, 0x15, 0x5c, 0x3f, 0xa1, 0x5f, 0xb7, 0xc3,
0x4c, 0x74, 0x08, 0xe4, 0xad, 0x48, 0xab, 0x0b, 0x6d, 0x22, 0x83, 0x50,
0x80, 0xd6, 0xcb, 0xe4, 0x3f, 0x12, 0xa5, 0x7e, 0xc8, 0x99, 0x9a, 0x50,
0x80, 0x91, 0xdc, 0x64, 0xb7, 0xfa, 0x76, 0x74, 0xe8, 0x41, 0x3b, 0x61,
0xba, 0xae, 0xc4, 0x82, 0xd3, 0x1d, 0x14, 0xbe, 0xb7, 0xfd, 0x54, 0x61,
0x5e, 0x48, 0x11, 0x89, 0x76, 0xd8, 0x08, 0x1d, 0x89, 0x13, 0x18, 0xc6,
0xb1, 0xef, 0x95, 0xf2, 0x64, 0x8b, 0x0e, 0x08, 0x7a, 0xb6, 0xed, 0xfe,
0xf8, 0x3f, 0xc7, 0xf7, 0x03, 0x46, 0xce, 0xcf, 0x2e, 0x5b, 0xc4, 0x70,
0xba, 0xeb, 0x04, 0x9e, 0x62, 0x58, 0xe1, 0x81, 0xe8, 0x44, 0x3c, 0x9b,
0xb3, 0x5b, 0xc3, 0x3c, 0xd8, 0xe0, 0xb6, 0x2b, 0xd4, 0x38, 0x1d, 0xbd,
0x42, 0x13, 0xef, 0xa9, 0x83, 0x02, 0xcf, 0xd4, 0x29, 0x5e, 0x4d, 0x19,
0xb4, 0x5c, 0x25, 0x88, 0xa0, 0x00, 0x94, 0x30, 0x76, 0x0f, 0xdc, 0x45,
0x33, 0x8a, 0xc1, 0xdf, 0x50, 0x58, 0x7d, 0xea, 0xae, 0x65, 0x77, 0x2f,
0xa5, 0x04, 0x8f, 0x5f, 0x3e, 0x37, 0x87, 0xac, 0x67, 0x30, 0x04, 0x5e,
0x47, 0x44, 0xca, 0x09, 0x9d, 0xa3, 0x0b, 0x04, 0xd3, 0x02, 0x74, 0x7e,
0xe1, 0xed, 0x8c, 0xe3, 0x0f, 0x47, 0x78, 0x4d, 0xb5, 0x71, 0x92, 0xdd,
0x32, 0x25, 0x50, 0xc4, 0x79, 0x0e, 0x56, 0xca, 0xfb, 0x32, 0x46, 0xb0,
0x03, 0x6b, 0xb4, 0xf9, 0xb3, 0xfd, 0x2c, 0xdd, 0xd0, 0xcb, 0x4f, 0x9b,
0xba, 0x81, 0xdc, 0x97, 0x8c, 0x07, 0xc6, 0x7b, 0xa8, 0x7e, 0xaa, 0xf0,
0x05, 0x2b, 0x5c, 0x30, 0xdb, 0x5f, 0x69, 0xeb, 0xb1, 0xe4, 0x66, 0x45,
0xff, 0xa8, 0x78, 0x71, 0xf3, 0x8a, 0xfc, 0x1f, 0x79, 0xf1, 0x10, 0x34,
0x9b, 0xc7, 0x96, 0x2d, 0xaf, 0x3b, 0x7a, 0xaf, 0x08, 0x22, 0x76, 0xc7,
0xb2, 0x62, 0xdf, 0x1a, 0x31, 0xb1, 0x7b, 0x2b, 0xeb, 0x42, 0xef, 0xca,
0x60, 0x74, 0xeb, 0xdc, 0xfe, 0x95, 0x6d, 0xd9, 0x8a, 0x3f, 0xb4, 0x5d,
0xdb, 0xd1, 0x21, 0x28, 0x3f, 0x05, 0x61, 0x7e, 0xc8, 0xd4, 0xea, 0x97,
0x7e, 0x0c, 0x85, 0x01, 0x5e, 0x74, 0xc4, 0x3b, 0x81, 0x07, 0xb5, 0x0e,
0x25, 0x26, 0x37, 0xd1, 0xc9, 0x6e, 0x9b, 0xe8, 0x16, 0xa5, 0xf4, 0xb9,
0x72, 0x37, 0xf1, 0xe5, 0x2e, 0x39, 0xbf, 0x5b, 0x46, 0x3d, 0x4a, 0x96,
0xb6, 0x95, 0xdf, 0xa3, 0xe8, 0xe0, 0x4c, 0xfb, 0x65, 0x48, 0x96, 0x75,
0x26, 0x8b, 0x0c, 0x19, 0x7f, 0x8e, 0xa0, 0x66, 0x3d, 0x93, 0xb4, 0xc8,
0x98, 0x9e, 0xa0, 0x21, 0x32, 0xc0, 0xc7, 0xec, 0xbb, 0xee, 0xed, 0xe6,
0x6d, 0xfa, 0xbd, 0x90, 0x6c, 0xe3, 0x1d, 0xc5, 0x48, 0x2b, 0xbe, 0x2e,
0x06, 0x43, 0xc7, 0xed, 0x80, 0xa2, 0xd2, 0xe1, 0x9b, 0x50, 0xf9, 0x83,
0xd2, 0x0d, 0xa5, 0x9a, 0xc1, 0x4e, 0x3c, 0xf7, 0xc4, 0xe8, 0x4d, 0xb7,
0x2b, 0x85, 0x43, 0xdb, 0x72, 0x16, 0x15, 0xac, 0x3a, 0x24, 0x6a, 0x5b,
0x6b, 0xd2, 0x89, 0x67, 0x07, 0x02, 0xc6, 0x4d, 0x1e, 0xc3, 0x6d, 0x82,
0xb9, 0x6f, 0xb8, 0xdb, 0xa2, 0xf5, 0x76, 0xd0, 0x26, 0x5e, 0x4c, 0xd2,
0x39, 0xd4, 0x17, 0x6c, 0xed, 0xff, 0x84, 0x73, 0xc1, 0x99, 0x29, 0xa0,
0x9b, 0xdd, 0xcf, 0xb4, 0x8c, 0xd6, 0x95, 0xd3, 0x83, 0x35, 0xad, 0xa8,
0x6e, 0x6b, 0x40, 0xfb, 0x3e, 0x19, 0xba, 0x29, 0x7a, 0x2b, 0x22, 0x76,
0x81, 0xee, 0xeb, 0xc9, 0xbf, 0xfc, 0x0f, 0xc8, 0x72, 0xd8, 0x05, 0x1e,
0x68, 0x00, 0x00
};
unsigned int alpine_min_js_gz_len = 8463;
#endif // USE_ALPINEJS
#endif // USE_WEBSERVER

View File

@ -858,18 +858,21 @@
// Log message prefix // Log message prefix
#define D_LOG_APPLICATION "APP: " // Application #define D_LOG_APPLICATION "APP: " // Application
#define D_LOG_BRIDGE "BRG: " // Bridge #define D_LOG_BRIDGE "BRG: " // Bridge
#define D_LOG_BERRY "BRY: " // Berry scripting language
#define D_LOG_CONFIG "CFG: " // Settings #define D_LOG_CONFIG "CFG: " // Settings
#define D_LOG_COMMAND "CMD: " // Command #define D_LOG_COMMAND "CMD: " // Command
#define D_LOG_DEBUG "DBG: " // Debug #define D_LOG_DEBUG "DBG: " // Debug
#define D_LOG_DHT "DHT: " // DHT sensor #define D_LOG_DHT "DHT: " // DHT sensor
#define D_LOG_DOMOTICZ "DOM: " // Domoticz #define D_LOG_DOMOTICZ "DOM: " // Domoticz
#define D_LOG_DSB "DSB: " // DS18xB20 sensor #define D_LOG_DSB "DSB: " // DS18xB20 sensor
#define D_LOG_ETH "ETH: " // Ethernet
#define D_LOG_HTTP "HTP: " // HTTP webserver #define D_LOG_HTTP "HTP: " // HTTP webserver
#define D_LOG_HRE "HRE: " #define D_LOG_HRE "HRE: " // Badger HR-E Water Meter
#define D_LOG_I2C "I2C: " // I2C #define D_LOG_I2C "I2C: " // I2C
#define D_LOG_IRR "IRR: " // Infra Red Received #define D_LOG_IRR "IRR: " // Infra Red Received
#define D_LOG_KNX "KNX: " #define D_LOG_KNX "KNX: " // KNX server
#define D_LOG_LOG "LOG: " // Logging #define D_LOG_LOG "LOG: " // Logging
#define D_LOG_LVGL "LVG: " // LVGL graphics engine
#define D_LOG_MODULE "MOD: " // Module #define D_LOG_MODULE "MOD: " // Module
#define D_LOG_MDNS "mDN: " // mDNS #define D_LOG_MDNS "mDN: " // mDNS
#define D_LOG_MQTT "MQT: " // MQTT #define D_LOG_MQTT "MQT: " // MQTT
@ -877,18 +880,17 @@
#define D_LOG_RESULT "RSL: " // Result #define D_LOG_RESULT "RSL: " // Result
#define D_LOG_RFR "RFR: " // RF Received #define D_LOG_RFR "RFR: " // RF Received
#define D_LOG_SERIAL "SER: " // Serial #define D_LOG_SERIAL "SER: " // Serial
#define D_LOG_SENSEAIR "SNA: " // Senseair driver
#define D_LOG_SENSOR "SNS: " // Sensor driver
#define D_LOG_SHT1 "SHT: " // SHT1x sensor #define D_LOG_SHT1 "SHT: " // SHT1x sensor
#define D_LOG_TCP "TCP: " // TCP bridge
#define D_LOG_TELNET "TEL: " // Telnet server
#define D_LOG_THERMOSTAT "THE: " // Thermostat driver
#define D_LOG_UFS "UFS: " // File system
#define D_LOG_UPLOAD "UPL: " // Upload #define D_LOG_UPLOAD "UPL: " // Upload
#define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_UPNP "UPP: " // UPnP
#define D_LOG_WIFI "WIF: " // Wifi #define D_LOG_WIFI "WIF: " // Wifi
#define D_LOG_ETH "ETH: " // Ethernet
#define D_LOG_ZIGBEE "ZIG: " // Zigbee #define D_LOG_ZIGBEE "ZIG: " // Zigbee
#define D_LOG_TCP "TCP: " // TCP bridge
#define D_LOG_BERRY "BRY: " // Berry scripting language
#define D_LOG_LVGL "LVG: " // LVGL graphics engine
#define D_LOG_THERMOSTAT "THE: " // Thermostat driver
#define D_LOG_SENSOR "SNS: " // Sensor driver
#define D_LOG_SENSEAIR "SNA: " // Senseair driver
/********************************************************************************************/ /********************************************************************************************/

View File

@ -20,6 +20,9 @@ class TASCONSOLE {
virtual size_t printf(const char*, char *, const char*&, const char*&, const char*&) = 0; virtual size_t printf(const char*, char *, const char*&, const char*&, const char*&) = 0;
virtual size_t printf(char *) = 0; virtual size_t printf(char *) = 0;
virtual size_t read() = 0; virtual size_t read() = 0;
virtual size_t write(uint8_t) = 0;
virtual size_t write(const uint8_t *buf, size_t size) = 0;
virtual size_t setRxBufferSize(size_t) = 0; virtual size_t setRxBufferSize(size_t) = 0;
// virtual size_t setTxBufferSize(size_t) = 0; // virtual size_t setTxBufferSize(size_t) = 0;
}; };
@ -62,6 +65,14 @@ public:
return object->read(); return object->read();
} }
size_t write(uint8_t data) {
return object->write(data);
}
size_t write(const uint8_t *buf, size_t size) {
return object->write(buf, size);
}
size_t setRxBufferSize(size_t rx_queue_len) { size_t setRxBufferSize(size_t rx_queue_len) {
return object->setRxBufferSize(rx_queue_len); return object->setRxBufferSize(rx_queue_len);
} }
@ -104,6 +115,14 @@ public:
return object.read(); return object.read();
} }
size_t write(uint8_t data) override {
return object.write(data);
}
size_t write(const uint8_t *buf, size_t size) override {
return object.write(buf, size);
}
size_t setRxBufferSize(size_t size) override { size_t setRxBufferSize(size_t size) override {
return object.setRxBufferSize(size); return object.setRxBufferSize(size);
} }

View File

@ -502,6 +502,8 @@ enum SettingsTextIndex { SET_OTAURL,
enum SpiInterfaces { SPI_NONE, SPI_MOSI, SPI_MISO, SPI_MOSI_MISO }; enum SpiInterfaces { SPI_NONE, SPI_MOSI, SPI_MISO, SPI_MOSI_MISO };
enum XYZModemProtocols { TXMP_NONE, TXMP_SERIAL, TXMP_TASCONSOLE, TXMP_TELNET };
enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND, DGR_MSGTYPFLAG_WITH_LOCAL = 128 }; enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND, DGR_MSGTYPFLAG_WITH_LOCAL = 128 };
enum DevGroupMessageFlag { DGR_FLAG_RESET = 1, DGR_FLAG_STATUS_REQUEST = 2, DGR_FLAG_FULL_STATUS = 4, DGR_FLAG_ACK = 8, DGR_FLAG_MORE_TO_COME = 16, DGR_FLAG_DIRECT = 32, DGR_FLAG_ANNOUNCEMENT = 64, DGR_FLAG_LOCAL = 128 }; enum DevGroupMessageFlag { DGR_FLAG_RESET = 1, DGR_FLAG_STATUS_REQUEST = 2, DGR_FLAG_FULL_STATUS = 4, DGR_FLAG_ACK = 8, DGR_FLAG_MORE_TO_COME = 16, DGR_FLAG_DIRECT = 32, DGR_FLAG_ANNOUNCEMENT = 64, DGR_FLAG_LOCAL = 128 };
@ -529,10 +531,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER, enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER, SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_SENSOR, SRC_WEB, SRC_MAX }; SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_SENSOR, SRC_WEB, SRC_TELNET, SRC_MAX };
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|" const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|" "Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
"Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47|Sensor|Web"; "Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47|Sensor|Web|Telnet";
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };

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