mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-26 12:14:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccfe7e0724 | ||
|
|
8061a41b38 | ||
|
|
39392b3690 | ||
|
|
54d4611eb6 | ||
|
|
34cdce750d | ||
|
|
f3fafb6759 | ||
|
|
0372c97ff5 | ||
|
|
b46136a0af | ||
|
|
ac3d41fb79 | ||
|
|
14be42c868 | ||
|
|
f0ec14543a | ||
|
|
f46c5b7214 | ||
|
|
ccd6bcd95f | ||
|
|
a3b63f3b0d | ||
|
|
f2905a5e10 | ||
|
|
1ef6c6aeb5 | ||
|
|
bd53529b45 | ||
|
|
cc8ecc5a42 | ||
|
|
5a816a1d41 | ||
|
|
9922286c67 | ||
|
|
cdc439bc38 | ||
|
|
ae8422e304 | ||
|
|
539d080346 | ||
|
|
041ec6e1f8 | ||
|
|
f618fe125c | ||
|
|
8ab514fabc | ||
|
|
08ad2c3145 | ||
|
|
c64fd404d4 | ||
|
|
143b0ac126 | ||
|
|
c2e2432010 | ||
|
|
1d2a768184 | ||
|
|
fb099641bc | ||
|
|
6da9afbf29 | ||
|
|
dceb4beb09 | ||
|
|
6f697db49d | ||
|
|
b44193780e | ||
|
|
8e0212c3db | ||
|
|
3861e2e1e7 | ||
|
|
21eefa4b55 | ||
|
|
fb6c6aafeb | ||
|
|
df07426e78 | ||
|
|
5cf1523a13 | ||
|
|
f2fe47e9f7 | ||
|
|
2557ab2e60 | ||
|
|
fbc1708000 | ||
|
|
0539cf1023 | ||
|
|
07b410447b | ||
|
|
fb69016196 | ||
|
|
169cbc044f | ||
|
|
08091d02e5 | ||
|
|
6f2dcf92a7 | ||
|
|
578e52618d | ||
|
|
ec0fe66a17 | ||
|
|
8fee24291a | ||
|
|
05bba2958d | ||
|
|
e656b1c792 | ||
|
|
e0ccbadd25 | ||
|
|
40a2a8822f | ||
|
|
e2ee356a87 | ||
|
|
189bef61d3 | ||
|
|
7d94f9f61b | ||
|
|
e37a0b9056 | ||
|
|
0b57b23951 | ||
|
|
c84826e84e | ||
|
|
064fc6ff7b | ||
|
|
042ea53478 | ||
|
|
900b0acf7a | ||
|
|
dc5f2e295a | ||
|
|
c1849c2b19 | ||
|
|
4eadf3699f | ||
|
|
b30cf6587c | ||
|
|
fbc231f33e | ||
|
|
bc8c839342 | ||
|
|
90a23fe230 | ||
|
|
065027843e | ||
|
|
8906b1ac0f | ||
|
|
05f9e61a41 | ||
|
|
782896b5d3 | ||
|
|
4258f62560 | ||
|
|
537ba64a54 | ||
|
|
25d20b7354 | ||
|
|
04d8362905 | ||
|
|
21266e9a45 | ||
|
|
7304e2171d | ||
|
|
61fc480850 | ||
|
|
562e82f5ac | ||
|
|
d7ff85bb48 | ||
|
|
55bc6105e1 | ||
|
|
306c0b6096 | ||
|
|
024078ae33 | ||
|
|
b5a9ba8390 | ||
|
|
93f36927ca | ||
|
|
1db90cafd1 | ||
|
|
bf23a0def7 | ||
|
|
ea1cbeea9d | ||
|
|
aeda7e5520 | ||
|
|
a7899af8b8 | ||
|
|
b0385f47af | ||
|
|
86c384657c | ||
|
|
6e569110d2 | ||
|
|
3b1024b13c | ||
|
|
b3f5d11275 | ||
|
|
1078ba0a92 | ||
|
|
005c8170d4 | ||
|
|
b8d1d7a10b | ||
|
|
76769fb4d5 | ||
|
|
6ff6f0a4c6 | ||
|
|
72a45d2f6a | ||
|
|
2fe7c8a410 | ||
|
|
5269eb9c39 | ||
|
|
a0d9b6a7e0 |
No files matched your search
@@ -0,0 +1,20 @@
|
|||||||
|
name: Fuzz
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 21 * * *' # run at 9 PM UTC
|
||||||
|
# Allow manual runs
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
CC: clang
|
||||||
|
jobs:
|
||||||
|
fuzz:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
target: [fuzz, fuzz_tls]
|
||||||
|
name: ${{ matrix.target }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: make -C test ${{ matrix.target }}
|
||||||
+65
-151
@@ -165,97 +165,12 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- run: make -C test riscv SSL=${{ matrix.ssl }}
|
- run: make -C test riscv SSL=${{ matrix.ssl }}
|
||||||
|
|
||||||
examples:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
|
|
||||||
name: examples ${{ matrix.ssl }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: sudo apt -y install libpcap-dev
|
|
||||||
- run: make -C test examples CFLAGS_EXTRA="${{ matrix.ssl }}"
|
|
||||||
- run: make -C test clean_examples
|
|
||||||
examples_win:
|
|
||||||
runs-on: windows-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
|
||||||
name: examples_win ${{ matrix.ssl }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# - uses: egor-tensin/setup-mingw@v2
|
|
||||||
# with:
|
|
||||||
# platform: x64
|
|
||||||
- name: test they build
|
|
||||||
run: make -C test examples_win CFLAGS_EXTRA="${{ matrix.ssl }}"
|
|
||||||
shell: cmd
|
|
||||||
- name: test they clean
|
|
||||||
run: make -C test clean_examples_win
|
|
||||||
shell: cmd
|
|
||||||
examples_mac:
|
|
||||||
runs-on: macos-latest
|
|
||||||
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
|
||||||
name: examples_mac ${{ matrix.ssl }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: make -C test examples_mac CFLAGS_EXTRA="${{ matrix.ssl }}"
|
|
||||||
- run: make -C test clean_examples_mac
|
|
||||||
|
|
||||||
refprojs:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
|
||||||
name: reference-projects ${{ matrix.ssl }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: make -C test refprojs CFLAGS_EXTRA="${{ matrix.ssl }}"
|
|
||||||
- run: make -C test clean_refprojs
|
|
||||||
refprojs_win:
|
|
||||||
runs-on: windows-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
|
||||||
name: reference-projects_win ${{ matrix.ssl }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# - uses: egor-tensin/setup-mingw@v2
|
|
||||||
# with:
|
|
||||||
# platform: x64
|
|
||||||
- name: test they build
|
|
||||||
run: make -C test refprojs_win CFLAGS_EXTRA="${{ matrix.ssl }}"
|
|
||||||
shell: cmd
|
|
||||||
- name: test they clean
|
|
||||||
run: make -C test clean_refprojs_win
|
|
||||||
shell: cmd
|
|
||||||
refprojs_mac:
|
|
||||||
runs-on: macos-latest
|
|
||||||
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
|
||||||
name: reference-projects_mac ${{ matrix.ssl }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: make -C test refprojs CFLAGS_EXTRA="${{ matrix.ssl }}"
|
|
||||||
- run: make -C test clean_refprojs
|
|
||||||
|
|
||||||
tutorials:
|
tutorials:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
name: tutorials ${{ matrix.ssl }}
|
name: tutorials ${{ matrix.ssl }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -267,7 +182,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
name: tutorials_win ${{ matrix.ssl }}
|
name: tutorials_win ${{ matrix.ssl }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -286,7 +201,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
name: tutorials_mac ${{ matrix.ssl }}
|
name: tutorials_mac ${{ matrix.ssl }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -300,11 +215,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: echo # nothing specific to install or do
|
- run: echo # nothing specific to install or do
|
||||||
- run: make -C examples/arduino arduino-xiao
|
- run: make -C test/arduino
|
||||||
# TODO(): - run: make -C examples/arduino arduino-esp32
|
- run: make -C test/arduino cleanall
|
||||||
# TODO(): - run: make -C examples/arduino arduino-teensy41
|
|
||||||
# - run: make -C examples/arduino arduino-nano
|
|
||||||
- run: make -C examples/arduino clean
|
|
||||||
|
|
||||||
|
|
||||||
# wizard_examples:
|
# wizard_examples:
|
||||||
@@ -322,7 +234,7 @@ jobs:
|
|||||||
# with: { fetch-depth: 2 }
|
# with: { fetch-depth: 2 }
|
||||||
# - run: echo # nothing specific to install or do
|
# - run: echo # nothing specific to install or do
|
||||||
# fi
|
# fi
|
||||||
# - run: make -C examples/${{ matrix.example.path }} build
|
# - run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
wizard_examples_arm:
|
wizard_examples_arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -330,7 +242,9 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: infineon/infineon-xmc7200
|
- path: infineon/xmc47_relax-make-baremetal-builtin
|
||||||
|
- path: infineon/xmc_plt2go_4400-make-baremetal-builtin
|
||||||
|
- path: infineon/xmc72_evk-make-baremetal-builtin
|
||||||
- path: nxp/frdm-mcxn947-make-baremetal-builtin
|
- path: nxp/frdm-mcxn947-make-baremetal-builtin
|
||||||
- path: nxp/frdm-mcxn947-make-freertos-builtin
|
- path: nxp/frdm-mcxn947-make-freertos-builtin
|
||||||
- path: nxp/rt1020-evk-make-baremetal-builtin
|
- path: nxp/rt1020-evk-make-baremetal-builtin
|
||||||
@@ -361,7 +275,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/${{ matrix.example.path }} build
|
- run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
|
||||||
generic_examples:
|
generic_examples:
|
||||||
@@ -370,9 +284,9 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: esp32/uart-bridge
|
- path: micropython/esp32
|
||||||
- path: esp32/micropython
|
- path: http/uart-bridge/esp32
|
||||||
- path: esp8266/http-client-server
|
- path: http/http-client/esp8266/http-client-server
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
env:
|
env:
|
||||||
GO: 0
|
GO: 0
|
||||||
@@ -380,7 +294,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: echo # nothing specific to install or do
|
- run: echo # nothing specific to install or do
|
||||||
- run: make -C examples/${{ matrix.example.path }} build
|
- run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
generic_examples_arm:
|
generic_examples_arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -388,8 +302,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: microchip/same54-xpro/mqtt-client
|
- path: mqtt/mqtt-client/microchip/same54-xpro
|
||||||
- path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos
|
|
||||||
- path: nxp/nxp-mimxrt1020-azurertos
|
- path: nxp/nxp-mimxrt1020-azurertos
|
||||||
- path: nxp/nxp-frdmk66f-freertos
|
- path: nxp/nxp-frdmk66f-freertos
|
||||||
- path: nxp/nxp-lpcxpresso54s018m-freertos
|
- path: nxp/nxp-lpcxpresso54s018m-freertos
|
||||||
@@ -420,7 +333,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/${{ matrix.example.path }} build
|
- run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
device_dashboard_examples:
|
device_dashboard_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -428,13 +341,14 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: esp32/device-dashboard
|
- path: esp32
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: echo # nothing specific to install or do
|
- run: echo # nothing specific to install or do
|
||||||
- run: make -C examples/${{ matrix.example.path }} build
|
- run: make -C tutorials/http/device-dashboard/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
|
||||||
device_dashboard_examples_arm:
|
device_dashboard_examples_arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -443,7 +357,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
example:
|
example:
|
||||||
- path: microchip/same54-xpro/device-dashboard
|
- path: tutorials/http/device-dashboard/microchip/same54-xpro
|
||||||
- path: nxp/rt1020-evk-make-freertos-builtin
|
- path: nxp/rt1020-evk-make-freertos-builtin
|
||||||
- path: nxp/rt1060-evk-make-freertos-builtin
|
- path: nxp/rt1060-evk-make-freertos-builtin
|
||||||
- path: nxp/rt1170-evk-make-freertos-builtin
|
- path: nxp/rt1170-evk-make-freertos-builtin
|
||||||
@@ -458,7 +372,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/${{ matrix.example.path }} build CFLAGS_EXTRA="${{ matrix.ssl }}"
|
- run: make -C tutorials/${{ matrix.example.path }} build CFLAGS_EXTRA="${{ matrix.ssl }}"
|
||||||
|
|
||||||
# mqtt_dashboard_examples:
|
# mqtt_dashboard_examples:
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
@@ -472,7 +386,7 @@ jobs:
|
|||||||
# - uses: actions/checkout@v4
|
# - uses: actions/checkout@v4
|
||||||
# with: { fetch-depth: 2 }
|
# with: { fetch-depth: 2 }
|
||||||
# - run: echo # nothing specific to install or do
|
# - run: echo # nothing specific to install or do
|
||||||
# - run: make -C examples/${{ matrix.example.path }} build
|
# - run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
mqtt_dashboard_examples_arm:
|
mqtt_dashboard_examples_arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -486,7 +400,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/${{ matrix.example.path }} build
|
- run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
# dual_examples:
|
# dual_examples:
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
@@ -500,8 +414,8 @@ jobs:
|
|||||||
# - uses: actions/checkout@v4
|
# - uses: actions/checkout@v4
|
||||||
# with: { fetch-depth: 2 }
|
# with: { fetch-depth: 2 }
|
||||||
# - run: echo # nothing specific to install or do
|
# - run: echo # nothing specific to install or do
|
||||||
# - run: make -C examples/${{ matrix.example.path }} device_dashboard
|
# - run: make -C tutorials/${{ matrix.example.path }} device_dashboard
|
||||||
# - run: make -C examples/${{ matrix.example.path }} mqtt_dashboard
|
# - run: make -C tutorials/${{ matrix.example.path }} mqtt_dashboard
|
||||||
|
|
||||||
cube_examples:
|
cube_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -517,17 +431,17 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/zephyr init REPO=zephyrprojectrtos/ci:v0.26.14 # "no space left on device" with newers
|
- run: make -C tutorials/zephyr init REPO=zephyrprojectrtos/ci:v0.26.14 # "no space left on device" with newers
|
||||||
- name: minify manifest
|
- name: minify manifest
|
||||||
uses: mikefarah/yq@master
|
uses: mikefarah/yq@master
|
||||||
with:
|
with:
|
||||||
cmd: yq -i eval '(.manifest.defaults, .manifest.remotes, .manifest.projects[] | select(.name == "cmsis" or .name == "hal_stm32" or .name == "mbedtls" or .name == "mcuboot" or .name == "picolibc" | del(.null) ), .manifest.self) as $i ireduce({};setpath($i | path; $i)) | del(.manifest.projects.[].null) | del(..|select(length==0))' examples/zephyr/zephyrproject/zephyr/west.yml
|
cmd: yq -i eval '(.manifest.defaults, .manifest.remotes, .manifest.projects[] | select(.name == "cmsis" or .name == "hal_stm32" or .name == "mbedtls" or .name == "mcuboot" or .name == "picolibc" | del(.null) ), .manifest.self) as $i ireduce({};setpath($i | path; $i)) | del(.manifest.projects.[].null) | del(..|select(length==0))' tutorials/zephyr/zephyrproject/zephyr/west.yml
|
||||||
- run: make -C examples/zephyr update
|
- run: make -C tutorials/zephyr update
|
||||||
- run: make -C examples/zephyr/device-dashboard build
|
- run: make -C tutorials/zephyr/device-dashboard build
|
||||||
- run: make -C examples/zephyr/http-client build
|
- run: make -C tutorials/zephyr/http-client build
|
||||||
- run: make -C examples/zephyr/http-server build
|
- run: make -C tutorials/zephyr/http-server build
|
||||||
- run: make -C examples/zephyr/mqtt-aws-client build
|
- run: make -C tutorials/zephyr/mqtt-aws-client build
|
||||||
- run: make -C examples/zephyr/websocket-server build
|
- run: make -C tutorials/zephyr/websocket-server build
|
||||||
|
|
||||||
test_f7:
|
test_f7:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -536,14 +450,14 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- name: Cube
|
- name: Cube
|
||||||
run: echo # nothing specific to install or do
|
run: echo # nothing specific to install or do
|
||||||
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
# - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
# - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
- run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
|
||||||
test_f4:
|
test_f4:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -552,13 +466,13 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- name: Cube
|
- name: Cube
|
||||||
run: echo # nothing specific to install or do
|
run: echo # nothing specific to install or do
|
||||||
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
# - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
# - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
- run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
|
||||||
test_h743:
|
test_h743:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -567,12 +481,12 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
# - name: Cube
|
# - name: Cube
|
||||||
# run: echo # nothing specific to install or do
|
# run: echo # nothing specific to install or do
|
||||||
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
# - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
# - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
|
||||||
test_h723:
|
test_h723:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -581,8 +495,8 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_h5:
|
test_h5:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -591,8 +505,8 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_rt1020:
|
test_rt1020:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -601,8 +515,8 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_rt1060:
|
test_rt1060:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -611,8 +525,8 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_rt1170:
|
test_rt1170:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -621,8 +535,8 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_ra6m4:
|
test_ra6m4:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -631,8 +545,8 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
# - run: make -C examples/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
# - run: make -C tutorials/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_tm4c:
|
test_tm4c:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -641,8 +555,8 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_same54:
|
test_same54:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -651,8 +565,8 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/microchip/same54-xpro/device-dashboard test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/http/device-dashboard/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/microchip/same54-xpro/mqtt-client test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/mqtt/mqtt-client/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_pico_w5500:
|
test_pico_w5500:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -661,5 +575,5 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: SDK
|
- name: SDK
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C tutorials/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
+99
-152
@@ -91,60 +91,6 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- run: make -C test riscv
|
- run: make -C test riscv
|
||||||
|
|
||||||
examples:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: make -C test examples_essential
|
|
||||||
- run: make -C test clean_examples_essential
|
|
||||||
examples_win:
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# - uses: egor-tensin/setup-mingw@v2
|
|
||||||
# with:
|
|
||||||
# platform: x64
|
|
||||||
- name: test they build
|
|
||||||
run: make -C test examples_win
|
|
||||||
shell: cmd
|
|
||||||
- name: test they clean
|
|
||||||
run: make -C test clean_examples_win
|
|
||||||
shell: cmd
|
|
||||||
examples_mac:
|
|
||||||
runs-on: macos-latest
|
|
||||||
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: make -C test examples_mac
|
|
||||||
- run: make -C test clean_examples_mac
|
|
||||||
|
|
||||||
refprojs:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: make -C test refprojs
|
|
||||||
- run: make -C test clean_refprojs
|
|
||||||
refprojs_win:
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# - uses: egor-tensin/setup-mingw@v2
|
|
||||||
# with:
|
|
||||||
# platform: x64
|
|
||||||
- name: test they build
|
|
||||||
run: make -C test refprojs_win
|
|
||||||
shell: cmd
|
|
||||||
- name: test they clean
|
|
||||||
run: make -C test clean_refprojs_win
|
|
||||||
shell: cmd
|
|
||||||
refprojs_mac:
|
|
||||||
runs-on: macos-latest
|
|
||||||
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: make -C test refprojs
|
|
||||||
- run: make -C test clean_refprojs
|
|
||||||
|
|
||||||
tutorials:
|
tutorials:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -192,7 +138,7 @@ jobs:
|
|||||||
# # nothing specific to install or do
|
# # nothing specific to install or do
|
||||||
# fi
|
# fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: make -C examples/${{ matrix.example.path }} build
|
# run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
wizard_examples_arm:
|
wizard_examples_arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -200,7 +146,9 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: infineon/infineon-xmc7200
|
- path: infineon/xmc47_relax-make-baremetal-builtin
|
||||||
|
- path: infineon/xmc_plt2go_4400-make-baremetal-builtin
|
||||||
|
- path: infineon/xmc72_evk-make-baremetal-builtin
|
||||||
- path: nxp/frdm-mcxn947-make-baremetal-builtin
|
- path: nxp/frdm-mcxn947-make-baremetal-builtin
|
||||||
- path: nxp/frdm-mcxn947-make-freertos-builtin
|
- path: nxp/frdm-mcxn947-make-freertos-builtin
|
||||||
- path: nxp/rt1020-evk-make-baremetal-builtin
|
- path: nxp/rt1020-evk-make-baremetal-builtin
|
||||||
@@ -236,7 +184,7 @@ jobs:
|
|||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/${{ matrix.example.path }} build
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
|
||||||
generic_examples:
|
generic_examples:
|
||||||
@@ -245,20 +193,20 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: esp32/uart-bridge
|
- path: http/uart-bridge/esp32
|
||||||
- path: esp8266/http-client-server
|
- path: http/http-client/esp8266/http-client-server
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
env:
|
env:
|
||||||
GO: 0
|
GO: 0
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: if ./test/match_changed_files.sh '^src|^examples/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
- run: if ./test/match_changed_files.sh '^src|^tutorials/http/uart-bridge|^tutorials/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
# nothing specific to install or do
|
# nothing specific to install or do
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/${{ matrix.example.path }} build
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
generic_examples_arm:
|
generic_examples_arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -266,7 +214,6 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos
|
|
||||||
- path: stm32/nucleo-g031-make-baremetal-builtin
|
- path: stm32/nucleo-g031-make-baremetal-builtin
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
env:
|
env:
|
||||||
@@ -274,11 +221,11 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: if ./test/match_changed_files.sh '^src|^examples/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
- run: if ./test/match_changed_files.sh '^src|^tutorials/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/${{ matrix.example.path }} build
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
device_dashboard_examples:
|
device_dashboard_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -286,7 +233,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: esp32/device-dashboard
|
- path: esp32
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
env:
|
env:
|
||||||
GO: 0
|
GO: 0
|
||||||
@@ -294,12 +241,12 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: |
|
- run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard'; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
# nothing specific to install or do
|
# nothing specific to install or do
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/${{ matrix.example.path }} build
|
run: make -C tutorials/http/device-dashboard/${{ matrix.example.path }} build
|
||||||
|
|
||||||
device_dashboard_examples_arm:
|
device_dashboard_examples_arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -307,7 +254,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: microchip/same54-xpro/device-dashboard
|
- path: http/device-dashboard/microchip/same54-xpro
|
||||||
- path: nxp/rt1020-evk-make-freertos-builtin
|
- path: nxp/rt1020-evk-make-freertos-builtin
|
||||||
- path: nxp/rt1060-evk-make-freertos-builtin
|
- path: nxp/rt1060-evk-make-freertos-builtin
|
||||||
- path: nxp/rt1170-evk-make-freertos-builtin
|
- path: nxp/rt1170-evk-make-freertos-builtin
|
||||||
@@ -324,12 +271,12 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: |
|
- run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|^tutorials/${{ matrix.example.path }}'; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/${{ matrix.example.path }} build
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
# mqtt_dashboard_examples:
|
# mqtt_dashboard_examples:
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
@@ -345,12 +292,12 @@ jobs:
|
|||||||
# - uses: actions/checkout@v4
|
# - uses: actions/checkout@v4
|
||||||
# with: { fetch-depth: 2 }
|
# with: { fetch-depth: 2 }
|
||||||
# - run: |
|
# - run: |
|
||||||
# if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
# if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-dashboard/device|^tutorials/${{ matrix.example.path }}'; then
|
||||||
# echo GO=1 >> $GITHUB_ENV
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
# # nothing specific to install or do
|
# # nothing specific to install or do
|
||||||
# fi
|
# fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: make -C examples/${{ matrix.example.path }} build
|
# run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
mqtt_dashboard_examples_arm:
|
mqtt_dashboard_examples_arm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -366,12 +313,12 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: |
|
- run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-dashboard/device|^tutorials/${{ matrix.example.path }}'; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/${{ matrix.example.path }} build
|
run: make -C tutorials/${{ matrix.example.path }} build
|
||||||
|
|
||||||
cube_examples:
|
cube_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -381,7 +328,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: |
|
- run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-*-cube-*'; then
|
if ./test/match_changed_files.sh '^src|tutorials/stm32/nucleo-*-cube-*'; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo pip install yq
|
sudo pip install yq
|
||||||
fi
|
fi
|
||||||
@@ -397,7 +344,7 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32|examples/nxp|examples/ti|examples/microchip/same" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f7.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
@@ -405,40 +352,40 @@ jobs:
|
|||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true # continue so next test has a chance to re-flash and exit from collisions and flash failures
|
continue-on-error: true # continue so next test has a chance to re-flash and exit from collisions and flash failures
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f746zg-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f746zg-make-baremetal-builtin'; then
|
||||||
make -C examples/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-make-freertos-builtin'; then
|
||||||
make -C examples/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-make-freertos-tcp'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-make-freertos-tcp'; then
|
||||||
make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- name: Cube
|
- name: Cube
|
||||||
run: |
|
run: |
|
||||||
echo GO=0 >> $GITHUB_ENV
|
echo GO=0 >> $GITHUB_ENV
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f7.*-cube-'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f7.*-cube-'; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
# nothing specific to install or do
|
# nothing specific to install or do
|
||||||
fi
|
fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: |
|
# run: |
|
||||||
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-baremetal-builtin'; then
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-cube-baremetal-builtin'; then
|
||||||
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
# fi
|
# fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: |
|
# run: |
|
||||||
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-freertos-builtin'; then
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-cube-freertos-builtin'; then
|
||||||
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
# fi
|
# fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-freertos-lwip'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-cube-freertos-lwip'; then
|
||||||
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -451,42 +398,42 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-f4.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f4.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f429zi-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f429zi-make-baremetal-builtin'; then
|
||||||
make -C examples/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-make-freertos-builtin'; then
|
||||||
make -C examples/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- name: Cube
|
- name: Cube
|
||||||
run: |
|
run: |
|
||||||
echo GO=0 >> $GITHUB_ENV
|
echo GO=0 >> $GITHUB_ENV
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f4.*-cube-'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f4.*-cube-'; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
# nothing specific to install or do
|
# nothing specific to install or do
|
||||||
fi
|
fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: |
|
# run: |
|
||||||
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-baremetal-builtin'; then
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-cube-baremetal-builtin'; then
|
||||||
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
# fi
|
# fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: |
|
# run: |
|
||||||
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-freertos-builtin'; then
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-cube-freertos-builtin'; then
|
||||||
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
# fi
|
# fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-freertos-lwip'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-cube-freertos-lwip'; then
|
||||||
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_h743:
|
test_h743:
|
||||||
@@ -498,37 +445,37 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h74.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h74.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h743zi-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h743zi-make-baremetal-builtin'; then
|
||||||
make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h743zi-make-freertos-builtin'; then
|
||||||
make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
# - name: Cube
|
# - name: Cube
|
||||||
# run: |
|
# run: |
|
||||||
# echo GO=0 >> $GITHUB_ENV
|
# echo GO=0 >> $GITHUB_ENV
|
||||||
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-h74.*-cube-'; then
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h74.*-cube-'; then
|
||||||
# echo GO=1 >> $GITHUB_ENV
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
# # nothing specific to install or do
|
# # nothing specific to install or do
|
||||||
# fi
|
# fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: |
|
# run: |
|
||||||
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-cube-baremetal-builtin'; then
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h743zi-cube-baremetal-builtin'; then
|
||||||
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
# fi
|
# fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: |
|
# run: |
|
||||||
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-cube-freertos-builtin'; then
|
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h743zi-cube-freertos-builtin'; then
|
||||||
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
# fi
|
# fi
|
||||||
|
|
||||||
test_h723:
|
test_h723:
|
||||||
@@ -540,20 +487,20 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h72.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h72.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h723zg-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h723zg-make-baremetal-builtin'; then
|
||||||
make -C examples/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h723zg-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h723zg-make-freertos-builtin'; then
|
||||||
make -C examples/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_h5:
|
test_h5:
|
||||||
@@ -565,20 +512,20 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h5.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h5.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h563zi-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h563zi-make-baremetal-builtin'; then
|
||||||
make -C examples/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h563zi-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h563zi-make-freertos-builtin'; then
|
||||||
make -C examples/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_rt1020:
|
test_rt1020:
|
||||||
@@ -590,20 +537,20 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/nxp/rt1020.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1020.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1020-evk-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1020-evk-make-baremetal-builtin'; then
|
||||||
make -C examples/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/nxp/rt1020-evk-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/nxp/rt1020-evk-make-freertos-builtin'; then
|
||||||
make -C examples/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_rt1060:
|
test_rt1060:
|
||||||
@@ -615,20 +562,20 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/nxp/rt1060.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1060.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1060-evk-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1060-evk-make-baremetal-builtin'; then
|
||||||
make -C examples/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/nxp/rt1060-evk-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/nxp/rt1060-evk-make-freertos-builtin'; then
|
||||||
make -C examples/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_rt1170:
|
test_rt1170:
|
||||||
@@ -640,20 +587,20 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/nxp/rt1170.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1170.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1170-evk-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1170-evk-make-baremetal-builtin'; then
|
||||||
make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/nxp/rt1170-evk-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/nxp/rt1170-evk-make-freertos-builtin'; then
|
||||||
make -C examples/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_ra6m4:
|
test_ra6m4:
|
||||||
@@ -665,20 +612,20 @@ jobs:
|
|||||||
with: { fetch-depth: 3 }
|
with: { fetch-depth: 3 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/renesas/ek-ra6m4.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/renesas/ek-ra6m4.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/renesas/ek-ra6m4-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/renesas/ek-ra6m4-make-baremetal-builtin'; then
|
||||||
make -C examples/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
# run: |
|
# run: |
|
||||||
# if ./test/match_changed_files.sh 'examples/renesas/ek-ra6m4-make-freertos-builtin'; then
|
# if ./test/match_changed_files.sh 'tutorials/renesas/ek-ra6m4-make-freertos-builtin'; then
|
||||||
# make -C examples/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
# make -C tutorials/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
# fi
|
# fi
|
||||||
|
|
||||||
test_tm4c:
|
test_tm4c:
|
||||||
@@ -690,19 +637,19 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/ti/ek-tm4c.*-make-" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/ti/ek-tm4c.*-make-" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/ti/ek-tm4c1294xl-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin'; then
|
||||||
make -C examples/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/ti/ek-tm4c1294xl-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'tutorials/ti/ek-tm4c1294xl-make-freertos-builtin'; then
|
||||||
make -C examples/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_same54:
|
test_same54:
|
||||||
@@ -714,19 +661,19 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/microchip/same54-xpro" ; then
|
if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/mqtt/mqtt-client" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/microchip/same54-xpro/device-dashboard'; then
|
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard'; then
|
||||||
make -C examples/microchip/same54-xpro/device-dashboard test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/http/device-dashboard/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/microchip/same54-xpro/mqtt-client'; then
|
if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-client'; then
|
||||||
make -C examples/microchip/same54-xpro/mqtt-client test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C tutorials/mqtt/mqtt-client/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_pico_w5500:
|
test_pico_w5500:
|
||||||
@@ -743,5 +690,5 @@ jobs:
|
|||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
run: make -C tutorials/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
@@ -171,6 +171,14 @@ We take security seriously:
|
|||||||
of which we get notified and in case of any issue, act similar to (3).
|
of which we get notified and in case of any issue, act similar to (3).
|
||||||
|
|
||||||
|
|
||||||
|
## Articles
|
||||||
|
|
||||||
|
Technical guides and deep dives into embedded web servers, WebUI integration and embedded networking technologies:
|
||||||
|
- [Embedded Web Server: A Comprehensive Guide for Modern Connected Devices](https://mongoose.ws/articles/embedded-web-server-a-comprehensive-guide-for-modern-connected-devices/)
|
||||||
|
- [Building Embedded Web Device Dashboards](https://mongoose.ws/articles/building-embedded-web-device-dashboard/)
|
||||||
|
- [ESP32 Device Dashboard: A Step-by-Step Guide for Developers](https://mongoose.ws/articles/esp32-device-dashboard/)
|
||||||
|
|
||||||
|
|
||||||
## Contributions
|
## Contributions
|
||||||
|
|
||||||
Contributions are welcome! Please follow the guidelines below:
|
Contributions are welcome! Please follow the guidelines below:
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
# Mongoose Network Library Examples
|
|
||||||
|
|
||||||
In order to build and run any of the existing examples, please follow:
|
|
||||||
https://mongoose.ws/documentation/#how-to-build-and-run-examples
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Rules for creating a new example:
|
|
||||||
|
|
||||||
- Makefile golden reference for desktop/server example: [http-server](http-server)
|
|
||||||
- Makefile golden reference for the embedded example:
|
|
||||||
[stm32/nucleo-f746zg-baremetal](stm32/nucleo-f746zg-baremetal)
|
|
||||||
- An example must build on Windows, Mac and Ubuntu Linux systems
|
|
||||||
- Assume that user installed tools according to https://mongoose.ws/tutorials/tools/
|
|
||||||
- Makefile must not include any other make files
|
|
||||||
- Use `CFLAGS` for system-specific compilation options
|
|
||||||
- Use `CFLAGS_MONGOOSE` for mongoose-specific compilation options
|
|
||||||
- Use `$(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA)` to compile
|
|
||||||
- If external repository is required, download it on demand using git
|
|
||||||
shallow clone. See embedded example golden reference
|
|
||||||
- Keep Makefile as short as possible, but verbose to understand it easily
|
|
||||||
- Symlink files when required, like `mongoose.c`, `ca.pem`, etc. Make no copies
|
|
||||||
- Example's README.md should contain only the title and the link to mongoose.ws
|
|
||||||
tutorial page
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
|
|
||||||
all:
|
|
||||||
example:
|
|
||||||
true
|
|
||||||
|
|
||||||
arduino: ENV = -v $(CWD):/root
|
|
||||||
arduino:
|
|
||||||
curl -sL http://downloads.arduino.cc/arduino-1.8.19-linux64.tar.xz | unxz | tar -xf -
|
|
||||||
mv arduino-* $@
|
|
||||||
|
|
||||||
arduino-xiao-board:
|
|
||||||
./arduino/arduino --pref "boardsmanager.additional.urls=https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json" --save-prefs
|
|
||||||
./arduino/arduino --pref "compiler.warning_level=all" --save-prefs
|
|
||||||
./arduino/arduino --install-boards Seeeduino:samd
|
|
||||||
|
|
||||||
arduino-xiao: arduino arduino-xiao-board
|
|
||||||
cd sim800-mqtt && ../arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 sim800-mqtt.ino
|
|
||||||
cd w5500-http && ../arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-http.ino
|
|
||||||
cd w5500-mqtt && ../arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-mqtt.ino
|
|
||||||
|
|
||||||
arduino-nano: arduino
|
|
||||||
cd w5500-http && ../arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano w5500-http.ino
|
|
||||||
cd w5500-mqtt && ../arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano w5500-mqtt.ino
|
|
||||||
|
|
||||||
arduino-esp32: arduino
|
|
||||||
# cd esp32-http && ../arduino/arduino --verbose --verify --board esp32-http.ino
|
|
||||||
# esp32-mqtt
|
|
||||||
|
|
||||||
arduino-teensy41: arduino
|
|
||||||
# cd teensy41-http && ../arduino/arduino --verbose --verify --board teensy41-http.ino
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf arduino
|
|
||||||
|
|
||||||
cleanall: clean #otherwise some parts of xiao-board installation will fail as already installed
|
|
||||||
rm -rf ~/.arduino15 ~/.oracle_jre_usage
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.h
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1 +0,0 @@
|
|||||||
/*! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter var,Helvetica,sans-serif;font-feature-settings:"cv11","ss01";font-variation-settings:"opsz" 32}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.bottom-0{bottom:0}.left-0{left:0}.right-auto{right:auto}.top-0{top:0}.isolate{isolation:isolate}.z-10{z-index:10}.z-\[48\]{z-index:48}.z-\[60\]{z-index:60}.col-span-2{grid-column:span 2/span 2}.m-4{margin:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-5{margin-top:1.25rem;margin-bottom:1.25rem}.mb-1{margin-bottom:.25rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-3{margin-top:.75rem}.mt-5{margin-top:1.25rem}.mt-7{margin-top:1.75rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-0{width:0}.w-11{width:2.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-72{width:18rem}.w-96{width:24rem}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.grow-0{flex-grow:0}.basis-\[30px\]{flex-basis:30px}.border-separate{border-collapse:initial}.border-spacing-0Line truncated
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../micropython/mongoose/micropython.cmake
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../micropython/mongoose/micropython.mk
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../micropython/mongoose/module.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../uart-bridge/net.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../uart-bridge/packed_fs.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.h
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
NAME ?= $(notdir $(CURDIR))
|
|
||||||
|
|
||||||
build:
|
|
||||||
git clone --depth 1 https://github.com/mongoose-examples/$(NAME)
|
|
||||||
cp ./../../../mongoose.[ch] $(NAME)
|
|
||||||
make -C $(NAME) build
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(NAME)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../mongoose.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../mongoose.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../device-dashboard/certs
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../mongoose.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../mongoose.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../device-dashboard/net.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../device-dashboard/net.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../device-dashboard/packed_fs.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mqtt-dashboard/device/net.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mqtt-dashboard/device/net.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
pico-sdk
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../mongoose.h
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
content: ['./web_root/*.{html,js}'],
|
|
||||||
xplugins: [ 'tailwindcss', 'xautoprefixer' ],
|
|
||||||
corePlugins: {outline: false},
|
|
||||||
theme: {
|
|
||||||
extend: {},
|
|
||||||
fontFamily: {
|
|
||||||
sans:
|
|
||||||
[
|
|
||||||
"Inter var, Helvetica, sans-serif", {
|
|
||||||
fontFeatureSettings: '"cv11", "ss01"',
|
|
||||||
fontVariationSettings: '"opsz" 32',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../device-dashboard/web_root/bundle.js
|
|
||||||
+2634
-385
File diff suppressed because it is too large.
Load diff
+305
-116
@@ -20,7 +20,7 @@
|
|||||||
#ifndef MONGOOSE_H
|
#ifndef MONGOOSE_H
|
||||||
#define MONGOOSE_H
|
#define MONGOOSE_H
|
||||||
|
|
||||||
#define MG_VERSION "7.17"
|
#define MG_VERSION "7.18"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -424,6 +424,18 @@ static inline int mg_mkdir(const char *path, mode_t mode) {
|
|||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_WIN32
|
#if MG_ARCH == MG_ARCH_WIN32
|
||||||
|
|
||||||
|
// Avoid name clashing; (macro expansion producing 'defined' has undefined
|
||||||
|
// behaviour). See config.h for user options
|
||||||
|
#ifndef MG_ENABLE_WINSOCK
|
||||||
|
#if (!defined(MG_ENABLE_TCPIP) || !MG_ENABLE_TCPIP) && \
|
||||||
|
(!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) && \
|
||||||
|
(!defined(MG_ENABLE_FREERTOS_TCP) || !MG_ENABLE_FREERTOS_TCP)
|
||||||
|
#define MG_ENABLE_WINSOCK 1
|
||||||
|
#else
|
||||||
|
#define MG_ENABLE_WINSOCK 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _CRT_RAND_S
|
#ifndef _CRT_RAND_S
|
||||||
#define _CRT_RAND_S
|
#define _CRT_RAND_S
|
||||||
#endif
|
#endif
|
||||||
@@ -469,12 +481,14 @@ typedef enum { false = 0, true = 1 } bool;
|
|||||||
#else
|
#else
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#if MG_ENABLE_WINSOCK
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <winerror.h>
|
#include <winerror.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h> // fix missing macros and types
|
||||||
|
|
||||||
// For mg_random()
|
// For mg_random()
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1700
|
#if defined(_MSC_VER) && _MSC_VER < 1700
|
||||||
@@ -485,6 +499,20 @@ typedef enum { false = 0, true = 1 } bool;
|
|||||||
#pragma comment(lib, "advapi32.lib")
|
#pragma comment(lib, "advapi32.lib")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||||
|
#ifndef IPPROTO_IP
|
||||||
|
#define IPPROTO_IP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef IP_ADD_MEMBERSHIP
|
||||||
|
struct ip_mreq {
|
||||||
|
struct in_addr imr_multiaddr;
|
||||||
|
struct in_addr imr_interface;
|
||||||
|
};
|
||||||
|
#define IP_ADD_MEMBERSHIP 12
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// Protect from calls like std::snprintf in app code
|
// Protect from calls like std::snprintf in app code
|
||||||
// See https://github.com/cesanta/mongoose/issues/1047
|
// See https://github.com/cesanta/mongoose/issues/1047
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
@@ -495,25 +523,30 @@ typedef enum { false = 0, true = 1 } bool;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MG_INVALID_SOCKET INVALID_SOCKET
|
|
||||||
#define MG_SOCKET_TYPE SOCKET
|
|
||||||
typedef unsigned long nfds_t;
|
typedef unsigned long nfds_t;
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
#if MG_ENABLE_WINSOCK
|
||||||
#pragma comment(lib, "ws2_32.lib")
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
|
#endif
|
||||||
#ifndef alloca
|
#ifndef alloca
|
||||||
#define alloca(a) _alloca(a)
|
#define alloca(a) _alloca(a)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#define poll(a, b, c) WSAPoll((a), (b), (c))
|
|
||||||
#define closesocket(x) closesocket(x)
|
|
||||||
|
|
||||||
typedef int socklen_t;
|
|
||||||
#define MG_DIRSEP '\\'
|
#define MG_DIRSEP '\\'
|
||||||
|
|
||||||
#ifndef MG_PATH_MAX
|
#ifndef MG_PATH_MAX
|
||||||
#define MG_PATH_MAX FILENAME_MAX
|
#define MG_PATH_MAX FILENAME_MAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MG_ENABLE_WINSOCK
|
||||||
|
|
||||||
|
#define MG_INVALID_SOCKET INVALID_SOCKET
|
||||||
|
#define MG_SOCKET_TYPE SOCKET
|
||||||
|
#define poll(a, b, c) WSAPoll((a), (b), (c))
|
||||||
|
#define closesocket(x) closesocket(x)
|
||||||
|
typedef int socklen_t;
|
||||||
|
|
||||||
#ifndef SO_EXCLUSIVEADDRUSE
|
#ifndef SO_EXCLUSIVEADDRUSE
|
||||||
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
|
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
|
||||||
#endif
|
#endif
|
||||||
@@ -528,13 +561,15 @@ typedef int socklen_t;
|
|||||||
#define MG_SOCK_RESET(errcode) \
|
#define MG_SOCK_RESET(errcode) \
|
||||||
(((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
|
(((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
|
||||||
|
|
||||||
|
#endif // MG_ENABLE_WINSOCK
|
||||||
|
|
||||||
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
||||||
#define sleep(x) Sleep((x) * 1000)
|
#define sleep(x) Sleep((x) *1000)
|
||||||
#define mkdir(a, b) _mkdir(a)
|
#define mkdir(a, b) _mkdir(a)
|
||||||
#define timegm(x) _mkgmtime(x)
|
#define timegm(x) _mkgmtime(x)
|
||||||
|
|
||||||
#ifndef S_ISDIR
|
#ifndef S_ISDIR
|
||||||
#define S_ISDIR(x) (((x) & _S_IFMT) == _S_IFDIR)
|
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_DIRLIST
|
#ifndef MG_ENABLE_DIRLIST
|
||||||
@@ -774,7 +809,8 @@ struct timeval {
|
|||||||
#define MG_ENABLE_MD5 1
|
#define MG_ENABLE_MD5 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
|
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with other external IP stack not
|
||||||
|
// mentioned in arch_win32.h
|
||||||
#ifndef MG_ENABLE_WINSOCK
|
#ifndef MG_ENABLE_WINSOCK
|
||||||
#define MG_ENABLE_WINSOCK 1
|
#define MG_ENABLE_WINSOCK 1
|
||||||
#endif
|
#endif
|
||||||
@@ -892,8 +928,8 @@ struct timeval {
|
|||||||
#define MG_SET_MAC_ADDRESS(mac)
|
#define MG_SET_MAC_ADDRESS(mac)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_SET_WIFI_CREDS
|
#ifndef MG_SET_WIFI_CONFIG
|
||||||
#define MG_SET_WIFI_CREDS(ssid, pass)
|
#define MG_SET_WIFI_CONFIG(data)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
|
#ifndef MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
|
||||||
@@ -1020,16 +1056,17 @@ void mg_log_set_fn(mg_pfn_t fn, void *param);
|
|||||||
|
|
||||||
|
|
||||||
struct mg_timer {
|
struct mg_timer {
|
||||||
unsigned long id; // Timer ID
|
uint64_t period_ms; // Timer period in milliseconds
|
||||||
uint64_t period_ms; // Timer period in milliseconds
|
uint64_t expire; // Expiration timestamp in milliseconds
|
||||||
uint64_t expire; // Expiration timestamp in milliseconds
|
unsigned flags; // Possible flags values below
|
||||||
unsigned flags; // Possible flags values below
|
#define MG_TIMER_ONCE 0 // Call function once
|
||||||
#define MG_TIMER_ONCE 0 // Call function once
|
#define MG_TIMER_REPEAT 1 // Call function periodically
|
||||||
#define MG_TIMER_REPEAT 1 // Call function periodically
|
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
||||||
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
#define MG_TIMER_CALLED 4 // Timer function was called at least once
|
||||||
void (*fn)(void *); // Function to call
|
#define MG_TIMER_AUTODELETE 8 // free() timer when done
|
||||||
void *arg; // Function argument
|
void (*fn)(void *); // Function to call
|
||||||
struct mg_timer *next; // Linkage
|
void *arg; // Function argument
|
||||||
|
struct mg_timer *next; // Linkage
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
||||||
@@ -1068,7 +1105,7 @@ struct mg_fs {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
|
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
|
||||||
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
|
extern struct mg_fs mg_fs_packed; // see tutorials/core/embedded-filesystem
|
||||||
extern struct mg_fs mg_fs_fat; // FAT FS
|
extern struct mg_fs mg_fs_fat; // FAT FS
|
||||||
|
|
||||||
// File descriptor
|
// File descriptor
|
||||||
@@ -1104,18 +1141,14 @@ struct mg_str mg_unpacked(const char *path); // Packed file as mg_str
|
|||||||
void mg_bzero(volatile unsigned char *buf, size_t len);
|
void mg_bzero(volatile unsigned char *buf, size_t len);
|
||||||
bool mg_random(void *buf, size_t len);
|
bool mg_random(void *buf, size_t len);
|
||||||
char *mg_random_str(char *buf, size_t len);
|
char *mg_random_str(char *buf, size_t len);
|
||||||
uint16_t mg_ntohs(uint16_t net);
|
|
||||||
uint32_t mg_ntohl(uint32_t net);
|
|
||||||
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
|
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
|
||||||
uint64_t mg_millis(void); // Return milliseconds since boot
|
uint64_t mg_millis(void); // Return milliseconds since boot
|
||||||
bool mg_path_is_sane(const struct mg_str path);
|
bool mg_path_is_sane(const struct mg_str path);
|
||||||
|
void mg_delayms(unsigned int ms);
|
||||||
|
|
||||||
#define mg_htons(x) mg_ntohs(x)
|
#define MG_U32(a, b, c, d) \
|
||||||
#define mg_htonl(x) mg_ntohl(x)
|
(((uint32_t) ((a) &255) << 24) | ((uint32_t) ((b) &255) << 16) | \
|
||||||
|
((uint32_t) ((c) &255) << 8) | (uint32_t) ((d) &255))
|
||||||
#define MG_U32(a, b, c, d) \
|
|
||||||
(((uint32_t) ((a) & 255) << 24) | ((uint32_t) ((b) & 255) << 16) | \
|
|
||||||
((uint32_t) ((c) & 255) << 8) | (uint32_t) ((d) & 255))
|
|
||||||
|
|
||||||
#define MG_IPV4(a, b, c, d) mg_htonl(MG_U32(a, b, c, d))
|
#define MG_IPV4(a, b, c, d) mg_htonl(MG_U32(a, b, c, d))
|
||||||
|
|
||||||
@@ -1124,9 +1157,15 @@ bool mg_path_is_sane(const struct mg_str path);
|
|||||||
#define MG_IPADDR_PARTS(ADDR) \
|
#define MG_IPADDR_PARTS(ADDR) \
|
||||||
MG_U8P(ADDR)[0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3]
|
MG_U8P(ADDR)[0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3]
|
||||||
|
|
||||||
#define MG_LOAD_BE16(p) ((uint16_t) ((MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
|
#define MG_LOAD_BE16(p) \
|
||||||
#define MG_LOAD_BE24(p) \
|
((uint16_t) (((uint16_t) MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
|
||||||
((uint32_t) ((MG_U8P(p)[0] << 16U) | (MG_U8P(p)[1] << 8U) | MG_U8P(p)[2]))
|
#define MG_LOAD_BE24(p) \
|
||||||
|
((uint32_t) (((uint32_t) MG_U8P(p)[0] << 16U) | \
|
||||||
|
((uint32_t) MG_U8P(p)[1] << 8U) | MG_U8P(p)[2]))
|
||||||
|
#define MG_LOAD_BE32(p) \
|
||||||
|
((uint32_t) (((uint32_t) MG_U8P(p)[0] << 24U) | \
|
||||||
|
((uint32_t) MG_U8P(p)[1] << 16U) | \
|
||||||
|
((uint32_t) MG_U8P(p)[2] << 8U) | MG_U8P(p)[3]))
|
||||||
#define MG_STORE_BE16(p, n) \
|
#define MG_STORE_BE16(p, n) \
|
||||||
do { \
|
do { \
|
||||||
MG_U8P(p)[0] = ((n) >> 8U) & 255; \
|
MG_U8P(p)[0] = ((n) >> 8U) & 255; \
|
||||||
@@ -1138,6 +1177,18 @@ bool mg_path_is_sane(const struct mg_str path);
|
|||||||
MG_U8P(p)[1] = ((n) >> 8U) & 255; \
|
MG_U8P(p)[1] = ((n) >> 8U) & 255; \
|
||||||
MG_U8P(p)[2] = (n) &255; \
|
MG_U8P(p)[2] = (n) &255; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#define MG_STORE_BE32(p, n) \
|
||||||
|
do { \
|
||||||
|
MG_U8P(p)[0] = ((n) >> 24U) & 255; \
|
||||||
|
MG_U8P(p)[1] = ((n) >> 16U) & 255; \
|
||||||
|
MG_U8P(p)[2] = ((n) >> 8U) & 255; \
|
||||||
|
MG_U8P(p)[3] = (n) &255; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
uint16_t mg_ntohs(uint16_t net);
|
||||||
|
uint32_t mg_ntohl(uint32_t net);
|
||||||
|
#define mg_htons(x) mg_ntohs(x)
|
||||||
|
#define mg_htonl(x) mg_ntohl(x)
|
||||||
|
|
||||||
#define MG_REG(x) ((volatile uint32_t *) (x))[0]
|
#define MG_REG(x) ((volatile uint32_t *) (x))[0]
|
||||||
#define MG_BIT(x) (((uint32_t) 1U) << (x))
|
#define MG_BIT(x) (((uint32_t) 1U) << (x))
|
||||||
@@ -2195,7 +2246,6 @@ struct mg_mgr {
|
|||||||
int dnstimeout; // DNS resolve timeout in milliseconds
|
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||||
bool use_dns6; // Use DNS6 server by default, see #1532
|
bool use_dns6; // Use DNS6 server by default, see #1532
|
||||||
unsigned long nextid; // Next connection ID
|
unsigned long nextid; // Next connection ID
|
||||||
unsigned long timerid; // Next timer ID
|
|
||||||
void *userdata; // Arbitrary user data pointer
|
void *userdata; // Arbitrary user data pointer
|
||||||
void *tls_ctx; // TLS context shared by all TLS sessions
|
void *tls_ctx; // TLS context shared by all TLS sessions
|
||||||
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
||||||
@@ -2211,40 +2261,41 @@ struct mg_mgr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mg_connection {
|
struct mg_connection {
|
||||||
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
||||||
struct mg_mgr *mgr; // Our container
|
struct mg_mgr *mgr; // Our container
|
||||||
struct mg_addr loc; // Local address
|
struct mg_addr loc; // Local address
|
||||||
struct mg_addr rem; // Remote address
|
struct mg_addr rem; // Remote address
|
||||||
void *fd; // Connected socket, or LWIP data
|
void *fd; // Connected socket, or LWIP data
|
||||||
unsigned long id; // Auto-incrementing unique connection ID
|
unsigned long id; // Auto-incrementing unique connection ID
|
||||||
struct mg_iobuf recv; // Incoming data
|
struct mg_iobuf recv; // Incoming data
|
||||||
struct mg_iobuf send; // Outgoing data
|
struct mg_iobuf send; // Outgoing data
|
||||||
struct mg_iobuf prof; // Profile data enabled by MG_ENABLE_PROFILE
|
struct mg_iobuf prof; // Profile data enabled by MG_ENABLE_PROFILE
|
||||||
struct mg_iobuf rtls; // TLS only. Incoming encrypted data
|
struct mg_iobuf rtls; // TLS only. Incoming encrypted data
|
||||||
mg_event_handler_t fn; // User-specified event handler function
|
mg_event_handler_t fn; // User-specified event handler function
|
||||||
void *fn_data; // User-specified function parameter
|
void *fn_data; // User-specified function parameter
|
||||||
mg_event_handler_t pfn; // Protocol-specific handler function
|
mg_event_handler_t pfn; // Protocol-specific handler function
|
||||||
void *pfn_data; // Protocol-specific function parameter
|
void *pfn_data; // Protocol-specific function parameter
|
||||||
char data[MG_DATA_SIZE]; // Arbitrary connection data
|
char data[MG_DATA_SIZE]; // Arbitrary connection data
|
||||||
void *tls; // TLS specific data
|
void *tls; // TLS specific data
|
||||||
unsigned is_listening : 1; // Listening connection
|
unsigned is_listening : 1; // Listening connection
|
||||||
unsigned is_client : 1; // Outbound (client) connection
|
unsigned is_client : 1; // Outbound (client) connection
|
||||||
unsigned is_accepted : 1; // Accepted (server) connection
|
unsigned is_accepted : 1; // Accepted (server) connection
|
||||||
unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
|
unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
|
||||||
unsigned is_arplooking : 1; // Non-blocking ARP resolution is in progress
|
unsigned is_arplooking : 1; // Non-blocking ARP resolution is in progress
|
||||||
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
||||||
unsigned is_tls : 1; // TLS-enabled connection
|
unsigned is_tls : 1; // TLS-enabled connection
|
||||||
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
||||||
unsigned is_udp : 1; // UDP connection
|
unsigned is_udp : 1; // UDP connection
|
||||||
unsigned is_websocket : 1; // WebSocket connection
|
unsigned is_websocket : 1; // WebSocket connection
|
||||||
unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator
|
unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator
|
||||||
unsigned is_hexdumping : 1; // Hexdump in/out traffic
|
unsigned is_hexdumping : 1; // Hexdump in/out traffic
|
||||||
unsigned is_draining : 1; // Send remaining data, then close and free
|
unsigned is_draining : 1; // Send remaining data, then close and free
|
||||||
unsigned is_closing : 1; // Close and free the connection immediately
|
unsigned is_closing : 1; // Close and free the connection immediately
|
||||||
unsigned is_full : 1; // Stop reads, until cleared
|
unsigned is_full : 1; // Stop reads, until cleared
|
||||||
unsigned is_resp : 1; // Response is still being generated
|
unsigned is_tls_throttled : 1; // Last TLS write: MG_SOCK_PENDING() was true
|
||||||
unsigned is_readable : 1; // Connection is ready to read
|
unsigned is_resp : 1; // Response is still being generated
|
||||||
unsigned is_writable : 1; // Connection is ready to write
|
unsigned is_readable : 1; // Connection is ready to read
|
||||||
|
unsigned is_writable : 1; // Connection is ready to write
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_mgr_poll(struct mg_mgr *, int ms);
|
void mg_mgr_poll(struct mg_mgr *, int ms);
|
||||||
@@ -2412,6 +2463,9 @@ struct mg_tls {
|
|||||||
#ifdef MBEDTLS_SSL_SESSION_TICKETS
|
#ifdef MBEDTLS_SSL_SESSION_TICKETS
|
||||||
mbedtls_ssl_ticket_context ticket; // Session tickets context
|
mbedtls_ssl_ticket_context ticket; // Session tickets context
|
||||||
#endif
|
#endif
|
||||||
|
// https://github.com/Mbed-TLS/mbedtls/blob/3b3c652d/include/mbedtls/ssl.h#L5071C18-L5076C29
|
||||||
|
unsigned char *throttled_buf; // see #3074
|
||||||
|
size_t throttled_len;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2616,6 +2670,8 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
|
|||||||
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
||||||
bool is_question, struct mg_dns_rr *);
|
bool is_question, struct mg_dns_rr *);
|
||||||
|
|
||||||
|
struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, char *name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2687,10 +2743,12 @@ void mg_rpc_list(struct mg_rpc_req *r);
|
|||||||
#define MG_OTA_CH32V307 100 // WCH CH32V307
|
#define MG_OTA_CH32V307 100 // WCH CH32V307
|
||||||
#define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
|
#define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
|
||||||
#define MG_OTA_RT1020 300 // IMXRT1020
|
#define MG_OTA_RT1020 300 // IMXRT1020
|
||||||
#define MG_OTA_RT1060 301 // IMXRT1060
|
#define MG_OTA_RT1050 301 // IMXRT1050
|
||||||
#define MG_OTA_RT1064 302 // IMXRT1064
|
#define MG_OTA_RT1060 302 // IMXRT1060
|
||||||
#define MG_OTA_RT1170 303 // IMXRT1170
|
#define MG_OTA_RT1064 303 // IMXRT1064
|
||||||
|
#define MG_OTA_RT1170 304 // IMXRT1170
|
||||||
#define MG_OTA_MCXN 310 // MCXN947
|
#define MG_OTA_MCXN 310 // MCXN947
|
||||||
|
#define MG_OTA_FRDM 320 // FRDM-RW612
|
||||||
#define MG_OTA_FLASH 900 // OTA via an internal flash
|
#define MG_OTA_FLASH 900 // OTA via an internal flash
|
||||||
#define MG_OTA_ESP32 910 // ESP32 OTA implementation
|
#define MG_OTA_ESP32 910 // ESP32 OTA implementation
|
||||||
#define MG_OTA_PICOSDK 920 // RP2040/2350 using Pico-SDK hardware_flash
|
#define MG_OTA_PICOSDK 920 // RP2040/2350 using Pico-SDK hardware_flash
|
||||||
@@ -2737,6 +2795,37 @@ bool mg_ota_flash_end(struct mg_flash *flash);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct mg_wifi_scan_bss_data {
|
||||||
|
struct mg_str SSID;
|
||||||
|
char *BSSID;
|
||||||
|
int16_t RSSI;
|
||||||
|
uint8_t security;
|
||||||
|
#define MG_WIFI_SECURITY_OPEN 0
|
||||||
|
#define MG_WIFI_SECURITY_WEP MG_BIT(0)
|
||||||
|
#define MG_WIFI_SECURITY_WPA MG_BIT(1)
|
||||||
|
#define MG_WIFI_SECURITY_WPA2 MG_BIT(2)
|
||||||
|
#define MG_WIFI_SECURITY_WPA3 MG_BIT(3)
|
||||||
|
uint8_t channel;
|
||||||
|
unsigned band :2;
|
||||||
|
#define MG_WIFI_BAND_2G 0
|
||||||
|
#define MG_WIFI_BAND_5G 1
|
||||||
|
unsigned has_n :1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool mg_wifi_scan(void);
|
||||||
|
bool mg_wifi_connect(char *ssid, char *pass);
|
||||||
|
bool mg_wifi_disconnect(void);
|
||||||
|
bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel);
|
||||||
|
bool mg_wifi_ap_stop(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if MG_ENABLE_TCPIP
|
||||||
|
|
||||||
struct mg_tcpip_if; // Mongoose TCP/IP network interface
|
struct mg_tcpip_if; // Mongoose TCP/IP network interface
|
||||||
|
|
||||||
@@ -2744,21 +2833,26 @@ struct mg_tcpip_driver {
|
|||||||
bool (*init)(struct mg_tcpip_if *); // Init driver
|
bool (*init)(struct mg_tcpip_if *); // Init driver
|
||||||
size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
|
size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
|
||||||
size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
|
size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
|
||||||
bool (*up)(struct mg_tcpip_if *); // Up/down status
|
bool (*poll)(struct mg_tcpip_if *, bool); // Poll, return Up/down status
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*mg_tcpip_event_handler_t)(struct mg_tcpip_if *ifp, int ev,
|
typedef void (*mg_tcpip_event_handler_t)(struct mg_tcpip_if *ifp, int ev,
|
||||||
void *ev_data);
|
void *ev_data);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
|
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
|
||||||
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
|
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
|
||||||
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
|
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
|
||||||
MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
|
MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
|
||||||
MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
|
MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
|
||||||
MG_TCPIP_EV_USER // Starting ID for user events
|
MG_TCPIP_EV_WIFI_SCAN_RESULT, // Wi-Fi scan results struct mg_wifi_scan_bss_data *
|
||||||
|
MG_TCPIP_EV_WIFI_SCAN_END, // Wi-Fi scan has finished NULL
|
||||||
|
MG_TCPIP_EV_WIFI_CONNECT_ERR, // Wi-Fi connect has failed driver and chip specific
|
||||||
|
MG_TCPIP_EV_DRIVER, // Driver event driver specific
|
||||||
|
MG_TCPIP_EV_USER // Starting ID for user events
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Network interface
|
// Network interface
|
||||||
struct mg_tcpip_if {
|
struct mg_tcpip_if {
|
||||||
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
|
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
|
||||||
@@ -2771,11 +2865,13 @@ struct mg_tcpip_if {
|
|||||||
bool enable_req_sntp; // DCHP client requests SNTP server
|
bool enable_req_sntp; // DCHP client requests SNTP server
|
||||||
bool enable_crc32_check; // Do a CRC check on RX frames and strip it
|
bool enable_crc32_check; // Do a CRC check on RX frames and strip it
|
||||||
bool enable_mac_check; // Do a MAC check on RX frames
|
bool enable_mac_check; // Do a MAC check on RX frames
|
||||||
|
bool update_mac_hash_table; // Signal drivers to update MAC controller
|
||||||
struct mg_tcpip_driver *driver; // Low level driver
|
struct mg_tcpip_driver *driver; // Low level driver
|
||||||
void *driver_data; // Driver-specific data
|
void *driver_data; // Driver-specific data
|
||||||
mg_tcpip_event_handler_t fn; // User-specified event handler function
|
mg_tcpip_event_handler_t fn; // User-specified event handler function
|
||||||
struct mg_mgr *mgr; // Mongoose event manager
|
struct mg_mgr *mgr; // Mongoose event manager
|
||||||
struct mg_queue recv_queue; // Receive queue
|
struct mg_queue recv_queue; // Receive queue
|
||||||
|
char dhcp_name[12]; // Name reported to DHCP, "mip" if unset
|
||||||
uint16_t mtu; // Interface MTU
|
uint16_t mtu; // Interface MTU
|
||||||
#define MG_TCPIP_MTU_DEFAULT 1500
|
#define MG_TCPIP_MTU_DEFAULT 1500
|
||||||
|
|
||||||
@@ -2804,6 +2900,7 @@ void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac);
|
|||||||
|
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
|
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
||||||
|
extern struct mg_tcpip_driver mg_tcpip_driver_w5100;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
|
extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_tms570;
|
extern struct mg_tcpip_driver mg_tcpip_driver_tms570;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
|
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
|
||||||
@@ -2816,6 +2913,7 @@ extern struct mg_tcpip_driver mg_tcpip_driver_xmc7;
|
|||||||
extern struct mg_tcpip_driver mg_tcpip_driver_ppp;
|
extern struct mg_tcpip_driver mg_tcpip_driver_ppp;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_pico_w;
|
extern struct mg_tcpip_driver mg_tcpip_driver_pico_w;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_rw612;
|
extern struct mg_tcpip_driver mg_tcpip_driver_rw612;
|
||||||
|
extern struct mg_tcpip_driver mg_tcpip_driver_cyw;
|
||||||
|
|
||||||
// Drivers that require SPI, can use this SPI abstraction
|
// Drivers that require SPI, can use this SPI abstraction
|
||||||
struct mg_tcpip_spi {
|
struct mg_tcpip_spi {
|
||||||
@@ -2825,6 +2923,8 @@ struct mg_tcpip_spi {
|
|||||||
uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
|
uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Macros to record timestamped events that happens with a connection.
|
// Macros to record timestamped events that happens with a connection.
|
||||||
@@ -2832,7 +2932,7 @@ struct mg_tcpip_spi {
|
|||||||
// timestamp in milliseconds since connection init time.
|
// timestamp in milliseconds since connection init time.
|
||||||
//
|
//
|
||||||
// Test (run in two separate terminals):
|
// Test (run in two separate terminals):
|
||||||
// make -C examples/http-server/ CFLAGS_EXTRA=-DMG_ENABLE_PROFILE=1
|
// make -C tutorials/http/http-server/ CFLAGS_EXTRA=-DMG_ENABLE_PROFILE=1
|
||||||
// curl localhost:8000
|
// curl localhost:8000
|
||||||
// Output:
|
// Output:
|
||||||
// 1ea1f1e7 2 net.c:150:mg_close_conn 3 profile:
|
// 1ea1f1e7 2 net.c:150:mg_close_conn 3 profile:
|
||||||
@@ -2908,6 +3008,60 @@ struct mg_profitem {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CYW) && MG_ENABLE_DRIVER_CYW
|
||||||
|
|
||||||
|
struct mg_tcpip_spi_ {
|
||||||
|
void *spi; // Opaque SPI bus descriptor
|
||||||
|
void (*begin)(void *); // SPI begin: slave select low
|
||||||
|
void (*end)(void *); // SPI end: slave select high
|
||||||
|
void (*txn)(void *, uint8_t *, uint8_t *,
|
||||||
|
size_t len); // SPI transaction: write-read len bytes
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mg_tcpip_driver_cyw_firmware {
|
||||||
|
const uint8_t *code_addr;
|
||||||
|
size_t code_len;
|
||||||
|
const uint8_t *nvram_addr;
|
||||||
|
size_t nvram_len;
|
||||||
|
const uint8_t *clm_addr;
|
||||||
|
size_t clm_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mg_tcpip_driver_cyw_data {
|
||||||
|
struct mg_tcpip_spi_ *spi;
|
||||||
|
struct mg_tcpip_driver_cyw_firmware *fw;
|
||||||
|
char *ssid;
|
||||||
|
char *pass;
|
||||||
|
char *apssid;
|
||||||
|
char *appass;
|
||||||
|
uint8_t security; // TBD
|
||||||
|
uint8_t apsecurity; // TBD
|
||||||
|
uint8_t apchannel;
|
||||||
|
bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL
|
||||||
|
bool hs; // use chip "high-speed" mode; otherwise SPI CPOL0 CPHA0 (DS 4.2.3 Table 6)
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
||||||
|
do { \
|
||||||
|
static struct mg_tcpip_driver_cyw_data driver_data_; \
|
||||||
|
static struct mg_tcpip_if mif_; \
|
||||||
|
MG_SET_WIFI_CONFIG(&driver_data_); \
|
||||||
|
mif_.ip = MG_TCPIP_IP; \
|
||||||
|
mif_.mask = MG_TCPIP_MASK; \
|
||||||
|
mif_.gw = MG_TCPIP_GW; \
|
||||||
|
mif_.driver = &mg_tcpip_driver_pico_w; \
|
||||||
|
mif_.driver_data = &driver_data_; \
|
||||||
|
mif_.recv_queue.size = 8192; \
|
||||||
|
mif_.mac[0] = 2; /* MAC read from OTP at driver init */ \
|
||||||
|
mg_tcpip_init(mgr, &mif_); \
|
||||||
|
MG_INFO(("Driver: cyw, MAC: %M", mg_print_mac, mif_.mac)); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_IMXRT) && MG_ENABLE_DRIVER_IMXRT
|
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_IMXRT) && MG_ENABLE_DRIVER_IMXRT
|
||||||
|
|
||||||
struct mg_tcpip_driver_imxrt_data {
|
struct mg_tcpip_driver_imxrt_data {
|
||||||
@@ -2986,13 +3140,19 @@ bool mg_phy_up(struct mg_phy *, uint8_t addr, bool *full_duplex,
|
|||||||
struct mg_tcpip_driver_pico_w_data {
|
struct mg_tcpip_driver_pico_w_data {
|
||||||
char *ssid;
|
char *ssid;
|
||||||
char *pass;
|
char *pass;
|
||||||
|
char *apssid;
|
||||||
|
char *appass;
|
||||||
|
uint8_t security; // TBD
|
||||||
|
uint8_t apsecurity; // TBD
|
||||||
|
uint8_t apchannel;
|
||||||
|
bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
||||||
do { \
|
do { \
|
||||||
static struct mg_tcpip_driver_pico_w_data driver_data_; \
|
static struct mg_tcpip_driver_pico_w_data driver_data_; \
|
||||||
static struct mg_tcpip_if mif_; \
|
static struct mg_tcpip_if mif_; \
|
||||||
MG_SET_WIFI_CREDS(&driver_data_.ssid, &driver_data_.pass); \
|
MG_SET_WIFI_CONFIG(&driver_data_); \
|
||||||
mif_.ip = MG_TCPIP_IP; \
|
mif_.ip = MG_TCPIP_IP; \
|
||||||
mif_.mask = MG_TCPIP_MASK; \
|
mif_.mask = MG_TCPIP_MASK; \
|
||||||
mif_.gw = MG_TCPIP_GW; \
|
mif_.gw = MG_TCPIP_GW; \
|
||||||
@@ -3027,6 +3187,35 @@ struct mg_tcpip_driver_ra_data {
|
|||||||
uint8_t phy_addr; // PHY address
|
uint8_t phy_addr; // PHY address
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef MG_DRIVER_CLK_FREQ
|
||||||
|
#define MG_DRIVER_CLK_FREQ 100000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_DRIVER_IRQ_NO
|
||||||
|
#define MG_DRIVER_IRQ_NO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_TCPIP_PHY_ADDR
|
||||||
|
#define MG_TCPIP_PHY_ADDR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
||||||
|
do { \
|
||||||
|
static struct mg_tcpip_driver_ra_data driver_data_; \
|
||||||
|
static struct mg_tcpip_if mif_; \
|
||||||
|
driver_data_.clock = MG_DRIVER_CLK_FREQ; \
|
||||||
|
driver_data_.irqno = MG_DRIVER_IRQ_NO; \
|
||||||
|
driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
|
||||||
|
mif_.ip = MG_TCPIP_IP; \
|
||||||
|
mif_.mask = MG_TCPIP_MASK; \
|
||||||
|
mif_.gw = MG_TCPIP_GW; \
|
||||||
|
mif_.driver = &mg_tcpip_driver_ra; \
|
||||||
|
mif_.driver_data = &driver_data_; \
|
||||||
|
MG_SET_MAC_ADDRESS(mif_.mac); \
|
||||||
|
mg_tcpip_init(mgr, &mif_); \
|
||||||
|
MG_INFO(("Driver: ra, MAC: %M", mg_print_mac, mif_.mac)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -3267,41 +3456,6 @@ struct mg_tcpip_driver_tms570_data {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7
|
|
||||||
|
|
||||||
struct mg_tcpip_driver_xmc7_data {
|
|
||||||
int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
|
|
||||||
uint8_t phy_addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef MG_TCPIP_PHY_ADDR
|
|
||||||
#define MG_TCPIP_PHY_ADDR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MG_DRIVER_MDC_CR
|
|
||||||
#define MG_DRIVER_MDC_CR 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
|
||||||
do { \
|
|
||||||
static struct mg_tcpip_driver_xmc7_data driver_data_; \
|
|
||||||
static struct mg_tcpip_if mif_; \
|
|
||||||
driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
|
|
||||||
driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
|
|
||||||
mif_.ip = MG_TCPIP_IP; \
|
|
||||||
mif_.mask = MG_TCPIP_MASK; \
|
|
||||||
mif_.gw = MG_TCPIP_GW; \
|
|
||||||
mif_.driver = &mg_tcpip_driver_xmc7; \
|
|
||||||
mif_.driver_data = &driver_data_; \
|
|
||||||
MG_SET_MAC_ADDRESS(mif_.mac); \
|
|
||||||
mg_tcpip_init(mgr, &mif_); \
|
|
||||||
MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC
|
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC
|
||||||
|
|
||||||
struct mg_tcpip_driver_xmc_data {
|
struct mg_tcpip_driver_xmc_data {
|
||||||
@@ -3348,6 +3502,41 @@ struct mg_tcpip_driver_xmc_data {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7
|
||||||
|
|
||||||
|
struct mg_tcpip_driver_xmc7_data {
|
||||||
|
int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
|
||||||
|
uint8_t phy_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef MG_TCPIP_PHY_ADDR
|
||||||
|
#define MG_TCPIP_PHY_ADDR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_DRIVER_MDC_CR
|
||||||
|
#define MG_DRIVER_MDC_CR 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
||||||
|
do { \
|
||||||
|
static struct mg_tcpip_driver_xmc7_data driver_data_; \
|
||||||
|
static struct mg_tcpip_if mif_; \
|
||||||
|
driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \
|
||||||
|
driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
|
||||||
|
mif_.ip = MG_TCPIP_IP; \
|
||||||
|
mif_.mask = MG_TCPIP_MASK; \
|
||||||
|
mif_.gw = MG_TCPIP_GW; \
|
||||||
|
mif_.driver = &mg_tcpip_driver_xmc7; \
|
||||||
|
mif_.driver_data = &driver_data_; \
|
||||||
|
MG_SET_MAC_ADDRESS(mif_.mac); \
|
||||||
|
mg_tcpip_init(mgr, &mif_); \
|
||||||
|
MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
See detailed tutorials at https://mongoose.ws/documentation/#reference-projects
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion
|
|
||||||
CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion
|
|
||||||
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
|
|
||||||
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_f7/Include
|
|
||||||
CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 $(CFLAGS_EXTRA)
|
|
||||||
LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nosys.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
|
||||||
|
|
||||||
SOURCES += cmsis_f7/Source/Templates/gcc/startup_stm32f746xx.s
|
|
||||||
|
|
||||||
SOURCES += main.c hal.c mongoose.c packed_fs.c net.c
|
|
||||||
CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" -DHTTPS_URL=\"https://0.0.0.0/\"
|
|
||||||
|
|
||||||
all build example: firmware.bin
|
|
||||||
|
|
||||||
firmware.bin: firmware.elf
|
|
||||||
arm-none-eabi-objcopy -O binary $< $@
|
|
||||||
arm-none-eabi-size --format=berkeley $<
|
|
||||||
|
|
||||||
firmware.elf: cmsis_core cmsis_f7 $(SOURCES) hal.h link.ld Makefile
|
|
||||||
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
|
|
||||||
|
|
||||||
flash: firmware.bin
|
|
||||||
st-flash --reset write $< 0x8000000
|
|
||||||
|
|
||||||
cmsis_core:
|
|
||||||
git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
|
||||||
cmsis_f7:
|
|
||||||
git clone --depth 1 -b v1.2.8 https://github.com/STMicroelectronics/cmsis_device_f7 $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf firmware.* cmsis_core cmsis_f7
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
// Copyright (c) 2024 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
static volatile uint64_t s_ticks; // Milliseconds since boot
|
|
||||||
void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
|
|
||||||
s_ticks++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
|
||||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
|
||||||
uint32_t r = rng_read();
|
|
||||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t mg_millis(void) { // Let Mongoose use our uptime function
|
|
||||||
return s_ticks; // Return number of milliseconds since boot
|
|
||||||
}
|
|
||||||
|
|
||||||
void hal_init(void) {
|
|
||||||
clock_init(); // Set system clock to SYS_FREQUENCY
|
|
||||||
SystemCoreClock = SYS_FREQUENCY; // Update SystemCoreClock global var
|
|
||||||
SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms
|
|
||||||
rng_init(); // Initialise random number generator
|
|
||||||
|
|
||||||
uart_init(UART_DEBUG, 115200); // Initialise UART
|
|
||||||
gpio_output(LED1); // Initialise LED1
|
|
||||||
gpio_output(LED2); // Initialise LED2
|
|
||||||
gpio_output(LED3); // Initialise LED3
|
|
||||||
ethernet_init(); // Initialise Ethernet pins
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__ARMCC_VERSION)
|
|
||||||
// Keil specific - implement IO printf redirection
|
|
||||||
int fputc(int c, FILE *stream) {
|
|
||||||
if (stream == stdout || stream == stderr) uart_write_byte(UART_DEBUG, c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
// ARM GCC specific. ARM GCC is shipped with Newlib C library.
|
|
||||||
// Implement newlib syscalls:
|
|
||||||
// _sbrk() for malloc
|
|
||||||
// _write() for printf redirection
|
|
||||||
// the rest are just stubs
|
|
||||||
#include <sys/stat.h> // For _fstat()
|
|
||||||
|
|
||||||
uint32_t SystemCoreClock;
|
|
||||||
void SystemInit(void) { // Called automatically by startup code
|
|
||||||
}
|
|
||||||
|
|
||||||
int _fstat(int fd, struct stat *st) {
|
|
||||||
(void) fd, (void) st;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern unsigned char _end[]; // End of data section, start of heap. See link.ld
|
|
||||||
static unsigned char *s_current_heap_end = _end;
|
|
||||||
|
|
||||||
size_t hal_ram_used(void) {
|
|
||||||
return (size_t) (s_current_heap_end - _end);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t hal_ram_free(void) {
|
|
||||||
unsigned char endofstack;
|
|
||||||
return (size_t) (&endofstack - s_current_heap_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *_sbrk(int incr) {
|
|
||||||
unsigned char *prev_heap;
|
|
||||||
unsigned char *heap_end = (unsigned char *) ((size_t) &heap_end - 256);
|
|
||||||
prev_heap = s_current_heap_end;
|
|
||||||
// Check how much space we got from the heap end to the stack end
|
|
||||||
if (s_current_heap_end + incr > heap_end) return (void *) -1;
|
|
||||||
s_current_heap_end += incr;
|
|
||||||
return prev_heap;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _open(const char *path) {
|
|
||||||
(void) path;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _close(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isatty(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _lseek(int fd, int ptr, int dir) {
|
|
||||||
(void) fd, (void) ptr, (void) dir;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _exit(int status) {
|
|
||||||
(void) status;
|
|
||||||
for (;;) asm volatile("BKPT #0");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _kill(int pid, int sig) {
|
|
||||||
(void) pid, (void) sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getpid(void) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _write(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _read(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _link(const char *a, const char *b) {
|
|
||||||
(void) a, (void) b;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _unlink(const char *a) {
|
|
||||||
(void) a;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _stat(const char *path, struct stat *st) {
|
|
||||||
(void) path, (void) st;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode) {
|
|
||||||
(void) path, (void) mode;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _init(void) {
|
|
||||||
}
|
|
||||||
#endif // __GNUC__
|
|
||||||
Whitespace-only changes.
@@ -1 +0,0 @@
|
|||||||
../../../windows-macos-linux/web-ui-dashboard/main.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../mongoose.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../mongoose.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../windows-macos-linux/web-ui-dashboard/net.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../windows-macos-linux/web-ui-dashboard/net.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../windows-macos-linux/web-ui-dashboard/packed_fs.c
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
# Environment setup: https://mongoose.ws/documentation/tutorials/tools/
|
|
||||||
|
|
||||||
PROG ?= ./example # Program we are building
|
|
||||||
DELETE = rm -rf # Command to remove files
|
|
||||||
NPX ?= npx # For generating optimised tailwind CSS
|
|
||||||
OUT ?= -o $(PROG) # Compiler argument for output file
|
|
||||||
|
|
||||||
SOURCES = main.c mongoose.c net.c packed_fs.c
|
|
||||||
CFLAGS += -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion -Wconversion -Wno-sign-conversion
|
|
||||||
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
|
||||||
CFLAGS += -g3 -Os -I.
|
|
||||||
|
|
||||||
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
|
|
||||||
CFLAGS_MONGOOSE += -DMG_ENABLE_PACKED_FS=1
|
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
|
|
||||||
PROG = example.exe # Use .exe suffix for the binary
|
|
||||||
CC = gcc # Use MinGW gcc compiler
|
|
||||||
CFLAGS += -lws2_32 # Link against Winsock library
|
|
||||||
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Default target. Build and run program
|
|
||||||
all: $(PROG)
|
|
||||||
$(RUN) $(PROG) $(ARGS)
|
|
||||||
|
|
||||||
# Build program from sources
|
|
||||||
$(PROG): $(SOURCES)
|
|
||||||
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
|
|
||||||
|
|
||||||
# Build using Microsoft Visual C compiler
|
|
||||||
vc: $(SOURCES) Makefile
|
|
||||||
cl $(SOURCES) /DMG_ENABLE_PACKED_FS=1 /MD /W3 /nologo /Fedemo.exe
|
|
||||||
|
|
||||||
# Bundle JS libraries (preact, preact-router, ...) into a single file
|
|
||||||
web_root/bundle.js:
|
|
||||||
curl -s https://npm.reversehttp.com/preact,preact/hooks,htm/preact,preact-router -o $@
|
|
||||||
|
|
||||||
# Create optimised CSS. Prerequisite: npm -g i tailwindcss tailwindcss-font-inter
|
|
||||||
css: web_root/index.html $(wildcard web_root/*.js)
|
|
||||||
$(NPX) tailwindcss -o web_root/main.css --minify
|
|
||||||
|
|
||||||
# Generate packed filesystem for serving Web UI
|
|
||||||
packed_fs.c: $(wildcard web_root/*) $(wildcard certs/*) Makefile
|
|
||||||
node pack.js $(addsuffix ::gzip, $(wildcard web_root/*)) certs/* > $@
|
|
||||||
|
|
||||||
# Cleanup. Delete built program and all build artifacts
|
|
||||||
clean:
|
|
||||||
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# A complete device dashboard
|
|
||||||
|
|
||||||
This example is a demonstration of how Mongoose Library could be integrated
|
|
||||||
into an embedded device and provide a complete device dashboard with the
|
|
||||||
following features:
|
|
||||||
|
|
||||||
- Authentication: login-protected dashboard
|
|
||||||
- Multiple logins (with possibly different permissions)
|
|
||||||
- The Web UI can be fully embedded into the firmware binary, then not
|
|
||||||
needing a filesystem to serve it; so being resilient to FS problems
|
|
||||||
- All changes are propagated to all connected clients
|
|
||||||
|
|
||||||
See a detailed tutorial at https://mongoose.ws/tutorials/device-dashboard/
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIBCTCBsAIJAK9wbIDkHnAoMAoGCCqGSM49BAMCMA0xCzAJBgNVBAYTAklFMB4X
|
|
||||||
DTIzMDEyOTIxMjEzOFoXDTMzMDEyNjIxMjEzOFowDTELMAkGA1UEBhMCSUUwWTAT
|
|
||||||
BgcqhkjOPQIBBggqhkjOPQMBBwNCAARzSQS5OHd17lUeNI+6kp9WYu0cxuEIi/JT
|
|
||||||
jphbCmdJD1cUvhmzM9/phvJT9ka10Z9toZhgnBq0o0xfTQ4jC1vwMAoGCCqGSM49
|
|
||||||
BAMCA0gAMEUCIQCe0T2E0GOiVe9KwvIEPeX1J1J0T7TNacgR0Ya33HV9VgIgNvdn
|
|
||||||
aEWiBp1xshs4iz6WbpxrS1IHucrqkZuJLfNZGZI=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
-----BEGIN EC PRIVATE KEY-----
|
|
||||||
MHcCAQEEICBz3HOkQLPBDtdknqC7k1PNsWj6HfhyNB5MenfjmqiooAoGCCqGSM49
|
|
||||||
AwEHoUQDQgAEc0kEuTh3de5VHjSPupKfVmLtHMbhCIvyU46YWwpnSQ9XFL4ZszPf
|
|
||||||
6YbyU/ZGtdGfbaGYYJwatKNMX00OIwtb8A==
|
|
||||||
-----END EC PRIVATE KEY-----
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// Copyright (c) 2024 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define LED1 0
|
|
||||||
#define LED2 1
|
|
||||||
#define UART_DEBUG NULL
|
|
||||||
|
|
||||||
// No-op HAL API implementation for a device with GPIO and UART
|
|
||||||
#define hal_init()
|
|
||||||
#define hal_ram_free() 0
|
|
||||||
#define hal_ram_used() 0
|
|
||||||
#define gpio_output(pin)
|
|
||||||
#define gpio_toggle(pin)
|
|
||||||
#define gpio_read(pin) 0
|
|
||||||
#define gpio_write(pin, val)
|
|
||||||
#define uart_init(uart, baud)
|
|
||||||
#define uart_read_ready(uart) 0
|
|
||||||
#define uart_write_byte(uart, ch)
|
|
||||||
#define uart_write_buf(uart, buf, len)
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
// Copyright (c) 2024 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "mongoose.h"
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis
|
|
||||||
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
gpio_toggle(LED1); // Blink LED
|
|
||||||
(void) arg; // Unused
|
|
||||||
}
|
|
||||||
|
|
||||||
// In RTOS environment, you can run this function in a separate task
|
|
||||||
static void run_mongoose(void) {
|
|
||||||
struct mg_mgr mgr; // Mongoose event manager
|
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level to debug
|
|
||||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, NULL);
|
|
||||||
|
|
||||||
net_init(&mgr); // Initialise application defined in net.c
|
|
||||||
for (;;) { // Infinite event loop
|
|
||||||
mg_mgr_poll(&mgr, 0); // Process network events
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
hal_init(); // Cross-platform hardware init
|
|
||||||
run_mongoose(); // Initialise and run network application
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,256 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
// Authenticated user.
|
|
||||||
// A user can be authenticated by:
|
|
||||||
// - a name:pass pair, passed in a header Authorization: Basic .....
|
|
||||||
// - an access_token, passed in a header Cookie: access_token=....
|
|
||||||
// When a user is shown a login screen, she enters a user:pass. If successful,
|
|
||||||
// a server responds with a http-only access_token cookie set.
|
|
||||||
struct user {
|
|
||||||
const char *name, *pass, *access_token;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Settings
|
|
||||||
struct settings {
|
|
||||||
bool log_enabled;
|
|
||||||
int log_level;
|
|
||||||
long brightness;
|
|
||||||
char *device_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct settings s_settings = {true, 1, 57, NULL};
|
|
||||||
|
|
||||||
static const char *s_json_header =
|
|
||||||
"Content-Type: application/json\r\n"
|
|
||||||
"Cache-Control: no-cache\r\n";
|
|
||||||
|
|
||||||
int ui_event_next(int no, struct ui_event *e) {
|
|
||||||
if (no < 0 || no >= MAX_EVENTS_NO) return 0;
|
|
||||||
|
|
||||||
srand((unsigned) no);
|
|
||||||
e->type = (uint8_t) rand() % 4;
|
|
||||||
e->prio = (uint8_t) rand() % 3;
|
|
||||||
e->timestamp =
|
|
||||||
(unsigned long) ((int64_t) mg_now() - 86400 * 1000 /* one day back */ +
|
|
||||||
no * 300 * 1000 /* 5 mins between alerts */ +
|
|
||||||
1000 * (rand() % 300) /* randomize event time */) /
|
|
||||||
1000UL;
|
|
||||||
|
|
||||||
mg_snprintf(e->text, MAX_EVENT_TEXT_SIZE, "event#%d", no);
|
|
||||||
return no + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
|
||||||
mg_sntp_connect(param, "udp://time.google.com:123", NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse HTTP requests, return authenticated user or NULL
|
|
||||||
static struct user *authenticate(struct mg_http_message *hm) {
|
|
||||||
// In production, make passwords strong and tokens randomly generated
|
|
||||||
// In this example, user list is kept in RAM. In production, it can
|
|
||||||
// be backed by file, database, or some other method.
|
|
||||||
static struct user users[] = {
|
|
||||||
{"admin", "admin", "admin_token"},
|
|
||||||
{"user1", "user1", "user1_token"},
|
|
||||||
{"user2", "user2", "user2_token"},
|
|
||||||
{NULL, NULL, NULL},
|
|
||||||
};
|
|
||||||
char user[64], pass[64];
|
|
||||||
struct user *u, *result = NULL;
|
|
||||||
mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass));
|
|
||||||
MG_VERBOSE(("user [%s] pass [%s]", user, pass));
|
|
||||||
|
|
||||||
if (user[0] != '\0' && pass[0] != '\0') {
|
|
||||||
// Both user and password is set, search by user/password
|
|
||||||
for (u = users; result == NULL && u->name != NULL; u++)
|
|
||||||
if (strcmp(user, u->name) == 0 && strcmp(pass, u->pass) == 0) result = u;
|
|
||||||
} else if (user[0] == '\0') {
|
|
||||||
// Only password is set, search by token
|
|
||||||
for (u = users; result == NULL && u->name != NULL; u++)
|
|
||||||
if (strcmp(pass, u->access_token) == 0) result = u;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_login(struct mg_connection *c, struct user *u) {
|
|
||||||
char cookie[256];
|
|
||||||
const char *cookie_name = c->is_tls ? "secure_access_token" : "access_token";
|
|
||||||
mg_snprintf(cookie, sizeof(cookie),
|
|
||||||
"Set-Cookie: %s=%s; Path=/; "
|
|
||||||
"%sHttpOnly; SameSite=Lax; Max-Age=%d\r\n",
|
|
||||||
cookie_name, u->access_token,
|
|
||||||
c->is_tls ? "Secure; " : "", 3600 * 24);
|
|
||||||
mg_http_reply(c, 200, cookie, "{%m:%m}", MG_ESC("user"), MG_ESC(u->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_logout(struct mg_connection *c) {
|
|
||||||
char cookie[256];
|
|
||||||
const char *cookie_name = c->is_tls ? "secure_access_token" : "access_token";
|
|
||||||
mg_snprintf(cookie, sizeof(cookie),
|
|
||||||
"Set-Cookie: %s=; Path=/; "
|
|
||||||
"Expires=Thu, 01 Jan 1970 00:00:00 UTC; "
|
|
||||||
"%sHttpOnly; Max-Age=0; \r\n", cookie_name,
|
|
||||||
c->is_tls ? "Secure; " : "");
|
|
||||||
mg_http_reply(c, 200, cookie, "true\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_debug(struct mg_connection *c, struct mg_http_message *hm) {
|
|
||||||
int level = (int) mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG);
|
|
||||||
mg_log_set(level);
|
|
||||||
mg_http_reply(c, 200, "", "Debug level set to %d\n", level);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t print_int_arr(void (*out)(char, void *), void *ptr, va_list *ap) {
|
|
||||||
size_t i, len = 0, num = va_arg(*ap, size_t); // Number of items in the array
|
|
||||||
int *arr = va_arg(*ap, int *); // Array ptr
|
|
||||||
for (i = 0; i < num; i++) {
|
|
||||||
len += mg_xprintf(out, ptr, "%s%d", i == 0 ? "" : ",", arr[i]);
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_stats_get(struct mg_connection *c) {
|
|
||||||
int points[] = {21, 22, 22, 19, 18, 20, 23, 23, 22, 22, 22, 23, 22};
|
|
||||||
mg_http_reply(c, 200, s_json_header, "{%m:%d,%m:%d,%m:[%M]}\n",
|
|
||||||
MG_ESC("temperature"), 21, //
|
|
||||||
MG_ESC("humidity"), 67, //
|
|
||||||
MG_ESC("points"), print_int_arr,
|
|
||||||
sizeof(points) / sizeof(points[0]), points);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t print_events(void (*out)(char, void *), void *ptr, va_list *ap) {
|
|
||||||
size_t len = 0;
|
|
||||||
struct ui_event ev;
|
|
||||||
int pageno = va_arg(*ap, int);
|
|
||||||
int no = (pageno - 1) * EVENTS_PER_PAGE;
|
|
||||||
int end = no + EVENTS_PER_PAGE;
|
|
||||||
|
|
||||||
while ((no = ui_event_next(no, &ev)) != 0 && no <= end) {
|
|
||||||
len += mg_xprintf(out, ptr, "%s{%m:%lu,%m:%d,%m:%d,%m:%m}\n", //
|
|
||||||
len == 0 ? "" : ",", //
|
|
||||||
MG_ESC("time"), ev.timestamp, //
|
|
||||||
MG_ESC("type"), ev.type, //
|
|
||||||
MG_ESC("prio"), ev.prio, //
|
|
||||||
MG_ESC("text"), MG_ESC(ev.text));
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_events_get(struct mg_connection *c,
|
|
||||||
struct mg_http_message *hm) {
|
|
||||||
int pageno = (int) mg_json_get_long(hm->body, "$.page", 1);
|
|
||||||
mg_http_reply(c, 200, s_json_header, "{%m:[%M], %m:%d}\n", MG_ESC("arr"),
|
|
||||||
print_events, pageno, MG_ESC("totalCount"), MAX_EVENTS_NO);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_settings_set(struct mg_connection *c, struct mg_str body) {
|
|
||||||
struct settings settings;
|
|
||||||
char *s = mg_json_get_str(body, "$.device_name");
|
|
||||||
bool ok = true;
|
|
||||||
memset(&settings, 0, sizeof(settings));
|
|
||||||
mg_json_get_bool(body, "$.log_enabled", &settings.log_enabled);
|
|
||||||
settings.log_level = (int) mg_json_get_long(body, "$.log_level", 0);
|
|
||||||
settings.brightness = mg_json_get_long(body, "$.brightness", 0);
|
|
||||||
if (s && strlen(s) < MAX_DEVICE_NAME) {
|
|
||||||
free(settings.device_name);
|
|
||||||
settings.device_name = s;
|
|
||||||
} else {
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
s_settings = settings; // Save to the device flash
|
|
||||||
mg_http_reply(c, 200, s_json_header,
|
|
||||||
"{%m:%s,%m:%m}", //
|
|
||||||
MG_ESC("status"), ok ? "true" : "false", //
|
|
||||||
MG_ESC("message"), MG_ESC(ok ? "Success" : "Failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_settings_get(struct mg_connection *c) {
|
|
||||||
mg_http_reply(c, 200, s_json_header, "{%m:%s,%m:%hhu,%m:%hhu,%m:%m}\n", //
|
|
||||||
MG_ESC("log_enabled"),
|
|
||||||
s_settings.log_enabled ? "true" : "false", //
|
|
||||||
MG_ESC("log_level"), s_settings.log_level, //
|
|
||||||
MG_ESC("brightness"), s_settings.brightness, //
|
|
||||||
MG_ESC("device_name"), MG_ESC(s_settings.device_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_firmware_upload(struct mg_connection *c,
|
|
||||||
struct mg_http_message *hm) {
|
|
||||||
char name[64], offset[20], total[20];
|
|
||||||
struct mg_str data = hm->body;
|
|
||||||
long ofs = -1, tot = -1;
|
|
||||||
name[0] = offset[0] = '\0';
|
|
||||||
mg_http_get_var(&hm->query, "name", name, sizeof(name));
|
|
||||||
mg_http_get_var(&hm->query, "offset", offset, sizeof(offset));
|
|
||||||
mg_http_get_var(&hm->query, "total", total, sizeof(total));
|
|
||||||
MG_INFO(("File %s, offset %s, len %lu", name, offset, data.len));
|
|
||||||
if ((ofs = mg_json_get_long(mg_str(offset), "$", -1)) < 0 ||
|
|
||||||
(tot = mg_json_get_long(mg_str(total), "$", -1)) < 0) {
|
|
||||||
mg_http_reply(c, 500, "", "offset and total not set\n");
|
|
||||||
} else if (ofs == 0 && mg_ota_begin((size_t) tot) == false) {
|
|
||||||
mg_http_reply(c, 500, "", "mg_ota_begin(%ld) failed\n", tot);
|
|
||||||
} else if (data.len > 0 && mg_ota_write(data.buf, data.len) == false) {
|
|
||||||
mg_http_reply(c, 500, "", "mg_ota_write(%lu) @%ld failed\n", data.len, ofs);
|
|
||||||
mg_ota_end();
|
|
||||||
} else if (data.len == 0 && mg_ota_end() == false) {
|
|
||||||
mg_http_reply(c, 500, "", "mg_ota_end() failed\n", tot);
|
|
||||||
} else {
|
|
||||||
mg_http_reply(c, 200, s_json_header, "true\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP request handler function
|
|
||||||
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
if (ev == MG_EV_ACCEPT) {
|
|
||||||
if (c->fn_data != NULL) { // TLS listener!
|
|
||||||
struct mg_tls_opts opts = {0};
|
|
||||||
opts.cert = mg_unpacked("/certs/server_cert.pem");
|
|
||||||
opts.key = mg_unpacked("/certs/server_key.pem");
|
|
||||||
mg_tls_init(c, &opts);
|
|
||||||
}
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
|
||||||
struct user *u = authenticate(hm);
|
|
||||||
|
|
||||||
if (mg_match(hm->uri, mg_str("/api/#"), NULL) && u == NULL) {
|
|
||||||
mg_http_reply(c, 403, "", "Not Authorised\n");
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/login"), NULL)) {
|
|
||||||
handle_login(c, u);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/logout"), NULL)) {
|
|
||||||
handle_logout(c);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/debug"), NULL)) {
|
|
||||||
handle_debug(c, hm);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/stats/get"), NULL)) {
|
|
||||||
handle_stats_get(c);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/events/get"), NULL)) {
|
|
||||||
handle_events_get(c, hm);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/settings/get"), NULL)) {
|
|
||||||
handle_settings_get(c);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/settings/set"), NULL)) {
|
|
||||||
handle_settings_set(c, hm->body);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/firmware/upload"), NULL)) {
|
|
||||||
handle_firmware_upload(c, hm);
|
|
||||||
} else {
|
|
||||||
struct mg_http_serve_opts opts;
|
|
||||||
memset(&opts, 0, sizeof(opts));
|
|
||||||
opts.fs = HAL_FS;
|
|
||||||
opts.root_dir = HAL_WEB_ROOT_DIR;
|
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
|
||||||
}
|
|
||||||
MG_DEBUG(("%lu %.*s %.*s -> %.*s", c->id, (int) hm->method.len,
|
|
||||||
hm->method.buf, (int) hm->uri.len, hm->uri.buf, (int) 3,
|
|
||||||
&c->send.buf[9]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void net_init(struct mg_mgr *mgr) {
|
|
||||||
s_settings.device_name = strdup("My Device");
|
|
||||||
mg_http_listen(mgr, HTTP_URL, ev_handler, NULL);
|
|
||||||
mg_http_listen(mgr, HTTPS_URL, ev_handler, (void *) 1);
|
|
||||||
mg_timer_add(mgr, 3600 * 1000, MG_TIMER_RUN_NOW | MG_TIMER_REPEAT,
|
|
||||||
timer_sntp_fn, mgr);
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
// Copyright (c) 2023-2024 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MG_ENABLE_FATFS
|
|
||||||
#define HAL_FS (&mg_fs_fat)
|
|
||||||
#define HAL_ROOT_DIR "/"
|
|
||||||
#elif MG_ENABLE_PACKED_FS
|
|
||||||
#define HAL_FS (&mg_fs_packed)
|
|
||||||
#define HAL_ROOT_DIR "/"
|
|
||||||
#else
|
|
||||||
#define HAL_FS (&mg_fs_posix)
|
|
||||||
#define HAL_ROOT_DIR "./"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define HAL_WEB_ROOT_DIR HAL_ROOT_DIR "web_root"
|
|
||||||
|
|
||||||
#if defined(HTTP_URL) && defined(HTTPS_URL)
|
|
||||||
// Allow to override via the build flags
|
|
||||||
#elif MG_ENABLE_TCPIP
|
|
||||||
#define HTTP_URL "http://0.0.0.0:80" // Embedded build:
|
|
||||||
#define HTTPS_URL "https://0.0.0.0:443" // Use standard privileged ports
|
|
||||||
#else
|
|
||||||
#define HTTP_URL "http://0.0.0.0:8000" // Workstation build:
|
|
||||||
#define HTTPS_URL "https://0.0.0.0:8443" // Use non-privileged ports
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_DEVICE_NAME 40
|
|
||||||
#define MAX_EVENTS_NO 400
|
|
||||||
#define MAX_EVENT_TEXT_SIZE 10
|
|
||||||
#define EVENTS_PER_PAGE 20
|
|
||||||
|
|
||||||
// Event log entry
|
|
||||||
struct ui_event {
|
|
||||||
uint8_t type, prio;
|
|
||||||
unsigned long timestamp;
|
|
||||||
char text[10];
|
|
||||||
};
|
|
||||||
|
|
||||||
void net_init(struct mg_mgr *mgr);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
// DO NOT EDIT. This file is generated using this command:
|
|
||||||
// /usr/local/bin/node /Users/cpq/src/mongoose/reference-projects/windows-macos-linux/web-ui-dashboard/pack.js web_root/bundle.js::gzip web_root/components.js::gzip web_root/history.min.js::gzip web_root/index.html::gzip web_root/main.css::gzip web_root/main.js::gzip certs/server_cert.pem certs/server_key.pem
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *mg_unlist(size_t no);
|
|
||||||
const char *mg_unpack(const char *, size_t *, time_t *);
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const unsigned char v0[] = {31,139,8,0,0,0,0,0,0,19,173,60,253,119,219,54,146,255,138,197,203,227,2,213,132,150,210,118,239,142,10,170,151,186,105,157,54,73,179,249,234,238,170,42,31,69,65,22,107,10,148,65,80,137,107,234,254,246,123,51,0,72,74,150,123,119,251,238,23,11,223,24,12,6,243,77,239,82,125,166,192,128,132,4,52,148,144,67,13,5,100,226,110,15,169,152,205,161,18,231,105,150,155,70,126,102,211,184,106,174,26,213,108,155,71,188,209,219,117,115,165,243,101,83,126,170,154,141,202,26,101,62,53,185,146,179,108,61,111,254,40,203,230,183,82,47,155,220,72,157,158,231,147,85,173,50,147,151,234,108,197,20,24,126,183,42,53,219,165,250,76,158,229,234,204,112,53,147,115,97,102,114,62,209,210,212,90,157,169,125,59,99,203,20,191,195,177,70,168,104,155,106,169,204,235,114,41,39,38,12,77,164,229,166,220,201,139,117,94,44,153,226,221,164,53,163,19,217,137,238,88,226,110,63,193,125,115,220,83,242,224,90,222,6,66,228,83,45,228,44,159,199,129,150,43,170,151,182,94,207,242,57,149,38,249,138,165,250,170,222,72,101,170,168,144,234,202,172,191,121,18,134,172,142,50,220,88,75,37,238,245,127,57,85,81,150,22,69,55,19,158,240,56,225,16,120,24,3,33,204,237,86,150,171,51,19,134,170,46,138,129,48,209,82,174,210,186,48,111,116,185,173,120,11,236,81,251,174,204,151,103,35,33,4,130,136,112,32,164,135,99,102,249,156,123,92,46,153,129,154,238,22,119,233,33,105,201,148,191,116,139,168,90,220,33,72,177,130,45,46,18,39,112,45,111,99,13,90,174,226,18,146,228,58,198,21,32,73,252,239,34,30,65,146,72,95,93,198,22,52,72,146,204,183,173,109,33,43,85,101,116,157,153,82,119,131,118,212,135,56,31,14,101,156,239,219,219,183,173,29,90,118,170,92,74,188,111,42,176,154,67,221,29,99,199,248,157,157,120,151,213,26,233,131,150,221,119,35,54,72,66,126,237,246,210,186,254,91,75,148,102,157,87,17,157,92,40,160,74,86,42,35,63,27,97,186,177,87,118,108,190,98,22,74,195,219,133,147,100,122,197,240,7,240,79,148,36,215,81,174,150,242,243,207,43,166,248,112,204,9,172,73,75,250,19,243,84,209,32,75,50,19,51,28,114,183,236,64,48,41,168,115,102,230,220,227,65,70,73,34,253,118,84,113,8,59,65,83,42,194,2,194,99,183,237,14,176,104,223,19,200,73,183,159,162,253,218,189,176,146,217,119,138,69,11,77,22,45,210,74,10,186,80,35,70,255,226,1,238,238,45,104,207,178,208,50,189,222,187,227,33,148,189,27,188,70,160,217,0,231,44,195,144,64,90,138,193,136,135,161,142,182,117,181,102,138,135,225,224,34,74,18,61,28,54,77,57,16,244,32,22,101,173,50,249,86,170,165,212,185,186,226,97,200,88,121,178,167,105,114,206,46,122,143,227,130,89,44,121,222,136,44,164,128,140,174,79,71,85,169,13,171,249,68,9,29,85,235,124,101,24,159,112,15,157,17,218,161,4,18,225,136,189,244,133,66,176,156,144,195,163,36,217,225,31,9,44,35,20,188,65,248,18,100,186,172,20,43,118,183,135,156,211,40,145,227,223,225,24,222,179,12,114,40,1,71,43,176,43,14,132,200,162,242,147,146,250,221,199,31,158,23,18,153,13,88,124,227,180,245,116,86,204,221,99,4,75,178,197,244,138,229,60,46,128,250,57,188,101,9,228,156,106,114,32,138,48,92,176,156,115,240,135,248,198,32,150,221,137,249,132,144,44,70,29,166,62,179,251,242,163,178,200,91,193,22,214,176,131,91,88,192,53,92,136,36,12,233,93,52,77,10,159,197,133,39,28,196,41,30,233,26,207,190,18,163,201,234,169,105,251,14,136,106,71,136,186,158,173,230,194,158,133,237,132,153,173,230,188,105,130,69,89,22,50,237,189,129,93,211,156,120,25,187,41,206,140,131,202,224,197,31,142,86,245,102,33,245,97,219,34,191,202,149,233,207,95,18,52,176,35,116,218,63,59,30,63,211,58,189,141,242,138,126,217,142,79,151,108,3,119,158,217,196,187,125,111,56,49,226,120,23,37,201,226,155,209,116,201,118,244,90,97,103,185,15,236,162,107,121,11,187,72,203,213,148,254,218,251,219,17,197,196,59,78,236,7,107,66,82,227,130,176,178,24,142,221,5,11,182,22,23,22,43,235,48,164,213,132,88,227,15,214,112,43,129,117,44,112,28,231,104,115,34,139,74,158,225,101,108,197,104,178,125,250,121,178,29,14,105,47,90,111,139,15,249,207,23,187,195,81,126,53,251,158,215,116,81,251,247,76,193,14,214,98,221,52,217,1,157,192,173,216,217,71,176,21,116,86,30,134,107,252,29,136,109,24,178,235,166,97,72,22,28,168,49,12,175,237,123,167,154,199,61,184,198,45,97,35,107,154,91,216,113,238,30,193,237,212,113,234,69,24,178,133,184,61,41,130,237,65,240,64,72,133,120,158,36,185,158,238,136,205,20,226,57,219,65,1,138,199,133,248,96,207,1,23,112,11,197,201,165,164,91,138,40,122,41,10,206,227,2,143,132,60,15,31,87,209,83,98,6,66,133,33,43,196,21,91,115,190,247,207,64,138,5,172,196,231,201,234,241,227,9,183,135,192,91,10,67,246,39,219,117,227,112,133,48,244,37,65,180,177,108,225,121,198,18,30,41,249,217,188,203,23,5,114,62,248,133,225,88,32,130,225,40,17,174,73,243,176,239,240,186,255,14,95,49,124,121,112,61,27,14,219,159,30,203,124,110,25,65,167,221,37,160,173,16,128,82,140,38,58,12,203,167,158,169,76,202,225,144,179,68,232,89,57,39,182,135,212,172,192,136,19,71,76,172,44,123,206,18,90,62,254,192,144,217,32,187,73,136,114,12,111,117,157,158,160,190,180,130,218,119,8,211,52,179,185,123,32,234,20,187,80,77,195,14,31,177,226,83,21,85,229,70,50,230,151,69,5Line truncated
|
|
||||||
|
|
||||||
static const unsigned char v1[] = {31,139,8,0,0,0,0,0,0,19,237,125,107,115,219,70,182,224,119,255,138,19,150,54,36,199,236,22,186,241,150,68,165,28,207,77,57,85,214,220,84,156,232,75,110,118,13,129,32,137,17,30,92,0,164,36,107,248,223,183,206,233,198,147,148,236,100,124,167,118,181,83,149,64,64,163,159,231,253,2,61,222,150,17,148,85,17,135,213,248,252,85,156,110,242,162,130,71,88,207,160,136,178,69,84,204,96,91,70,31,170,160,138,232,238,63,150,203,40,172,232,246,231,104,57,131,117,149,38,51,248,57,223,86,81,1,123,88,22,121,10,48,230,167,55,219,108,145,68,252,239,229,248,252,213,171,211,83,120,23,37,155,168,128,229,54,11,171,56,207,160,90,7,21,20,81,181,45,178,18,2,216,20,121,26,151,81,221,92,230,201,46,42,33,88,226,172,139,40,9,30,94,133,121,86,86,240,87,188,135,57,76,210,114,6,187,32,153,194,252,18,178,232,14,126,82,19,76,244,88,108,46,163,234,151,56,141,242,109,85,183,206,160,30,54,61,127,245,42,186,167,179,170,137,127,196,63,48,135,199,87,0,235,40,40,170,51,220,211,166,196,137,240,140,31,47,202,221,10,194,36,40,203,249,201,35,189,226,244,180,135,251,52,201,202,249,104,93,85,155,179,211,211,187,187,59,126,103,242,188,88,157,74,195,48,78,203,221,106,4,203,56,73,230,163,44,207,162,17,236,226,232,238,251,252,126,62,50,192,0,105,129,180,70,151,23,155,160,90,35,22,242,219,136,37,113,22,133,193,102,62,42,242,109,182,24,117,155,255,158,199,217,176,253,46,94,84,235,249,72,142,96,49,31,93,89,220,20,30,56,120,13,44,110,3,254,111,128,97,24,216,230,88,239,133,4,105,224,93,226,114,199,147,140,174,189,158,140,58,178,166,187,203,29,211,73,152,192,41,213,245,72,119,48,62,141,46,47,78,241,24,151,23,120,230,203,143,179,87,0,139,252,46,123,83,20,57,30,248,95,9,208,1,108,4,183,235,166,249,40,220,22,69,148,85,111,243,36,47,70,151,240,167,64,143,144,246,193,227,210,126,231,114,59,144,92,218,64,23,130,72,243,184,243,7,175,154,167,245,177,55,52,112,199,134,175,88,243,238,157,176,175,124,16,50,49,193,76,13,48,18,147,153,41,51,193,188,198,183,35,56,189,132,14,240,183,155,127,131,254,107,130,62,53,152,153,48,4,57,130,30,193,158,154,204,188,22,7,128,15,243,213,139,131,56,183,125,11,76,238,91,33,55,124,198,109,75,114,219,97,220,183,64,112,33,240,102,45,185,237,155,33,183,17,116,130,27,146,155,190,71,111,185,111,37,92,10,19,4,151,158,8,185,225,152,220,116,81,82,153,220,241,28,238,88,54,247,92,110,184,22,55,44,46,44,151,27,158,201,165,228,66,186,220,148,22,23,190,195,93,196,130,139,19,187,54,23,210,74,4,151,194,101,220,178,157,64,112,33,109,80,87,3,12,33,184,233,114,203,199,46,190,131,216,180,220,131,62,140,75,7,4,183,76,129,178,205,48,76,238,73,55,100,92,250,38,151,22,227,150,233,113,71,152,120,35,184,239,203,192,225,174,237,131,186,226,4,6,112,105,219,33,227,134,225,114,211,245,184,48,61,238,218,220,50,185,143,75,27,134,205,61,233,133,220,146,22,55,109,110,155,22,247,109,171,94,22,87,149,190,247,212,238,4,55,29,159,91,62,237,174,62,104,200,184,105,219,140,11,211,100,220,181,25,55,92,137,155,119,29,132,72,224,112,219,5,186,232,3,34,4,61,28,100,10,46,60,147,113,219,19,220,242,109,198,29,203,226,158,227,39,172,193,11,30,196,231,182,133,189,28,238,91,184,5,66,157,88,51,196,172,21,50,66,45,174,39,25,226,150,213,152,87,179,48,133,93,198,13,7,223,187,22,227,166,144,12,49,76,235,49,238,185,184,69,9,116,169,183,200,16,203,184,71,137,7,243,29,198,93,201,16,213,234,96,140,112,173,96,112,20,215,10,82,12,209,77,16,117,217,113,136,114,233,48,133,110,68,13,238,70,186,33,151,62,46,102,113,203,116,25,162,155,227,249,21,182,125,19,119,138,87,194,54,35,108,35,178,241,112,30,34,193,83,72,80,67,20,21,209,188,222,81,98,163,213,147,231,182,136,100,203,8,231,120,92,135,48,206,77,219,65,124,115,215,70,120,72,104,161,66,216,231,134,133,44,227,48,110,120,174,6,167,199,77,19,111,60,147,219,158,196,25,109,141,0,199,71,70,180,20,170,62,41,185,245,103,69,130,176,65,200,192,4,19,217,93,48,7,12,80,15,134,112,208,28,24,8,197,50,170,170,56,91,149,239,94,154,104,20,6,183,193,89,251,220,181,245,125,32,56,162,213,86,128,49,193,72,77,48,186,141,6,54,94,33,78,193,65,45,150,154,32,36,205,144,50,188,246,122,27,199,166,48,104,138,148,209,28,6,205,225,51,103,109,210,20,230,31,154,66,45,72,171,63,133,179,235,151,134,51,7,132,201,237,107,2,151,1,120,244,30,180,12,52,175,152,217,3,22,181,1,142,184,22,14,183,83,33,153,249,79,77,192,28,230,215,19,152,95,62,129,79,19,24,252,16,89,97,144,189,52,60,185,220,38,216,188,115,222,244,13,51,197,59,59,193,237,43,4,166,234,36,188,126,47,33,13,188,163,110,8,185,235,131,14,194,3,234,179,102,216,133,249,96,12,87,18,180,146,240,118,140,214,250,98,153,7,202,255,137,202,219,42,223,188,52,180,248,32,92,180,151,81,227,185,65,13,1,84,240,62,160,205,33,223,35,226,164,88,163,129,225,72,65,151,55,117,63,4,34,218,239,238,53,205,146,58,76,200,107,49,48,229,69,107,202,191,179,185,180,135,88,1,97,95,99,123,42,60,48,6,196,33,208,14,3,243,200,56,195,132,102,208,181,144,127,116,73,73,75,14,25,47,72,162,127,109,184,224,95,162,213,44,238,161,185,141,182,184,12,164,201,61,203,3,253,7,1,105,115,203,182,40,28,240,198,227,190,227,130,186,106,166,66,33,181,99,220,189Line truncated
|
|
||||||
|
|
||||||
static const unsigned char v2[] = {31,139,8,0,0,0,0,0,0,19,237,91,109,111,219,184,150,254,43,182,6,43,144,48,163,218,157,185,179,187,114,57,70,218,166,47,64,130,4,77,218,249,96,24,3,69,166,108,78,100,210,165,40,39,134,173,255,190,56,164,168,23,91,73,211,189,157,189,131,221,253,18,75,124,61,60,58,60,231,121,14,153,126,146,139,88,115,41,144,38,2,239,60,121,251,39,139,181,71,169,222,174,153,76,122,236,97,45,149,206,124,255,168,102,37,231,121,202,38,246,39,40,219,81,129,112,232,185,49,235,198,115,150,112,193,124,223,254,6,209,106,62,177,143,104,58,35,2,135,143,205,59,41,127,131,15,60,211,82,109,205,248,186,249,86,32,189,228,25,169,150,129,119,138,233,92,137,94,189,48,188,115,207,61,129,36,222,241,4,177,169,156,225,178,33,60,59,249,199,155,72,245,20,133,34,186,43,203,194,93,65,248,60,148,36,149,209,156,205,195,254,168,24,151,93,53,116,141,163,52,69,202,141,64,20,169,159,5,38,42,176,221,104,127,88,87,20,48,13,163,187,106,32,17,172,168,38,34,136,41,35,34,88,83,207,35,2,13,113,129,166,205,239,67,24,222,121,121,198,122,153,86,60,214,222,184,90,151,132,85,58,161,124,95,7,127,252,193,178,11,251,133,116,184,155,179,36,202,83,29,234,162,16,141,42,144,73,4,177,98,145,102,87,145,94,82,17,172,35,149,185,231,84,198,17,140,158,157,42,118,246,53,143,82,234,26,159,151,53,85,193,5,91,73,181,173,62,75,89,250,33,202,150,135,101,175,149,188,207,152,114,197,27,201,231,189,161,83,59,122,137,199,151,198,18,2,107,30,87,74,174,153,210,91,36,136,215,158,218,35,59,38,242,21,83,209,109,202,194,254,144,44,152,14,143,173,64,29,72,92,20,152,60,58,195,209,130,159,61,201,81,207,162,192,102,81,156,50,52,122,98,81,149,190,159,57,21,175,191,208,147,75,169,63,234,179,7,174,187,56,225,35,202,208,191,99,18,83,137,34,76,114,202,208,127,96,146,81,137,114,76,18,202,208,127,98,146,82,137,18,60,126,228,235,198,65,105,121,164,203,36,178,163,218,182,25,165,174,190,32,7,94,170,185,7,14,12,122,44,130,104,62,63,103,209,156,139,197,117,26,101,75,218,244,4,118,181,222,11,143,82,170,131,120,25,169,83,141,134,120,162,67,239,133,55,208,5,17,1,12,188,254,254,1,130,44,191,205,180,66,35,28,214,195,92,41,150,240,7,218,22,191,212,248,208,140,192,197,156,61,92,38,72,52,134,16,65,202,196,66,47,155,35,221,168,136,167,207,151,72,151,67,156,140,204,184,41,143,25,26,146,19,39,92,189,205,155,35,193,55,23,84,239,247,222,11,143,48,112,66,18,254,40,42,42,49,189,159,60,60,86,125,74,79,70,190,143,36,21,78,102,133,137,168,223,134,68,97,183,1,26,157,39,208,185,180,55,55,6,171,123,241,131,49,56,134,130,57,139,229,156,125,254,244,17,9,76,118,235,72,47,69,180,98,161,32,25,139,84,188,12,189,9,172,156,77,60,47,100,100,25,101,203,208,251,9,74,36,148,200,162,104,187,184,142,245,6,110,76,194,168,14,236,168,68,82,29,192,96,68,81,38,42,1,140,106,170,53,48,223,247,38,94,159,82,230,251,72,13,104,41,73,195,42,24,72,55,96,152,72,223,247,126,130,166,178,108,106,69,108,52,149,32,246,64,98,162,138,182,189,255,53,94,255,25,206,189,229,155,75,79,19,101,25,95,136,253,190,21,93,165,66,86,149,163,177,120,21,169,69,190,98,66,103,165,5,142,197,96,96,85,205,104,85,55,21,179,177,235,38,123,92,244,24,46,39,88,43,169,37,128,0,208,254,229,189,112,78,205,134,89,70,36,246,125,4,113,215,4,105,92,184,229,23,196,184,218,33,38,17,149,96,73,49,188,142,192,109,73,20,131,219,50,142,248,104,145,109,77,19,105,69,229,110,241,229,230,2,213,139,69,13,79,244,4,113,138,134,36,171,119,18,70,26,19,30,100,58,210,140,10,28,34,78,21,218,21,68,99,98,199,162,148,242,202,212,124,31,213,47,212,243,76,87,99,121,19,107,82,238,181,182,16,211,197,22,130,165,13,220,11,14,235,98,143,112,99,181,19,107,108,246,229,96,8,40,2,251,27,216,71,232,110,139,188,82,208,62,165,194,247,27,66,155,53,217,233,203,213,129,184,119,108,75,25,24,118,99,37,19,239,133,157,215,21,28,204,93,173,24,13,73,228,220,59,110,84,16,89,61,98,144,172,234,208,40,39,188,232,52,224,78,47,91,239,110,74,13,190,113,250,119,59,221,20,219,71,40,52,170,128,34,120,128,2,88,38,188,223,177,173,239,163,33,201,107,177,181,213,135,113,209,145,102,248,91,27,215,88,59,109,196,222,98,172,43,228,44,255,242,93,95,161,172,159,49,225,20,73,240,217,13,97,160,86,83,145,167,41,105,108,139,134,38,169,104,54,215,212,152,9,178,93,96,237,172,209,11,182,18,81,6,107,67,117,159,106,183,177,58,216,129,158,104,232,129,67,61,62,218,105,124,210,209,65,78,36,226,68,225,80,161,254,16,254,66,52,233,143,112,193,210,140,245,76,97,65,36,157,206,136,234,112,248,253,97,83,84,188,19,160,196,104,189,78,183,200,26,61,169,252,20,174,16,186,12,214,121,182,68,172,165,50,65,251,35,34,169,12,18,158,106,166,208,113,88,238,105,8,15,5,168,135,55,231,116,206,79,211,67,127,73,4,61,85,42,218,130,59,97,116,56,102,175,244,152,13,6,88,76,217,172,225,64,217,108,44,131,68,170,179,40,94,118,206,219,94,145,192,69,181,150,93,198,244,149,146,171,181,14,5,137,165,72,184,90,221,168,72,100,28,198,184,145,33,35,209,122,205,196,252,156,103,154,9,166,66,69,132,212,60,217,186,130,44,228,128,17,133,219,10,148,127,39,68,139,35,241,57,99,111,47,47,104,31,121,185,176,248,117,94,127,224,123,46,230,242,126,191,239,219,135,96,46,99,179,238,227,146,210,1Line truncated
|
|
||||||
|
|
||||||
static const unsigned char v3[] = {31,139,8,0,0,0,0,0,0,19,93,147,77,115,219,32,16,134,239,249,21,91,46,58,52,66,232,91,206,8,205,164,105,14,61,116,218,67,219,105,143,68,90,75,36,8,84,192,114,252,239,59,178,108,215,201,133,133,125,159,133,133,93,234,15,159,191,61,252,248,243,253,17,6,63,170,230,166,94,12,40,161,123,78,80,19,104,149,112,142,147,33,220,238,148,130,167,62,220,15,210,35,105,110,0,234,1,69,183,76,0,106,47,189,194,166,142,86,187,250,70,244,2,218,65,88,135,158,147,157,223,134,21,129,232,90,28,188,159,66,252,187,147,51,39,191,195,159,247,225,131,25,39,225,229,147,66,2,173,209,30,181,231,228,203,35,199,174,199,119,177,90,140,200,201,44,113,63,25,235,175,240,189,236,252,192,59,156,101,139,225,113,113,11,82,75,47,133,10,93,43,20,242,152,178,255,155,41,169,95,192,162,226,68,182,70,19,240,135,9,57,145,163,232,49,114,115,255,241,117,84,4,6,139,91,78,58,225,197,221,27,229,182,118,115,15,175,163,210,142,7,203,109,238,162,104,191,223,211,125,74,141,237,163,132,49,182,160,1,108,165,82,60,208,70,99,0,75,206,159,204,43,15,24,48,72,50,72,178,0,156,183,230,229,148,46,15,98,154,159,93,60,104,119,214,162,246,15,70,25,27,52,80,79,194,15,103,94,73,141,173,152,120,96,205,78,119,193,181,251,217,72,125,241,119,60,248,26,103,180,202,75,136,75,202,170,68,36,41,173,178,10,78,134,1,99,57,205,242,44,140,105,26,223,87,116,83,148,176,142,12,88,28,87,176,161,101,62,135,180,252,181,185,47,160,56,6,20,176,153,105,153,139,247,116,152,208,52,78,160,160,44,73,218,152,150,105,74,139,12,82,154,23,16,83,86,229,176,156,148,195,114,210,152,211,50,206,128,137,36,163,73,158,195,201,28,119,57,73,23,36,133,20,24,196,23,33,128,168,129,122,121,222,230,93,53,215,106,141,66,106,218,58,71,214,234,58,127,80,232,6,68,127,162,235,232,220,191,245,147,233,14,231,78,31,165,14,135,208,181,22,81,147,166,142,22,237,8,185,214,202,201,131,179,45,39,131,116,222,216,3,29,165,166,207,110,193,86,245,26,92,27,105,52,221,110,233,230,99,216,49,165,183,124,29,173,255,238,31,169,238,250,235,136,3,0,0,0};
|
|
||||||
|
|
||||||
static const unsigned char v4[] = {31,139,8,0,0,0,0,0,0,19,237,60,217,142,228,56,114,191,34,247,96,128,202,177,168,214,153,89,169,130,141,53,22,48,188,192,142,31,108,63,120,209,213,15,76,137,153,201,45,93,38,169,170,204,214,202,223,110,4,41,74,212,145,215,28,246,236,194,24,84,87,49,46,6,131,100,40,24,12,206,231,31,254,206,18,152,102,31,180,72,19,206,173,247,192,9,28,223,250,139,245,227,31,254,195,250,35,77,72,193,137,245,23,235,40,68,197,227,207,159,13,82,39,41,243,31,62,255,96,199,120,47,8,179,227,29,217,151,140,52,187,242,132,56,253,70,139,67,188,43,89,74,24,218,149,167,23,245,103,236,90,188,204,104,106,125,71,34,178,33,187,118,194,139,144,248,64,73,89,8,82,136,248,211,167,246,40,242,172,201,104,65,208,145,208,195,81,196,158,19,189,160,15,178,123,163,2,9,114,18,208,19,65,56,253,115,205,69,236,185,238,247,47,40,47,191,33,129,119,18,19,135,47,168,52,91,198,159,251,178,16,104,143,115,154,157,227,63,20,130,48,235,29,51,251,159,24,197,153,253,47,36,123,39,130,38,216,230,184,224,136,19,70,247,29,3,193,162,102,4,113,34,4,45,14,60,254,148,188,123,222,39,251,19,231,174,247,73,209,188,99,70,177,160,101,97,80,149,21,255,246,201,10,252,118,87,166,231,38,199,236,64,139,216,125,49,199,70,139,35,97,84,180,71,214,116,16,247,37,41,179,146,105,76,103,68,36,202,10,125,208,84,28,99,175,58,181,120,183,99,241,199,145,48,242,244,69,80,145,145,175,171,102,100,162,148,36,37,147,250,196,117,145,18,6,125,90,105,41,4,73,95,110,17,180,71,207,62,250,246,49,176,143,161,125,140,236,227,186,145,67,148,54,212,106,73,200,199,120,16,184,25,171,62,237,72,211,237,108,46,88,89,28,26,83,200,174,204,82,194,218,164,76,137,253,182,75,237,138,17,155,227,188,106,204,57,171,41,202,203,162,228,21,78,136,253,239,255,252,99,89,148,232,223,200,161,206,48,179,127,36,69,86,218,63,150,5,78,74,251,247,101,193,203,12,115,251,143,116,71,84,247,22,80,219,191,47,107,70,9,179,254,149,124,216,189,168,151,97,124,30,201,91,158,227,44,51,198,252,236,126,223,242,122,103,243,186,50,160,155,232,251,209,84,186,47,85,201,169,28,40,35,25,22,244,157,188,188,19,6,43,42,67,56,163,7,48,0,21,20,103,32,172,217,149,66,148,121,140,28,63,130,46,235,170,17,101,21,35,7,90,2,239,50,210,72,243,209,34,133,125,225,234,117,176,184,56,146,50,203,112,197,73,172,255,104,119,181,16,101,97,211,162,170,133,93,86,226,192,202,186,178,57,201,72,34,108,16,140,25,193,35,211,142,38,86,153,2,182,214,194,60,47,45,224,201,162,237,215,122,133,211,20,188,130,171,53,82,42,168,177,9,134,11,190,47,89,30,23,101,65,218,47,226,92,145,127,80,116,95,109,213,98,132,19,161,27,188,222,229,84,124,181,21,73,191,224,113,85,17,204,112,145,144,88,97,94,118,56,121,131,17,23,105,111,47,105,120,19,65,115,124,32,170,227,88,250,143,125,153,212,156,209,226,208,148,181,128,33,198,184,22,101,135,172,41,162,197,59,206,104,170,124,221,17,167,229,135,226,174,88,121,96,132,243,230,194,100,199,177,86,148,22,5,97,136,87,180,64,157,53,6,92,89,139,49,78,251,3,169,68,55,126,130,89,114,252,186,52,112,176,231,158,146,44,125,233,148,71,229,126,207,137,136,145,95,157,12,21,148,8,99,83,46,9,83,70,233,121,246,52,35,168,174,178,18,167,232,166,233,97,189,244,27,157,215,121,142,217,185,73,41,175,50,124,142,51,202,5,162,130,228,237,46,43,147,183,255,170,75,65,236,52,181,211,204,222,211,67,205,136,61,115,61,246,145,217,21,56,131,222,127,182,114,156,156,136,57,196,206,200,129,20,105,51,172,186,156,20,181,93,102,118,13,159,20,46,16,23,231,76,13,112,105,141,246,27,131,17,185,3,244,140,182,114,31,197,106,41,84,25,78,200,81,122,171,126,39,205,81,77,89,225,132,138,115,236,117,91,227,187,109,130,3,188,215,162,150,165,220,35,224,11,43,179,97,155,116,19,146,212,140,151,44,174,74,10,95,181,54,78,41,7,31,146,106,68,74,246,184,206,68,139,235,148,150,118,130,139,119,204,109,146,239,72,106,211,61,195,57,177,105,126,176,203,221,159,193,63,240,247,131,253,78,83,82,246,19,39,167,107,234,205,114,154,166,25,105,129,81,81,231,248,164,191,81,224,58,70,11,248,72,211,148,20,95,123,137,114,141,253,96,199,49,108,201,148,149,213,52,164,144,97,65,231,223,192,73,211,226,128,78,177,251,178,4,63,107,184,244,40,25,22,100,32,29,64,61,21,43,5,22,68,183,248,27,249,24,200,101,171,167,228,9,206,64,150,103,54,207,186,89,225,2,157,98,107,104,156,251,6,45,146,35,250,86,150,185,134,240,132,149,89,134,120,129,43,196,5,163,137,40,8,231,113,197,202,19,205,169,56,43,170,3,195,41,37,224,148,89,153,163,254,123,98,77,176,239,20,95,70,138,114,134,43,89,74,11,156,245,186,100,152,31,73,138,190,17,86,106,88,81,231,132,209,4,169,125,56,133,118,134,158,17,51,156,152,253,128,247,68,180,0,191,99,66,148,43,234,150,134,91,157,230,168,110,133,239,247,123,3,215,1,131,221,179,191,95,63,187,115,174,206,11,187,150,107,125,231,186,174,73,177,140,186,6,85,221,145,116,138,221,101,53,211,163,217,49,88,209,114,226,58,8,196,173,12,115,97,204,194,89,174,18,13,56,214,68,175,183,14,66,11,216,71,253,92,64,104,105,96,57,169,40,214,13,216,23,90,105,173,66,183,93,198,122,245,192,153,130,61,106,170,105,143,152,169,220,99,230,186,247,168,241,32,122,176,246,89,83,248,116,148,3,66,13,183,117,56,67,101,145,157,155,126,233,226Line truncated
|
|
||||||
|
|
||||||
static const unsigned char v5[] = {31,139,8,0,0,0,0,0,0,19,189,59,107,115,219,56,146,223,253,43,122,180,222,145,228,33,41,82,150,223,150,167,146,76,102,146,173,76,146,138,157,212,237,186,92,9,68,66,36,198,36,193,2,160,215,104,248,159,238,55,220,47,187,106,128,79,73,86,50,179,123,151,170,200,36,1,116,55,26,141,126,161,49,24,0,188,125,119,247,242,18,158,189,127,13,62,137,99,9,201,76,42,144,138,8,5,11,166,34,232,146,140,13,186,192,82,224,34,160,2,20,7,73,197,156,130,138,40,144,44,3,162,128,164,43,248,248,225,245,193,65,119,38,41,72,37,152,175,186,87,7,44,201,184,80,176,134,200,2,65,211,128,10,11,102,146,222,42,162,168,126,122,57,157,82,95,233,199,15,116,106,65,164,146,216,130,15,124,166,168,128,28,166,130,39,0,93,103,48,153,165,65,76,157,223,100,19,232,107,159,167,210,130,55,60,100,169,5,183,84,41,150,134,22,60,159,41,197,241,131,34,202,2,197,178,23,60,230,66,90,160,255,210,192,130,183,92,177,41,243,137,98,216,239,61,9,89,90,60,127,204,98,78,130,159,89,76,13,148,146,134,174,51,240,121,146,241,148,166,74,26,50,14,16,187,66,236,28,198,144,9,158,73,24,223,232,25,124,185,150,243,16,252,152,72,57,62,92,235,38,71,191,229,176,76,226,84,142,59,145,82,217,229,96,176,88,44,156,197,177,195,69,56,24,186,174,59,144,243,176,3,115,70,23,207,249,114,220,113,193,5,111,232,156,159,233,223,147,206,205,117,64,167,242,230,90,170,85,76,111,156,56,182,253,88,218,222,122,202,226,248,50,229,41,189,146,74,240,71,122,249,55,215,117,139,103,59,97,138,138,152,37,76,93,122,213,199,5,11,84,116,233,58,39,217,242,42,191,30,24,128,215,3,3,62,4,22,140,59,111,200,138,138,207,195,14,4,68,17,59,37,9,45,190,193,176,211,238,227,217,187,122,121,157,155,235,140,168,168,96,67,167,164,182,3,193,184,243,171,55,116,78,135,150,231,156,15,63,157,59,23,222,51,207,57,57,183,244,143,107,185,150,103,121,158,229,185,206,232,252,213,136,120,206,104,100,233,31,221,100,123,182,115,124,246,204,57,189,112,78,47,138,222,67,231,124,100,121,110,108,59,158,237,120,67,226,156,123,206,185,87,244,119,188,19,219,25,157,127,58,113,78,206,136,115,126,230,156,159,21,195,156,243,83,219,57,63,125,53,114,206,142,63,157,57,195,115,226,156,159,58,231,167,186,217,181,244,203,201,171,11,103,132,16,79,156,243,147,170,225,196,118,206,79,62,29,59,163,147,103,173,33,158,235,120,199,214,177,229,156,157,58,103,245,71,77,32,113,134,23,206,208,144,236,34,153,182,227,225,188,46,204,143,249,172,39,247,106,232,28,95,124,66,230,32,95,206,44,253,99,72,30,89,206,240,228,149,231,109,53,212,12,253,87,103,176,151,243,200,86,195,220,79,222,54,227,207,157,11,13,235,213,78,244,206,240,196,242,188,79,199,206,197,104,155,2,231,124,104,13,145,252,115,231,130,180,39,230,225,216,227,179,216,241,134,142,71,26,220,241,44,199,243,28,111,212,224,34,126,26,57,163,179,114,69,42,198,123,182,121,121,117,238,120,199,229,114,214,204,183,205,178,156,190,194,101,105,46,52,182,96,183,79,23,206,168,41,26,174,229,120,39,206,232,60,118,60,45,52,181,68,97,203,177,227,121,86,91,246,92,51,11,205,224,65,88,252,151,243,240,230,203,213,193,193,116,150,250,168,67,224,21,37,1,21,189,117,204,67,62,51,170,77,88,32,169,186,141,248,226,150,5,116,66,240,189,126,201,251,176,62,0,16,84,205,68,106,244,199,193,117,192,230,229,250,77,66,123,17,49,133,106,149,249,143,43,80,60,179,93,248,221,190,31,157,63,192,114,97,79,103,113,12,19,173,155,237,9,100,43,123,8,135,235,6,124,248,254,123,232,102,177,125,54,236,230,160,4,73,37,67,66,109,18,199,16,204,132,214,124,246,177,235,154,182,41,23,73,231,230,0,160,73,66,182,180,135,80,96,202,86,182,11,9,254,76,99,186,4,166,104,34,109,159,166,138,10,61,14,224,122,98,116,167,90,101,116,220,49,47,29,224,169,31,51,255,113,124,184,166,115,84,148,109,142,244,244,183,239,230,253,188,196,169,232,82,217,50,38,138,218,35,215,45,64,3,92,31,174,181,222,119,38,68,200,227,170,119,100,159,118,96,80,224,31,148,15,141,41,104,98,241,199,246,32,36,153,189,180,71,32,105,60,181,165,18,84,249,17,196,225,165,249,126,90,227,106,140,23,52,38,138,205,41,52,0,117,110,42,84,59,144,53,57,83,161,220,129,5,224,90,102,36,109,207,59,129,205,249,199,60,12,105,128,102,152,200,75,56,92,163,92,229,13,252,109,10,34,22,4,52,69,116,147,152,251,143,248,16,25,244,11,59,91,234,239,161,29,10,178,178,135,174,219,1,34,24,177,205,152,113,71,137,25,109,77,77,115,221,24,196,28,20,83,49,106,121,45,222,29,96,62,79,199,229,154,24,153,207,27,107,93,126,169,217,52,104,175,146,254,131,63,95,174,14,242,230,62,42,5,99,61,19,177,217,47,197,70,49,118,247,45,153,191,97,233,35,140,161,183,214,36,89,154,20,11,34,129,142,196,76,196,121,191,178,199,133,56,23,136,137,238,51,238,252,237,112,141,15,121,167,100,154,121,135,241,24,135,195,143,208,157,132,197,10,156,184,102,61,38,241,140,218,167,174,11,161,224,179,172,11,151,208,213,223,53,39,207,92,23,34,62,167,226,178,221,215,124,43,249,125,82,14,206,141,40,25,113,56,6,193,103,105,64,3,59,9,32,179,135,80,138,65,76,73,192,210,208,62,133,41,79,149,45,105,194,38,60,14,154,251,1,231,93,109,132,133,125,10,184,25,42,134,31,26,246,228,37,211,43,174,127,185,250,138,214,153,51,30,83,101,123,56,5,105,227,36,98,178,106,60,218,60,163,2Line truncated
|
|
||||||
|
|
||||||
static const unsigned char v6[] = {45,45,45,45,45,66,69,71,73,78,32,67,69,82,84,73,70,73,67,65,84,69,45,45,45,45,45,10,77,73,73,66,67,84,67,66,115,65,73,74,65,75,57,119,98,73,68,107,72,110,65,111,77,65,111,71,67,67,113,71,83,77,52,57,66,65,77,67,77,65,48,120,67,122,65,74,66,103,78,86,66,65,89,84,65,107,108,70,77,66,52,88,10,68,84,73,122,77,68,69,121,79,84,73,120,77,106,69,122,79,70,111,88,68,84,77,122,77,68,69,121,78,106,73,120,77,106,69,122,79,70,111,119,68,84,69,76,77,65,107,71,65,49,85,69,66,104,77,67,83,85,85,119,87,84,65,84,10,66,103,99,113,104,107,106,79,80,81,73,66,66,103,103,113,104,107,106,79,80,81,77,66,66,119,78,67,65,65,82,122,83,81,83,53,79,72,100,49,55,108,85,101,78,73,43,54,107,112,57,87,89,117,48,99,120,117,69,73,105,47,74,84,10,106,112,104,98,67,109,100,74,68,49,99,85,118,104,109,122,77,57,47,112,104,118,74,84,57,107,97,49,48,90,57,116,111,90,104,103,110,66,113,48,111,48,120,102,84,81,52,106,67,49,118,119,77,65,111,71,67,67,113,71,83,77,52,57,10,66,65,77,67,65,48,103,65,77,69,85,67,73,81,67,101,48,84,50,69,48,71,79,105,86,101,57,75,119,118,73,69,80,101,88,49,74,49,74,48,84,55,84,78,97,99,103,82,48,89,97,51,51,72,86,57,86,103,73,103,78,118,100,110,10,97,69,87,105,66,112,49,120,115,104,115,52,105,122,54,87,98,112,120,114,83,49,73,72,117,99,114,113,107,90,117,74,76,102,78,90,71,90,73,61,10,45,45,45,45,45,69,78,68,32,67,69,82,84,73,70,73,67,65,84,69,45,45,45,45,45,10,0};
|
|
||||||
|
|
||||||
static const unsigned char v7[] = {45,45,45,45,45,66,69,71,73,78,32,69,67,32,80,82,73,86,65,84,69,32,75,69,89,45,45,45,45,45,10,77,72,99,67,65,81,69,69,73,67,66,122,51,72,79,107,81,76,80,66,68,116,100,107,110,113,67,55,107,49,80,78,115,87,106,54,72,102,104,121,78,66,53,77,101,110,102,106,109,113,105,111,111,65,111,71,67,67,113,71,83,77,52,57,10,65,119,69,72,111,85,81,68,81,103,65,69,99,48,107,69,117,84,104,51,100,101,53,86,72,106,83,80,117,112,75,102,86,109,76,116,72,77,98,104,67,73,118,121,85,52,54,89,87,119,112,110,83,81,57,88,70,76,52,90,115,122,80,102,10,54,89,98,121,85,47,90,71,116,100,71,102,98,97,71,89,89,74,119,97,116,75,78,77,88,48,48,79,73,119,116,98,56,65,61,61,10,45,45,45,45,45,69,78,68,32,69,67,32,80,82,73,86,65,84,69,32,75,69,89,45,45,45,45,45,10,0};
|
|
||||||
|
|
||||||
static const struct packed_file {
|
|
||||||
const char *name;
|
|
||||||
const unsigned char *data;
|
|
||||||
size_t size;
|
|
||||||
time_t mtime;
|
|
||||||
} packed_files[] = {
|
|
||||||
{"/web_root/bundle.js.gz", v0, sizeof(v0) - 1, 1710000285},
|
|
||||||
{"/web_root/components.js.gz", v1, sizeof(v1) - 1, 1713984696},
|
|
||||||
{"/web_root/history.min.js.gz", v2, sizeof(v2) - 1, 1710000285},
|
|
||||||
{"/web_root/index.html.gz", v3, sizeof(v3) - 1, 1710000285},
|
|
||||||
{"/web_root/main.css.gz", v4, sizeof(v4) - 1, 1713984502},
|
|
||||||
{"/web_root/main.js.gz", v5, sizeof(v5) - 1, 1713984681},
|
|
||||||
{"/certs/server_cert.pem", v6, sizeof(v6) - 1, 1710000285},
|
|
||||||
{"/certs/server_key.pem", v7, sizeof(v7) - 1, 1710000285},
|
|
||||||
{NULL, NULL, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int scmp(const char *a, const char *b) {
|
|
||||||
while (*a && (*a == *b)) a++, b++;
|
|
||||||
return *(const unsigned char *) a - *(const unsigned char *) b;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *mg_unlist(size_t no) {
|
|
||||||
return packed_files[no].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *mg_unpack(const char *name, size_t *size, time_t *mtime) {
|
|
||||||
const struct packed_file *p;
|
|
||||||
for (p = packed_files; p->name != NULL; p++) {
|
|
||||||
if (scmp(p->name, name) != 0) continue;
|
|
||||||
if (size != NULL) *size = p->size;
|
|
||||||
if (mtime != NULL) *mtime = p->mtime;
|
|
||||||
return (const char *) p->data;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
var n,t,e,_,r,o,i,u,l,c={},a=[],s=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function f(n,t){for(var e in t)n[e]=t[e];return n}function p(n){var t=n.parentNode;t&&t.removeChild(n)}function h(t,e,_){var r,o,i,u={};for(i in e)"key"==i?r=e[i]:"ref"==i?o=e[i]:u[i]=e[i];if(arguments.length>2&&(u.children=arguments.length>3?n.call(arguments,2):_),"function"==typeof t&&null!=t.defaultProps)for(i in t.defaultProps)void 0===u[i]&&(u[i]=t.defaultProps[i]);return d(t,u,r,o,null)}function d(n,_,r,o,i){var u={type:n,props:_,key:r,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==i?++e:i};return null==i&&null!=t.vnode&&t.vnode(u),u}function v(){return{current:null}}function m(n){return n.children}function y(n,t){this.props=n,this.context=t}function g(n,t){if(null==t)return n.__?g(n.__,n.__.__k.indexOf(n)+1):null;for(var e;t<n.__k.length;t++)if(null!=(e=n.__k[t])&&null!=e.__e)return e.__e;return"function"==typeof n.type?g(n):null}function b(n){var t,e;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,t=0;t<n.__k.length;t++)if(null!=(e=n.__k[t])&&null!=e.__e){n.__e=n.__c.base=e.__e;break}return b(n)}}function k(n){(!n.__d&&(n.__d=!0)&&r.push(n)&&!C.__r++||o!==t.debounceRendering)&&((o=t.debounceRendering)||i)(C)}function C(){var n,t,e,_,o,i,l,c;for(r.sort(u);n=r.shift();)n.__d&&(t=r.length,_=void 0,o=void 0,l=(i=(e=n).__v).__e,(c=e.__P)&&(_=[],(o=f({},i)).__v=i.__v+1,T(c,i,o,e.__n,void 0!==c.ownerSVGElement,null!=i.__h?[l]:null,_,null==l?g(i):l,i.__h),R(_,i),i.__e!=l&&b(i)),r.length>t&&r.sort(u));C.__r=0}function x(n,t,e,_,r,o,i,u,l,s){var f,p,h,v,y,b,k,C=_&&_.__k||a,x=C.length;for(e.__k=[],f=0;f<t.length;f++)if(null!=(v=e.__k[f]=null==(v=t[f])||"boolean"==typeof v||"function"==typeof v?null:"string"==typeof v||"number"==typeof v||"bigint"==typeof v?d(null,v,null,null,v):Array.isArray(v)?d(m,{children:v},null,null,null):v.__b>0?d(v.type,v.props,v.key,v.ref?v.ref:null,v.__v):v)){if(v.__=e,v.__b=e.__b+1,null===(h=C[f])||h&&v.key==h.key&&v.type===h.type)C[f]=void 0;else for(p=0;p<x;p++){if((h=C[p])&&v.key==h.key&&v.type===h.type){C[p]=void 0;break}h=null}T(n,v,h=h||c,r,o,i,u,l,s),y=v.__e,(p=v.ref)&&h.ref!=p&&(k||(k=[]),h.ref&&k.push(h.ref,null,v),k.push(p,v.__c||y,v)),null!=y?(null==b&&(b=y),"function"==typeof v.type&&v.__k===h.__k?v.__d=l=E(v,l,n):l=U(n,v,h,C,y,l),"function"==typeof e.type&&(e.__d=l)):l&&h.__e==l&&l.parentNode!=n&&(l=g(h))}for(e.__e=b,f=x;f--;)null!=C[f]&&("function"==typeof e.type&&null!=C[f].__e&&C[f].__e==e.__d&&(e.__d=A(_).nextSibling),W(C[f],C[f]));if(k)for(f=0;f<k.length;f++)M(k[f],k[++f],k[++f])}function E(n,t,e){for(var _,r=n.__k,o=0;r&&o<r.length;o++)(_=r[o])&&(_.__=n,t="function"==typeof _.type?E(_,t,e):U(e,_,_,r,_.__e,t));return t}function H(n,t){return t=t||[],null==n||"boolean"==typeof n||(Array.isArray(n)?n.some((function(n){H(n,t)})):t.push(n)),t}function U(n,t,e,_,r,o){var i,u,l;if(void 0!==t.__d)i=t.__d,t.__d=void 0;else if(null==e||r!=o||null==r.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(r),i=null;else{for(u=o,l=0;(u=u.nextSibling)&&l<_.length;l+=1)if(u==r)break n;n.insertBefore(r,o),i=o}return void 0!==i?i:r.nextSibling}function A(n){var t,e,_;if(null==n.type||"string"==typeof n.type)return n.__e;if(n.__k)for(t=n.__k.length-1;t>=0;t--)if((e=n.__k[t])&&(_=A(e)))return _;return null}function P(n,t,e,_,r){var o;for(o in e)"children"===o||"key"===o||o in t||N(n,o,null,e[o],_);for(o in t)r&&"function"!=typeof t[o]||"children"===o||"key"===o||"value"===o||"checked"===o||e[o]===t[o]||N(n,o,t[o],e[o],_)}function S(n,t,e){"-"===t[0]?n.setProperty(t,null==e?"":e):n[t]=null==e?"":"number"!=typeof e||s.test(t)?e:e+"px"}function N(n,t,e,_,r){var o;n:if("style"===t)if("string"==typeof e)n.style.cssText=e;else{if("string"==typeof _&&(n.style.cssText=_=""),_)for(t in _)e&&t in e||S(n.style,t,"");if(e)for(t in e)_&&e[t]===_[t]||S(n.style,t,e[t])}else if("o"===t[0]&&"n"===t[1])o=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in n?t.toLowerCase().slice(2):t.slice(2),n.l||(n.l={}),n.l[t+o]=e,e?_||n.addEventListener(t,o?D:w,o):n.removeEventListener(t,o?D:w,o);else if("dangerouslySetInnerHTML"!==t){if(r)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in n)try{n[t]=null==e?"":e;break n}catch(n){}"function"==typeof e||(null==e||!1===e&&"-"!==t[4]?n.removeAttribute(t):n.setAttribute(t,e))}}function w(n){return this.l[n.type+!1](t.event?t.event(n):n)}function D(n){return this.l[n.type+!0](t.event?t.event(n):n)}function T(n,e,_,r,o,i,u,l,c){var a,s,p,h,d,v,g,b,k,C,E,H,U,A,P,S=e.type;if(void 0!==e.constructor)return null;null!=_.__h&&(c=_.__h,l=e.__e=_.__e,e.__h=null,i=[l]),(a=t.__b)&&a(e);try{n:if("function"==typeof S){if(b=e.props,k=(a=S.contextType)&&r[a.__c],C=a?k?k.props.value:a.__:r,_.__c?g=(s=e.__c=_.__c).__=s.__E:("prototype"in S&&S.prototype.render?e.__c=s=new S(b,C):(e.__c=s=new y(b,C),s.constructor=S,s.rLine truncated
|
|
||||||
@@ -1,356 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
import { h, render, useState, useEffect, useRef, html, Router } from './bundle.js';
|
|
||||||
|
|
||||||
// Helper function that returns a promise that resolves after delay
|
|
||||||
const Delay = (ms, val) => new Promise(resolve => setTimeout(resolve, ms, val));
|
|
||||||
|
|
||||||
export const Icons = {
|
|
||||||
heart: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path></svg>`,
|
|
||||||
downArrowBox: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15M9 12l3 3m0 0l3-3m-3 3V2.25" /> </svg>`,
|
|
||||||
upArrowBox: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg>`,
|
|
||||||
cog: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" /> <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> </svg>`,
|
|
||||||
settingsH: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75" /> </svg>`,
|
|
||||||
settingsV: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M6 13.5V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m12-3V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m-6-9V3.75m0 3.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 9.75V10.5" /> </svg>`,
|
|
||||||
scan: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M7.5 3.75H6A2.25 2.25 0 003.75 6v1.5M16.5 3.75H18A2.25 2.25 0 0120.25 6v1.5m0 9V18A2.25 2.25 0 0118 20.25h-1.5m-9 0H6A2.25 2.25 0 013.75 18v-1.5M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> </svg> `,
|
|
||||||
desktop: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 17.25v1.007a3 3 0 01-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0115 18.257V17.25m6-12V15a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15V5.25m18 0A2.25 2.25 0 0018.75 3H5.25A2.25 2.25 0 003 5.25m18 0V12a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 12V5.25" /> </svg>`,
|
|
||||||
alert: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0M3.124 7.5A8.969 8.969 0 015.292 3m13.416 0a8.969 8.969 0 012.168 4.5" /> </svg>`,
|
|
||||||
bell: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0M3.124 7.5A8.969 8.969 0 015.292 3m13.416 0a8.969 8.969 0 012.168 4.5" /> </svg>`,
|
|
||||||
refresh: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" /> </svg> `,
|
|
||||||
bars4: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 5.25h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5m-16.5 4.5h16.5" /> </svg>`,
|
|
||||||
bars3: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" /> </svg>`,
|
|
||||||
logout: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12.75 15l3-3m0 0l-3-3m3 3h-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg>`,
|
|
||||||
save: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9" /> </svg>`,
|
|
||||||
email: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" /> </svg>`,
|
|
||||||
expand: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15" /> </svg>`,
|
|
||||||
shrink: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 9V4.5M9 9H4.5M9 9L3.75 3.75M9 15v4.5M9 15H4.5M9 15l-5.25 5.25M15 9h4.5M15 9V4.5M15 9l5.25-5.25M15 15h4.5M15 15v4.5m0-4.5l5.25 5.25" /> </svg>`,
|
|
||||||
ok: props => html`<svg class=${props.class} fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg>`,
|
|
||||||
fail: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg>`,
|
|
||||||
upload: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" /> </svg> `,
|
|
||||||
download: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" /> </svg> `,
|
|
||||||
bolt: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>`,
|
|
||||||
home: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" /> </svg> `,
|
|
||||||
link: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244" /> </svg> `,
|
|
||||||
shield: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z" /> </svg> `,
|
|
||||||
barsdown: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M3 4.5h14.25M3 9h9.75M3 13.5h9.75m4.5-4.5v12m0 0l-3.75-3.75M17.25 21L21 17.25" /> </svg> `,
|
|
||||||
arrowdown: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m0 0l6.75-6.75M12 19.5l-6.75-6.75" /> </svg> `,
|
|
||||||
arrowup: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 19.5v-15m0 0l-6.75 6.75M12 4.5l6.75 6.75" /> </svg>`,
|
|
||||||
warn: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" /> </svg>`,
|
|
||||||
info: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" /> </svg>`,
|
|
||||||
exclamationTriangle: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" /> </svg>`,
|
|
||||||
thumbUp: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M6.633 10.5c.806 0 1.533-.446 2.031-1.08a9.041 9.041 0 012.861-2.4c.723-.384 1.35-.956 1.653-1.715a4.498 4.498 0 00.322-1.672V3a.75.75 0 01.75-.75A2.25 2.25 0 0116.5 4.5c0 1.152-.26 2.243-.723 3.218-.266.558.107 1.282.725 1.282h3.126c1.026 0 1.945.694 2.054 1.715.045.422.068.85.068 1.285a11.95 11.95 0 01-2.649 7.521c-.388.482-.987.729-1.605.729H13.48c-.483 0-.964-.078-1.423-.23l-3.114-1.04a4.501 4.501 0 00-1.423-.23H5.904M14.25 9h2.25M5.904 18.75c.083.205.173.405.27.602.197.4-.078.898-.523.898h-.908c-.889 0-1.713-.518-1.972-1.368a12 12 0 01-.521-3.507c0-1.553.295-3.036.831-4.398C3.387 10.203 4.167 9.75 5 9.75h1.053c.472 0 .745.556.5.96a8.958 8.958 0 00-1.302 4.665c0 1.194.232 2.333.654 3.375z" /> </svg>`,
|
|
||||||
backward: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M21 16.811c0 .864-.933 1.405-1.683.977l-7.108-4.062a1.125 1.125 0 010-1.953l7.108-4.062A1.125 1.125 0 0121 8.688v8.123zM11.25 16.811c0 .864-.933 1.405-1.683.977l-7.108-4.062a1.125 1.125 0 010-1.953L9.567 7.71a1.125 1.125 0 011.683.977v8.123z" /> </svg>`,
|
|
||||||
chip: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 3v1.5M4.5 8.25H3m18 0h-1.5M4.5 12H3m18 0h-1.5m-15 3.75H3m18 0h-1.5M8.25 19.5V21M12 3v1.5m0 15V21m3.75-18v1.5m0 15V21m-9-1.5h10.5a2.25 2.25 0 002.25-2.25V6.75a2.25 2.25 0 00-2.25-2.25H6.75A2.25 2.25 0 004.5 6.75v10.5a2.25 2.25 0 002.25 2.25zm.75-12h9v9h-9v-9z" /> </svg>`,
|
|
||||||
camera: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 015.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 00-1.134-.175 2.31 2.31 0 01-1.64-1.055l-.822-1.316a2.192 2.192 0 00-1.736-1.039 48.774 48.774 0 00-5.232 0 2.192 2.192 0 00-1.736 1.039l-.821 1.316z" /> <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zM18.75 10.5h.008v.008h-.008V10.5z" /> </svg>`,
|
|
||||||
arrows: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5" /> </svg>`,
|
|
||||||
doc: props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>`,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const tipColors = {
|
|
||||||
green: 'bg-green-100 text-green-900 ring-green-300',
|
|
||||||
yellow: 'bg-yellow-100 text-yellow-900 ring-yellow-300',
|
|
||||||
red: 'bg-red-100 text-red-900 ring-red-300',
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Button({title, onclick, disabled, cls, icon, ref, colors, hovercolor, disabledcolor}) {
|
|
||||||
const [spin, setSpin] = useState(false);
|
|
||||||
const cb = function(ev) {
|
|
||||||
const res = onclick ? onclick() : null;
|
|
||||||
if (res && typeof (res.catch) === 'function') {
|
|
||||||
setSpin(true);
|
|
||||||
res.catch(() => false).then(() => setSpin(false));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!colors) colors = 'bg-blue-600 hover:bg-blue-500 disabled:bg-blue-400';
|
|
||||||
return html`
|
|
||||||
<button type="button" class="inline-flex justify-center items-center gap-2 rounded px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm ${colors} ${cls}"
|
|
||||||
ref=${ref} onclick=${cb} disabled=${disabled || spin} >
|
|
||||||
${title}
|
|
||||||
<${spin ? Icons.refresh : icon} class="w-4 ${spin ? 'animate-spin' : ''}" />
|
|
||||||
<//>`
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Notification({ok, text, close}) {
|
|
||||||
const closebtn = useRef(null);
|
|
||||||
const from = 'translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2';
|
|
||||||
const to = 'translate-y-0 opacity-100 sm:translate-x-0';
|
|
||||||
const [tr, setTr] = useState(from);
|
|
||||||
useEffect(function() {
|
|
||||||
setTr(to);
|
|
||||||
setTimeout(ev => closebtn && closebtn.current.click && closebtn.current.click(), 1500);
|
|
||||||
}, []);
|
|
||||||
const onclose = ev => { setTr(from); setTimeout(close, 300); };
|
|
||||||
return html`
|
|
||||||
<div aria-live="assertive" class="z-10 pointer-events-none absolute inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6">
|
|
||||||
<div class="flex w-full flex-col items-center space-y-4 sm:items-end">
|
|
||||||
<div class="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5 transform ease-out duration-300 transition ${tr}">
|
|
||||||
<div class="p-4">
|
|
||||||
<div class="flex items-start">
|
|
||||||
<div class="flex-shrink-0">
|
|
||||||
<${ok ? Icons.ok : Icons.fail} class="h-6 w-6 ${ok ? 'text-green-400' : 'text-red-400'}" />
|
|
||||||
<//>
|
|
||||||
<div class="ml-3 w-0 flex-1 pt-0.5">
|
|
||||||
<p class="text-sm font-medium text-gray-900">${text}</p>
|
|
||||||
<p class="hidden mt-1 text-sm text-gray-500">Anyone with a link can now view this file.</p>
|
|
||||||
<//>
|
|
||||||
<div class="ml-4 flex flex-shrink-0">
|
|
||||||
<button type="button" ref=${closebtn} onclick=${onclose} class="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none">
|
|
||||||
<span class="sr-only">Close</span>
|
|
||||||
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
||||||
<path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Login({loginFn, logoIcon, title, tipText}) {
|
|
||||||
const [user, setUser] = useState('');
|
|
||||||
const [pass, setPass] = useState('');
|
|
||||||
const onsubmit = function(ev) {
|
|
||||||
const authhdr = 'Basic ' + btoa(user + ':' + pass);
|
|
||||||
const headers = {Authorization: authhdr};
|
|
||||||
return fetch('api/login', {headers}).then(loginFn).finally(r => setPass(''));
|
|
||||||
};
|
|
||||||
return html`
|
|
||||||
<div class="h-screen flex items-center justify-center bg-slate-200">
|
|
||||||
<div class="border rounded bg-white w-96 p-5">
|
|
||||||
<div class="my-5 py-2 flex items-center justify-center gap-x-4">
|
|
||||||
<${logoIcon} class="h-12 stroke-cyan-600 stroke-1" />
|
|
||||||
<h1 class="font-bold text-xl">${title || 'Login'}<//>
|
|
||||||
<//>
|
|
||||||
<div class="my-3">
|
|
||||||
<label class="block text-sm mb-1 dark:text-white">Username</label>
|
|
||||||
<input type="text" autocomplete="current-user" required
|
|
||||||
class="font-normal bg-white rounded border border-gray-300 w-full
|
|
||||||
flex-1 py-0.5 px-2 text-gray-900 placeholder:text-gray-400
|
|
||||||
focus:outline-none sm:text-sm sm:leading-6 disabled:cursor-not-allowed
|
|
||||||
disabled:bg-gray-100 disabled:text-gray-500"
|
|
||||||
oninput=${ev => setUser(ev.target.value)} value=${user} />
|
|
||||||
<//>
|
|
||||||
<div class="my-3">
|
|
||||||
<label class="block text-sm mb-1 dark:text-white">Password</label>
|
|
||||||
<input type="password" autocomplete="current-password" required
|
|
||||||
class="font-normal bg-white rounded border border-gray-300 w-full flex-1 py-0.5 px-2 text-gray-900 placeholder:text-gray-400 focus:outline-none sm:text-sm sm:leading-6 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:text-gray-500"
|
|
||||||
oninput=${ev => setPass(ev.target.value)}
|
|
||||||
value=${pass} onchange=${onsubmit} />
|
|
||||||
<//>
|
|
||||||
<div class="mt-7">
|
|
||||||
<${Button} title="Sign In" icon=${Icons.logout} onclick=${onsubmit} cls="flex w-full justify-center" />
|
|
||||||
<//>
|
|
||||||
<div class="mt-5 text-slate-400 text-xs">${tipText}<//>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Colored({icon, text, colors}) {
|
|
||||||
colors ||= 'bg-slate-100 text-slate-900';
|
|
||||||
return html`
|
|
||||||
<span class="inline-flex items-center gap-1.5 py-0.5">
|
|
||||||
${icon && html`<${icon} class="w-5 h-5" />`}
|
|
||||||
<span class="inline-block font-medium rounded-md px-2 py-1 text-xs ring-1 ring-inset ${colors}">${text}<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Stat({title, text, tipText, tipIcon, tipColors, colors}) {
|
|
||||||
return html`
|
|
||||||
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-slate-900 dark:border-gray-800">
|
|
||||||
<div class="overflow-auto rounded-lg bg-white px-4 py-2 ">
|
|
||||||
<div class="flex items-center gap-x-2">
|
|
||||||
<p class="text-sm truncate text-gray-500 font-medium"> ${title} </p>
|
|
||||||
<//>
|
|
||||||
<div class="mt-1 flex items-center gap-x-2">
|
|
||||||
<h3 class="text-xl truncate font-semibold tracking-tight ${colors || 'text-gray-800 dark:text-gray-200'}">
|
|
||||||
${text}
|
|
||||||
<//>
|
|
||||||
<span class="flex items-center ${tipText || 'hidden'}">
|
|
||||||
<${Colored} text=${tipText} icon=${tipIcon} colors=${tipColors} />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function TextValue({value, setfn, disabled, placeholder, type, addonRight, addonLeft, attr, min, max, step, mult}) {
|
|
||||||
const [bg, setBg] = useState('bg-white');
|
|
||||||
useEffect(() => { if (type == 'number') checkval(+min, +max, +value); }, []);
|
|
||||||
step ||= '1', mult ||= 1;
|
|
||||||
const checkval = function(min, max, v) {
|
|
||||||
setBg('bg-white');
|
|
||||||
if (min && v < min) setBg('bg-red-100 border-red-200');
|
|
||||||
if (max && v > max) setBg('bg-red-100 border-red-200');
|
|
||||||
};
|
|
||||||
const m = step.match(/^.+\.(.+)/);
|
|
||||||
const digits = m ? m[1].length : 0;
|
|
||||||
const onchange = ev => {
|
|
||||||
let v = ev.target.value;
|
|
||||||
if (type == 'number') {
|
|
||||||
checkval(+min, +max, +v);
|
|
||||||
v = +(parseFloat(v) / mult).toFixed(digits);
|
|
||||||
}
|
|
||||||
setfn(v);
|
|
||||||
};
|
|
||||||
if (type == 'number') value = +(value * mult).toFixed(digits);
|
|
||||||
return html`
|
|
||||||
<div class="flex w-full items-center rounded border shadow-sm ${bg}">
|
|
||||||
${addonLeft && html`<span class="inline-flex font-normal truncate py-1 border-r bg-slate-100 items-center border-gray-300 px-2 text-gray-500 text-xs">${addonLeft}<//>` }
|
|
||||||
<input type=${type || 'text'} disabled=${disabled} value=${value}
|
|
||||||
step=${step} min=${min} max=${max}
|
|
||||||
onchange=${onchange} ...${attr}
|
|
||||||
class="${bg} font-normal text-sm rounded w-full flex-1 py-0.5 px-2 text-gray-700 placeholder:text-gray-400 focus:outline-none disabled:cursor-not-allowed disabled:bg-gray-100 disabled:text-gray-500" placeholder=${placeholder} />
|
|
||||||
${addonRight && html`<span class="inline-flex font-normal truncate py-1 border-l bg-slate-100 items-center border-gray-300 px-2 text-gray-500 text-xs overflow-scroll" style="min-width: 50%;">${addonRight}<//>` }
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function SelectValue({value, setfn, options, disabled}) {
|
|
||||||
const toInt = x => x == parseInt(x) ? parseInt(x) : x;
|
|
||||||
const onchange = ev => setfn(toInt(ev.target.value));
|
|
||||||
return html`
|
|
||||||
<select onchange=${onchange} class="w-full rounded font-normal border py-0.5 px-1 text-gray-600 focus:outline-none text-sm disabled:cursor-not-allowed" disabled=${disabled}>
|
|
||||||
${options.map(v => html`<option value=${v[0]} selected=${v[0] == value}>${v[1]}<//>`) }
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function SwitchValue({value, setfn}) {
|
|
||||||
const onclick = ev => setfn(!value);
|
|
||||||
const bg = !!value ? 'bg-blue-600' : 'bg-gray-200';
|
|
||||||
const tr = !!value ? 'translate-x-5' : 'translate-x-0';
|
|
||||||
return html`
|
|
||||||
<button type="button" onclick=${onclick} class="${bg} inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-0 ring-0" role="switch" aria-checked=${!!value}>
|
|
||||||
<span aria-hidden="true" class="${tr} pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 focus:ring-0 transition duration-200 ease-in-out"></span>
|
|
||||||
</button>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Setting(props) {
|
|
||||||
let input = TextValue;
|
|
||||||
if (props.type == 'switch') input = SwitchValue;
|
|
||||||
if (props.type == 'select') input = SelectValue;
|
|
||||||
return html`
|
|
||||||
<div class=${props.cls || 'grid grid-cols-2 gap-2 my-1'}>
|
|
||||||
<label class="flex items-center text-sm text-gray-700 mr-2 font-medium ${props.title || 'hidden'}">${props.title}<//>
|
|
||||||
<div class="flex items-center">${h(input, props)}<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Pagination({ totalItems, itemsPerPage, currentPage, setPageFn, colors }) {
|
|
||||||
const totalPages = Math.ceil(totalItems / itemsPerPage);
|
|
||||||
const maxPageRange = 2;
|
|
||||||
const lessThanSymbol = "<";
|
|
||||||
const greaterThanSymbol = ">";
|
|
||||||
const whiteSpace = " ";
|
|
||||||
const itemcls = 'relative inline-flex items-center px-3 py-1 text-sm focus:z-20 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:outline-blue-600';
|
|
||||||
colors ||= 'bg-blue-600';
|
|
||||||
|
|
||||||
const PageItem = ({ page, isActive }) => (
|
|
||||||
html`<a
|
|
||||||
onClick=${() => setPageFn(page)}
|
|
||||||
class="${itemcls} ${isActive ? `${colors} text-white` : 'cursor-pointer text-gray-700 ring-1 ring-inset ring-gray-300 hover:bg-gray-50'}"
|
|
||||||
>
|
|
||||||
${page}
|
|
||||||
</a>`
|
|
||||||
);
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<div class="flex items-center justify-between bg-white px-3 py-2">
|
|
||||||
<div class="sm:flex sm:flex-1 sm:items-center sm:justify-between space-x-4 whitespace-nowrap select-none">
|
|
||||||
<p class="text-sm text-slate-500 font-medium">
|
|
||||||
showing <span class="font-bold text-slate-700">${(currentPage - 1) * itemsPerPage + 1}</span> - <span class="font-medium">${Math.min(currentPage * itemsPerPage, totalItems)}</span> of ${whiteSpace}
|
|
||||||
<span class="font-bold text-slate-700">${totalItems}</span> results
|
|
||||||
</p>
|
|
||||||
<div>
|
|
||||||
<nav class="isolate inline-flex -space-x-px rounded-md" aria-label="Pagination">
|
|
||||||
<a
|
|
||||||
onClick=${() => setPageFn(Math.max(currentPage - 1, 1))}
|
|
||||||
class="relative inline-flex px-3 items-center text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 ${currentPage != 1 ? 'cursor-pointer' : ''} focus:z-20 focus:outline-offset-0">
|
|
||||||
${lessThanSymbol}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<${PageItem} page=${1} isActive=${currentPage === 1} />
|
|
||||||
${currentPage > maxPageRange + 2 ? html`<span class="${itemcls} ring-1 ring-inset ring-gray-300 text-slate-300">...</span>` : ''}
|
|
||||||
${Array.from({length: Math.min(totalPages, maxPageRange * 2 + 1)}, (_, i) => Math.max(2, currentPage - maxPageRange) + i).map(page => page > 1 && page < totalPages && html`<${PageItem} page=${page} isActive=${currentPage === page} />`)}
|
|
||||||
${currentPage < totalPages - (maxPageRange + 1) ? html`<span class="${itemcls} ring-1 ring-inset ring-gray-300 text-slate-300">...</span>` : ''}
|
|
||||||
${totalPages > 1 ? html`<${PageItem} page=${totalPages} isActive=${currentPage === totalPages} />` : ''}
|
|
||||||
|
|
||||||
<a
|
|
||||||
onClick=${() => setPageFn(Math.min(currentPage + 1, totalPages))}
|
|
||||||
class="relative inline-flex px-3 items-center text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 ${currentPage != totalPages ? 'cursor-pointer' : ''} focus:z-20 focus:outline-offset-0">
|
|
||||||
${greaterThanSymbol}
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function UploadFileButton(props) {
|
|
||||||
const [upload, setUpload] = useState(null); // Upload promise
|
|
||||||
const [status, setStatus] = useState(''); // Current upload status
|
|
||||||
const btn = useRef(null);
|
|
||||||
const input = useRef(null);
|
|
||||||
|
|
||||||
// Send a large file chunk by chunk
|
|
||||||
const sendFileData = function(url, fileName, fileData, chunkSize) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
const finish = ok => {
|
|
||||||
setUpload(null);
|
|
||||||
const res = props.onupload ? props.onupload(ok, fileName, fileData.length) : null;
|
|
||||||
if (res && typeof (res.catch) === 'function') {
|
|
||||||
res.catch(() => false).then(() => ok ? resolve() : reject());
|
|
||||||
} else {
|
|
||||||
ok ? resolve() : reject();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const sendChunk = function(offset) {
|
|
||||||
var chunk = fileData.subarray(offset, offset + chunkSize) || '';
|
|
||||||
var opts = {method: 'POST', body: chunk};
|
|
||||||
var fullUrl = url + '?offset=' + offset +
|
|
||||||
'&total=' + fileData.length +
|
|
||||||
'&name=' + encodeURIComponent(fileName);
|
|
||||||
var ok;
|
|
||||||
setStatus('Uploading ' + fileName + ', bytes ' + offset + '..' +
|
|
||||||
(offset + chunk.length) + ' of ' + fileData.length);
|
|
||||||
fetch(fullUrl, opts)
|
|
||||||
.then(function(res) {
|
|
||||||
if (res.ok && chunk.length > 0) sendChunk(offset + chunk.length);
|
|
||||||
ok = res.ok;
|
|
||||||
return res.text();
|
|
||||||
})
|
|
||||||
.then(function(text) {
|
|
||||||
if (!ok) setStatus('Error: ' + text), finish(ok); // Fail
|
|
||||||
if (chunk.length > 0) return; // More chunks to send
|
|
||||||
setStatus(x => x + '. Done, resetting device...');
|
|
||||||
finish(ok); // All chunks sent
|
|
||||||
});
|
|
||||||
};
|
|
||||||
sendChunk(0);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onchange = function(ev) {
|
|
||||||
if (!ev.target.files[0]) return;
|
|
||||||
let r = new FileReader(), f = ev.target.files[0];
|
|
||||||
r.readAsArrayBuffer(f);
|
|
||||||
r.onload = function() {
|
|
||||||
setUpload(sendFileData(props.url, f.name, new Uint8Array(r.result), 2048));
|
|
||||||
ev.target.value = '';
|
|
||||||
ev.preventDefault();
|
|
||||||
btn && btn.current.base.click();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const onclick = function(ev) {
|
|
||||||
let fn; setUpload(x => fn = x);
|
|
||||||
if (!fn) input.current.click(); // No upload in progress, show file dialog
|
|
||||||
return fn;
|
|
||||||
};
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<div class="inline-flex flex-col ${props.class}">
|
|
||||||
<input class="hidden" type="file" ref=${input} onchange=${onchange} accept=${props.accept} />
|
|
||||||
<${Button} title=${props.title} icon=${Icons.download} onclick=${onclick} ref=${btn} colors=${props.colors} />
|
|
||||||
<div class="pt-2 text-sm text-slate-400 ${status || 'hidden'}">${status}<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.History=n():t.History=n()}(this,function(){return function(t){function n(o){if(e[o])return e[o].exports;var r=e[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,n),r.loaded=!0,r.exports}var e={};return n.m=t,n.c=e,n.p="",n(0)}([function(t,n,e){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0,n.createPath=n.parsePath=n.locationsAreEqual=n.createLocation=n.createMemoryHistory=n.createHashHistory=n.createBrowserHistory=void 0;var r=e(2);Object.defineProperty(n,"createLocation",{enumerable:!0,get:function(){return r.createLocation}}),Object.defineProperty(n,"locationsAreEqual",{enumerable:!0,get:function(){return r.locationsAreEqual}});var i=e(1);Object.defineProperty(n,"parsePath",{enumerable:!0,get:function(){return i.parsePath}}),Object.defineProperty(n,"createPath",{enumerable:!0,get:function(){return i.createPath}});var a=e(7),c=o(a),u=e(8),s=o(u),f=e(9),l=o(f);n.createBrowserHistory=c.default,n.createHashHistory=s.default,n.createMemoryHistory=l.default},function(t,n){"use strict";n.__esModule=!0;n.addLeadingSlash=function(t){return"/"===t.charAt(0)?t:"/"+t},n.stripLeadingSlash=function(t){return"/"===t.charAt(0)?t.substr(1):t},n.stripPrefix=function(t,n){return 0===t.indexOf(n)?t.substr(n.length):t},n.stripTrailingSlash=function(t){return"/"===t.charAt(t.length-1)?t.slice(0,-1):t},n.parsePath=function(t){var n=t||"/",e="",o="",r=n.indexOf("#");r!==-1&&(o=n.substr(r),n=n.substr(0,r));var i=n.indexOf("?");return i!==-1&&(e=n.substr(i),n=n.substr(0,i)),n=decodeURI(n),{pathname:n,search:"?"===e?"":e,hash:"#"===o?"":o}},n.createPath=function(t){var n=t.pathname,e=t.search,o=t.hash,r=encodeURI(n||"/");return e&&"?"!==e&&(r+="?"===e.charAt(0)?e:"?"+e),o&&"#"!==o&&(r+="#"===o.charAt(0)?o:"#"+o),r}},function(t,n,e){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0,n.locationsAreEqual=n.createLocation=void 0;var r=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},i=e(10),a=o(i),c=e(11),u=o(c),s=e(1);n.createLocation=function(t,n,e,o){var i=void 0;return"string"==typeof t?(i=(0,s.parsePath)(t),i.state=n):(i=r({},t),void 0===i.pathname&&(i.pathname=""),i.search?"?"!==i.search.charAt(0)&&(i.search="?"+i.search):i.search="",i.hash?"#"!==i.hash.charAt(0)&&(i.hash="#"+i.hash):i.hash="",void 0!==n&&void 0===i.state&&(i.state=n)),i.key=e,o&&(i.pathname?"/"!==i.pathname.charAt(0)&&(i.pathname=(0,a.default)(i.pathname,o.pathname)):i.pathname=o.pathname),i},n.locationsAreEqual=function(t,n){return t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash&&t.key===n.key&&(0,u.default)(t.state,n.state)}},function(t,n,e){"use strict";var o=function(){};t.exports=o},function(t,n,e){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0;var r=e(3),i=(o(r),function(){var t=null,n=function(n){return t=n,function(){t===n&&(t=null)}},e=function(n,e,o,r){if(null!=t){var i="function"==typeof t?t(n,e):t;"string"==typeof i?"function"==typeof o?o(i,r):r(!0):r(i!==!1)}else r(!0)},o=[],r=function(t){var n=!0,e=function(){n&&t.apply(void 0,arguments)};return o.push(e),function(){n=!1,o=o.filter(function(t){return t!==e})}},i=function(){for(var t=arguments.length,n=Array(t),e=0;e<t;e++)n[e]=arguments[e];o.forEach(function(t){return t.apply(void 0,n)})};return{setPrompt:n,confirmTransitionTo:e,appendListener:r,notifyListeners:i}});n.default=i},function(t,n){"use strict";n.__esModule=!0;n.canUseDOM=!("undefined"==typeof window||!window.document||!window.document.createElement),n.addEventListener=function(t,n,e){return t.addEventListener?t.addEventListener(n,e,!1):t.attachEvent("on"+n,e)},n.removeEventListener=function(t,n,e){return t.removeEventListener?t.removeEventListener(n,e,!1):t.detachEvent("on"+n,e)},n.getConfirmation=function(t,n){return n(window.confirm(t))},n.supportsHistory=function(){var t=window.navigator.userAgent;return(t.indexOf("Android 2.")===-1&&t.indexOf("Android 4.0")===-1||t.indexOf("Mobile Safari")===-1||t.indexOf("Chrome")!==-1||t.indexOf("Windows Phone")!==-1)&&(window.history&&"pushState"in window.history)},n.supportsPopStateOnHashChange=function(){return window.navigator.userAgent.indexOf("Trident")===-1},n.supportsGoWithoutReloadUsingHash=function(){return window.navigator.userAgent.indexOf("Firefox")===-1},n.isExtraneousPopstateEvent=function(t){return void 0===t.state&&navigator.userAgent.indexOf("CriOS")===-1}},function(t,n,e){"use strict";var o=function(t,n,e,o,r,i,a,c){if(!t){var u;if(void 0===n)u=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var s=[e,o,r,i,a,c],f=0;u=new Error(n.replace(/%s/g,function(){return s[f++]})),u.name="InLine truncated
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" class="h-full bg-white">
|
|
||||||
<head>
|
|
||||||
<title></title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor'> <path stroke-linecap='round' stroke-linejoin='round' d='M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0' /> </svg>" />
|
|
||||||
<link href="main.css" rel="stylesheet" />
|
|
||||||
</head>
|
|
||||||
<body class="min-h-screen"></body>
|
|
||||||
<script src="history.min.js"></script>
|
|
||||||
<script type="module" src="main.js"></script>
|
|
||||||
</html>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/*! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter var,Arial,Helvetica,sans-serif;font-feature-settings:"cv11","ss01";font-variation-settings:"opsz" 32}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.bottom-0{bottom:0}.left-0{left:0}.right-auto{right:auto}.top-0{top:0}.isolate{isolation:isolate}.z-10{z-index:10}.z-\[48\]{z-index:48}.z-\[60\]{z-index:60}.col-span-2{grid-column:span 2/span 2}.m-4{margin:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-5{margin-top:1.25rem;margin-bottom:1.25rem}.mb-1{margin-bottom:.25rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-3{margin-top:.75rem}.mt-5{margin-top:1.25rem}.mt-7{margin-top:1.75rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-full{height:100%}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-0{width:0}.w-11{width:2.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-72{width:18rem}.w-96{width:24rem}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.grow-0{flex-grow:0}.basis-\[30px\]{flex-basis:30px}.border-separate{border-collaLine truncated
|
|
||||||
@@ -1,376 +0,0 @@
|
|||||||
// NOTE: API calls must start with 'api/' in order to serve the app at any URI
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
import { h, render, useState, useEffect, useRef, html, Router } from './bundle.js';
|
|
||||||
import { Icons, Login, Setting, Button, Stat, tipColors, Colored, Notification, Pagination, UploadFileButton } from './components.js';
|
|
||||||
|
|
||||||
const Logo = props => html`<svg class=${props.class} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12.87 12.85"><defs><style>.ll-cls-1{fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:0.5px;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="ll-cls-1" d="M12.62,1.82V8.91A1.58,1.58,0,0,1,11,10.48H4a1.44,1.44,0,0,1-1-.37A.69.69,0,0,1,2.84,10l-.1-.12a.81.81,0,0,1-.15-.48V5.57a.87.87,0,0,1,.86-.86H4.73V7.28a.86.86,0,0,0,.86.85H9.42a.85.85,0,0,0,.85-.85V3.45A.86.86,0,0,0,10.13,3,.76.76,0,0,0,10,2.84a.29.29,0,0,0-.12-.1,1.49,1.49,0,0,0-1-.37H2.39V1.82A1.57,1.57,0,0,1,4,.25H11A1.57,1.57,0,0,1,12.62,1.82Z"/><path class="ll-cls-1" d="M10.48,10.48V11A1.58,1.58,0,0,1,8.9,12.6H1.82A1.57,1.57,0,0,1,.25,11V3.94A1.57,1.57,0,0,1,1.82,2.37H8.9a1.49,1.49,0,0,1,1,.37l.12.1a.76.76,0,0,1,.11.14.86.86,0,0,1,.14.47V7.28a.85.85,0,0,1-.85.85H8.13V5.57a.86.86,0,0,0-.85-.86H3.45a.87.87,0,0,0-.86.86V9.4a.81.81,0,0,0,.15.48l.1.12a.69.69,0,0,0,.13.11,1.44,1.44,0,0,0,1,.37Z"/></g></g></svg>`;
|
|
||||||
|
|
||||||
function Header({logout, user, setShowSidebar, showSidebar}) {
|
|
||||||
return html`
|
|
||||||
<div class="bg-white sticky top-0 z-[48] xw-full border-b py-2 ${showSidebar && 'pl-72'} transition-all duration-300 transform">
|
|
||||||
<div class="px-2 w-full py-0 my-0 flex items-center">
|
|
||||||
<button type="button" onclick=${ev => setShowSidebar(v => !v)} class="text-slate-400">
|
|
||||||
<${Icons.bars3} class="h-6" />
|
|
||||||
<//>
|
|
||||||
<div class="flex flex-1 gap-x-4 self-stretch lg:gap-x-6">
|
|
||||||
<div class="relative flex flex-1"><//>
|
|
||||||
<div class="flex items-center gap-x-4 lg:gap-x-6">
|
|
||||||
<span class="text-sm text-slate-400">logged in as: ${user}<//>
|
|
||||||
<div class="hidden lg:block lg:h-4 lg:w-px lg:bg-gray-200" aria-hidden="true"><//>
|
|
||||||
<${Button} title="Logout" icon=${Icons.logout} onclick=${logout} />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
function Sidebar({url, show}) {
|
|
||||||
const NavLink = ({title, icon, href, url}) => html`
|
|
||||||
<div>
|
|
||||||
<a href="#${href}" class="${href == url ? 'bg-slate-50 text-blue-600 group' : 'text-gray-700 hover:text-blue-600 hover:bg-gray-50 group'} flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
|
|
||||||
<${icon} class="w-6 h-6"/>
|
|
||||||
${title}
|
|
||||||
<///>
|
|
||||||
<//>`;
|
|
||||||
return html`
|
|
||||||
<div class="bg-violet-100 hs-overlay hs-overlay-open:translate-x-0
|
|
||||||
-translate-x-full transition-all duration-300 transform
|
|
||||||
fixed top-0 left-0 bottom-0 z-[60] w-72 bg-white border-r
|
|
||||||
border-gray-200 overflow-y-auto scrollbar-y
|
|
||||||
${show && 'translate-x-0'} right-auto bottom-0">
|
|
||||||
<div class="flex flex-col m-4 gap-y-6">
|
|
||||||
<div class="flex h-10 shrink-0 items-center gap-x-4 font-bold text-xl text-slate-500">
|
|
||||||
<${Logo} class="h-full"/> Your Brand
|
|
||||||
<//>
|
|
||||||
<div class="flex flex-1 flex-col">
|
|
||||||
<${NavLink} title="Dashboard" icon=${Icons.home} href="/" url=${url} />
|
|
||||||
<${NavLink} title="Settings" icon=${Icons.cog} href="/settings" url=${url} />
|
|
||||||
<${NavLink} title="Firmware Update" icon=${Icons.download} href="/update" url=${url} />
|
|
||||||
<${NavLink} title="Events" icon=${Icons.alert} href="/events" url=${url} />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
function Events({}) {
|
|
||||||
const [events, setEvents] = useState([]);
|
|
||||||
const [page, setPage] = useState(1);
|
|
||||||
|
|
||||||
const refresh = () =>
|
|
||||||
fetch('api/events/get', {
|
|
||||||
method: 'POST', body: JSON.stringify({page: page}),
|
|
||||||
}).then(r => r.json())
|
|
||||||
.then(r => setEvents(r));
|
|
||||||
|
|
||||||
useEffect(refresh, [page]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setPage(JSON.parse(localStorage.getItem('page')));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
localStorage.setItem('page', page.toString());
|
|
||||||
}, [page]);
|
|
||||||
|
|
||||||
const Th = props => html`<th scope="col" class="sticky top-0 z-10 border-b border-slate-300 bg-white bg-opacity-75 py-1.5 px-4 text-left text-sm font-semibold text-slate-900 backdrop-blur backdrop-filter">${props.title}</th>`;
|
|
||||||
const Td = props => html`<td class="whitespace-nowrap border-b border-slate-200 py-2 px-4 pr-3 text-sm text-slate-900">${props.text}</td>`;
|
|
||||||
const Prio = ({prio}) => {
|
|
||||||
const text = ['high', 'medium', 'low'][prio];
|
|
||||||
const colors = [tipColors.red, tipColors.yellow, tipColors.green][prio];
|
|
||||||
return html`<${Colored} colors=${colors} text=${text} />`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Event = ({e}) => html`
|
|
||||||
<tr>
|
|
||||||
<${Td} text=${['power', 'hardware', 'tier3', 'tier4'][e.type]} />
|
|
||||||
<${Td} text=${html`<${Prio} prio=${e.prio}/>`} />
|
|
||||||
<${Td} text=${e.time ? (new Date(e.time * 1000)).toLocaleString() : '1970-01-01'} />
|
|
||||||
<${Td} text=${e.text} />
|
|
||||||
<//>`;
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<div class="m-4 divide-y divide-gray-200 overflow-auto rounded bg-white">
|
|
||||||
<div class="font-semibold flex items-center text-gray-600 px-3 justify-between whitespace-nowrap">
|
|
||||||
<div class="font-semibold flex items-center text-gray-600">
|
|
||||||
<div class="mr-4">EVENT LOG</div>
|
|
||||||
</div>
|
|
||||||
<${Pagination} currentPage=${page} setPageFn=${setPage} totalItems=400 itemsPerPage=20 />
|
|
||||||
<//>
|
|
||||||
<div class="inline-block min-w-full align-middle" style="max-height: 82vh; overflow: auto;">
|
|
||||||
<table class="min-w-full border-separate border-spacing-0">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<${Th} title="Type" />
|
|
||||||
<${Th} title="Prio" />
|
|
||||||
<${Th} title="Time" />
|
|
||||||
<${Th} title="Description" />
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
${(events.arr ? events.arr : []).map(e => h(Event, {e}))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
function Chart({data}) {
|
|
||||||
const n = data.length /* entries */, w = 20 /* entry width */, ls = 15/* left space */;
|
|
||||||
const h = 100 /* graph height */, yticks = 5 /* Y axis ticks */, bs = 10 /* bottom space */;
|
|
||||||
const ymax = 25;
|
|
||||||
const yt = i => (h - bs) / yticks * (i + 1);
|
|
||||||
const bh = p => (h - bs) * p / 100; // Bar height
|
|
||||||
const by = p => (h - bs) - bh(p);
|
|
||||||
const range = (start, size, step) => Array.from({length: size}, (_, i) => i * (step || 1) + start);
|
|
||||||
// console.log(ds);
|
|
||||||
return html`
|
|
||||||
<div class="my-4 divide-y divide-gray-200 overflow-auto rounded bg-white">
|
|
||||||
<div class="font-light uppercase flex items-center text-gray-600 px-4 py-2">
|
|
||||||
Temperature, last 24h
|
|
||||||
<//>
|
|
||||||
<div class="relative">
|
|
||||||
<svg class="bg-yellow-x50 w-full p-4" viewBox="0 0 ${n*w+ls} ${h}">
|
|
||||||
${range(0, yticks).map(i => html`
|
|
||||||
<line x1=0 y1=${yt(i)} x2=${ls+n*w} y2=${yt(i)} stroke-width=0.3 class="stroke-slate-300" stroke-dasharray="1,1" />
|
|
||||||
<text x=0 y=${yt(i)-2} class="text-[6px] fill-slate-400">${ymax-ymax/yticks*(i+1)}<//>
|
|
||||||
`)}
|
|
||||||
${range(0, n).map(x => html`
|
|
||||||
<rect x=${ls+x*w} y=${by(data[x]*100/ymax)} width=12 height=${bh(data[x]*100/ymax)} rx=2 class="fill-cyan-500" />
|
|
||||||
<text x=${ls+x*w} y=100 class="text-[6px] fill-slate-400">${x*2}:00<//>
|
|
||||||
`)}
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
function DeveloperNote({text, children}) {
|
|
||||||
return html`
|
|
||||||
<div class="flex p-4 gap-2">
|
|
||||||
<div class="text-sm text-slate-500">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<${Icons.info} class="self-start basis-[30px] grow-0 shrink-0 text-green-600 mr-2" />
|
|
||||||
<div class="font-semibold">Developer Note<//>
|
|
||||||
<//>
|
|
||||||
${(text || '').split('.').map(v => html` <p class="my-2 ">${v}<//>`)}
|
|
||||||
${children}
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
function Main({}) {
|
|
||||||
const [stats, setStats] = useState(null);
|
|
||||||
const refresh = () => fetch('api/stats/get').then(r => r.json()).then(r => setStats(r));
|
|
||||||
useEffect(refresh, []);
|
|
||||||
if (!stats) return '';
|
|
||||||
return html`
|
|
||||||
<div class="p-2">
|
|
||||||
<div class="p-4 sm:p-2 mx-auto grid grid-cols-2 lg:grid-cols-4 gap-4">
|
|
||||||
<${Stat} title="Temperature" text="${stats.temperature} °C" tipText="good" tipIcon=${Icons.ok} tipColors=${tipColors.green} />
|
|
||||||
<${Stat} title="Humidity" text="${stats.humidity} %" tipText="warn" tipIcon=${Icons.warn} tipColors=${tipColors.yellow} />
|
|
||||||
<div class="bg-white col-span-2 border rounded-md shadow-lg" role="alert">
|
|
||||||
<${DeveloperNote} text="Stats data is received from the Mongoose backend" />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<div class="p-4 sm:p-2 mx-auto grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
||||||
|
|
||||||
<${Chart} data=${stats.points} />
|
|
||||||
|
|
||||||
<div class="my-4 hx-24 bg-white border rounded-md shadow-lg" role="alert">
|
|
||||||
<${DeveloperNote}
|
|
||||||
text="This chart is an SVG image, generated on the fly from the
|
|
||||||
data returned by the api/stats/get API call" />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
function FirmwareStatus({title, info, children}) {
|
|
||||||
const state = ['UNAVAILABLE', 'FIRST_BOOT', 'NOT_COMMITTED', 'COMMITTED'][(info.status || 0) % 4];
|
|
||||||
const valid = info.status > 0;
|
|
||||||
return html`
|
|
||||||
<div class="bg-white py-1 divide-y border rounded">
|
|
||||||
<div class="font-light uppercase flex items-center text-gray-600 px-4 py-2">
|
|
||||||
${title}
|
|
||||||
<//>
|
|
||||||
<div class="px-4 py-2 relative">
|
|
||||||
<div class="my-1">Status: ${state}<//>
|
|
||||||
<div class="my-1">CRC32: ${valid ? info.crc32.toString(16) : 'n/a'}<//>
|
|
||||||
<div class="my-1">Size: ${valid ? info.size : 'n/a'}<//>
|
|
||||||
<div class="my-1">Flashed at: ${valid ? new Date(info.timestamp * 1000).toLocaleString() : 'n/a'}<//>
|
|
||||||
${children}
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function FirmwareUpdate({}) {
|
|
||||||
const [info, setInfo] = useState([{}, {}]);
|
|
||||||
const refresh = () => fetch('api/firmware/status').then(r => r.json()).then(r => setInfo(r));
|
|
||||||
useEffect(refresh, []);
|
|
||||||
const oncommit = ev => fetch('api/firmware/commit')
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(refresh);
|
|
||||||
const onreboot = ev => fetch('api/device/reset')
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(r => new Promise(r => setTimeout(ev => { refresh(); r(); }, 3000)));
|
|
||||||
const onrollback = ev => fetch('api/firmware/rollback')
|
|
||||||
.then(onreboot);
|
|
||||||
const onerase = ev => fetch('api/device/eraselast').then(refresh);
|
|
||||||
const onupload = function(ok, name, size) {
|
|
||||||
if (!ok) return false;
|
|
||||||
return new Promise(r => setTimeout(ev => { refresh(); r(); }, 3000));
|
|
||||||
};
|
|
||||||
return html`
|
|
||||||
<div class="m-4 gap-4 grid grid-cols-1 lg:grid-cols-3">
|
|
||||||
<${FirmwareStatus} title="Current firmware image" info=${info[0]}>
|
|
||||||
<div class="flex flex-wrap gap-2">
|
|
||||||
<${Button} title="Commit this firmware" onclick=${oncommit}
|
|
||||||
icon=${Icons.thumbUp} disabled=${info[0].status == 3} cls="w-full" />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<${FirmwareStatus} title="Previous firmware image" info=${info[1]}>
|
|
||||||
<${Button} title="Rollback to this firmware" onclick=${onrollback}
|
|
||||||
icon=${Icons.backward} disabled=${info[1].status == 0} cls="w-full" />
|
|
||||||
<//>
|
|
||||||
<div class="bg-white xm-4 divide-y border rounded flex flex-col">
|
|
||||||
<div class="font-light uppercase flex items-center text-gray-600 px-4 py-2">
|
|
||||||
Device control
|
|
||||||
<//>
|
|
||||||
<div class="px-4 py-3 flex flex-col gap-2 grow">
|
|
||||||
<${UploadFileButton}
|
|
||||||
title="Upload new firmware .bin file" onupload=${onupload}
|
|
||||||
url="api/firmware/upload" accept=".bin,.uf2" />
|
|
||||||
<div class="grow"><//>
|
|
||||||
<${Button} title="Reboot device" onclick=${onreboot} icon=${Icons.refresh} cls="w-full" />
|
|
||||||
<${Button} title="Erase last sector" onclick=${onerase} icon=${Icons.doc} cls="w-full hidden" />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="m-4 gap-4 grid grid-cols-1 lg:grid-cols-2">
|
|
||||||
<div class="bg-white border shadow-lg">
|
|
||||||
<${DeveloperNote}>
|
|
||||||
<div class="my-2">
|
|
||||||
Firmware status and other information is stored in the last sector
|
|
||||||
of flash
|
|
||||||
<//>
|
|
||||||
<div class="my-2">
|
|
||||||
Firmware status can be FIRST_BOOT, UNCOMMITTED or COMMITTED. If no
|
|
||||||
information is available, it is UNAVAILABLE.
|
|
||||||
<//>
|
|
||||||
<div class="my-2">
|
|
||||||
This GUI loads a firmware file and sends it chunk by chunk to the
|
|
||||||
device, passing current chunk offset, total firmware size and a file name:
|
|
||||||
api/firmware/upload?offset=X&total=Y&name=Z
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
|
|
||||||
<div class="bg-white border shadow-lg">
|
|
||||||
<${DeveloperNote}>
|
|
||||||
<div>
|
|
||||||
Firmware update mechanism defines 3 API functions that the target
|
|
||||||
device must implement: mg_ota_begin(), mg_ota_write() and mg_ota_end()
|
|
||||||
<//>
|
|
||||||
<div class="my-2">
|
|
||||||
RESTful API handlers use ota_xxx() API to save firmware to flash.
|
|
||||||
The last 0-length chunk triggers ota_end() which performs firmware
|
|
||||||
update using saved firmware image
|
|
||||||
<//>
|
|
||||||
<div class="my-2">
|
|
||||||
<a class="link text-blue-600 underline"
|
|
||||||
href="https://mongoose.ws/webinars/">Join our free webinar</a> to
|
|
||||||
get detailed explanations about possible firmware updates strategies
|
|
||||||
and implementation demo
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
function Settings({}) {
|
|
||||||
const [settings, setSettings] = useState(null);
|
|
||||||
const [saveResult, setSaveResult] = useState(null);
|
|
||||||
const refresh = () => fetch('api/settings/get')
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(r => setSettings(r));
|
|
||||||
useEffect(refresh, []);
|
|
||||||
|
|
||||||
const mksetfn = k => (v => setSettings(x => Object.assign({}, x, {[k]: v})));
|
|
||||||
const onsave = ev => fetch('api/settings/set', {
|
|
||||||
method: 'post', body: JSON.stringify(settings)
|
|
||||||
}).then(r => r.json())
|
|
||||||
.then(r => setSaveResult(r))
|
|
||||||
.then(refresh);
|
|
||||||
|
|
||||||
if (!settings) return '';
|
|
||||||
const logOptions = [[0, 'Disable'], [1, 'Error'], [2, 'Info'], [3, 'Debug']];
|
|
||||||
return html`
|
|
||||||
<div class="m-4 grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
||||||
|
|
||||||
<div class="py-1 divide-y border rounded bg-white flex flex-col">
|
|
||||||
<div class="font-light uppercase flex items-center text-gray-600 px-4 py-2">
|
|
||||||
Device Settings
|
|
||||||
<//>
|
|
||||||
<div class="py-2 px-5 flex-1 flex flex-col relative">
|
|
||||||
${saveResult && html`<${Notification} ok=${saveResult.status}
|
|
||||||
text=${saveResult.message} close=${() => setSaveResult(null)} />`}
|
|
||||||
|
|
||||||
<${Setting} title="Enable Logs" value=${settings.log_enabled} setfn=${mksetfn('log_enabled')} type="switch" />
|
|
||||||
<${Setting} title="Log Level" value=${settings.log_level} setfn=${mksetfn('log_level')} type="select" addonLeft="0-3" disabled=${!settings.log_enabled} options=${logOptions}/>
|
|
||||||
<${Setting} title="Brightness" value=${settings.brightness} setfn=${mksetfn('brightness')} type="number" addonRight="%" />
|
|
||||||
<${Setting} title="Device Name" value=${settings.device_name} setfn=${mksetfn('device_name')} type="" />
|
|
||||||
<div class="mb-1 mt-3 flex place-content-end"><${Button} icon=${Icons.save} onclick=${onsave} title="Save Settings" /><//>
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
|
|
||||||
<div class="bg-white border rounded-md text-ellipsis overflow-auto" role="alert">
|
|
||||||
<${DeveloperNote}
|
|
||||||
text="A variety of controls are pre-defined to ease the development:
|
|
||||||
toggle button, dropdown select, input field with left and right
|
|
||||||
addons. Device settings are received by calling
|
|
||||||
api/settings/get API call, which returns settings JSON object.
|
|
||||||
Clicking on the save button calls api/settings/set
|
|
||||||
API call" />
|
|
||||||
<//>
|
|
||||||
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const App = function({}) {
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [url, setUrl] = useState('/');
|
|
||||||
const [user, setUser] = useState('');
|
|
||||||
const [showSidebar, setShowSidebar] = useState(true);
|
|
||||||
|
|
||||||
const logout = () => fetch('api/logout').then(r => setUser(''));
|
|
||||||
const login = r => !r.ok ? setLoading(false) && setUser(null) : r.json()
|
|
||||||
.then(r => setUser(r.user))
|
|
||||||
.finally(r => setLoading(false));
|
|
||||||
|
|
||||||
useEffect(() => fetch('api/login').then(login), []);
|
|
||||||
|
|
||||||
if (loading) return ''; // Show blank page on initial load
|
|
||||||
if (!user) return html`<${Login} loginFn=${login} logoIcon=${Logo}
|
|
||||||
title="Device Dashboard Login"
|
|
||||||
tipText="To login, use: admin/admin, user1/user1, user2/user2" />`; // If not logged in, show login screen
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<div class="h-screen bg-slate-100">
|
|
||||||
<${Sidebar} url=${url} show=${showSidebar} />
|
|
||||||
<${Header} logout=${logout} user=${user} showSidebar=${showSidebar} setShowSidebar=${setShowSidebar} />
|
|
||||||
<div class="${showSidebar && 'pl-72'} transition-all duration-300 transform">
|
|
||||||
<${Router} onChange=${ev => setUrl(ev.url)} history=${History.createHashHistory()} >
|
|
||||||
<${Main} default=${true} />
|
|
||||||
<${Settings} path="settings" />
|
|
||||||
<${FirmwareUpdate} path="update" />
|
|
||||||
<${Events} path="events" />
|
|
||||||
<//>
|
|
||||||
<//>
|
|
||||||
<//>`;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.onload = () => render(h(App), document.body);
|
|
||||||
+43
-8
@@ -2,6 +2,18 @@
|
|||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_WIN32
|
#if MG_ARCH == MG_ARCH_WIN32
|
||||||
|
|
||||||
|
// Avoid name clashing; (macro expansion producing 'defined' has undefined
|
||||||
|
// behaviour). See config.h for user options
|
||||||
|
#ifndef MG_ENABLE_WINSOCK
|
||||||
|
#if (!defined(MG_ENABLE_TCPIP) || !MG_ENABLE_TCPIP) && \
|
||||||
|
(!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) && \
|
||||||
|
(!defined(MG_ENABLE_FREERTOS_TCP) || !MG_ENABLE_FREERTOS_TCP)
|
||||||
|
#define MG_ENABLE_WINSOCK 1
|
||||||
|
#else
|
||||||
|
#define MG_ENABLE_WINSOCK 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _CRT_RAND_S
|
#ifndef _CRT_RAND_S
|
||||||
#define _CRT_RAND_S
|
#define _CRT_RAND_S
|
||||||
#endif
|
#endif
|
||||||
@@ -47,12 +59,14 @@ typedef enum { false = 0, true = 1 } bool;
|
|||||||
#else
|
#else
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#if MG_ENABLE_WINSOCK
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <winerror.h>
|
#include <winerror.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h> // fix missing macros and types
|
||||||
|
|
||||||
// For mg_random()
|
// For mg_random()
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1700
|
#if defined(_MSC_VER) && _MSC_VER < 1700
|
||||||
@@ -63,6 +77,20 @@ typedef enum { false = 0, true = 1 } bool;
|
|||||||
#pragma comment(lib, "advapi32.lib")
|
#pragma comment(lib, "advapi32.lib")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||||
|
#ifndef IPPROTO_IP
|
||||||
|
#define IPPROTO_IP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef IP_ADD_MEMBERSHIP
|
||||||
|
struct ip_mreq {
|
||||||
|
struct in_addr imr_multiaddr;
|
||||||
|
struct in_addr imr_interface;
|
||||||
|
};
|
||||||
|
#define IP_ADD_MEMBERSHIP 12
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// Protect from calls like std::snprintf in app code
|
// Protect from calls like std::snprintf in app code
|
||||||
// See https://github.com/cesanta/mongoose/issues/1047
|
// See https://github.com/cesanta/mongoose/issues/1047
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
@@ -73,25 +101,30 @@ typedef enum { false = 0, true = 1 } bool;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MG_INVALID_SOCKET INVALID_SOCKET
|
|
||||||
#define MG_SOCKET_TYPE SOCKET
|
|
||||||
typedef unsigned long nfds_t;
|
typedef unsigned long nfds_t;
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
#if MG_ENABLE_WINSOCK
|
||||||
#pragma comment(lib, "ws2_32.lib")
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
|
#endif
|
||||||
#ifndef alloca
|
#ifndef alloca
|
||||||
#define alloca(a) _alloca(a)
|
#define alloca(a) _alloca(a)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#define poll(a, b, c) WSAPoll((a), (b), (c))
|
|
||||||
#define closesocket(x) closesocket(x)
|
|
||||||
|
|
||||||
typedef int socklen_t;
|
|
||||||
#define MG_DIRSEP '\\'
|
#define MG_DIRSEP '\\'
|
||||||
|
|
||||||
#ifndef MG_PATH_MAX
|
#ifndef MG_PATH_MAX
|
||||||
#define MG_PATH_MAX FILENAME_MAX
|
#define MG_PATH_MAX FILENAME_MAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MG_ENABLE_WINSOCK
|
||||||
|
|
||||||
|
#define MG_INVALID_SOCKET INVALID_SOCKET
|
||||||
|
#define MG_SOCKET_TYPE SOCKET
|
||||||
|
#define poll(a, b, c) WSAPoll((a), (b), (c))
|
||||||
|
#define closesocket(x) closesocket(x)
|
||||||
|
typedef int socklen_t;
|
||||||
|
|
||||||
#ifndef SO_EXCLUSIVEADDRUSE
|
#ifndef SO_EXCLUSIVEADDRUSE
|
||||||
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
|
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
|
||||||
#endif
|
#endif
|
||||||
@@ -106,13 +139,15 @@ typedef int socklen_t;
|
|||||||
#define MG_SOCK_RESET(errcode) \
|
#define MG_SOCK_RESET(errcode) \
|
||||||
(((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
|
(((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET))
|
||||||
|
|
||||||
|
#endif // MG_ENABLE_WINSOCK
|
||||||
|
|
||||||
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
||||||
#define sleep(x) Sleep((x) * 1000)
|
#define sleep(x) Sleep((x) *1000)
|
||||||
#define mkdir(a, b) _mkdir(a)
|
#define mkdir(a, b) _mkdir(a)
|
||||||
#define timegm(x) _mkgmtime(x)
|
#define timegm(x) _mkgmtime(x)
|
||||||
|
|
||||||
#ifndef S_ISDIR
|
#ifndef S_ISDIR
|
||||||
#define S_ISDIR(x) (((x) & _S_IFMT) == _S_IFDIR)
|
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_DIRLIST
|
#ifndef MG_ENABLE_DIRLIST
|
||||||
|
|||||||
+4
-3
@@ -56,7 +56,8 @@
|
|||||||
#define MG_ENABLE_MD5 1
|
#define MG_ENABLE_MD5 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
|
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with other external IP stack not
|
||||||
|
// mentioned in arch_win32.h
|
||||||
#ifndef MG_ENABLE_WINSOCK
|
#ifndef MG_ENABLE_WINSOCK
|
||||||
#define MG_ENABLE_WINSOCK 1
|
#define MG_ENABLE_WINSOCK 1
|
||||||
#endif
|
#endif
|
||||||
@@ -174,8 +175,8 @@
|
|||||||
#define MG_SET_MAC_ADDRESS(mac)
|
#define MG_SET_MAC_ADDRESS(mac)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_SET_WIFI_CREDS
|
#ifndef MG_SET_WIFI_CONFIG
|
||||||
#define MG_SET_WIFI_CREDS(ssid, pass)
|
#define MG_SET_WIFI_CONFIG(data)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
|
#ifndef MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
|
|||||||
const struct mg_dns_header *h = (struct mg_dns_header *) buf;
|
const struct mg_dns_header *h = (struct mg_dns_header *) buf;
|
||||||
struct mg_dns_rr rr;
|
struct mg_dns_rr rr;
|
||||||
size_t i, n, num_answers, ofs = sizeof(*h);
|
size_t i, n, num_answers, ofs = sizeof(*h);
|
||||||
|
bool is_response;
|
||||||
memset(dm, 0, sizeof(*dm));
|
memset(dm, 0, sizeof(*dm));
|
||||||
|
|
||||||
if (len < sizeof(*h)) return 0; // Too small, headers dont fit
|
if (len < sizeof(*h)) return 0; // Too small, headers dont fit
|
||||||
@@ -110,12 +111,22 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
|
|||||||
num_answers = 10; // Sanity cap
|
num_answers = 10; // Sanity cap
|
||||||
}
|
}
|
||||||
dm->txnid = mg_ntohs(h->txnid);
|
dm->txnid = mg_ntohs(h->txnid);
|
||||||
|
is_response = mg_ntohs(h->flags) & 0x8000;
|
||||||
|
|
||||||
for (i = 0; i < mg_ntohs(h->num_questions); i++) {
|
for (i = 0; i < mg_ntohs(h->num_questions); i++) {
|
||||||
if ((n = mg_dns_parse_rr(buf, len, ofs, true, &rr)) == 0) return false;
|
if ((n = mg_dns_parse_rr(buf, len, ofs, true, &rr)) == 0) return false;
|
||||||
// MG_INFO(("Q %lu %lu %hu/%hu", ofs, n, rr.atype, rr.aclass));
|
// MG_INFO(("Q %lu %lu %hu/%hu", ofs, n, rr.atype, rr.aclass));
|
||||||
|
mg_dns_parse_name(buf, len, ofs, dm->name, sizeof(dm->name));
|
||||||
ofs += n;
|
ofs += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_response) {
|
||||||
|
// For queries, there is no need to parse the answers. In this way,
|
||||||
|
// we also ensure the domain name (dm->name) is parsed from
|
||||||
|
// the question field.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_answers; i++) {
|
for (i = 0; i < num_answers; i++) {
|
||||||
if ((n = mg_dns_parse_rr(buf, len, ofs, false, &rr)) == 0) return false;
|
if ((n = mg_dns_parse_rr(buf, len, ofs, false, &rr)) == 0) return false;
|
||||||
// MG_INFO(("A -- %lu %lu %hu/%hu %s", ofs, n, rr.atype, rr.aclass,
|
// MG_INFO(("A -- %lu %lu %hu/%hu %s", ofs, n, rr.atype, rr.aclass,
|
||||||
@@ -265,3 +276,72 @@ void mg_resolve(struct mg_connection *c, const char *url) {
|
|||||||
mg_sendnsreq(c, &host, c->mgr->dnstimeout, dns, c->mgr->use_dns6);
|
mg_sendnsreq(c, &host, c->mgr->dnstimeout, dns, c->mgr->use_dns6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint8_t mdns_answer[] = {
|
||||||
|
0, 1, // 2 bytes - record type, A
|
||||||
|
0, 1, // 2 bytes - address class, INET
|
||||||
|
0, 0, 0, 120, // 4 bytes - TTL
|
||||||
|
0, 4 // 2 bytes - address length
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mdns_cb(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_READ) {
|
||||||
|
struct mg_dns_header *qh = (struct mg_dns_header *) c->recv.buf;
|
||||||
|
if (c->recv.len > 12 && (qh->flags & mg_htons(0xF800)) == 0) {
|
||||||
|
// flags -> !resp, opcode=0 => query; ignore other opcodes and responses
|
||||||
|
struct mg_dns_rr rr; // Parse first question, offset 12 is header size
|
||||||
|
size_t n = mg_dns_parse_rr(c->recv.buf, c->recv.len, 12, true, &rr);
|
||||||
|
MG_VERBOSE(("mDNS request parsed, result=%d", (int) n));
|
||||||
|
if (n > 0) {
|
||||||
|
// RFC-6762 Appendix C, RFC2181 11: m(n + 1-63), max 255 + 0x0
|
||||||
|
// buf and h declared here to ease future expansion to DNS-SD
|
||||||
|
uint8_t buf[sizeof(struct mg_dns_header) + 256 + sizeof(mdns_answer) + 4];
|
||||||
|
struct mg_dns_header *h = (struct mg_dns_header *) buf;
|
||||||
|
char local_name[63 + 7]; // name label + '.' + local label + '\0'
|
||||||
|
uint8_t name_len = (uint8_t) strlen((char *)c->fn_data);
|
||||||
|
struct mg_dns_message dm;
|
||||||
|
bool unicast = (rr.aclass & MG_BIT(15)) != 0; // QU
|
||||||
|
// uint16_t q = mg_ntohs(qh->num_questions);
|
||||||
|
rr.aclass &= (uint16_t) ~MG_BIT(15); // remove "QU" (unicast response)
|
||||||
|
qh->num_questions = mg_htons(1); // parser sanity
|
||||||
|
mg_dns_parse(c->recv.buf, c->recv.len, &dm);
|
||||||
|
if (name_len > (sizeof(local_name) - 7)) // leave room for .local\0
|
||||||
|
name_len = sizeof(local_name) - 7;
|
||||||
|
memcpy(local_name, c->fn_data, name_len);
|
||||||
|
strcpy(local_name + name_len, ".local"); // ensure proper name.local\0
|
||||||
|
if (strcmp(local_name, dm.name) == 0) {
|
||||||
|
uint8_t *p = &buf[sizeof(*h)];
|
||||||
|
memset(h, 0, sizeof(*h)); // clear header
|
||||||
|
h->txnid = unicast ? qh->txnid : 0; // RFC-6762 18.1
|
||||||
|
// RFC-6762 6: 0 questions, 1 Answer, 0 Auth, 0 Additional RRs
|
||||||
|
h->num_answers = mg_htons(1); // only one answer
|
||||||
|
h->flags = mg_htons(0x8400); // Authoritative response
|
||||||
|
*p++ = name_len; // label 1
|
||||||
|
memcpy(p, c->fn_data, name_len), p += name_len;
|
||||||
|
*p++ = 5; // label 2
|
||||||
|
memcpy(p, "local", 5), p += 5;
|
||||||
|
*p++ = 0; // no more labels
|
||||||
|
memcpy(p, mdns_answer, sizeof(mdns_answer)), p += sizeof(mdns_answer);
|
||||||
|
#if MG_ENABLE_TCPIP
|
||||||
|
memcpy(p, &c->mgr->ifp->ip, 4), p += 4;
|
||||||
|
#else
|
||||||
|
memcpy(p, c->data, 4), p += 4;
|
||||||
|
#endif
|
||||||
|
if (!unicast) memcpy(&c->rem, &c->loc, sizeof(c->rem));
|
||||||
|
mg_send(c, buf, (size_t)(p - buf)); // And send it!
|
||||||
|
MG_DEBUG(("mDNS %c response sent", unicast ? 'U' : 'M'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mg_iobuf_del(&c->recv, 0, c->recv.len);
|
||||||
|
}
|
||||||
|
(void) ev_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_multicast_add(struct mg_connection *c, char *ip);
|
||||||
|
struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, char *name) {
|
||||||
|
struct mg_connection *c =
|
||||||
|
mg_listen(mgr, "udp://224.0.0.251:5353", mdns_cb, name);
|
||||||
|
if (c != NULL) mg_multicast_add(c, (char *)"224.0.0.251");
|
||||||
|
return c;
|
||||||
|
}
|
||||||
@@ -36,3 +36,5 @@ void mg_resolve_cancel(struct mg_connection *);
|
|||||||
bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
|
bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
|
||||||
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
||||||
bool is_question, struct mg_dns_rr *);
|
bool is_question, struct mg_dns_rr *);
|
||||||
|
|
||||||
|
struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, char *name);
|
||||||
+17
-3
@@ -13,12 +13,12 @@ static struct mg_tcpip_if *s_ifp;
|
|||||||
|
|
||||||
static void mac_cb(uint32_t);
|
static void mac_cb(uint32_t);
|
||||||
static bool cmsis_init(struct mg_tcpip_if *);
|
static bool cmsis_init(struct mg_tcpip_if *);
|
||||||
static bool cmsis_up(struct mg_tcpip_if *);
|
static bool cmsis_poll(struct mg_tcpip_if *, bool);
|
||||||
static size_t cmsis_tx(const void *, size_t, struct mg_tcpip_if *);
|
static size_t cmsis_tx(const void *, size_t, struct mg_tcpip_if *);
|
||||||
static size_t cmsis_rx(void *, size_t, struct mg_tcpip_if *);
|
static size_t cmsis_rx(void *, size_t, struct mg_tcpip_if *);
|
||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_cmsis = {cmsis_init, cmsis_tx, NULL,
|
struct mg_tcpip_driver mg_tcpip_driver_cmsis = {cmsis_init, cmsis_tx, NULL,
|
||||||
cmsis_up};
|
cmsis_poll};
|
||||||
|
|
||||||
static bool cmsis_init(struct mg_tcpip_if *ifp) {
|
static bool cmsis_init(struct mg_tcpip_if *ifp) {
|
||||||
ARM_ETH_MAC_ADDR addr;
|
ARM_ETH_MAC_ADDR addr;
|
||||||
@@ -56,7 +56,21 @@ static size_t cmsis_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cmsis_up(struct mg_tcpip_if *ifp) {
|
static void cmsis_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
|
||||||
|
ARM_ETH_MAC_ADDR addr;
|
||||||
|
memcpy(&addr, mcast_addr, sizeof(addr));
|
||||||
|
mac->SetAddressFilter(&addr, 1);
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool cmsis_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
cmsis_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
ARM_DRIVER_ETH_PHY *phy = &Driver_ETH_PHY0;
|
ARM_DRIVER_ETH_PHY *phy = &Driver_ETH_PHY0;
|
||||||
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
|
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
|
||||||
bool up = (phy->GetLinkState() == ARM_ETH_LINK_UP) ? 1 : 0; // link state
|
bool up = (phy->GetLinkState() == ARM_ETH_LINK_UP) ? 1 : 0; // link state
|
||||||
|
|||||||
+1200
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CYW) && MG_ENABLE_DRIVER_CYW
|
||||||
|
|
||||||
|
struct mg_tcpip_spi_ {
|
||||||
|
void *spi; // Opaque SPI bus descriptor
|
||||||
|
void (*begin)(void *); // SPI begin: slave select low
|
||||||
|
void (*end)(void *); // SPI end: slave select high
|
||||||
|
void (*txn)(void *, uint8_t *, uint8_t *,
|
||||||
|
size_t len); // SPI transaction: write-read len bytes
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mg_tcpip_driver_cyw_firmware {
|
||||||
|
const uint8_t *code_addr;
|
||||||
|
size_t code_len;
|
||||||
|
const uint8_t *nvram_addr;
|
||||||
|
size_t nvram_len;
|
||||||
|
const uint8_t *clm_addr;
|
||||||
|
size_t clm_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mg_tcpip_driver_cyw_data {
|
||||||
|
struct mg_tcpip_spi_ *spi;
|
||||||
|
struct mg_tcpip_driver_cyw_firmware *fw;
|
||||||
|
char *ssid;
|
||||||
|
char *pass;
|
||||||
|
char *apssid;
|
||||||
|
char *appass;
|
||||||
|
uint8_t security; // TBD
|
||||||
|
uint8_t apsecurity; // TBD
|
||||||
|
uint8_t apchannel;
|
||||||
|
bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL
|
||||||
|
bool hs; // use chip "high-speed" mode; otherwise SPI CPOL0 CPHA0 (DS 4.2.3 Table 6)
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
||||||
|
do { \
|
||||||
|
static struct mg_tcpip_driver_cyw_data driver_data_; \
|
||||||
|
static struct mg_tcpip_if mif_; \
|
||||||
|
MG_SET_WIFI_CONFIG(&driver_data_); \
|
||||||
|
mif_.ip = MG_TCPIP_IP; \
|
||||||
|
mif_.mask = MG_TCPIP_MASK; \
|
||||||
|
mif_.gw = MG_TCPIP_GW; \
|
||||||
|
mif_.driver = &mg_tcpip_driver_pico_w; \
|
||||||
|
mif_.driver_data = &driver_data_; \
|
||||||
|
mif_.recv_queue.size = 8192; \
|
||||||
|
mif_.mac[0] = 2; /* MAC read from OTP at driver init */ \
|
||||||
|
mg_tcpip_init(mgr, &mif_); \
|
||||||
|
MG_INFO(("Driver: cyw, MAC: %M", mg_print_mac, mif_.mac)); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
+24
-2
@@ -115,9 +115,14 @@ static bool mg_tcpip_driver_imxrt_init(struct mg_tcpip_if *ifp) {
|
|||||||
ENET->RDAR = MG_BIT(24); // Receive Descriptors have changed
|
ENET->RDAR = MG_BIT(24); // Receive Descriptors have changed
|
||||||
ENET->TDAR = MG_BIT(24); // Transmit Descriptors have changed
|
ENET->TDAR = MG_BIT(24); // Transmit Descriptors have changed
|
||||||
// ENET->OPD = 0x10014;
|
// ENET->OPD = 0x10014;
|
||||||
|
ENET->IAUR = 0;
|
||||||
|
ENET->IALR = 0;
|
||||||
|
ENET->GAUR = 0;
|
||||||
|
ENET->GALR = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Transmit frame
|
// Transmit frame
|
||||||
static size_t mg_tcpip_driver_imxrt_tx(const void *buf, size_t len,
|
static size_t mg_tcpip_driver_imxrt_tx(const void *buf, size_t len,
|
||||||
struct mg_tcpip_if *ifp) {
|
struct mg_tcpip_if *ifp) {
|
||||||
@@ -142,7 +147,24 @@ static size_t mg_tcpip_driver_imxrt_tx(const void *buf, size_t len,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_imxrt_up(struct mg_tcpip_if *ifp) {
|
static void mg_tcpip_driver_imxrt_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
// RM 37.3.4.3.2
|
||||||
|
uint32_t hash_table[2] = {0, 0};
|
||||||
|
// uint8_t hash64 = ((~mg_crc32(0, mcast_addr, 6)) >> 26) & 0x3f;
|
||||||
|
// hash_table[((uint8_t)hash64) >> 5] |= (1 << (hash64 & 0x1f));
|
||||||
|
hash_table[1] = MG_BIT(1); // above reduces to this for mDNS addr
|
||||||
|
ENET->GAUR = hash_table[1];
|
||||||
|
ENET->GALR = hash_table[0];
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mg_tcpip_driver_imxrt_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
mg_tcpip_driver_imxrt_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
struct mg_tcpip_driver_imxrt_data *d =
|
struct mg_tcpip_driver_imxrt_data *d =
|
||||||
(struct mg_tcpip_driver_imxrt_data *) ifp->driver_data;
|
(struct mg_tcpip_driver_imxrt_data *) ifp->driver_data;
|
||||||
uint8_t speed = MG_PHY_SPEED_10M;
|
uint8_t speed = MG_PHY_SPEED_10M;
|
||||||
@@ -188,6 +210,6 @@ void ENET_IRQHandler(void) {
|
|||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_imxrt = {mg_tcpip_driver_imxrt_init,
|
struct mg_tcpip_driver mg_tcpip_driver_imxrt = {mg_tcpip_driver_imxrt_init,
|
||||||
mg_tcpip_driver_imxrt_tx, NULL,
|
mg_tcpip_driver_imxrt_tx, NULL,
|
||||||
mg_tcpip_driver_imxrt_up};
|
mg_tcpip_driver_imxrt_poll};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+121
-20
@@ -1,8 +1,8 @@
|
|||||||
#if MG_ENABLE_TCPIP && MG_ARCH == MG_ARCH_PICOSDK && \
|
#if MG_ENABLE_TCPIP && MG_ARCH == MG_ARCH_PICOSDK && \
|
||||||
defined(MG_ENABLE_DRIVER_PICO_W) && MG_ENABLE_DRIVER_PICO_W
|
defined(MG_ENABLE_DRIVER_PICO_W) && MG_ENABLE_DRIVER_PICO_W
|
||||||
|
|
||||||
#include "net_builtin.h"
|
|
||||||
#include "drivers/pico-w.h"
|
#include "drivers/pico-w.h"
|
||||||
|
#include "net_builtin.h"
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
static struct mg_tcpip_if *s_ifp;
|
static struct mg_tcpip_if *s_ifp;
|
||||||
@@ -13,49 +13,150 @@ static bool mg_tcpip_driver_pico_w_init(struct mg_tcpip_if *ifp) {
|
|||||||
s_ifp = ifp;
|
s_ifp = ifp;
|
||||||
if (cyw43_arch_init() != 0)
|
if (cyw43_arch_init() != 0)
|
||||||
return false; // initialize async_context and WiFi chip
|
return false; // initialize async_context and WiFi chip
|
||||||
cyw43_arch_enable_sta_mode();
|
if (d->apmode && d->apssid != NULL) {
|
||||||
// start connecting to network
|
MG_DEBUG(("Starting AP '%s' (%u)", d->apssid, d->apchannel));
|
||||||
if (cyw43_arch_wifi_connect_bssid_async(d->ssid, NULL, d->pass,
|
if (!mg_wifi_ap_start(d->apssid, d->appass, d->apchannel)) return false;
|
||||||
CYW43_AUTH_WPA2_AES_PSK) != 0)
|
cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac); // same MAC
|
||||||
return false;
|
} else {
|
||||||
cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac);
|
cyw43_arch_enable_sta_mode();
|
||||||
|
cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac);
|
||||||
|
if (d->ssid != NULL) {
|
||||||
|
MG_DEBUG(("Connecting to '%s'", d->ssid));
|
||||||
|
return mg_wifi_connect(d->ssid, d->pass);
|
||||||
|
} else {
|
||||||
|
cyw43_arch_disable_sta_mode();
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t mg_tcpip_driver_pico_w_tx(const void *buf, size_t len,
|
static size_t mg_tcpip_driver_pico_w_tx(const void *buf, size_t len,
|
||||||
struct mg_tcpip_if *ifp) {
|
struct mg_tcpip_if *ifp) {
|
||||||
(void) ifp;
|
struct mg_tcpip_driver_pico_w_data *d =
|
||||||
return cyw43_send_ethernet(&cyw43_state, CYW43_ITF_STA, len, buf, false)
|
(struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
|
||||||
? 0
|
return cyw43_send_ethernet(&cyw43_state,
|
||||||
: len;
|
d->apmode ? CYW43_ITF_AP : CYW43_ITF_STA, len, buf,
|
||||||
|
false) == 0
|
||||||
|
? len
|
||||||
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_pico_w_up(struct mg_tcpip_if *ifp) {
|
static bool s_aplink = false, s_scanning = false;
|
||||||
(void) ifp;
|
static bool s_stalink = false, s_connecting = false;
|
||||||
return (cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA) ==
|
|
||||||
CYW43_LINK_JOIN);
|
static bool mg_tcpip_driver_pico_w_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
cyw43_arch_poll(); // not necessary, except when IRQs are disabled (OTA)
|
||||||
|
if (s_scanning && !cyw43_wifi_scan_active(&cyw43_state)) {
|
||||||
|
MG_VERBOSE(("scan complete"));
|
||||||
|
s_scanning = 0;
|
||||||
|
mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_END, NULL);
|
||||||
|
}
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
// first call to _poll() is after _init(), so this is safe
|
||||||
|
cyw43_wifi_update_multicast_filter(&cyw43_state, (uint8_t *)mcast_addr, true);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
|
struct mg_tcpip_driver_pico_w_data *d =
|
||||||
|
(struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
|
||||||
|
if (d->apmode) return s_aplink;
|
||||||
|
int sdkstate = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA);
|
||||||
|
MG_VERBOSE(("conn: %c state: %d", s_connecting ? '1' : '0', sdkstate));
|
||||||
|
if (sdkstate < 0 && s_connecting) {
|
||||||
|
mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_CONNECT_ERR, &sdkstate);
|
||||||
|
s_connecting = false;
|
||||||
|
}
|
||||||
|
return s_stalink;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_pico_w = {
|
struct mg_tcpip_driver mg_tcpip_driver_pico_w = {
|
||||||
mg_tcpip_driver_pico_w_init,
|
mg_tcpip_driver_pico_w_init,
|
||||||
mg_tcpip_driver_pico_w_tx,
|
mg_tcpip_driver_pico_w_tx,
|
||||||
NULL,
|
NULL,
|
||||||
mg_tcpip_driver_pico_w_up,
|
mg_tcpip_driver_pico_w_poll,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Called once per outstanding frame by async_context
|
// Called once per outstanding frame by async_context
|
||||||
void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len,
|
void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len,
|
||||||
const uint8_t *buf) {
|
const uint8_t *buf) {
|
||||||
if (itf != CYW43_ITF_STA) return;
|
|
||||||
mg_tcpip_qwrite((void *) buf, len, s_ifp);
|
mg_tcpip_qwrite((void *) buf, len, s_ifp);
|
||||||
(void) cb_data;
|
(void) cb_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by async_context
|
// Called by async_context
|
||||||
void cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) {}
|
void cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) {
|
||||||
void cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) {}
|
if (itf == CYW43_ITF_AP) {
|
||||||
|
s_aplink = true;
|
||||||
|
} else {
|
||||||
|
s_stalink = true;
|
||||||
|
s_connecting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) {
|
||||||
|
if (itf == CYW43_ITF_AP) {
|
||||||
|
s_aplink = false;
|
||||||
|
} else {
|
||||||
|
s_stalink = false;
|
||||||
|
// SDK calls this before we check status, don't clear s_connecting here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// there's life beyond lwIP
|
// there's life beyond lwIP
|
||||||
void pbuf_copy_partial(void) {(void) 0;}
|
void pbuf_copy_partial(void) {
|
||||||
|
(void) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int result_cb(void *arg, const cyw43_ev_scan_result_t *data) {
|
||||||
|
struct mg_wifi_scan_bss_data bss;
|
||||||
|
bss.SSID = mg_str_n(data->ssid, data->ssid_len);
|
||||||
|
bss.BSSID = (char *) data->bssid;
|
||||||
|
bss.RSSI = (int8_t) data->rssi;
|
||||||
|
bss.has_n = 0; // SDK ignores this
|
||||||
|
bss.channel = (uint8_t) data->channel;
|
||||||
|
bss.band = MG_WIFI_BAND_2G;
|
||||||
|
// SDK-internal dependency, 2.1.0
|
||||||
|
bss.security = data->auth_mode & MG_BIT(0) ? MG_WIFI_SECURITY_WEP
|
||||||
|
: MG_WIFI_SECURITY_OPEN;
|
||||||
|
if (data->auth_mode & MG_BIT(1)) bss.security |= MG_WIFI_SECURITY_WPA;
|
||||||
|
if (data->auth_mode & MG_BIT(2)) bss.security |= MG_WIFI_SECURITY_WPA2;
|
||||||
|
MG_VERBOSE(("BSS: %.*s (%u) (%M) %d dBm %u", bss.SSID.len, bss.SSID.buf,
|
||||||
|
bss.channel, mg_print_mac, bss.BSSID, (int) bss.RSSI,
|
||||||
|
bss.security));
|
||||||
|
mg_tcpip_call(s_ifp, MG_TCPIP_EV_WIFI_SCAN_RESULT, &bss);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mg_wifi_scan(void) {
|
||||||
|
cyw43_wifi_scan_options_t opts;
|
||||||
|
memset(&opts, 0, sizeof(opts));
|
||||||
|
bool res = (cyw43_wifi_scan(&cyw43_state, &opts, NULL, result_cb) == 0);
|
||||||
|
if (res) s_scanning = true;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mg_wifi_connect(char *ssid, char *pass) {
|
||||||
|
cyw43_arch_enable_sta_mode();
|
||||||
|
int res = cyw43_arch_wifi_connect_async(ssid, pass, CYW43_AUTH_WPA2_AES_PSK);
|
||||||
|
MG_VERBOSE(("res: %d", res));
|
||||||
|
if (res == 0) s_connecting = true;
|
||||||
|
return (res == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mg_wifi_disconnect(void) {
|
||||||
|
cyw43_arch_disable_sta_mode();
|
||||||
|
s_connecting = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mg_wifi_ap_start(char *ssid, char *pass, unsigned int channel) {
|
||||||
|
cyw43_wifi_ap_set_channel(&cyw43_state, channel);
|
||||||
|
cyw43_arch_enable_ap_mode(ssid, pass, CYW43_AUTH_WPA2_AES_PSK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mg_wifi_ap_stop(void) {
|
||||||
|
cyw43_arch_disable_ap_mode();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,13 +10,19 @@
|
|||||||
struct mg_tcpip_driver_pico_w_data {
|
struct mg_tcpip_driver_pico_w_data {
|
||||||
char *ssid;
|
char *ssid;
|
||||||
char *pass;
|
char *pass;
|
||||||
|
char *apssid;
|
||||||
|
char *appass;
|
||||||
|
uint8_t security; // TBD
|
||||||
|
uint8_t apsecurity; // TBD
|
||||||
|
uint8_t apchannel;
|
||||||
|
bool apmode; // start in AP mode; 'false' starts connection to 'ssid' if not NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
||||||
do { \
|
do { \
|
||||||
static struct mg_tcpip_driver_pico_w_data driver_data_; \
|
static struct mg_tcpip_driver_pico_w_data driver_data_; \
|
||||||
static struct mg_tcpip_if mif_; \
|
static struct mg_tcpip_if mif_; \
|
||||||
MG_SET_WIFI_CREDS(&driver_data_.ssid, &driver_data_.pass); \
|
MG_SET_WIFI_CONFIG(&driver_data_); \
|
||||||
mif_.ip = MG_TCPIP_IP; \
|
mif_.ip = MG_TCPIP_IP; \
|
||||||
mif_.mask = MG_TCPIP_MASK; \
|
mif_.mask = MG_TCPIP_MASK; \
|
||||||
mif_.gw = MG_TCPIP_GW; \
|
mif_.gw = MG_TCPIP_GW; \
|
||||||
|
|||||||
+2
-1
@@ -96,7 +96,8 @@ static uint32_t fcs_do(uint32_t fcs, uint8_t x) {
|
|||||||
return fcs;
|
return fcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_ppp_up(struct mg_tcpip_if *ifp) {
|
static bool mg_ppp_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
(void) s1;
|
||||||
return ifp->driver_data != NULL;
|
return ifp->driver_data != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-12
@@ -101,9 +101,9 @@ static uint16_t smi_rd(uint16_t header) {
|
|||||||
pir = 0; // read, mdc = 0
|
pir = 0; // read, mdc = 0
|
||||||
ETHERC->PIR = pir;
|
ETHERC->PIR = pir;
|
||||||
raspin(s_smispin / 2); // 1/4 clock period, 300ns max access time
|
raspin(s_smispin / 2); // 1/4 clock period, 300ns max access time
|
||||||
data |= (uint16_t)(ETHERC->PIR & MG_BIT(3) ? 1 : 0); // read mdio
|
data |= (uint16_t) (ETHERC->PIR & MG_BIT(3) ? 1 : 0); // read mdio
|
||||||
raspin(s_smispin / 2); // 1/4 clock period
|
raspin(s_smispin / 2); // 1/4 clock period
|
||||||
pir |= MG_BIT(0); // mdc = 1
|
pir |= MG_BIT(0); // mdc = 1
|
||||||
ETHERC->PIR = pir;
|
ETHERC->PIR = pir;
|
||||||
raspin(s_smispin);
|
raspin(s_smispin);
|
||||||
}
|
}
|
||||||
@@ -111,11 +111,14 @@ static uint16_t smi_rd(uint16_t header) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t raeth_read_phy(uint8_t addr, uint8_t reg) {
|
static uint16_t raeth_read_phy(uint8_t addr, uint8_t reg) {
|
||||||
return smi_rd((uint16_t)((1 << 14) | (2 << 12) | (addr << 7) | (reg << 2) | (2 << 0)));
|
return smi_rd(
|
||||||
|
(uint16_t) ((1 << 14) | (2 << 12) | (addr << 7) | (reg << 2) | (2 << 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raeth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
|
static void raeth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
|
||||||
smi_wr((uint16_t)((1 << 14) | (1 << 12) | (addr << 7) | (reg << 2) | (2 << 0)), val);
|
smi_wr(
|
||||||
|
(uint16_t) ((1 << 14) | (1 << 12) | (addr << 7) | (reg << 2) | (2 << 0)),
|
||||||
|
val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MDC clock is generated manually; as per 802.3, it must not exceed 2.5MHz
|
// MDC clock is generated manually; as per 802.3, it must not exceed 2.5MHz
|
||||||
@@ -152,7 +155,7 @@ static bool mg_tcpip_driver_ra_init(struct mg_tcpip_if *ifp) {
|
|||||||
|
|
||||||
MG_DEBUG(("PHY addr: %d, smispin: %d", d->phy_addr, s_smispin));
|
MG_DEBUG(("PHY addr: %d, smispin: %d", d->phy_addr, s_smispin));
|
||||||
struct mg_phy phy = {raeth_read_phy, raeth_write_phy};
|
struct mg_phy phy = {raeth_read_phy, raeth_write_phy};
|
||||||
mg_phy_init(&phy, d->phy_addr, 0); // MAC clocks PHY
|
mg_phy_init(&phy, d->phy_addr, 0); // MAC clocks PHY
|
||||||
|
|
||||||
// Select RMII mode,
|
// Select RMII mode,
|
||||||
ETHERC->ECMR = MG_BIT(2) | MG_BIT(1); // 100M, Full-duplex, CRC
|
ETHERC->ECMR = MG_BIT(2) | MG_BIT(1); // 100M, Full-duplex, CRC
|
||||||
@@ -171,9 +174,9 @@ static bool mg_tcpip_driver_ra_init(struct mg_tcpip_if *ifp) {
|
|||||||
EDMAC->FDR = 0x070f; // (27.2.11)
|
EDMAC->FDR = 0x070f; // (27.2.11)
|
||||||
EDMAC->RMCR = MG_BIT(0); // (27.2.12)
|
EDMAC->RMCR = MG_BIT(0); // (27.2.12)
|
||||||
ETHERC->ECMR |= MG_BIT(6) | MG_BIT(5); // TE RE
|
ETHERC->ECMR |= MG_BIT(6) | MG_BIT(5); // TE RE
|
||||||
EDMAC->EESIPR = MG_BIT(18); // Enable Rx IRQ
|
EDMAC->EESIPR = MG_BIT(18); // FR: Enable Rx (frame) IRQ
|
||||||
EDMAC->EDRRR = MG_BIT(0); // Receive Descriptors have changed
|
EDMAC->EDRRR = MG_BIT(0); // Receive Descriptors have changed
|
||||||
EDMAC->EDTRR = MG_BIT(0); // Transmit Descriptors have changed
|
EDMAC->EDTRR = MG_BIT(0); // Transmit Descriptors have changed
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +201,12 @@ static size_t mg_tcpip_driver_ra_tx(const void *buf, size_t len,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_ra_up(struct mg_tcpip_if *ifp) {
|
static bool mg_tcpip_driver_ra_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
EDMAC->EESIPR = MG_BIT(18) | MG_BIT(7); // FR, RMAF: Frame and mcast IRQ
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
struct mg_tcpip_driver_ra_data *d =
|
struct mg_tcpip_driver_ra_data *d =
|
||||||
(struct mg_tcpip_driver_ra_data *) ifp->driver_data;
|
(struct mg_tcpip_driver_ra_data *) ifp->driver_data;
|
||||||
uint8_t speed = MG_PHY_SPEED_10M;
|
uint8_t speed = MG_PHY_SPEED_10M;
|
||||||
@@ -224,7 +232,7 @@ static uint32_t s_rxno;
|
|||||||
void EDMAC_IRQHandler(void) {
|
void EDMAC_IRQHandler(void) {
|
||||||
struct mg_tcpip_driver_ra_data *d =
|
struct mg_tcpip_driver_ra_data *d =
|
||||||
(struct mg_tcpip_driver_ra_data *) s_ifp->driver_data;
|
(struct mg_tcpip_driver_ra_data *) s_ifp->driver_data;
|
||||||
EDMAC->EESR = MG_BIT(18); // Ack IRQ in EDMAC 1st
|
EDMAC->EESR = MG_BIT(18) | MG_BIT(7); // Ack IRQ in EDMAC 1st
|
||||||
ICU_IELSR[d->irqno] &= ~MG_BIT(16); // Ack IRQ in ICU last
|
ICU_IELSR[d->irqno] &= ~MG_BIT(16); // Ack IRQ in ICU last
|
||||||
// Frame received, loop
|
// Frame received, loop
|
||||||
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
||||||
@@ -245,6 +253,6 @@ void EDMAC_IRQHandler(void) {
|
|||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_ra = {mg_tcpip_driver_ra_init,
|
struct mg_tcpip_driver mg_tcpip_driver_ra = {mg_tcpip_driver_ra_init,
|
||||||
mg_tcpip_driver_ra_tx, NULL,
|
mg_tcpip_driver_ra_tx, NULL,
|
||||||
mg_tcpip_driver_ra_up};
|
mg_tcpip_driver_ra_poll};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -9,4 +9,33 @@ struct mg_tcpip_driver_ra_data {
|
|||||||
uint8_t phy_addr; // PHY address
|
uint8_t phy_addr; // PHY address
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef MG_DRIVER_CLK_FREQ
|
||||||
|
#define MG_DRIVER_CLK_FREQ 100000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_DRIVER_IRQ_NO
|
||||||
|
#define MG_DRIVER_IRQ_NO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_TCPIP_PHY_ADDR
|
||||||
|
#define MG_TCPIP_PHY_ADDR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MG_TCPIP_DRIVER_INIT(mgr) \
|
||||||
|
do { \
|
||||||
|
static struct mg_tcpip_driver_ra_data driver_data_; \
|
||||||
|
static struct mg_tcpip_if mif_; \
|
||||||
|
driver_data_.clock = MG_DRIVER_CLK_FREQ; \
|
||||||
|
driver_data_.irqno = MG_DRIVER_IRQ_NO; \
|
||||||
|
driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \
|
||||||
|
mif_.ip = MG_TCPIP_IP; \
|
||||||
|
mif_.mask = MG_TCPIP_MASK; \
|
||||||
|
mif_.gw = MG_TCPIP_GW; \
|
||||||
|
mif_.driver = &mg_tcpip_driver_ra; \
|
||||||
|
mif_.driver_data = &driver_data_; \
|
||||||
|
MG_SET_MAC_ADDRESS(mif_.mac); \
|
||||||
|
mg_tcpip_init(mgr, &mif_); \
|
||||||
|
MG_INFO(("Driver: ra, MAC: %M", mg_print_mac, mif_.mac)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+19
-3
@@ -89,6 +89,10 @@ static bool mg_tcpip_driver_rw612_init(struct mg_tcpip_if *ifp) {
|
|||||||
ENET->PALR =
|
ENET->PALR =
|
||||||
ifp->mac[0] << 24 | ifp->mac[1] << 16 | ifp->mac[2] << 8 | ifp->mac[3];
|
ifp->mac[0] << 24 | ifp->mac[1] << 16 | ifp->mac[2] << 8 | ifp->mac[3];
|
||||||
ENET->PAUR |= (ifp->mac[4] << 24 | ifp->mac[5] << 16);
|
ENET->PAUR |= (ifp->mac[4] << 24 | ifp->mac[5] << 16);
|
||||||
|
ENET->IALR = 0;
|
||||||
|
ENET->IAUR = 0;
|
||||||
|
ENET->GALR = 0;
|
||||||
|
ENET->GAUR = 0;
|
||||||
ENET->MSCR = ((d->mdc_cr & 0x3f) << 1) | ((d->mdc_holdtime & 7) << 8);
|
ENET->MSCR = ((d->mdc_cr & 0x3f) << 1) | ((d->mdc_holdtime & 7) << 8);
|
||||||
ENET->EIMR = MG_BIT(25); // Enable RX interrupt
|
ENET->EIMR = MG_BIT(25); // Enable RX interrupt
|
||||||
ENET->ECR |= MG_BIT(8) | MG_BIT(1); // DBSWP, Enable
|
ENET->ECR |= MG_BIT(8) | MG_BIT(1); // DBSWP, Enable
|
||||||
@@ -121,7 +125,19 @@ static size_t mg_tcpip_driver_rw612_tx(const void *buf, size_t len,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_rw612_up(struct mg_tcpip_if *ifp) {
|
|
||||||
|
static void mg_tcpip_driver_rw612_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
ENET->GAUR = MG_BIT(1); // see imxrt, it reduces to this for mDNS
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mg_tcpip_driver_rw612_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
mg_tcpip_driver_rw612_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
struct mg_tcpip_driver_rw612_data *d =
|
struct mg_tcpip_driver_rw612_data *d =
|
||||||
(struct mg_tcpip_driver_rw612_data *) ifp->driver_data;
|
(struct mg_tcpip_driver_rw612_data *) ifp->driver_data;
|
||||||
uint8_t speed = MG_PHY_SPEED_10M;
|
uint8_t speed = MG_PHY_SPEED_10M;
|
||||||
@@ -157,7 +173,7 @@ static bool mg_tcpip_driver_rw612_up(struct mg_tcpip_if *ifp) {
|
|||||||
|
|
||||||
void ENET_IRQHandler(void) {
|
void ENET_IRQHandler(void) {
|
||||||
if (ENET->EIR & MG_BIT(25)) {
|
if (ENET->EIR & MG_BIT(25)) {
|
||||||
ENET->EIR = MG_BIT(25); // Ack RX
|
ENET->EIR = MG_BIT(25); // Ack RX
|
||||||
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
||||||
if ((s_rxdesc[s_rxno][0] & MG_BIT(31)) != 0) break; // exit when done
|
if ((s_rxdesc[s_rxno][0] & MG_BIT(31)) != 0) break; // exit when done
|
||||||
// skip partial/errored frames
|
// skip partial/errored frames
|
||||||
@@ -177,5 +193,5 @@ void ENET_IRQHandler(void) {
|
|||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_rw612 = {mg_tcpip_driver_rw612_init,
|
struct mg_tcpip_driver mg_tcpip_driver_rw612 = {mg_tcpip_driver_rw612_init,
|
||||||
mg_tcpip_driver_rw612_tx, NULL,
|
mg_tcpip_driver_rw612_tx, NULL,
|
||||||
mg_tcpip_driver_rw612_up};
|
mg_tcpip_driver_rw612_poll};
|
||||||
#endif
|
#endif
|
||||||
+31
-14
@@ -1,6 +1,7 @@
|
|||||||
#include "net_builtin.h"
|
#include "net_builtin.h"
|
||||||
|
|
||||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_SAME54) && MG_ENABLE_DRIVER_SAME54
|
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_SAME54) && \
|
||||||
|
MG_ENABLE_DRIVER_SAME54
|
||||||
|
|
||||||
#include <sam.h>
|
#include <sam.h>
|
||||||
|
|
||||||
@@ -164,21 +165,37 @@ static size_t mg_tcpip_driver_same54_tx(const void *buf, size_t len,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_same54_up(struct mg_tcpip_if *ifp) {
|
static void mg_tcpip_driver_same54_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
uint16_t bsr = eth_read_phy(MG_PHY_ADDR, MG_PHYREG_BSR);
|
// TODO(): read database, rebuild hash table
|
||||||
bool up = bsr & MG_PHYREGBIT_BSR_LINK_STATUS ? 1 : 0;
|
// Setting Hash Index for 01:00:5e:00:00:fb (multicast)
|
||||||
|
// 24.6.9 Hash addressing
|
||||||
|
// computed hash is 55, which means bit 23 (55 - 32) in
|
||||||
|
// HRT register must be set
|
||||||
|
GMAC_REGS->GMAC_HRT = MG_BIT(23);
|
||||||
|
GMAC_REGS->GMAC_NCFGR |= MG_BIT(6); // enable multicast hash filtering
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
// If PHY is ready, update NCFGR accordingly
|
static bool mg_tcpip_driver_same54_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
if (ifp->state == MG_TCPIP_STATE_DOWN && up) {
|
if (ifp->update_mac_hash_table) {
|
||||||
uint16_t bcr = eth_read_phy(MG_PHY_ADDR, MG_PHYREG_BCR);
|
mg_tcpip_driver_same54_update_hash_table(ifp);
|
||||||
bool fd = bcr & MG_PHYREGBIT_BCR_DUPLEX_MODE ? 1 : 0;
|
ifp->update_mac_hash_table = false;
|
||||||
bool spd = bcr & MG_PHYREGBIT_BCR_SPEED ? 1 : 0;
|
|
||||||
GMAC_REGS->GMAC_NCFGR = (GMAC_REGS->GMAC_NCFGR &
|
|
||||||
~(GMAC_NCFGR_SPD_Msk | MG_PHYREGBIT_BCR_SPEED)) |
|
|
||||||
GMAC_NCFGR_SPD(spd) | GMAC_NCFGR_FD(fd);
|
|
||||||
}
|
}
|
||||||
|
if (s1) {
|
||||||
|
uint16_t bsr = eth_read_phy(MG_PHY_ADDR, MG_PHYREG_BSR);
|
||||||
|
bool up = bsr & MG_PHYREGBIT_BSR_LINK_STATUS ? 1 : 0;
|
||||||
|
|
||||||
return up;
|
// If PHY is ready, update NCFGR accordingly
|
||||||
|
if (ifp->state == MG_TCPIP_STATE_DOWN && up) {
|
||||||
|
uint16_t bcr = eth_read_phy(MG_PHY_ADDR, MG_PHYREG_BCR);
|
||||||
|
bool fd = bcr & MG_PHYREGBIT_BCR_DUPLEX_MODE ? 1 : 0;
|
||||||
|
bool spd = bcr & MG_PHYREGBIT_BCR_SPEED ? 1 : 0;
|
||||||
|
GMAC_REGS->GMAC_NCFGR = (GMAC_REGS->GMAC_NCFGR &
|
||||||
|
~(GMAC_NCFGR_SPD_Msk | MG_PHYREGBIT_BCR_SPEED)) |
|
||||||
|
GMAC_NCFGR_SPD(spd) | GMAC_NCFGR_FD(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMAC_Handler(void);
|
void GMAC_Handler(void);
|
||||||
@@ -211,5 +228,5 @@ void GMAC_Handler(void) {
|
|||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_same54 = {
|
struct mg_tcpip_driver mg_tcpip_driver_same54 = {
|
||||||
mg_tcpip_driver_same54_init, mg_tcpip_driver_same54_tx, NULL,
|
mg_tcpip_driver_same54_init, mg_tcpip_driver_same54_tx, NULL,
|
||||||
mg_tcpip_driver_same54_up};
|
mg_tcpip_driver_same54_poll};
|
||||||
#endif
|
#endif
|
||||||
+18
-3
@@ -136,7 +136,7 @@ static bool mg_tcpip_driver_stm32f_init(struct mg_tcpip_if *ifp) {
|
|||||||
// MG_BIT(25);
|
// MG_BIT(25);
|
||||||
ETH->MACIMR = MG_BIT(3) | MG_BIT(9); // Mask timestamp & PMT IT
|
ETH->MACIMR = MG_BIT(3) | MG_BIT(9); // Mask timestamp & PMT IT
|
||||||
ETH->MACFCR = MG_BIT(7); // Disable zero quarta pause
|
ETH->MACFCR = MG_BIT(7); // Disable zero quarta pause
|
||||||
// ETH->MACFFR = MG_BIT(31); // Receive all
|
ETH->MACFFR = MG_BIT(10); // Perfect filtering
|
||||||
struct mg_phy phy = {eth_read_phy, eth_write_phy};
|
struct mg_phy phy = {eth_read_phy, eth_write_phy};
|
||||||
mg_phy_init(&phy, phy_addr, MG_PHY_CLOCKS_MAC);
|
mg_phy_init(&phy, phy_addr, MG_PHY_CLOCKS_MAC);
|
||||||
ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
|
ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
|
||||||
@@ -178,7 +178,22 @@ static size_t mg_tcpip_driver_stm32f_tx(const void *buf, size_t len,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_stm32f_up(struct mg_tcpip_if *ifp) {
|
static void mg_tcpip_driver_stm32f_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
ETH->MACA1LR = (uint32_t) mcast_addr[3] << 24 |
|
||||||
|
(uint32_t) mcast_addr[2] << 16 |
|
||||||
|
(uint32_t) mcast_addr[1] << 8 | (uint32_t) mcast_addr[0];
|
||||||
|
ETH->MACA1HR = (uint32_t) mcast_addr[5] << 8 | (uint32_t) mcast_addr[4];
|
||||||
|
ETH->MACA1HR |= MG_BIT(31); // AE
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mg_tcpip_driver_stm32f_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
mg_tcpip_driver_stm32f_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
struct mg_tcpip_driver_stm32f_data *d =
|
struct mg_tcpip_driver_stm32f_data *d =
|
||||||
(struct mg_tcpip_driver_stm32f_data *) ifp->driver_data;
|
(struct mg_tcpip_driver_stm32f_data *) ifp->driver_data;
|
||||||
uint8_t phy_addr = d == NULL ? 0 : d->phy_addr;
|
uint8_t phy_addr = d == NULL ? 0 : d->phy_addr;
|
||||||
@@ -229,5 +244,5 @@ void ETH_IRQHandler(void) {
|
|||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_stm32f = {
|
struct mg_tcpip_driver mg_tcpip_driver_stm32f = {
|
||||||
mg_tcpip_driver_stm32f_init, mg_tcpip_driver_stm32f_tx, NULL,
|
mg_tcpip_driver_stm32f_init, mg_tcpip_driver_stm32f_tx, NULL,
|
||||||
mg_tcpip_driver_stm32f_up};
|
mg_tcpip_driver_stm32f_poll};
|
||||||
#endif
|
#endif
|
||||||
+26
-4
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#if MG_ENABLE_TCPIP && (MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN)
|
#if MG_ENABLE_TCPIP && (MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN)
|
||||||
// STM32H: vendor modded single-queue Synopsys v4.2
|
// STM32H: vendor modded single-queue Synopsys v4.2
|
||||||
// MCXNx4x: dual-queue Synopsys v5.2
|
// MCXNx4x: dual-queue Synopsys v5.2 with no hash table option
|
||||||
// RT1170 ENET_QOS: quad-queue Synopsys v5.1
|
// RT1170 ENET_QOS: quad-queue Synopsys v5.1
|
||||||
struct synopsys_enet_qos {
|
struct synopsys_enet_qos {
|
||||||
volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
|
volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
|
||||||
@@ -102,7 +102,9 @@ static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
|||||||
ETH->DMASBMR |= MG_BIT(12); // AAL NOTE(scaprile): is this actually needed
|
ETH->DMASBMR |= MG_BIT(12); // AAL NOTE(scaprile): is this actually needed
|
||||||
ETH->MACIER = 0; // Do not enable additional irq sources (reset value)
|
ETH->MACIER = 0; // Do not enable additional irq sources (reset value)
|
||||||
ETH->MACTFCR = MG_BIT(7); // Disable zero-quanta pause
|
ETH->MACTFCR = MG_BIT(7); // Disable zero-quanta pause
|
||||||
// ETH->MACPFR = MG_BIT(31); // Receive all
|
#if !MG_ENABLE_DRIVER_MCXN
|
||||||
|
ETH->MACPFR = MG_BIT(10); // Perfect filtering
|
||||||
|
#endif
|
||||||
struct mg_phy phy = {eth_read_phy, eth_write_phy};
|
struct mg_phy phy = {eth_read_phy, eth_write_phy};
|
||||||
mg_phy_init(&phy, phy_addr, phy_conf);
|
mg_phy_init(&phy, phy_addr, phy_conf);
|
||||||
ETH->DMACRDLAR =
|
ETH->DMACRDLAR =
|
||||||
@@ -168,7 +170,27 @@ static size_t mg_tcpip_driver_stm32h_tx(const void *buf, size_t len,
|
|||||||
(void) ifp;
|
(void) ifp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_stm32h_up(struct mg_tcpip_if *ifp) {
|
static void mg_tcpip_driver_stm32h_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
#if MG_ENABLE_DRIVER_MCXN
|
||||||
|
ETH->MACPFR = MG_BIT(4); // Pass Multicast (pass all multicast frames)
|
||||||
|
#else
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
// add mDNS / DNS-SD multicast address
|
||||||
|
ETH->MACA1LR = (uint32_t) mcast_addr[3] << 24 |
|
||||||
|
(uint32_t) mcast_addr[2] << 16 |
|
||||||
|
(uint32_t) mcast_addr[1] << 8 | (uint32_t) mcast_addr[0];
|
||||||
|
ETH->MACA1HR = (uint32_t) mcast_addr[5] << 8 | (uint32_t) mcast_addr[4];
|
||||||
|
ETH->MACA1HR |= MG_BIT(31); // AE
|
||||||
|
#endif
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mg_tcpip_driver_stm32h_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
mg_tcpip_driver_stm32h_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
struct mg_tcpip_driver_stm32h_data *d =
|
struct mg_tcpip_driver_stm32h_data *d =
|
||||||
(struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
|
(struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
|
||||||
uint8_t phy_addr = d == NULL ? 0 : d->phy_addr;
|
uint8_t phy_addr = d == NULL ? 0 : d->phy_addr;
|
||||||
@@ -223,5 +245,5 @@ void ETH_IRQHandler(void) {
|
|||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
|
struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
|
||||||
mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, NULL,
|
mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, NULL,
|
||||||
mg_tcpip_driver_stm32h_up};
|
mg_tcpip_driver_stm32h_poll};
|
||||||
#endif
|
#endif
|
||||||
+42
-22
@@ -55,7 +55,8 @@ static uint32_t emac_read_phy(uint8_t addr, uint8_t reg) {
|
|||||||
static void emac_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
|
static void emac_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
|
||||||
EMAC->EMACMIIDATA = val;
|
EMAC->EMACMIIDATA = val;
|
||||||
EMAC->EMACMIIADDR &= (0xf << 2);
|
EMAC->EMACMIIADDR &= (0xf << 2);
|
||||||
EMAC->EMACMIIADDR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | MG_BIT(1);
|
EMAC->EMACMIIADDR |=
|
||||||
|
((uint32_t) addr << 11) | ((uint32_t) reg << 6) | MG_BIT(1);
|
||||||
EMAC->EMACMIIADDR |= MG_BIT(0);
|
EMAC->EMACMIIADDR |= MG_BIT(0);
|
||||||
while (EMAC->EMACMIIADDR & MG_BIT(0)) tm4cspin(1);
|
while (EMAC->EMACMIIADDR & MG_BIT(0)) tm4cspin(1);
|
||||||
}
|
}
|
||||||
@@ -133,8 +134,8 @@ static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
|
|||||||
|
|
||||||
// Init RX descriptors
|
// Init RX descriptors
|
||||||
for (int i = 0; i < ETH_DESC_CNT; i++) {
|
for (int i = 0; i < ETH_DESC_CNT; i++) {
|
||||||
s_rxdesc[i][0] = MG_BIT(31); // Own
|
s_rxdesc[i][0] = MG_BIT(31); // Own
|
||||||
s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | MG_BIT(14); // 2nd address chained
|
s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | MG_BIT(14); // 2nd address chained
|
||||||
s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
|
s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
|
||||||
s_rxdesc[i][3] =
|
s_rxdesc[i][3] =
|
||||||
(uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
|
(uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
|
||||||
@@ -148,8 +149,9 @@ static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
|
|||||||
(uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain
|
(uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain
|
||||||
}
|
}
|
||||||
|
|
||||||
EMAC->EMACDMABUSMOD |= MG_BIT(0); // Software reset
|
EMAC->EMACDMABUSMOD |= MG_BIT(0); // Software reset
|
||||||
while ((EMAC->EMACDMABUSMOD & MG_BIT(0)) != 0) tm4cspin(1); // Wait until done
|
while ((EMAC->EMACDMABUSMOD & MG_BIT(0)) != 0)
|
||||||
|
tm4cspin(1); // Wait until done
|
||||||
|
|
||||||
// Set MDC clock divider. If user told us the value, use it. Otherwise, guess
|
// Set MDC clock divider. If user told us the value, use it. Otherwise, guess
|
||||||
int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
|
int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
|
||||||
@@ -157,25 +159,25 @@ static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
|
|||||||
|
|
||||||
// NOTE(cpq): we do not use extended descriptor bit 7, and do not use
|
// NOTE(cpq): we do not use extended descriptor bit 7, and do not use
|
||||||
// hardware checksum. Therefore, descriptor size is 4, not 8
|
// hardware checksum. Therefore, descriptor size is 4, not 8
|
||||||
// EMAC->EMACDMABUSMOD = MG_BIT(13) | MG_BIT(16) | MG_BIT(22) | MG_BIT(23) | MG_BIT(25);
|
// EMAC->EMACDMABUSMOD = MG_BIT(13) | MG_BIT(16) | MG_BIT(22) | MG_BIT(23) |
|
||||||
|
// MG_BIT(25);
|
||||||
EMAC->EMACIM = MG_BIT(3) | MG_BIT(9); // Mask timestamp & PMT IT
|
EMAC->EMACIM = MG_BIT(3) | MG_BIT(9); // Mask timestamp & PMT IT
|
||||||
EMAC->EMACFLOWCTL = MG_BIT(7); // Disable zero-quanta pause
|
EMAC->EMACFLOWCTL = MG_BIT(7); // Disable zero-quanta pause
|
||||||
// EMAC->EMACFRAMEFLTR = MG_BIT(31); // Receive all
|
EMAC->EMACFRAMEFLTR = MG_BIT(10); // Perfect filtering
|
||||||
// EMAC->EMACPC defaults to internal PHY (EPHY) in MMI mode
|
// EMAC->EMACPC defaults to internal PHY (EPHY) in MMI mode
|
||||||
emac_write_phy(EPHY_ADDR, EPHYBMCR, MG_BIT(15)); // Reset internal PHY (EPHY)
|
emac_write_phy(EPHY_ADDR, EPHYBMCR, MG_BIT(15)); // Reset internal PHY (EPHY)
|
||||||
emac_write_phy(EPHY_ADDR, EPHYBMCR, MG_BIT(12)); // Set autonegotiation
|
emac_write_phy(EPHY_ADDR, EPHYBMCR, MG_BIT(12)); // Set autonegotiation
|
||||||
EMAC->EMACRXDLADDR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
|
EMAC->EMACRXDLADDR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
|
||||||
EMAC->EMACTXDLADDR = (uint32_t) (uintptr_t) s_txdesc; // TX descriptors
|
EMAC->EMACTXDLADDR = (uint32_t) (uintptr_t) s_txdesc; // TX descriptors
|
||||||
EMAC->EMACDMAIM = MG_BIT(6) | MG_BIT(16); // RIE, NIE
|
EMAC->EMACDMAIM = MG_BIT(6) | MG_BIT(16); // RIE, NIE
|
||||||
EMAC->EMACCFG = MG_BIT(2) | MG_BIT(3) | MG_BIT(11) | MG_BIT(14); // RE, TE, Duplex, Fast
|
EMAC->EMACCFG =
|
||||||
|
MG_BIT(2) | MG_BIT(3) | MG_BIT(11) | MG_BIT(14); // RE, TE, Duplex, Fast
|
||||||
EMAC->EMACDMAOPMODE =
|
EMAC->EMACDMAOPMODE =
|
||||||
MG_BIT(1) | MG_BIT(13) | MG_BIT(21) | MG_BIT(25); // SR, ST, TSF, RSF
|
MG_BIT(1) | MG_BIT(13) | MG_BIT(21) | MG_BIT(25); // SR, ST, TSF, RSF
|
||||||
EMAC->EMACADDR0H = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
|
EMAC->EMACADDR0H = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
|
||||||
EMAC->EMACADDR0L = (uint32_t) (ifp->mac[3] << 24) |
|
EMAC->EMACADDR0L = (uint32_t) (ifp->mac[3] << 24) |
|
||||||
((uint32_t) ifp->mac[2] << 16) |
|
((uint32_t) ifp->mac[2] << 16) |
|
||||||
((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
|
((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
|
||||||
// NOTE(scaprile) There are 3 additional slots for filtering, disabled by
|
|
||||||
// default. This also applies to the STM32 driver (at least for F7)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,12 +202,28 @@ static size_t mg_tcpip_driver_tm4c_tx(const void *buf, size_t len,
|
|||||||
if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
|
if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
|
||||||
}
|
}
|
||||||
EMAC->EMACDMARIS = MG_BIT(2) | MG_BIT(5); // Clear any prior TU/UNF
|
EMAC->EMACDMARIS = MG_BIT(2) | MG_BIT(5); // Clear any prior TU/UNF
|
||||||
EMAC->EMACTXPOLLD = 0; // and resume
|
EMAC->EMACTXPOLLD = 0; // and resume
|
||||||
return len;
|
return len;
|
||||||
(void) ifp;
|
(void) ifp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_tm4c_up(struct mg_tcpip_if *ifp) {
|
static void mg_tcpip_driver_tm4c_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
// add mDNS / DNS-SD multicast address
|
||||||
|
EMAC->EMACADDR1L = (uint32_t) mcast_addr[3] << 24 |
|
||||||
|
(uint32_t) mcast_addr[2] << 16 |
|
||||||
|
(uint32_t) mcast_addr[1] << 8 | (uint32_t) mcast_addr[0];
|
||||||
|
EMAC->EMACADDR1H = (uint32_t) mcast_addr[5] << 8 | (uint32_t) mcast_addr[4];
|
||||||
|
EMAC->EMACADDR1H |= MG_BIT(31); // AE
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mg_tcpip_driver_tm4c_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
mg_tcpip_driver_tm4c_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
|
uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
|
||||||
bool up = (bmsr & MG_BIT(2)) ? 1 : 0;
|
bool up = (bmsr & MG_BIT(2)) ? 1 : 0;
|
||||||
if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
|
if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // link state just went up
|
||||||
@@ -213,9 +231,10 @@ static bool mg_tcpip_driver_tm4c_up(struct mg_tcpip_if *ifp) {
|
|||||||
// tmp = reg with flags set to the most likely situation: 100M full-duplex
|
// tmp = reg with flags set to the most likely situation: 100M full-duplex
|
||||||
// if(link is slow or half) set flags otherwise
|
// if(link is slow or half) set flags otherwise
|
||||||
// reg = tmp
|
// reg = tmp
|
||||||
uint32_t emaccfg = EMAC->EMACCFG | MG_BIT(14) | MG_BIT(11); // 100M, Full-duplex
|
uint32_t emaccfg =
|
||||||
if (sts & MG_BIT(1)) emaccfg &= ~MG_BIT(14); // 10M
|
EMAC->EMACCFG | MG_BIT(14) | MG_BIT(11); // 100M, Full-duplex
|
||||||
if ((sts & MG_BIT(2)) == 0) emaccfg &= ~MG_BIT(11); // Half-duplex
|
if (sts & MG_BIT(1)) emaccfg &= ~MG_BIT(14); // 10M
|
||||||
|
if ((sts & MG_BIT(2)) == 0) emaccfg &= ~MG_BIT(11); // Half-duplex
|
||||||
EMAC->EMACCFG = emaccfg; // IRQ handler does not fiddle with this register
|
EMAC->EMACCFG = emaccfg; // IRQ handler does not fiddle with this register
|
||||||
MG_DEBUG(("Link is %uM %s-duplex", emaccfg & MG_BIT(14) ? 100 : 10,
|
MG_DEBUG(("Link is %uM %s-duplex", emaccfg & MG_BIT(14) ? 100 : 10,
|
||||||
emaccfg & MG_BIT(11) ? "full" : "half"));
|
emaccfg & MG_BIT(11) ? "full" : "half"));
|
||||||
@@ -226,11 +245,12 @@ static bool mg_tcpip_driver_tm4c_up(struct mg_tcpip_if *ifp) {
|
|||||||
void EMAC0_IRQHandler(void);
|
void EMAC0_IRQHandler(void);
|
||||||
static uint32_t s_rxno;
|
static uint32_t s_rxno;
|
||||||
void EMAC0_IRQHandler(void) {
|
void EMAC0_IRQHandler(void) {
|
||||||
if (EMAC->EMACDMARIS & MG_BIT(6)) { // Frame received, loop
|
if (EMAC->EMACDMARIS & MG_BIT(6)) { // Frame received, loop
|
||||||
EMAC->EMACDMARIS = MG_BIT(16) | MG_BIT(6); // Clear flag
|
EMAC->EMACDMARIS = MG_BIT(16) | MG_BIT(6); // Clear flag
|
||||||
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
||||||
if (s_rxdesc[s_rxno][0] & MG_BIT(31)) break; // exit when done
|
if (s_rxdesc[s_rxno][0] & MG_BIT(31)) break; // exit when done
|
||||||
if (((s_rxdesc[s_rxno][0] & (MG_BIT(8) | MG_BIT(9))) == (MG_BIT(8) | MG_BIT(9))) &&
|
if (((s_rxdesc[s_rxno][0] & (MG_BIT(8) | MG_BIT(9))) ==
|
||||||
|
(MG_BIT(8) | MG_BIT(9))) &&
|
||||||
!(s_rxdesc[s_rxno][0] & MG_BIT(15))) { // skip partial/errored frames
|
!(s_rxdesc[s_rxno][0] & MG_BIT(15))) { // skip partial/errored frames
|
||||||
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (MG_BIT(14) - 1));
|
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (MG_BIT(14) - 1));
|
||||||
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
|
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
|
||||||
@@ -242,10 +262,10 @@ void EMAC0_IRQHandler(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
EMAC->EMACDMARIS = MG_BIT(7); // Clear possible RU while processing
|
EMAC->EMACDMARIS = MG_BIT(7); // Clear possible RU while processing
|
||||||
EMAC->EMACRXPOLLD = 0; // and resume RX
|
EMAC->EMACRXPOLLD = 0; // and resume RX
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_tm4c = {mg_tcpip_driver_tm4c_init,
|
struct mg_tcpip_driver mg_tcpip_driver_tm4c = {mg_tcpip_driver_tm4c_init,
|
||||||
mg_tcpip_driver_tm4c_tx, NULL,
|
mg_tcpip_driver_tm4c_tx, NULL,
|
||||||
mg_tcpip_driver_tm4c_up};
|
mg_tcpip_driver_tm4c_poll};
|
||||||
#endif
|
#endif
|
||||||
+35
-20
@@ -105,10 +105,6 @@ static bool mg_tcpip_driver_tms570_init(struct mg_tcpip_if *ifp) {
|
|||||||
while (delay-- != 0) (void) 0;
|
while (delay-- != 0) (void) 0;
|
||||||
struct mg_phy phy = {emac_read_phy, emac_write_phy};
|
struct mg_phy phy = {emac_read_phy, emac_write_phy};
|
||||||
mg_phy_init(&phy, d->phy_addr, MG_PHY_CLOCKS_MAC);
|
mg_phy_init(&phy, d->phy_addr, MG_PHY_CLOCKS_MAC);
|
||||||
// set the mac address
|
|
||||||
EMAC->MACSRCADDRHI = ifp->mac[0] | (ifp->mac[1] << 8) | (ifp->mac[2] << 16) |
|
|
||||||
(ifp->mac[3] << 24);
|
|
||||||
EMAC->MACSRCADDRLO = ifp->mac[4] | (ifp->mac[5] << 8);
|
|
||||||
uint32_t channel;
|
uint32_t channel;
|
||||||
for (channel = 0; channel < 8; channel++) {
|
for (channel = 0; channel < 8; channel++) {
|
||||||
EMAC->MACINDEX = channel;
|
EMAC->MACINDEX = channel;
|
||||||
@@ -118,7 +114,8 @@ static bool mg_tcpip_driver_tms570_init(struct mg_tcpip_if *ifp) {
|
|||||||
MG_BIT(19) | (channel << 16);
|
MG_BIT(19) | (channel << 16);
|
||||||
}
|
}
|
||||||
EMAC->RXUNICASTSET = 1; // accept unicast frames;
|
EMAC->RXUNICASTSET = 1; // accept unicast frames;
|
||||||
EMAC->RXMBPENABLE = MG_BIT(30) | MG_BIT(13); // CRC, broadcast;
|
|
||||||
|
EMAC->RXMBPENABLE |= MG_BIT(30) | MG_BIT(13); // CRC, broadcast
|
||||||
|
|
||||||
// Initialize the descriptors
|
// Initialize the descriptors
|
||||||
for (i = 0; i < ETH_DESC_CNT; i++) {
|
for (i = 0; i < ETH_DESC_CNT; i++) {
|
||||||
@@ -172,12 +169,30 @@ static size_t mg_tcpip_driver_tms570_tx(const void *buf, size_t len,
|
|||||||
return len;
|
return len;
|
||||||
(void) ifp;
|
(void) ifp;
|
||||||
}
|
}
|
||||||
static bool mg_tcpip_driver_tms570_up(struct mg_tcpip_if *ifp) {
|
|
||||||
|
static void mg_tcpip_driver_tms570_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
// Setting Hash Index for 01:00:5e:00:00:fb (multicast)
|
||||||
|
// using TMS570 XOR method (32.5.37).
|
||||||
|
// computed hash is 55, which means bit 23 (55 - 32) in
|
||||||
|
// HASH2 register must be set
|
||||||
|
EMAC->MACHASH2 = MG_BIT(23);
|
||||||
|
EMAC->RXMBPENABLE = MG_BIT(5); // enable hash filtering
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mg_tcpip_driver_tms570_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
mg_tcpip_driver_tms570_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
struct mg_tcpip_driver_tms570_data *d =
|
struct mg_tcpip_driver_tms570_data *d =
|
||||||
(struct mg_tcpip_driver_tms570_data *) ifp->driver_data;
|
(struct mg_tcpip_driver_tms570_data *) ifp->driver_data;
|
||||||
uint8_t speed = MG_PHY_SPEED_10M;
|
uint8_t speed = MG_PHY_SPEED_10M;
|
||||||
bool up = false, full_duplex = false;
|
bool up = false, full_duplex = false;
|
||||||
struct mg_phy phy = {emac_read_phy, emac_write_phy};
|
struct mg_phy phy = {emac_read_phy, emac_write_phy};
|
||||||
|
if (!s1) return false;
|
||||||
up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
|
up = mg_phy_up(&phy, d->phy_addr, &full_duplex, &speed);
|
||||||
if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) {
|
if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) {
|
||||||
// link state just went up
|
// link state just went up
|
||||||
@@ -186,6 +201,7 @@ static bool mg_tcpip_driver_tms570_up(struct mg_tcpip_if *ifp) {
|
|||||||
}
|
}
|
||||||
return up;
|
return up;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma CODE_STATE(EMAC_TX_IRQHandler, 32)
|
#pragma CODE_STATE(EMAC_TX_IRQHandler, 32)
|
||||||
#pragma INTERRUPT(EMAC_TX_IRQHandler, IRQ)
|
#pragma INTERRUPT(EMAC_TX_IRQHandler, IRQ)
|
||||||
void EMAC_TX_IRQHandler(void) {
|
void EMAC_TX_IRQHandler(void) {
|
||||||
@@ -206,19 +222,18 @@ void EMAC_RX_IRQHandler(void) {
|
|||||||
uint32_t i;
|
uint32_t i;
|
||||||
//MG_INFO(("RX interrupt"));
|
//MG_INFO(("RX interrupt"));
|
||||||
for (i = 0; i < 10; i++) { // read as they arrive but not forever
|
for (i = 0; i < 10; i++) { // read as they arrive but not forever
|
||||||
if ((s_rxdesc[s_rxno][3] & SWAP32(MG_BIT(29))) == 0) {
|
if (s_rxdesc[s_rxno][3] & SWAP32(MG_BIT(29))) break;
|
||||||
uint32_t len = SWAP32(s_rxdesc[s_rxno][3]) & 0xffff;
|
uint32_t len = SWAP32(s_rxdesc[s_rxno][3]) & 0xffff;
|
||||||
//MG_INFO(("recv len: %d", len));
|
//MG_INFO(("recv len: %d", len));
|
||||||
//mg_hexdump(s_rxbuf[s_rxno], len);
|
//mg_hexdump(s_rxbuf[s_rxno], len);
|
||||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||||
uint32_t flags = s_rxdesc[s_rxno][3];
|
uint32_t flags = s_rxdesc[s_rxno][3];
|
||||||
s_rxdesc[s_rxno][3] = SWAP32(MG_BIT(29));
|
s_rxdesc[s_rxno][3] = SWAP32(MG_BIT(29));
|
||||||
s_rxdesc[s_rxno][2] = SWAP32(ETH_PKT_SIZE);
|
s_rxdesc[s_rxno][2] = SWAP32(ETH_PKT_SIZE);
|
||||||
EMAC->RXCP[0] = (uint32_t) &s_rxdesc[s_rxno][0];
|
EMAC->RXCP[0] = (uint32_t) &s_rxdesc[s_rxno][0];
|
||||||
if (flags & SWAP32(MG_BIT(28))) {
|
if (flags & SWAP32(MG_BIT(28))) {
|
||||||
//MG_INFO(("EOQ detected"));
|
//MG_INFO(("EOQ detected"));
|
||||||
EMAC->RXHDP[0] = (uint32_t) &s_rxdesc[0][0];
|
EMAC->RXHDP[0] = (uint32_t) &s_rxdesc[0][0];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||||
}
|
}
|
||||||
@@ -228,6 +243,6 @@ void EMAC_RX_IRQHandler(void) {
|
|||||||
}
|
}
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_tms570 = {mg_tcpip_driver_tms570_init,
|
struct mg_tcpip_driver mg_tcpip_driver_tms570 = {mg_tcpip_driver_tms570_init,
|
||||||
mg_tcpip_driver_tms570_tx, NULL,
|
mg_tcpip_driver_tms570_tx, NULL,
|
||||||
mg_tcpip_driver_tms570_up};
|
mg_tcpip_driver_tms570_poll};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
+27
-26
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5100) && MG_ENABLE_DRIVER_W5100
|
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5100) && MG_ENABLE_DRIVER_W5100
|
||||||
|
|
||||||
static void w5100_txn(struct mg_tcpip_spi *s, uint16_t addr,
|
static void w5100_txn(struct mg_tcpip_spi *s, uint16_t addr, bool wr, void *buf,
|
||||||
bool wr, void *buf, size_t len) {
|
size_t len) {
|
||||||
size_t i;
|
size_t i;
|
||||||
uint8_t *p = (uint8_t *) buf;
|
uint8_t *p = (uint8_t *) buf;
|
||||||
uint8_t control = wr ? 0xF0 : 0x0F;
|
uint8_t control = wr ? 0xF0 : 0x0F;
|
||||||
@@ -28,8 +28,8 @@ static uint16_t w5100_r2(struct mg_tcpip_spi *s, uint16_t addr) { uint8_t buf[2
|
|||||||
|
|
||||||
static size_t w5100_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
|
static size_t w5100_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
|
||||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||||
uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2; // Read recv len
|
uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2; // Read recv len
|
||||||
while ((n2 = w5100_r2(s, 0x426)) > n) n = n2; // Until it is stable
|
while ((n2 = w5100_r2(s, 0x426)) > n) n = n2; // Until it is stable
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
uint16_t ptr = w5100_r2(s, 0x428); // Get read pointer
|
uint16_t ptr = w5100_r2(s, 0x428); // Get read pointer
|
||||||
if (n <= len + 2 && n > 1) {
|
if (n <= len + 2 && n > 1) {
|
||||||
@@ -46,7 +46,7 @@ static size_t w5100_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
|
|||||||
w5100_rn(s, rxbuf_addr, buf + remaining_len, n - remaining_len);
|
w5100_rn(s, rxbuf_addr, buf + remaining_len, n - remaining_len);
|
||||||
}
|
}
|
||||||
w5100_w2(s, 0x428, (uint16_t) (ptr + n));
|
w5100_w2(s, 0x428, (uint16_t) (ptr + n));
|
||||||
w5100_w1(s, 0x401, 0x40); // Sock0 CR -> RECV
|
w5100_w1(s, 0x401, 0x40); // Sock0 CR -> RECV
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -55,27 +55,27 @@ static size_t w5100_tx(const void *buf, size_t buflen,
|
|||||||
struct mg_tcpip_if *ifp) {
|
struct mg_tcpip_if *ifp) {
|
||||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||||
uint16_t i, n = 0, ptr = 0, len = (uint16_t) buflen;
|
uint16_t i, n = 0, ptr = 0, len = (uint16_t) buflen;
|
||||||
while (n < len) n = w5100_r2(s, 0x420); // Wait for space
|
while (n < len) n = w5100_r2(s, 0x420); // Wait for space
|
||||||
ptr = w5100_r2(s, 0x424); // Get write pointer
|
ptr = w5100_r2(s, 0x424); // Get write pointer
|
||||||
uint16_t txbuf_size = (1 << (w5100_r1(s, 0x1b) & 3)) * 1024;
|
uint16_t txbuf_size = (1 << (w5100_r1(s, 0x1b) & 3)) * 1024;
|
||||||
uint16_t ptr_ofs = ptr & (txbuf_size - 1);
|
uint16_t ptr_ofs = ptr & (txbuf_size - 1);
|
||||||
uint16_t txbuf_addr = 0x4000;
|
uint16_t txbuf_addr = 0x4000;
|
||||||
if (ptr_ofs + len > txbuf_size) {
|
if (ptr_ofs + len > txbuf_size) {
|
||||||
uint16_t size = txbuf_size - ptr_ofs;
|
uint16_t size = txbuf_size - ptr_ofs;
|
||||||
w5100_wn(s, txbuf_addr + ptr_ofs, (char*) buf, size);
|
w5100_wn(s, txbuf_addr + ptr_ofs, (char *) buf, size);
|
||||||
w5100_wn(s, txbuf_addr, (char*) buf + size, len - size);
|
w5100_wn(s, txbuf_addr, (char *) buf + size, len - size);
|
||||||
} else {
|
} else {
|
||||||
w5100_wn(s, txbuf_addr + ptr_ofs, (char*) buf, len);
|
w5100_wn(s, txbuf_addr + ptr_ofs, (char *) buf, len);
|
||||||
}
|
}
|
||||||
w5100_w2(s, 0x424, (uint16_t) (ptr + len)); // Advance write pointer
|
w5100_w2(s, 0x424, (uint16_t) (ptr + len)); // Advance write pointer
|
||||||
w5100_w1(s, 0x401, 0x20); // Sock0 CR -> SEND
|
w5100_w1(s, 0x401, 0x20); // Sock0 CR -> SEND
|
||||||
for (i = 0; i < 40; i++) {
|
for (i = 0; i < 40; i++) {
|
||||||
uint8_t ir = w5100_r1(s, 0x402); // Read S0 IR
|
uint8_t ir = w5100_r1(s, 0x402); // Read S0 IR
|
||||||
if (ir == 0) continue;
|
if (ir == 0) continue;
|
||||||
// printf("IR %d, len=%d, free=%d, ptr %d\n", ir, (int) len, (int) n, ptr);
|
// printf("IR %d, len=%d, free=%d, ptr %d\n", ir, (int) len, (int) n, ptr);
|
||||||
w5100_w1(s, 0x402, ir); // Write S0 IR: clear it!
|
w5100_w1(s, 0x402, ir); // Write S0 IR: clear it!
|
||||||
if (ir & 8) len = 0; // Timeout. Report error
|
if (ir & 8) len = 0; // Timeout. Report error
|
||||||
if (ir & (16 | 8)) break; // Stop on SEND_OK or timeout
|
if (ir & (16 | 8)) break; // Stop on SEND_OK or timeout
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@@ -83,24 +83,25 @@ static size_t w5100_tx(const void *buf, size_t buflen,
|
|||||||
static bool w5100_init(struct mg_tcpip_if *ifp) {
|
static bool w5100_init(struct mg_tcpip_if *ifp) {
|
||||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||||
s->end(s->spi);
|
s->end(s->spi);
|
||||||
w5100_w1(s, 0, 0x80); // Reset chip: CR -> 0x80
|
w5100_w1(s, 0, 0x80); // Reset chip: CR -> 0x80
|
||||||
w5100_w1(s, 0x72, 0x53); // CR PHYLCKR -> unlock PHY
|
w5100_w1(s, 0x72, 0x53); // CR PHYLCKR -> unlock PHY
|
||||||
w5100_w1(s, 0x46, 0); // CR PHYCR0 -> autonegotiation
|
w5100_w1(s, 0x46, 0); // CR PHYCR0 -> autonegotiation
|
||||||
w5100_w1(s, 0x47, 0); // CR PHYCR1 -> reset
|
w5100_w1(s, 0x47, 0); // CR PHYCR1 -> reset
|
||||||
w5100_w1(s, 0x72, 0x00); // CR PHYLCKR -> lock PHY
|
w5100_w1(s, 0x72, 0x00); // CR PHYLCKR -> lock PHY
|
||||||
w5100_w1(s, 0x1a, 6); // Sock0 RX buf size - 4KB
|
w5100_wn(s, 0x09, ifp->mac, 6); // SHAR
|
||||||
w5100_w1(s, 0x1b, 6); // Sock0 TX buf size - 4KB
|
w5100_w1(s, 0x1a, 6); // Sock0 RX buf size - 4KB
|
||||||
w5100_w1(s, 0x400, 4); // Sock0 MR -> MACRAW
|
w5100_w1(s, 0x1b, 6); // Sock0 TX buf size - 4KB
|
||||||
|
w5100_w1(s, 0x400, 0x44); // Sock0 MR -> MACRAW, MAC filter
|
||||||
w5100_w1(s, 0x401, 1); // Sock0 CR -> OPEN
|
w5100_w1(s, 0x401, 1); // Sock0 CR -> OPEN
|
||||||
return w5100_r1(s, 0x403) == 0x42; // Sock0 SR == MACRAW
|
return w5100_r1(s, 0x403) == 0x42; // Sock0 SR == MACRAW
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool w5100_up(struct mg_tcpip_if *ifp) {
|
static bool w5100_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
|
struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||||
uint8_t physr0 = w5100_r1(spi, 0x3c);
|
return s1 ? w5100_r1(spi, 0x3c /* PHYSR */) & 1
|
||||||
return physr0 & 1; // Bit 0 of PHYSR is LNK (0 - down, 1 - up)
|
: false; // Bit 0 of PHYSR is LNK (0 - down, 1 - up)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_w5100 = {w5100_init, w5100_tx, w5100_rx,
|
struct mg_tcpip_driver mg_tcpip_driver_w5100 = {w5100_init, w5100_tx, w5100_rx,
|
||||||
w5100_up};
|
w5100_poll};
|
||||||
#endif
|
#endif
|
||||||
+4
-4
@@ -81,12 +81,12 @@ static bool w5500_init(struct mg_tcpip_if *ifp) {
|
|||||||
return w5500_r1(s, W5500_S0, 3) == 0x42; // Sock0 SR == MACRAW
|
return w5500_r1(s, W5500_S0, 3) == 0x42; // Sock0 SR == MACRAW
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool w5500_up(struct mg_tcpip_if *ifp) {
|
static bool w5500_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
|
struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||||
uint8_t phycfgr = w5500_r1(spi, W5500_CR, 0x2e);
|
return s1 ? w5500_r1(spi, W5500_CR, 0x2e /* PHYCFGR */) & 1
|
||||||
return phycfgr & 1; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up)
|
: false; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx,
|
struct mg_tcpip_driver mg_tcpip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx,
|
||||||
w5500_up};
|
w5500_poll};
|
||||||
#endif
|
#endif
|
||||||
+73
-59
@@ -4,34 +4,34 @@
|
|||||||
|
|
||||||
struct ETH_GLOBAL_TypeDef {
|
struct ETH_GLOBAL_TypeDef {
|
||||||
volatile uint32_t MAC_CONFIGURATION, MAC_FRAME_FILTER, HASH_TABLE_HIGH,
|
volatile uint32_t MAC_CONFIGURATION, MAC_FRAME_FILTER, HASH_TABLE_HIGH,
|
||||||
HASH_TABLE_LOW, GMII_ADDRESS, GMII_DATA, FLOW_CONTROL, VLAN_TAG, VERSION,
|
HASH_TABLE_LOW, GMII_ADDRESS, GMII_DATA, FLOW_CONTROL, VLAN_TAG, VERSION,
|
||||||
DEBUG, REMOTE_WAKE_UP_FRAME_FILTER, PMT_CONTROL_STATUS, RESERVED[2],
|
DEBUG, REMOTE_WAKE_UP_FRAME_FILTER, PMT_CONTROL_STATUS, RESERVED[2],
|
||||||
INTERRUPT_STATUS, INTERRUPT_MASK, MAC_ADDRESS0_HIGH, MAC_ADDRESS0_LOW,
|
INTERRUPT_STATUS, INTERRUPT_MASK, MAC_ADDRESS0_HIGH, MAC_ADDRESS0_LOW,
|
||||||
MAC_ADDRESS1_HIGH, MAC_ADDRESS1_LOW, MAC_ADDRESS2_HIGH, MAC_ADDRESS2_LOW,
|
MAC_ADDRESS1_HIGH, MAC_ADDRESS1_LOW, MAC_ADDRESS2_HIGH, MAC_ADDRESS2_LOW,
|
||||||
MAC_ADDRESS3_HIGH, MAC_ADDRESS3_LOW, RESERVED1[40], MMC_CONTROL,
|
MAC_ADDRESS3_HIGH, MAC_ADDRESS3_LOW, RESERVED1[40], MMC_CONTROL,
|
||||||
MMC_RECEIVE_INTERRUPT, MMC_TRANSMIT_INTERRUPT, MMC_RECEIVE_INTERRUPT_MASK,
|
MMC_RECEIVE_INTERRUPT, MMC_TRANSMIT_INTERRUPT, MMC_RECEIVE_INTERRUPT_MASK,
|
||||||
MMC_TRANSMIT_INTERRUPT_MASK, TX_STATISTICS[26], RESERVED2,
|
MMC_TRANSMIT_INTERRUPT_MASK, TX_STATISTICS[26], RESERVED2,
|
||||||
RX_STATISTICS_1[26], RESERVED3[6], MMC_IPC_RECEIVE_INTERRUPT_MASK,
|
RX_STATISTICS_1[26], RESERVED3[6], MMC_IPC_RECEIVE_INTERRUPT_MASK,
|
||||||
RESERVED4, MMC_IPC_RECEIVE_INTERRUPT, RESERVED5, RX_STATISTICS_2[30],
|
RESERVED4, MMC_IPC_RECEIVE_INTERRUPT, RESERVED5, RX_STATISTICS_2[30],
|
||||||
RESERVED7[286], TIMESTAMP_CONTROL, SUB_SECOND_INCREMENT,
|
RESERVED7[286], TIMESTAMP_CONTROL, SUB_SECOND_INCREMENT,
|
||||||
SYSTEM_TIME_SECONDS, SYSTEM_TIME_NANOSECONDS,
|
SYSTEM_TIME_SECONDS, SYSTEM_TIME_NANOSECONDS, SYSTEM_TIME_SECONDS_UPDATE,
|
||||||
SYSTEM_TIME_SECONDS_UPDATE, SYSTEM_TIME_NANOSECONDS_UPDATE,
|
SYSTEM_TIME_NANOSECONDS_UPDATE, TIMESTAMP_ADDEND, TARGET_TIME_SECONDS,
|
||||||
TIMESTAMP_ADDEND, TARGET_TIME_SECONDS, TARGET_TIME_NANOSECONDS,
|
TARGET_TIME_NANOSECONDS, SYSTEM_TIME_HIGHER_WORD_SECONDS,
|
||||||
SYSTEM_TIME_HIGHER_WORD_SECONDS, TIMESTAMP_STATUS,
|
TIMESTAMP_STATUS, PPS_CONTROL, RESERVED8[564], BUS_MODE,
|
||||||
PPS_CONTROL, RESERVED8[564], BUS_MODE, TRANSMIT_POLL_DEMAND,
|
TRANSMIT_POLL_DEMAND, RECEIVE_POLL_DEMAND,
|
||||||
RECEIVE_POLL_DEMAND, RECEIVE_DESCRIPTOR_LIST_ADDRESS,
|
RECEIVE_DESCRIPTOR_LIST_ADDRESS, TRANSMIT_DESCRIPTOR_LIST_ADDRESS, STATUS,
|
||||||
TRANSMIT_DESCRIPTOR_LIST_ADDRESS, STATUS, OPERATION_MODE,
|
OPERATION_MODE, INTERRUPT_ENABLE,
|
||||||
INTERRUPT_ENABLE, MISSED_FRAME_AND_BUFFER_OVERFLOW_COUNTER,
|
MISSED_FRAME_AND_BUFFER_OVERFLOW_COUNTER,
|
||||||
RECEIVE_INTERRUPT_WATCHDOG_TIMER, RESERVED9, AHB_STATUS,
|
RECEIVE_INTERRUPT_WATCHDOG_TIMER, RESERVED9, AHB_STATUS, RESERVED10[6],
|
||||||
RESERVED10[6], CURRENT_HOST_TRANSMIT_DESCRIPTOR,
|
CURRENT_HOST_TRANSMIT_DESCRIPTOR, CURRENT_HOST_RECEIVE_DESCRIPTOR,
|
||||||
CURRENT_HOST_RECEIVE_DESCRIPTOR, CURRENT_HOST_TRANSMIT_BUFFER_ADDRESS,
|
CURRENT_HOST_TRANSMIT_BUFFER_ADDRESS, CURRENT_HOST_RECEIVE_BUFFER_ADDRESS,
|
||||||
CURRENT_HOST_RECEIVE_BUFFER_ADDRESS, HW_FEATURE;
|
HW_FEATURE;
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef ETH0
|
#undef ETH0
|
||||||
#define ETH0 ((struct ETH_GLOBAL_TypeDef*) 0x5000C000UL)
|
#define ETH0 ((struct ETH_GLOBAL_TypeDef *) 0x5000C000UL)
|
||||||
|
|
||||||
#define ETH_PKT_SIZE 1536 // Max frame size
|
#define ETH_PKT_SIZE 1536 // Max frame size
|
||||||
#define ETH_DESC_CNT 4 // Descriptors count
|
#define ETH_DESC_CNT 4 // Descriptors count
|
||||||
#define ETH_DS 4 // Descriptor size (words)
|
#define ETH_DS 4 // Descriptor size (words)
|
||||||
|
|
||||||
@@ -43,27 +43,27 @@ struct ETH_GLOBAL_TypeDef {
|
|||||||
|
|
||||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE] ETH_RAM_SECTION;
|
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE] ETH_RAM_SECTION;
|
||||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE] ETH_RAM_SECTION;
|
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE] ETH_RAM_SECTION;
|
||||||
static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS] ETH_RAM_SECTION; // RX descriptors
|
static uint32_t s_rxdesc[ETH_DESC_CNT]
|
||||||
static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS] ETH_RAM_SECTION; // TX descriptors
|
[ETH_DS] ETH_RAM_SECTION; // RX descriptors
|
||||||
static uint8_t s_txno; // Current TX descriptor
|
static uint32_t s_txdesc[ETH_DESC_CNT]
|
||||||
static uint8_t s_rxno; // Current RX descriptor
|
[ETH_DS] ETH_RAM_SECTION; // TX descriptors
|
||||||
|
static uint8_t s_txno; // Current TX descriptor
|
||||||
|
static uint8_t s_rxno; // Current RX descriptor
|
||||||
|
|
||||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||||
enum { MG_PHY_ADDR = 0, MG_PHYREG_BCR = 0, MG_PHYREG_BSR = 1 };
|
enum { MG_PHY_ADDR = 0, MG_PHYREG_BCR = 0, MG_PHYREG_BSR = 1 };
|
||||||
|
|
||||||
static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
|
static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
|
||||||
ETH0->GMII_ADDRESS = (ETH0->GMII_ADDRESS & 0x3c) |
|
ETH0->GMII_ADDRESS = (ETH0->GMII_ADDRESS & 0x3c) | ((uint32_t) addr << 11) |
|
||||||
((uint32_t)addr << 11) |
|
((uint32_t) reg << 6) | 1;
|
||||||
((uint32_t)reg << 6) | 1;
|
|
||||||
while ((ETH0->GMII_ADDRESS & 1) != 0) (void) 0;
|
while ((ETH0->GMII_ADDRESS & 1) != 0) (void) 0;
|
||||||
return (uint16_t)(ETH0->GMII_DATA & 0xffff);
|
return (uint16_t) (ETH0->GMII_DATA & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
|
static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
|
||||||
ETH0->GMII_DATA = val;
|
ETH0->GMII_DATA = val;
|
||||||
ETH0->GMII_ADDRESS = (ETH0->GMII_ADDRESS & 0x3c) |
|
ETH0->GMII_ADDRESS = (ETH0->GMII_ADDRESS & 0x3c) | ((uint32_t) addr << 11) |
|
||||||
((uint32_t)addr << 11) |
|
((uint32_t) reg << 6) | 3;
|
||||||
((uint32_t)reg << 6) | 3;
|
|
||||||
while ((ETH0->GMII_ADDRESS & 1) != 0) (void) 0;
|
while ((ETH0->GMII_ADDRESS & 1) != 0) (void) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,21 +99,21 @@ static bool mg_tcpip_driver_xmc_init(struct mg_tcpip_if *ifp) {
|
|||||||
// set the MAC address
|
// set the MAC address
|
||||||
ETH0->MAC_ADDRESS0_HIGH = MG_U32(0, 0, ifp->mac[5], ifp->mac[4]);
|
ETH0->MAC_ADDRESS0_HIGH = MG_U32(0, 0, ifp->mac[5], ifp->mac[4]);
|
||||||
ETH0->MAC_ADDRESS0_LOW =
|
ETH0->MAC_ADDRESS0_LOW =
|
||||||
MG_U32(ifp->mac[3], ifp->mac[2], ifp->mac[1], ifp->mac[0]);
|
MG_U32(ifp->mac[3], ifp->mac[2], ifp->mac[1], ifp->mac[0]);
|
||||||
|
|
||||||
// Configure the receive filter
|
// Configure the receive filter
|
||||||
ETH0->MAC_FRAME_FILTER = MG_BIT(10) | MG_BIT(2); // HFP, HMC
|
ETH0->MAC_FRAME_FILTER = MG_BIT(10); // Perfect filter
|
||||||
// Disable flow control
|
// Disable flow control
|
||||||
ETH0->FLOW_CONTROL = 0;
|
ETH0->FLOW_CONTROL = 0;
|
||||||
// Enable store and forward mode
|
// Enable store and forward mode
|
||||||
ETH0->OPERATION_MODE = MG_BIT(25) | MG_BIT(21); // RSF, TSF
|
ETH0->OPERATION_MODE = MG_BIT(25) | MG_BIT(21); // RSF, TSF
|
||||||
|
|
||||||
// Configure DMA bus mode (AAL, USP, RPBL, PBL)
|
// Configure DMA bus mode (AAL, USP, RPBL, PBL)
|
||||||
ETH0->BUS_MODE = MG_BIT(25) | MG_BIT(23) | (32 << 17) | (32 << 8);
|
ETH0->BUS_MODE = MG_BIT(25) | MG_BIT(23) | (32 << 17) | (32 << 8);
|
||||||
|
|
||||||
// init RX descriptors
|
// init RX descriptors
|
||||||
for (int i = 0; i < ETH_DESC_CNT; i++) {
|
for (int i = 0; i < ETH_DESC_CNT; i++) {
|
||||||
s_rxdesc[i][0] = MG_BIT(31); // OWN descriptor
|
s_rxdesc[i][0] = MG_BIT(31); // OWN descriptor
|
||||||
s_rxdesc[i][1] = MG_BIT(14) | ETH_PKT_SIZE;
|
s_rxdesc[i][1] = MG_BIT(14) | ETH_PKT_SIZE;
|
||||||
s_rxdesc[i][2] = (uint32_t) s_rxbuf[i];
|
s_rxdesc[i][2] = (uint32_t) s_rxbuf[i];
|
||||||
if (i == ETH_DESC_CNT - 1) {
|
if (i == ETH_DESC_CNT - 1) {
|
||||||
@@ -143,9 +143,9 @@ static bool mg_tcpip_driver_xmc_init(struct mg_tcpip_if *ifp) {
|
|||||||
ETH0->MMC_TRANSMIT_INTERRUPT_MASK = 0xFFFFFFFF;
|
ETH0->MMC_TRANSMIT_INTERRUPT_MASK = 0xFFFFFFFF;
|
||||||
ETH0->MMC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF;
|
ETH0->MMC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF;
|
||||||
ETH0->MMC_IPC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF;
|
ETH0->MMC_IPC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF;
|
||||||
ETH0->INTERRUPT_MASK = MG_BIT(9) | MG_BIT(3); // TSIM, PMTIM
|
ETH0->INTERRUPT_MASK = MG_BIT(9) | MG_BIT(3); // TSIM, PMTIM
|
||||||
|
|
||||||
//Enable interrupts (NIE, RIE, TIE)
|
// Enable interrupts (NIE, RIE, TIE)
|
||||||
ETH0->INTERRUPT_ENABLE = MG_BIT(16) | MG_BIT(6) | MG_BIT(0);
|
ETH0->INTERRUPT_ENABLE = MG_BIT(16) | MG_BIT(6) | MG_BIT(0);
|
||||||
|
|
||||||
// Enable MAC transmission and reception (TE, RE)
|
// Enable MAC transmission and reception (TE, RE)
|
||||||
@@ -156,7 +156,7 @@ static bool mg_tcpip_driver_xmc_init(struct mg_tcpip_if *ifp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t mg_tcpip_driver_xmc_tx(const void *buf, size_t len,
|
static size_t mg_tcpip_driver_xmc_tx(const void *buf, size_t len,
|
||||||
struct mg_tcpip_if *ifp) {
|
struct mg_tcpip_if *ifp) {
|
||||||
if (len > sizeof(s_txbuf[s_txno])) {
|
if (len > sizeof(s_txbuf[s_txno])) {
|
||||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||||
len = 0; // Frame is too big
|
len = 0; // Frame is too big
|
||||||
@@ -174,12 +174,27 @@ static size_t mg_tcpip_driver_xmc_tx(const void *buf, size_t len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resume processing
|
// Resume processing
|
||||||
ETH0->STATUS = MG_BIT(2); // clear Transmit unavailable
|
ETH0->STATUS = MG_BIT(2); // clear Transmit unavailable
|
||||||
ETH0->TRANSMIT_POLL_DEMAND = 0;
|
ETH0->TRANSMIT_POLL_DEMAND = 0;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_xmc_up(struct mg_tcpip_if *ifp) {
|
static void mg_tcpip_driver_xmc_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
// set the multicast address filter
|
||||||
|
ETH0->MAC_ADDRESS1_HIGH =
|
||||||
|
MG_U32(0, 0, mcast_addr[5], mcast_addr[4]) | MG_BIT(31);
|
||||||
|
ETH0->MAC_ADDRESS1_LOW =
|
||||||
|
MG_U32(mcast_addr[3], mcast_addr[2], mcast_addr[1], mcast_addr[0]);
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mg_tcpip_driver_xmc_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
mg_tcpip_driver_xmc_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
struct mg_tcpip_driver_xmc_data *d =
|
struct mg_tcpip_driver_xmc_data *d =
|
||||||
(struct mg_tcpip_driver_xmc_data *) ifp->driver_data;
|
(struct mg_tcpip_driver_xmc_data *) ifp->driver_data;
|
||||||
uint8_t speed = MG_PHY_SPEED_10M;
|
uint8_t speed = MG_PHY_SPEED_10M;
|
||||||
@@ -199,16 +214,15 @@ void ETH0_0_IRQHandler(void) {
|
|||||||
|
|
||||||
// check if a frame was received
|
// check if a frame was received
|
||||||
if (irq_status & MG_BIT(6)) {
|
if (irq_status & MG_BIT(6)) {
|
||||||
for (uint8_t i = 0; i < ETH_DESC_CNT; i++) {
|
for (uint8_t i = 0; i < 10; i++) { // read as they arrive, but not forever
|
||||||
if ((s_rxdesc[s_rxno][0] & MG_BIT(31)) == 0) {
|
if (s_rxdesc[s_rxno][0] & MG_BIT(31)) break;
|
||||||
size_t len = (s_rxdesc[s_rxno][0] & 0x3fff0000) >> 16;
|
size_t len = (s_rxdesc[s_rxno][0] & 0x3fff0000) >> 16;
|
||||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
|
mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
|
||||||
s_rxdesc[s_rxno][0] = MG_BIT(31); // OWN bit: handle control to DMA
|
s_rxdesc[s_rxno][0] = MG_BIT(31); // OWN bit: handle control to DMA
|
||||||
// Resume processing
|
// Resume processing
|
||||||
ETH0->STATUS = MG_BIT(7) | MG_BIT(6); // clear RU and RI
|
ETH0->STATUS = MG_BIT(7) | MG_BIT(6); // clear RU and RI
|
||||||
ETH0->RECEIVE_POLL_DEMAND = 0;
|
ETH0->RECEIVE_POLL_DEMAND = 0;
|
||||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ETH0->STATUS = MG_BIT(6);
|
ETH0->STATUS = MG_BIT(6);
|
||||||
}
|
}
|
||||||
@@ -224,7 +238,7 @@ void ETH0_0_IRQHandler(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_xmc = {
|
struct mg_tcpip_driver mg_tcpip_driver_xmc = {mg_tcpip_driver_xmc_init,
|
||||||
mg_tcpip_driver_xmc_init, mg_tcpip_driver_xmc_tx, NULL,
|
mg_tcpip_driver_xmc_tx, NULL,
|
||||||
mg_tcpip_driver_xmc_up};
|
mg_tcpip_driver_xmc_poll};
|
||||||
#endif
|
#endif
|
||||||
+25
-13
@@ -66,8 +66,8 @@ static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE];
|
|||||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE];
|
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE];
|
||||||
static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS] MG_8BYTE_ALIGNED;
|
static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS] MG_8BYTE_ALIGNED;
|
||||||
static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS] MG_8BYTE_ALIGNED;
|
static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS] MG_8BYTE_ALIGNED;
|
||||||
static uint8_t s_txno MG_8BYTE_ALIGNED; // Current TX descriptor
|
static uint8_t s_txno MG_8BYTE_ALIGNED; // Current TX descriptor
|
||||||
static uint8_t s_rxno MG_8BYTE_ALIGNED; // Current RX descriptor
|
static uint8_t s_rxno MG_8BYTE_ALIGNED; // Current RX descriptor
|
||||||
|
|
||||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||||
enum { MG_PHY_ADDR = 0, MG_PHYREG_BCR = 0, MG_PHYREG_BSR = 1 };
|
enum { MG_PHY_ADDR = 0, MG_PHYREG_BCR = 0, MG_PHYREG_BSR = 1 };
|
||||||
@@ -104,8 +104,7 @@ static bool mg_tcpip_driver_xmc7_init(struct mg_tcpip_if *ifp) {
|
|||||||
// set NSP change, ignore RX FCS, data bus width, clock rate
|
// set NSP change, ignore RX FCS, data bus width, clock rate
|
||||||
// frame length 1536, full duplex, speed
|
// frame length 1536, full duplex, speed
|
||||||
ETH0->NETWORK_CONFIG = MG_BIT(29) | MG_BIT(26) | MG_BIT(21) |
|
ETH0->NETWORK_CONFIG = MG_BIT(29) | MG_BIT(26) | MG_BIT(21) |
|
||||||
((cr & 7) << 18) | MG_BIT(8) | MG_BIT(4) | MG_BIT(1) |
|
((cr & 7) << 18) | MG_BIT(8) | MG_BIT(1) | MG_BIT(0);
|
||||||
MG_BIT(0);
|
|
||||||
|
|
||||||
// config DMA settings: Force TX burst, Discard on Error, set RX buffer size
|
// config DMA settings: Force TX burst, Discard on Error, set RX buffer size
|
||||||
// to 1536, TX_PBUF_SIZE, RX_PBUF_SIZE, AMBA_BURST_LENGTH
|
// to 1536, TX_PBUF_SIZE, RX_PBUF_SIZE, AMBA_BURST_LENGTH
|
||||||
@@ -181,7 +180,21 @@ static size_t mg_tcpip_driver_xmc7_tx(const void *buf, size_t len,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mg_tcpip_driver_xmc7_up(struct mg_tcpip_if *ifp) {
|
static void mg_tcpip_driver_xmc7_update_hash_table(struct mg_tcpip_if *ifp) {
|
||||||
|
// TODO(): read database, rebuild hash table
|
||||||
|
// set multicast MAC address
|
||||||
|
ETH0->SPEC_ADD2_BOTTOM = mcast_addr[3] << 24 | mcast_addr[2] << 16 |
|
||||||
|
mcast_addr[1] << 8 | mcast_addr[0];
|
||||||
|
ETH0->SPEC_ADD2_TOP = mcast_addr[5] << 8 | mcast_addr[4];
|
||||||
|
(void) ifp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mg_tcpip_driver_xmc7_poll(struct mg_tcpip_if *ifp, bool s1) {
|
||||||
|
if (ifp->update_mac_hash_table) {
|
||||||
|
mg_tcpip_driver_xmc7_update_hash_table(ifp);
|
||||||
|
ifp->update_mac_hash_table = false;
|
||||||
|
}
|
||||||
|
if (!s1) return false;
|
||||||
struct mg_tcpip_driver_xmc7_data *d =
|
struct mg_tcpip_driver_xmc7_data *d =
|
||||||
(struct mg_tcpip_driver_xmc7_data *) ifp->driver_data;
|
(struct mg_tcpip_driver_xmc7_data *) ifp->driver_data;
|
||||||
uint8_t speed = MG_PHY_SPEED_10M;
|
uint8_t speed = MG_PHY_SPEED_10M;
|
||||||
@@ -219,13 +232,12 @@ static bool mg_tcpip_driver_xmc7_up(struct mg_tcpip_if *ifp) {
|
|||||||
void ETH_IRQHandler(void) {
|
void ETH_IRQHandler(void) {
|
||||||
uint32_t irq_status = ETH0->INT_STATUS;
|
uint32_t irq_status = ETH0->INT_STATUS;
|
||||||
if (irq_status & MG_BIT(1)) {
|
if (irq_status & MG_BIT(1)) {
|
||||||
for (uint8_t i = 0; i < ETH_DESC_CNT; i++) {
|
for (uint8_t i = 0; i < 10; i++) { // read as they arrive, but not forever
|
||||||
if (s_rxdesc[s_rxno][0] & MG_BIT(0)) {
|
if ((s_rxdesc[s_rxno][0] & MG_BIT(0)) == 0) break;
|
||||||
size_t len = s_rxdesc[s_rxno][1] & (MG_BIT(13) - 1);
|
size_t len = s_rxdesc[s_rxno][1] & (MG_BIT(13) - 1);
|
||||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
|
mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
|
||||||
s_rxdesc[s_rxno][0] &= ~MG_BIT(0); // OWN bit: handle control to DMA
|
s_rxdesc[s_rxno][0] &= ~MG_BIT(0); // OWN bit: handle control to DMA
|
||||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,5 +246,5 @@ void ETH_IRQHandler(void) {
|
|||||||
|
|
||||||
struct mg_tcpip_driver mg_tcpip_driver_xmc7 = {mg_tcpip_driver_xmc7_init,
|
struct mg_tcpip_driver mg_tcpip_driver_xmc7 = {mg_tcpip_driver_xmc7_init,
|
||||||
mg_tcpip_driver_xmc7_tx, NULL,
|
mg_tcpip_driver_xmc7_tx, NULL,
|
||||||
mg_tcpip_driver_xmc7_up};
|
mg_tcpip_driver_xmc7_poll};
|
||||||
#endif
|
#endif
|
||||||
@@ -28,7 +28,7 @@ struct mg_fs {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
|
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
|
||||||
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
|
extern struct mg_fs mg_fs_packed; // see tutorials/core/embedded-filesystem
|
||||||
extern struct mg_fs mg_fs_fat; // FAT FS
|
extern struct mg_fs mg_fs_fat; // FAT FS
|
||||||
|
|
||||||
// File descriptor
|
// File descriptor
|
||||||
|
|||||||
@@ -502,6 +502,7 @@ static struct mg_str s_known_types[] = {
|
|||||||
MG_C_STR("htm"), MG_C_STR("text/html; charset=utf-8"),
|
MG_C_STR("htm"), MG_C_STR("text/html; charset=utf-8"),
|
||||||
MG_C_STR("css"), MG_C_STR("text/css; charset=utf-8"),
|
MG_C_STR("css"), MG_C_STR("text/css; charset=utf-8"),
|
||||||
MG_C_STR("js"), MG_C_STR("text/javascript; charset=utf-8"),
|
MG_C_STR("js"), MG_C_STR("text/javascript; charset=utf-8"),
|
||||||
|
MG_C_STR("mjs"), MG_C_STR("text/javascript; charset=utf-8"),
|
||||||
MG_C_STR("gif"), MG_C_STR("image/gif"),
|
MG_C_STR("gif"), MG_C_STR("image/gif"),
|
||||||
MG_C_STR("png"), MG_C_STR("image/png"),
|
MG_C_STR("png"), MG_C_STR("image/png"),
|
||||||
MG_C_STR("jpg"), MG_C_STR("image/jpeg"),
|
MG_C_STR("jpg"), MG_C_STR("image/jpeg"),
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ void mg_hexdump(const void *buf, size_t len) {
|
|||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if ((i % 16) == 0) {
|
if ((i % 16) == 0) {
|
||||||
// Print buffered ascii chars
|
// Print buffered ascii chars
|
||||||
if (i > 0) logs(" ", 2), logs((char *) ascii, 16), logc('\n'), alen = 0;
|
if (i > 0)
|
||||||
|
logs(" ", 2), logs((char *) ascii, 16), logs("\r\n", 2), alen = 0;
|
||||||
// Print hex address, then \t
|
// Print hex address, then \t
|
||||||
logc(nibble((i >> 12) & 15)), logc(nibble((i >> 8) & 15)),
|
logc(nibble((i >> 12) & 15)), logc(nibble((i >> 8) & 15)),
|
||||||
logc(nibble((i >> 4) & 15)), logc('0'), logs(" ", 3);
|
logc(nibble((i >> 4) & 15)), logc('0'), logs(" ", 3);
|
||||||
@@ -67,5 +68,5 @@ void mg_hexdump(const void *buf, size_t len) {
|
|||||||
ascii[alen++] = ISPRINT(p[i]) ? p[i] : '.'; // Add to the ascii buf
|
ascii[alen++] = ISPRINT(p[i]) ? p[i] : '.'; // Add to the ascii buf
|
||||||
}
|
}
|
||||||
while (alen < 16) logs(" ", 3), ascii[alen++] = ' ';
|
while (alen < 16) logs(" ", 3), ascii[alen++] = ' ';
|
||||||
logs(" ", 2), logs((char *) ascii, 16), logc('\n');
|
logs(" ", 2), logs((char *) ascii, 16), logs("\r\n", 2);
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "net.h"
|
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "net.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@@ -218,8 +218,8 @@ struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
|||||||
unsigned flags, void (*fn)(void *), void *arg) {
|
unsigned flags, void (*fn)(void *), void *arg) {
|
||||||
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
||||||
if (t != NULL) {
|
if (t != NULL) {
|
||||||
|
flags |= MG_TIMER_AUTODELETE; // We have calloc-ed it, so autodelete
|
||||||
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
||||||
t->id = mgr->timerid++;
|
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@@ -247,6 +247,9 @@ void mg_mgr_free(struct mg_mgr *mgr) {
|
|||||||
if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
|
if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
|
||||||
#endif
|
#endif
|
||||||
mg_tls_ctx_free(mgr);
|
mg_tls_ctx_free(mgr);
|
||||||
|
#if MG_ENABLE_TCPIP
|
||||||
|
if (mgr->ifp) mg_tcpip_free(mgr->ifp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_mgr_init(struct mg_mgr *mgr) {
|
void mg_mgr_init(struct mg_mgr *mgr) {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ struct mg_mgr {
|
|||||||
int dnstimeout; // DNS resolve timeout in milliseconds
|
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||||
bool use_dns6; // Use DNS6 server by default, see #1532
|
bool use_dns6; // Use DNS6 server by default, see #1532
|
||||||
unsigned long nextid; // Next connection ID
|
unsigned long nextid; // Next connection ID
|
||||||
unsigned long timerid; // Next timer ID
|
|
||||||
void *userdata; // Arbitrary user data pointer
|
void *userdata; // Arbitrary user data pointer
|
||||||
void *tls_ctx; // TLS context shared by all TLS sessions
|
void *tls_ctx; // TLS context shared by all TLS sessions
|
||||||
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
||||||
@@ -43,40 +42,41 @@ struct mg_mgr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mg_connection {
|
struct mg_connection {
|
||||||
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
||||||
struct mg_mgr *mgr; // Our container
|
struct mg_mgr *mgr; // Our container
|
||||||
struct mg_addr loc; // Local address
|
struct mg_addr loc; // Local address
|
||||||
struct mg_addr rem; // Remote address
|
struct mg_addr rem; // Remote address
|
||||||
void *fd; // Connected socket, or LWIP data
|
void *fd; // Connected socket, or LWIP data
|
||||||
unsigned long id; // Auto-incrementing unique connection ID
|
unsigned long id; // Auto-incrementing unique connection ID
|
||||||
struct mg_iobuf recv; // Incoming data
|
struct mg_iobuf recv; // Incoming data
|
||||||
struct mg_iobuf send; // Outgoing data
|
struct mg_iobuf send; // Outgoing data
|
||||||
struct mg_iobuf prof; // Profile data enabled by MG_ENABLE_PROFILE
|
struct mg_iobuf prof; // Profile data enabled by MG_ENABLE_PROFILE
|
||||||
struct mg_iobuf rtls; // TLS only. Incoming encrypted data
|
struct mg_iobuf rtls; // TLS only. Incoming encrypted data
|
||||||
mg_event_handler_t fn; // User-specified event handler function
|
mg_event_handler_t fn; // User-specified event handler function
|
||||||
void *fn_data; // User-specified function parameter
|
void *fn_data; // User-specified function parameter
|
||||||
mg_event_handler_t pfn; // Protocol-specific handler function
|
mg_event_handler_t pfn; // Protocol-specific handler function
|
||||||
void *pfn_data; // Protocol-specific function parameter
|
void *pfn_data; // Protocol-specific function parameter
|
||||||
char data[MG_DATA_SIZE]; // Arbitrary connection data
|
char data[MG_DATA_SIZE]; // Arbitrary connection data
|
||||||
void *tls; // TLS specific data
|
void *tls; // TLS specific data
|
||||||
unsigned is_listening : 1; // Listening connection
|
unsigned is_listening : 1; // Listening connection
|
||||||
unsigned is_client : 1; // Outbound (client) connection
|
unsigned is_client : 1; // Outbound (client) connection
|
||||||
unsigned is_accepted : 1; // Accepted (server) connection
|
unsigned is_accepted : 1; // Accepted (server) connection
|
||||||
unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
|
unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
|
||||||
unsigned is_arplooking : 1; // Non-blocking ARP resolution is in progress
|
unsigned is_arplooking : 1; // Non-blocking ARP resolution is in progress
|
||||||
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
||||||
unsigned is_tls : 1; // TLS-enabled connection
|
unsigned is_tls : 1; // TLS-enabled connection
|
||||||
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
||||||
unsigned is_udp : 1; // UDP connection
|
unsigned is_udp : 1; // UDP connection
|
||||||
unsigned is_websocket : 1; // WebSocket connection
|
unsigned is_websocket : 1; // WebSocket connection
|
||||||
unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator
|
unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator
|
||||||
unsigned is_hexdumping : 1; // Hexdump in/out traffic
|
unsigned is_hexdumping : 1; // Hexdump in/out traffic
|
||||||
unsigned is_draining : 1; // Send remaining data, then close and free
|
unsigned is_draining : 1; // Send remaining data, then close and free
|
||||||
unsigned is_closing : 1; // Close and free the connection immediately
|
unsigned is_closing : 1; // Close and free the connection immediately
|
||||||
unsigned is_full : 1; // Stop reads, until cleared
|
unsigned is_full : 1; // Stop reads, until cleared
|
||||||
unsigned is_resp : 1; // Response is still being generated
|
unsigned is_tls_throttled : 1; // Last TLS write: MG_SOCK_PENDING() was true
|
||||||
unsigned is_readable : 1; // Connection is ready to read
|
unsigned is_resp : 1; // Response is still being generated
|
||||||
unsigned is_writable : 1; // Connection is ready to write
|
unsigned is_readable : 1; // Connection is ready to read
|
||||||
|
unsigned is_writable : 1; // Connection is ready to write
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_mgr_poll(struct mg_mgr *, int ms);
|
void mg_mgr_poll(struct mg_mgr *, int ms);
|
||||||
|
|||||||
+147
-90
@@ -1,6 +1,6 @@
|
|||||||
#include "net_builtin.h"
|
#include "net_builtin.h"
|
||||||
|
|
||||||
#if defined(MG_ENABLE_TCPIP) && MG_ENABLE_TCPIP
|
#if MG_ENABLE_TCPIP
|
||||||
#define MG_EPHEMERAL_PORT_BASE 32768
|
#define MG_EPHEMERAL_PORT_BASE 32768
|
||||||
#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
|
#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
|
||||||
|
|
||||||
@@ -16,11 +16,12 @@
|
|||||||
|
|
||||||
struct connstate {
|
struct connstate {
|
||||||
uint32_t seq, ack; // TCP seq/ack counters
|
uint32_t seq, ack; // TCP seq/ack counters
|
||||||
uint64_t timer; // TCP keep-alive / ACK timer
|
uint64_t timer; // TCP timer (see 'ttype' below)
|
||||||
uint32_t acked; // Last ACK-ed number
|
uint32_t acked; // Last ACK-ed number
|
||||||
size_t unacked; // Not acked bytes
|
size_t unacked; // Not acked bytes
|
||||||
|
uint16_t dmss; // destination MSS (from TCP opts)
|
||||||
uint8_t mac[6]; // Peer MAC address
|
uint8_t mac[6]; // Peer MAC address
|
||||||
uint8_t ttype; // Timer type. 0: ack, 1: keep-alive
|
uint8_t ttype; // Timer type:
|
||||||
#define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive
|
#define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive
|
||||||
#define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon
|
#define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon
|
||||||
#define MIP_TTYPE_ARP 2 // ARP resolve sent, waiting for response
|
#define MIP_TTYPE_ARP 2 // ARP resolve sent, waiting for response
|
||||||
@@ -121,7 +122,7 @@ struct dhcp {
|
|||||||
uint32_t ciaddr, yiaddr, siaddr, giaddr;
|
uint32_t ciaddr, yiaddr, siaddr, giaddr;
|
||||||
uint8_t hwaddr[208];
|
uint8_t hwaddr[208];
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint8_t options[32];
|
uint8_t options[30 + sizeof(((struct mg_tcpip_if *) 0)->dhcp_name)];
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
@@ -176,6 +177,7 @@ static void settmout(struct mg_connection *c, uint8_t type) {
|
|||||||
: type == MIP_TTYPE_SYN ? MIP_TCP_SYN_MS
|
: type == MIP_TTYPE_SYN ? MIP_TCP_SYN_MS
|
||||||
: type == MIP_TTYPE_FIN ? MIP_TCP_FIN_MS
|
: type == MIP_TTYPE_FIN ? MIP_TCP_FIN_MS
|
||||||
: MIP_TCP_KEEPALIVE_MS;
|
: MIP_TCP_KEEPALIVE_MS;
|
||||||
|
if (s->ttype == MIP_TTYPE_FIN) return; // skip if 3-way closing
|
||||||
s->timer = ifp->now + n;
|
s->timer = ifp->now + n;
|
||||||
s->ttype = type;
|
s->ttype = type;
|
||||||
MG_VERBOSE(("%lu %d -> %llx", c->id, type, s->timer));
|
MG_VERBOSE(("%lu %d -> %llx", c->id, type, s->timer));
|
||||||
@@ -280,22 +282,26 @@ static const uint8_t broadcast[] = {255, 255, 255, 255, 255, 255};
|
|||||||
// RFC-2131 #4.3.6, #4.4.1; RFC-2132 #9.8
|
// RFC-2131 #4.3.6, #4.4.1; RFC-2132 #9.8
|
||||||
static void tx_dhcp_request_sel(struct mg_tcpip_if *ifp, uint32_t ip_req,
|
static void tx_dhcp_request_sel(struct mg_tcpip_if *ifp, uint32_t ip_req,
|
||||||
uint32_t ip_srv) {
|
uint32_t ip_srv) {
|
||||||
uint8_t opts[] = {
|
uint8_t extra = (uint8_t) ((ifp->enable_req_dns ? 1 : 0) +
|
||||||
53, 1, 3, // Type: DHCP request
|
(ifp->enable_req_sntp ? 1 : 0));
|
||||||
12, 3, 'm', 'i', 'p', // Host name: "mip"
|
size_t len = strlen(ifp->dhcp_name);
|
||||||
54, 4, 0, 0, 0, 0, // DHCP server ID
|
size_t olen = 21 + len + extra + 2 + 1; // Total length of options
|
||||||
50, 4, 0, 0, 0, 0, // Requested IP
|
#define OPTS_MAXLEN (21 + sizeof(ifp->dhcp_name) + 2 + 2 + 1)
|
||||||
55, 2, 1, 3, 255, 255, // GW, mask [DNS] [SNTP]
|
uint8_t opts[OPTS_MAXLEN]; // Allocate options (max size possible)
|
||||||
255 // End of options
|
uint8_t *p = opts;
|
||||||
};
|
assert(olen <= sizeof(opts));
|
||||||
uint8_t addopts = 0;
|
memset(opts, 0, sizeof(opts));
|
||||||
memcpy(opts + 10, &ip_srv, sizeof(ip_srv));
|
*p++ = 53, *p++ = 1, *p++ = 3; // Type: DHCP request
|
||||||
memcpy(opts + 16, &ip_req, sizeof(ip_req));
|
*p++ = 54, *p++ = 4, memcpy(p, &ip_srv, 4), p += 4; // DHCP server ID
|
||||||
if (ifp->enable_req_dns) opts[24 + addopts++] = 6; // DNS
|
*p++ = 50, *p++ = 4, memcpy(p, &ip_req, 4), p += 4; // Requested IP
|
||||||
if (ifp->enable_req_sntp) opts[24 + addopts++] = 42; // SNTP
|
*p++ = 12, *p++ = (uint8_t) (len & 255); // DHCP host
|
||||||
opts[21] += addopts;
|
memcpy(p, ifp->dhcp_name, len), p += len; // name
|
||||||
tx_dhcp(ifp, (uint8_t *) broadcast, 0, 0xffffffff, opts,
|
*p++ = 55, *p++ = 2 + extra, *p++ = 1, *p++ = 3; // GW, MASK
|
||||||
sizeof(opts) + addopts - 2, false);
|
if (ifp->enable_req_dns) *p++ = 6; // DNS
|
||||||
|
if (ifp->enable_req_sntp) *p++ = 42; // SNTP
|
||||||
|
*p++ = 255; // End of options
|
||||||
|
// assert((size_t) (p - opts) < olen);
|
||||||
|
tx_dhcp(ifp, (uint8_t *) broadcast, 0, 0xffffffff, opts, olen, 0);
|
||||||
MG_DEBUG(("DHCP req sent"));
|
MG_DEBUG(("DHCP req sent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,17 +526,17 @@ static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||||
uint8_t flags, uint16_t sport, uint16_t dport,
|
uint8_t flags, uint16_t sport, uint16_t dport,
|
||||||
uint32_t seq, uint32_t ack, const void *buf, size_t len) {
|
uint32_t seq, uint32_t ack, const void *buf, size_t len) {
|
||||||
#if 0
|
struct ip *ip;
|
||||||
uint8_t opts[] = {2, 4, 5, 0xb4, 4, 2, 0, 0}; // MSS = 1460, SACK permitted
|
struct tcp *tcp;
|
||||||
if (flags & TH_SYN) {
|
uint16_t opts[4 / 2];
|
||||||
// Handshake? Set MSS
|
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
||||||
|
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
||||||
|
opts[1] = mg_htons(ifp->mtu - 40); // RFC-6691
|
||||||
buf = opts;
|
buf = opts;
|
||||||
len = sizeof(opts);
|
len = sizeof(opts);
|
||||||
}
|
}
|
||||||
#endif
|
ip = tx_ip(ifp, dst_mac, 6, ifp->ip, dst_ip, sizeof(struct tcp) + len);
|
||||||
struct ip *ip =
|
tcp = (struct tcp *) (ip + 1);
|
||||||
tx_ip(ifp, dst_mac, 6, ifp->ip, dst_ip, sizeof(struct tcp) + len);
|
|
||||||
struct tcp *tcp = (struct tcp *) (ip + 1);
|
|
||||||
memset(tcp, 0, sizeof(*tcp));
|
memset(tcp, 0, sizeof(*tcp));
|
||||||
if (buf != NULL && len) memmove(tcp + 1, buf, len);
|
if (buf != NULL && len) memmove(tcp + 1, buf, len);
|
||||||
tcp->sport = sport;
|
tcp->sport = sport;
|
||||||
@@ -540,7 +546,7 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
|||||||
tcp->flags = flags;
|
tcp->flags = flags;
|
||||||
tcp->win = mg_htons(MIP_TCP_WIN);
|
tcp->win = mg_htons(MIP_TCP_WIN);
|
||||||
tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
|
tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
|
||||||
// if (flags & TH_SYN) tcp->off = 0x70; // Handshake? header size 28 bytes
|
if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4);
|
||||||
|
|
||||||
uint32_t cs = 0;
|
uint32_t cs = 0;
|
||||||
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
||||||
@@ -574,6 +580,7 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
struct connstate *s = (struct connstate *) (c + 1);
|
struct connstate *s = (struct connstate *) (c + 1);
|
||||||
|
s->dmss = 1460; // TODO(scaprile): 536; // assume default, RFC-9293 3.7.1
|
||||||
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
||||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||||
settmout(c, MIP_TTYPE_KEEPALIVE);
|
settmout(c, MIP_TTYPE_KEEPALIVE);
|
||||||
@@ -627,10 +634,11 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
|
|||||||
len = trim_len(c, len);
|
len = trim_len(c, len);
|
||||||
if (c->is_udp) {
|
if (c->is_udp) {
|
||||||
tx_udp(ifp, s->mac, ifp->ip, c->loc.port, dst_ip, c->rem.port, buf, len);
|
tx_udp(ifp, s->mac, ifp->ip, c->loc.port, dst_ip, c->rem.port, buf, len);
|
||||||
} else {
|
} else { // TCP, cap to peer's MSS
|
||||||
size_t sent =
|
size_t sent;
|
||||||
tx_tcp(ifp, s->mac, dst_ip, TH_PUSH | TH_ACK, c->loc.port, c->rem.port,
|
if (len > s->dmss) len = s->dmss; // RFC-6691: reduce if sending opts
|
||||||
mg_htonl(s->seq), mg_htonl(s->ack), buf, len);
|
sent = tx_tcp(ifp, s->mac, dst_ip, TH_PUSH | TH_ACK, c->loc.port,
|
||||||
|
c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), buf, len);
|
||||||
if (sent == 0) {
|
if (sent == 0) {
|
||||||
return MG_IO_WAIT;
|
return MG_IO_WAIT;
|
||||||
} else if (sent == (size_t) -1) {
|
} else if (sent == (size_t) -1) {
|
||||||
@@ -651,7 +659,8 @@ static void handle_tls_recv(struct mg_connection *c) {
|
|||||||
mg_error(c, "oom");
|
mg_error(c, "oom");
|
||||||
} else {
|
} else {
|
||||||
// Decrypt data directly into c->recv
|
// Decrypt data directly into c->recv
|
||||||
long n = mg_tls_recv(c, &io->buf[io->len], io->size - io->len);
|
long n = mg_tls_recv(c, io->buf != NULL ? &io->buf[io->len] : io->buf,
|
||||||
|
io->size - io->len);
|
||||||
if (n == MG_IO_ERR) {
|
if (n == MG_IO_ERR) {
|
||||||
mg_error(c, "TLS recv error");
|
mg_error(c, "TLS recv error");
|
||||||
} else if (n > 0) {
|
} else if (n > 0) {
|
||||||
@@ -689,8 +698,10 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) {
|
|||||||
}
|
}
|
||||||
tx_tcp(c->mgr->ifp, s->mac, rem_ip, flags, c->loc.port, c->rem.port,
|
tx_tcp(c->mgr->ifp, s->mac, rem_ip, flags, c->loc.port, c->rem.port,
|
||||||
mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
|
mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
|
||||||
} else if (pkt->pay.len == 0) { // this is an ACK
|
if (pkt->pay.len == 0) return; // if no data, we're done
|
||||||
|
} else if (pkt->pay.len == 0) { // this is an ACK
|
||||||
if (s->fin_rcvd && s->ttype == MIP_TTYPE_FIN) s->twclosure = true;
|
if (s->fin_rcvd && s->ttype == MIP_TTYPE_FIN) s->twclosure = true;
|
||||||
|
return; // no data to process
|
||||||
} else if (seq != s->ack) {
|
} else if (seq != s->ack) {
|
||||||
uint32_t ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
|
uint32_t ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
|
||||||
if (s->ack == ack) {
|
if (s->ack == ack) {
|
||||||
@@ -700,44 +711,62 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) {
|
|||||||
tx_tcp(c->mgr->ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port,
|
tx_tcp(c->mgr->ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port,
|
||||||
mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
|
mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
|
||||||
}
|
}
|
||||||
|
return; // drop it
|
||||||
} else if (io->size - io->len < pkt->pay.len &&
|
} else if (io->size - io->len < pkt->pay.len &&
|
||||||
!mg_iobuf_resize(io, io->len + pkt->pay.len)) {
|
!mg_iobuf_resize(io, io->len + pkt->pay.len)) {
|
||||||
mg_error(c, "oom");
|
mg_error(c, "oom");
|
||||||
|
return; // drop it
|
||||||
|
}
|
||||||
|
// Copy TCP payload into the IO buffer. If the connection is plain text,
|
||||||
|
// we copy to c->recv. If the connection is TLS, this data is encrypted,
|
||||||
|
// therefore we copy that encrypted data to the c->rtls iobuffer instead,
|
||||||
|
// and then call mg_tls_recv() to decrypt it. NOTE: mg_tls_recv() will
|
||||||
|
// call back mg_io_recv() which grabs raw data from c->rtls
|
||||||
|
memcpy(&io->buf[io->len], pkt->pay.buf, pkt->pay.len);
|
||||||
|
io->len += pkt->pay.len;
|
||||||
|
MG_VERBOSE(("%lu SEQ %x -> %x", c->id, mg_htonl(pkt->tcp->seq), s->ack));
|
||||||
|
// Advance ACK counter
|
||||||
|
s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
|
||||||
|
s->unacked += pkt->pay.len;
|
||||||
|
// size_t diff = s->acked <= s->ack ? s->ack - s->acked : s->ack;
|
||||||
|
if (s->unacked > MIP_TCP_WIN / 2 && s->acked != s->ack) {
|
||||||
|
// Send ACK immediately
|
||||||
|
MG_VERBOSE(("%lu imm ACK %lu", c->id, s->acked));
|
||||||
|
tx_tcp(c->mgr->ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port,
|
||||||
|
mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
|
||||||
|
s->unacked = 0;
|
||||||
|
s->acked = s->ack;
|
||||||
|
if (s->ttype != MIP_TTYPE_KEEPALIVE) settmout(c, MIP_TTYPE_KEEPALIVE);
|
||||||
} else {
|
} else {
|
||||||
// Copy TCP payload into the IO buffer. If the connection is plain text,
|
// if not already running, setup a timer to send an ACK later
|
||||||
// we copy to c->recv. If the connection is TLS, this data is encrypted,
|
if (s->ttype != MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_ACK);
|
||||||
// therefore we copy that encrypted data to the c->rtls iobuffer instead,
|
}
|
||||||
// and then call mg_tls_recv() to decrypt it. NOTE: mg_tls_recv() will
|
if (c->is_tls && c->is_tls_hs) {
|
||||||
// call back mg_io_recv() which grabs raw data from c->rtls
|
mg_tls_handshake(c);
|
||||||
memcpy(&io->buf[io->len], pkt->pay.buf, pkt->pay.len);
|
} else if (c->is_tls) {
|
||||||
io->len += pkt->pay.len;
|
handle_tls_recv(c);
|
||||||
|
} else {
|
||||||
|
// Plain text connection, data is already in c->recv, trigger MG_EV_READ
|
||||||
|
mg_call(c, MG_EV_READ, &pkt->pay.len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MG_VERBOSE(("%lu SEQ %x -> %x", c->id, mg_htonl(pkt->tcp->seq), s->ack));
|
// process options (MSS)
|
||||||
// Advance ACK counter
|
static void handle_opt(struct connstate *s, struct tcp *tcp) {
|
||||||
s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
|
uint8_t *opts = (uint8_t *) (tcp + 1);
|
||||||
s->unacked += pkt->pay.len;
|
int len = 4 * ((int) (tcp->off >> 4) - ((int) sizeof(*tcp) / 4));
|
||||||
// size_t diff = s->acked <= s->ack ? s->ack - s->acked : s->ack;
|
s->dmss = 536; // assume default, RFC-9293 3.7.1
|
||||||
if (s->unacked > MIP_TCP_WIN / 2 && s->acked != s->ack) {
|
while (len > 0) { // RFC-9293 3.1 3.2
|
||||||
// Send ACK immediately
|
uint8_t kind = opts[0], optlen = 1;
|
||||||
MG_VERBOSE(("%lu imm ACK %lu", c->id, s->acked));
|
if (kind != 1) { // No-Operation
|
||||||
tx_tcp(c->mgr->ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port,
|
if (kind == 0) break; // End of Option List
|
||||||
mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
|
optlen = opts[1];
|
||||||
s->unacked = 0;
|
if (kind == 2 && optlen == 4) // set received MSS
|
||||||
s->acked = s->ack;
|
s->dmss = (uint16_t) (((uint16_t) opts[2] << 8) + opts[3]);
|
||||||
if (s->ttype != MIP_TTYPE_KEEPALIVE) settmout(c, MIP_TTYPE_KEEPALIVE);
|
|
||||||
} else {
|
|
||||||
// if not already running, setup a timer to send an ACK later
|
|
||||||
if (s->ttype != MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_ACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c->is_tls && c->is_tls_hs) {
|
|
||||||
mg_tls_handshake(c);
|
|
||||||
} else if (c->is_tls) {
|
|
||||||
handle_tls_recv(c);
|
|
||||||
} else {
|
|
||||||
// Plain text connection, data is already in c->recv, trigger MG_EV_READ
|
|
||||||
mg_call(c, MG_EV_READ, &pkt->pay.len);
|
|
||||||
}
|
}
|
||||||
|
MG_VERBOSE(("kind: %u, optlen: %u, len: %d\n", kind, optlen, len));
|
||||||
|
opts += optlen;
|
||||||
|
len -= optlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -748,6 +777,7 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len));
|
MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len));
|
||||||
#endif
|
#endif
|
||||||
if (c != NULL && c->is_connecting && pkt->tcp->flags == (TH_SYN | TH_ACK)) {
|
if (c != NULL && c->is_connecting && pkt->tcp->flags == (TH_SYN | TH_ACK)) {
|
||||||
|
handle_opt(s, pkt->tcp); // process options (MSS)
|
||||||
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1;
|
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1;
|
||||||
tx_tcp_pkt(ifp, pkt, TH_ACK, pkt->tcp->ack, NULL, 0);
|
tx_tcp_pkt(ifp, pkt, TH_ACK, pkt->tcp->ack, NULL, 0);
|
||||||
c->is_connecting = 0; // Client connected
|
c->is_connecting = 0; // Client connected
|
||||||
@@ -777,6 +807,8 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
if (c->is_accepted) mg_error(c, "peer RST"); // RFC-1122 4.2.2.13
|
if (c->is_accepted) mg_error(c, "peer RST"); // RFC-1122 4.2.2.13
|
||||||
// ignore RST if not connected
|
// ignore RST if not connected
|
||||||
} else if (pkt->tcp->flags & TH_SYN) {
|
} else if (pkt->tcp->flags & TH_SYN) {
|
||||||
|
// TODO(): handle_opt(s, pkt->tcp); // process options (MSS)
|
||||||
|
// At this point, s = NULL, there is no connection.
|
||||||
// Use peer's source port as ISN, in order to recognise the handshake
|
// Use peer's source port as ISN, in order to recognise the handshake
|
||||||
uint32_t isn = mg_htonl((uint32_t) mg_ntohs(pkt->tcp->sport));
|
uint32_t isn = mg_htonl((uint32_t) mg_ntohs(pkt->tcp->sport));
|
||||||
tx_tcp_pkt(ifp, pkt, TH_SYN | TH_ACK, isn, NULL, 0);
|
tx_tcp_pkt(ifp, pkt, TH_SYN | TH_ACK, isn, NULL, 0);
|
||||||
@@ -914,24 +946,27 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
|
|||||||
ifp->state = MG_TCPIP_STATE_READY; // keep best-effort MAC
|
ifp->state = MG_TCPIP_STATE_READY; // keep best-effort MAC
|
||||||
onstatechange(ifp);
|
onstatechange(ifp);
|
||||||
}
|
}
|
||||||
// Handle physical interface up/down status
|
// poll driver
|
||||||
if (expired_1000ms && ifp->driver->up) {
|
if (ifp->driver->poll) {
|
||||||
bool up = ifp->driver->up(ifp);
|
bool up = ifp->driver->poll(ifp, expired_1000ms);
|
||||||
bool current = ifp->state != MG_TCPIP_STATE_DOWN;
|
// Handle physical interface up/down status
|
||||||
if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
|
if (expired_1000ms) {
|
||||||
if (up != current) { // link state has changed
|
bool current = ifp->state != MG_TCPIP_STATE_DOWN;
|
||||||
ifp->state = up == false ? MG_TCPIP_STATE_DOWN
|
if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
|
||||||
: ifp->enable_dhcp_client || ifp->ip == 0
|
if (up != current) { // link state has changed
|
||||||
? MG_TCPIP_STATE_UP
|
ifp->state = up == false ? MG_TCPIP_STATE_DOWN
|
||||||
: MG_TCPIP_STATE_IP;
|
: ifp->enable_dhcp_client || ifp->ip == 0
|
||||||
onstatechange(ifp);
|
? MG_TCPIP_STATE_UP
|
||||||
} else if (!ifp->enable_dhcp_client && ifp->state == MG_TCPIP_STATE_UP &&
|
: MG_TCPIP_STATE_IP;
|
||||||
ifp->ip) {
|
onstatechange(ifp);
|
||||||
ifp->state = MG_TCPIP_STATE_IP; // ifp->fn has set an IP
|
} else if (!ifp->enable_dhcp_client && ifp->state == MG_TCPIP_STATE_UP &&
|
||||||
onstatechange(ifp);
|
ifp->ip) {
|
||||||
|
ifp->state = MG_TCPIP_STATE_IP; // ifp->fn has set an IP
|
||||||
|
onstatechange(ifp);
|
||||||
|
}
|
||||||
|
if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
|
||||||
|
mg_tcpip_call(ifp, MG_TCPIP_EV_TIMER_1S, NULL);
|
||||||
}
|
}
|
||||||
if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
|
|
||||||
mg_tcpip_call(ifp, MG_TCPIP_EV_TIMER_1S, NULL);
|
|
||||||
}
|
}
|
||||||
if (ifp->state == MG_TCPIP_STATE_DOWN) return;
|
if (ifp->state == MG_TCPIP_STATE_DOWN) return;
|
||||||
|
|
||||||
@@ -953,14 +988,14 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read data from the network
|
// Read data from the network
|
||||||
if (ifp->driver->rx != NULL) { // Polling driver. We must call it
|
if (ifp->driver->rx != NULL) { // Simple polling driver, returns one frame
|
||||||
size_t len =
|
size_t len =
|
||||||
ifp->driver->rx(ifp->recv_queue.buf, ifp->recv_queue.size, ifp);
|
ifp->driver->rx(ifp->recv_queue.buf, ifp->recv_queue.size, ifp);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
ifp->nrecv++;
|
ifp->nrecv++;
|
||||||
mg_tcpip_rx(ifp, ifp->recv_queue.buf, len);
|
mg_tcpip_rx(ifp, ifp->recv_queue.buf, len);
|
||||||
}
|
}
|
||||||
} else { // Interrupt-based driver. Fills recv queue itself
|
} else { // Complex poll / Interrupt-based driver. Queues recvd frames
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t len = mg_queue_next(&ifp->recv_queue, &buf);
|
size_t len = mg_queue_next(&ifp->recv_queue, &buf);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
@@ -1029,6 +1064,12 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
|
|||||||
MG_INFO(("MAC not set. Generated random: %M", mg_print_mac, ifp->mac));
|
MG_INFO(("MAC not set. Generated random: %M", mg_print_mac, ifp->mac));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If DHCP name is not set, use "mip"
|
||||||
|
if (ifp->dhcp_name[0] == '\0') {
|
||||||
|
memcpy(ifp->dhcp_name, "mip", 4);
|
||||||
|
}
|
||||||
|
ifp->dhcp_name[sizeof(ifp->dhcp_name) - 1] = '\0'; // Just in case
|
||||||
|
|
||||||
if (ifp->driver->init && !ifp->driver->init(ifp)) {
|
if (ifp->driver->init && !ifp->driver->init(ifp)) {
|
||||||
MG_ERROR(("driver init failed"));
|
MG_ERROR(("driver init failed"));
|
||||||
} else {
|
} else {
|
||||||
@@ -1075,6 +1116,13 @@ static void mac_resolved(struct mg_connection *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ip4_mcastmac(uint8_t *mac, uint32_t *ip) {
|
||||||
|
uint8_t mcastp[3] = {0x01, 0x00, 0x5E}; // multicast group MAC
|
||||||
|
memcpy(mac, mcastp, 3);
|
||||||
|
memcpy(mac + 3, ((uint8_t *) ip) + 1, 3); // 23 LSb
|
||||||
|
mac[3] &= 0x7F;
|
||||||
|
}
|
||||||
|
|
||||||
void mg_connect_resolved(struct mg_connection *c) {
|
void mg_connect_resolved(struct mg_connection *c) {
|
||||||
struct mg_tcpip_if *ifp = c->mgr->ifp;
|
struct mg_tcpip_if *ifp = c->mgr->ifp;
|
||||||
uint32_t rem_ip;
|
uint32_t rem_ip;
|
||||||
@@ -1100,10 +1148,7 @@ void mg_connect_resolved(struct mg_connection *c) {
|
|||||||
c->is_arplooking = 1;
|
c->is_arplooking = 1;
|
||||||
} else if ((*((uint8_t *) &rem_ip) & 0xE0) == 0xE0) {
|
} else if ((*((uint8_t *) &rem_ip) & 0xE0) == 0xE0) {
|
||||||
struct connstate *s = (struct connstate *) (c + 1); // 224 to 239, E0 to EF
|
struct connstate *s = (struct connstate *) (c + 1); // 224 to 239, E0 to EF
|
||||||
uint8_t mcastp[3] = {0x01, 0x00, 0x5E}; // multicast group
|
ip4_mcastmac(s->mac, &rem_ip); // multicast group
|
||||||
memcpy(s->mac, mcastp, 3);
|
|
||||||
memcpy(s->mac + 3, ((uint8_t *) &rem_ip) + 1, 3); // 23 LSb
|
|
||||||
s->mac[3] &= 0x7F;
|
|
||||||
mac_resolved(c);
|
mac_resolved(c);
|
||||||
} else {
|
} else {
|
||||||
struct connstate *s = (struct connstate *) (c + 1);
|
struct connstate *s = (struct connstate *) (c + 1);
|
||||||
@@ -1114,6 +1159,10 @@ void mg_connect_resolved(struct mg_connection *c) {
|
|||||||
|
|
||||||
bool mg_open_listener(struct mg_connection *c, const char *url) {
|
bool mg_open_listener(struct mg_connection *c, const char *url) {
|
||||||
c->loc.port = mg_htons(mg_url_port(url));
|
c->loc.port = mg_htons(mg_url_port(url));
|
||||||
|
if (!mg_aton(mg_url_host(url), &c->loc)) {
|
||||||
|
MG_ERROR(("invalid listening URL: %s", url));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1201,4 +1250,12 @@ bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t mcast_addr[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb};
|
||||||
|
void mg_multicast_add(struct mg_connection *c, char *ip) {
|
||||||
|
(void) ip; // ip4_mcastmac(mcast_mac, &ip);
|
||||||
|
// TODO(): actual IP -> MAC; check database, update
|
||||||
|
c->mgr->ifp->update_mac_hash_table = true; // mark dirty
|
||||||
|
}
|
||||||
|
|
||||||
#endif // MG_ENABLE_TCPIP
|
#endif // MG_ENABLE_TCPIP
|
||||||
+20
-7
@@ -5,27 +5,34 @@
|
|||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
|
||||||
|
#if MG_ENABLE_TCPIP
|
||||||
|
|
||||||
struct mg_tcpip_if; // Mongoose TCP/IP network interface
|
struct mg_tcpip_if; // Mongoose TCP/IP network interface
|
||||||
|
|
||||||
struct mg_tcpip_driver {
|
struct mg_tcpip_driver {
|
||||||
bool (*init)(struct mg_tcpip_if *); // Init driver
|
bool (*init)(struct mg_tcpip_if *); // Init driver
|
||||||
size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
|
size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
|
||||||
size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
|
size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
|
||||||
bool (*up)(struct mg_tcpip_if *); // Up/down status
|
bool (*poll)(struct mg_tcpip_if *, bool); // Poll, return Up/down status
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*mg_tcpip_event_handler_t)(struct mg_tcpip_if *ifp, int ev,
|
typedef void (*mg_tcpip_event_handler_t)(struct mg_tcpip_if *ifp, int ev,
|
||||||
void *ev_data);
|
void *ev_data);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
|
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
|
||||||
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
|
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
|
||||||
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
|
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
|
||||||
MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
|
MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
|
||||||
MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
|
MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
|
||||||
MG_TCPIP_EV_USER // Starting ID for user events
|
MG_TCPIP_EV_WIFI_SCAN_RESULT, // Wi-Fi scan results struct mg_wifi_scan_bss_data *
|
||||||
|
MG_TCPIP_EV_WIFI_SCAN_END, // Wi-Fi scan has finished NULL
|
||||||
|
MG_TCPIP_EV_WIFI_CONNECT_ERR, // Wi-Fi connect has failed driver and chip specific
|
||||||
|
MG_TCPIP_EV_DRIVER, // Driver event driver specific
|
||||||
|
MG_TCPIP_EV_USER // Starting ID for user events
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Network interface
|
// Network interface
|
||||||
struct mg_tcpip_if {
|
struct mg_tcpip_if {
|
||||||
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
|
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
|
||||||
@@ -38,11 +45,13 @@ struct mg_tcpip_if {
|
|||||||
bool enable_req_sntp; // DCHP client requests SNTP server
|
bool enable_req_sntp; // DCHP client requests SNTP server
|
||||||
bool enable_crc32_check; // Do a CRC check on RX frames and strip it
|
bool enable_crc32_check; // Do a CRC check on RX frames and strip it
|
||||||
bool enable_mac_check; // Do a MAC check on RX frames
|
bool enable_mac_check; // Do a MAC check on RX frames
|
||||||
|
bool update_mac_hash_table; // Signal drivers to update MAC controller
|
||||||
struct mg_tcpip_driver *driver; // Low level driver
|
struct mg_tcpip_driver *driver; // Low level driver
|
||||||
void *driver_data; // Driver-specific data
|
void *driver_data; // Driver-specific data
|
||||||
mg_tcpip_event_handler_t fn; // User-specified event handler function
|
mg_tcpip_event_handler_t fn; // User-specified event handler function
|
||||||
struct mg_mgr *mgr; // Mongoose event manager
|
struct mg_mgr *mgr; // Mongoose event manager
|
||||||
struct mg_queue recv_queue; // Receive queue
|
struct mg_queue recv_queue; // Receive queue
|
||||||
|
char dhcp_name[12]; // Name reported to DHCP, "mip" if unset
|
||||||
uint16_t mtu; // Interface MTU
|
uint16_t mtu; // Interface MTU
|
||||||
#define MG_TCPIP_MTU_DEFAULT 1500
|
#define MG_TCPIP_MTU_DEFAULT 1500
|
||||||
|
|
||||||
@@ -71,6 +80,7 @@ void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac);
|
|||||||
|
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
|
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
||||||
|
extern struct mg_tcpip_driver mg_tcpip_driver_w5100;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
|
extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_tms570;
|
extern struct mg_tcpip_driver mg_tcpip_driver_tms570;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
|
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
|
||||||
@@ -83,6 +93,7 @@ extern struct mg_tcpip_driver mg_tcpip_driver_xmc7;
|
|||||||
extern struct mg_tcpip_driver mg_tcpip_driver_ppp;
|
extern struct mg_tcpip_driver mg_tcpip_driver_ppp;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_pico_w;
|
extern struct mg_tcpip_driver mg_tcpip_driver_pico_w;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_rw612;
|
extern struct mg_tcpip_driver mg_tcpip_driver_rw612;
|
||||||
|
extern struct mg_tcpip_driver mg_tcpip_driver_cyw;
|
||||||
|
|
||||||
// Drivers that require SPI, can use this SPI abstraction
|
// Drivers that require SPI, can use this SPI abstraction
|
||||||
struct mg_tcpip_spi {
|
struct mg_tcpip_spi {
|
||||||
@@ -91,3 +102,5 @@ struct mg_tcpip_spi {
|
|||||||
void (*end)(void *); // SPI end: slave select high
|
void (*end)(void *); // SPI end: slave select high
|
||||||
uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
|
uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -13,10 +13,12 @@
|
|||||||
#define MG_OTA_CH32V307 100 // WCH CH32V307
|
#define MG_OTA_CH32V307 100 // WCH CH32V307
|
||||||
#define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
|
#define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
|
||||||
#define MG_OTA_RT1020 300 // IMXRT1020
|
#define MG_OTA_RT1020 300 // IMXRT1020
|
||||||
#define MG_OTA_RT1060 301 // IMXRT1060
|
#define MG_OTA_RT1050 301 // IMXRT1050
|
||||||
#define MG_OTA_RT1064 302 // IMXRT1064
|
#define MG_OTA_RT1060 302 // IMXRT1060
|
||||||
#define MG_OTA_RT1170 303 // IMXRT1170
|
#define MG_OTA_RT1064 303 // IMXRT1064
|
||||||
|
#define MG_OTA_RT1170 304 // IMXRT1170
|
||||||
#define MG_OTA_MCXN 310 // MCXN947
|
#define MG_OTA_MCXN 310 // MCXN947
|
||||||
|
#define MG_OTA_FRDM 320 // FRDM-RW612
|
||||||
#define MG_OTA_FLASH 900 // OTA via an internal flash
|
#define MG_OTA_FLASH 900 // OTA via an internal flash
|
||||||
#define MG_OTA_ESP32 910 // ESP32 OTA implementation
|
#define MG_OTA_ESP32 910 // ESP32 OTA implementation
|
||||||
#define MG_OTA_PICOSDK 920 // RP2040/2350 using Pico-SDK hardware_flash
|
#define MG_OTA_PICOSDK 920 // RP2040/2350 using Pico-SDK hardware_flash
|
||||||
|
|||||||
+364
@@ -0,0 +1,364 @@
|
|||||||
|
#include "flash.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "ota.h"
|
||||||
|
|
||||||
|
#if MG_OTA == MG_OTA_FRDM
|
||||||
|
|
||||||
|
MG_IRAM static bool mg_frdm_write(void *, const void *, size_t);
|
||||||
|
static bool mg_frdm_swap(void);
|
||||||
|
|
||||||
|
static struct mg_flash s_mg_flash_frdm = {(void *) 0x08000000, // Start,
|
||||||
|
0x200000, // Size
|
||||||
|
0x1000, // Sector size
|
||||||
|
0x100, // Align
|
||||||
|
mg_frdm_write,
|
||||||
|
mg_frdm_swap};
|
||||||
|
|
||||||
|
struct mg_flexspi_lut_seq {
|
||||||
|
uint8_t seqNum;
|
||||||
|
uint8_t seqId;
|
||||||
|
uint16_t reserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mg_flexspi_mem_config {
|
||||||
|
uint32_t tag;
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t reserved0;
|
||||||
|
uint8_t readSampleClkSrc;
|
||||||
|
uint8_t csHoldTime;
|
||||||
|
uint8_t csSetupTime;
|
||||||
|
uint8_t columnAddressWidth;
|
||||||
|
uint8_t deviceModeCfgEnable;
|
||||||
|
uint8_t deviceModeType;
|
||||||
|
uint16_t waitTimeCfgCommands;
|
||||||
|
struct mg_flexspi_lut_seq deviceModeSeq;
|
||||||
|
uint32_t deviceModeArg;
|
||||||
|
uint8_t configCmdEnable;
|
||||||
|
uint8_t configModeType[3];
|
||||||
|
struct mg_flexspi_lut_seq configCmdSeqs[3];
|
||||||
|
uint32_t reserved1;
|
||||||
|
uint32_t configCmdArgs[3];
|
||||||
|
uint32_t reserved2;
|
||||||
|
uint32_t controllerMiscOption;
|
||||||
|
uint8_t deviceType;
|
||||||
|
uint8_t sflashPadType;
|
||||||
|
uint8_t serialClkFreq;
|
||||||
|
uint8_t lutCustomSeqEnable;
|
||||||
|
uint32_t reserved3[2];
|
||||||
|
uint32_t sflashA1Size;
|
||||||
|
uint32_t sflashA2Size;
|
||||||
|
uint32_t sflashB1Size;
|
||||||
|
uint32_t sflashB2Size;
|
||||||
|
uint32_t csPadSettingOverride;
|
||||||
|
uint32_t sclkPadSettingOverride;
|
||||||
|
uint32_t dataPadSettingOverride;
|
||||||
|
uint32_t dqsPadSettingOverride;
|
||||||
|
uint32_t timeoutInMs;
|
||||||
|
uint32_t commandInterval;
|
||||||
|
uint16_t dataValidTime[2];
|
||||||
|
uint16_t busyOffset;
|
||||||
|
uint16_t busyBitPolarity;
|
||||||
|
uint32_t lookupTable[64];
|
||||||
|
struct mg_flexspi_lut_seq lutCustomSeq[12];
|
||||||
|
uint32_t reserved4[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mg_flexspi_nor_config {
|
||||||
|
struct mg_flexspi_mem_config memConfig;
|
||||||
|
uint32_t pageSize;
|
||||||
|
uint32_t sectorSize;
|
||||||
|
uint8_t ipcmdSerialClkFreq;
|
||||||
|
uint8_t isUniformBlockSize;
|
||||||
|
uint8_t isDataOrderSwapped;
|
||||||
|
uint8_t reserved0[1];
|
||||||
|
uint8_t serialNorType;
|
||||||
|
uint8_t needExitNoCmdMode;
|
||||||
|
uint8_t halfClkForNonReadCmd;
|
||||||
|
uint8_t needRestoreNoCmdMode;
|
||||||
|
uint32_t blockSize;
|
||||||
|
uint32_t flashStateCtx;
|
||||||
|
uint32_t reserve2[10];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mg_flexspi_nor_driver_interface {
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
|
||||||
|
uint32_t (*wait_busy)(uint32_t instance, struct mg_flexspi_nor_config *config,
|
||||||
|
uint32_t address, bool keepState);
|
||||||
|
uint32_t (*page_program)(uint32_t instance,
|
||||||
|
struct mg_flexspi_nor_config *config,
|
||||||
|
uint32_t dstAddr, const uint32_t *src,
|
||||||
|
bool keepState);
|
||||||
|
uint32_t (*erase_all)(uint32_t instance,
|
||||||
|
struct mg_flexspi_nor_config *config);
|
||||||
|
uint32_t (*erase)(uint32_t instance, struct mg_flexspi_nor_config *config,
|
||||||
|
uint32_t start, uint32_t length);
|
||||||
|
uint32_t (*erase_sector)(uint32_t instance,
|
||||||
|
struct mg_flexspi_nor_config *config,
|
||||||
|
uint32_t address);
|
||||||
|
uint32_t (*erase_block)(uint32_t instance,
|
||||||
|
struct mg_flexspi_nor_config *config,
|
||||||
|
uint32_t address);
|
||||||
|
uint32_t (*read)(uint32_t instance, struct mg_flexspi_nor_config *config,
|
||||||
|
uint32_t *dst, uint32_t start, uint32_t bytes);
|
||||||
|
void (*config_clock)(uint32_t instance, uint32_t freqOption,
|
||||||
|
uint32_t sampleClkMode);
|
||||||
|
uint32_t (*set_clock_source)(uint32_t clockSrc);
|
||||||
|
uint32_t (*get_config)(uint32_t instance,
|
||||||
|
struct mg_flexspi_nor_config *config,
|
||||||
|
uint32_t *option);
|
||||||
|
void (*hw_reset)(uint32_t instance, uint32_t reset_logic);
|
||||||
|
uint32_t (*xfer)(uint32_t instance, char *xfer);
|
||||||
|
uint32_t (*update_lut)(uint32_t instance, uint32_t seqIndex,
|
||||||
|
const uint32_t *lutBase, uint32_t numberOfSeq);
|
||||||
|
uint32_t (*partial_program)(uint32_t instance,
|
||||||
|
struct mg_flexspi_nor_config *config,
|
||||||
|
uint32_t dstAddr, const uint32_t *src,
|
||||||
|
uint32_t length, bool keepState);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MG_FLEXSPI_CFG_BLK_TAG (0x42464346UL)
|
||||||
|
#define MG_FLEXSPI_BASE 0x40134000UL
|
||||||
|
|
||||||
|
#define MG_CMD_SDR 0x01
|
||||||
|
#define MG_RADDR_SDR 0x02
|
||||||
|
#define MG_WRITE_SDR 0x08
|
||||||
|
#define MG_READ_SDR 0x09
|
||||||
|
#define MG_DUMMY_SDR 0x0C
|
||||||
|
#define MG_STOP_EXE 0
|
||||||
|
|
||||||
|
#define MG_FLEXSPI_1PAD 0
|
||||||
|
#define MG_FLEXSPI_4PAD 2
|
||||||
|
|
||||||
|
#define MG_FLEXSPI_LUT_OPERAND0(x) (((x) &0xFF) << 0)
|
||||||
|
#define MG_FLEXSPI_LUT_NUM_PADS0(x) (((x) &0x3) << 8)
|
||||||
|
#define MG_FLEXSPI_LUT_OPCODE0(x) (((x) &0x3F) << 10)
|
||||||
|
#define MG_FLEXSPI_LUT_OPERAND1(x) (((x) &0xFF) << 16)
|
||||||
|
#define MG_FLEXSPI_LUT_NUM_PADS1(x) (((x) &0x3) << 24)
|
||||||
|
#define MG_FLEXSPI_LUT_OPCODE1(x) (((x) &0x3F) << 26)
|
||||||
|
|
||||||
|
#define MG_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
|
||||||
|
(MG_FLEXSPI_LUT_OPERAND0(op0) | MG_FLEXSPI_LUT_NUM_PADS0(pad0) | \
|
||||||
|
MG_FLEXSPI_LUT_OPCODE0(cmd0) | MG_FLEXSPI_LUT_OPERAND1(op1) | \
|
||||||
|
MG_FLEXSPI_LUT_NUM_PADS1(pad1) | MG_FLEXSPI_LUT_OPCODE1(cmd1))
|
||||||
|
|
||||||
|
struct mg_flexspi_nor_config default_config = {
|
||||||
|
.memConfig =
|
||||||
|
{
|
||||||
|
.tag = MG_FLEXSPI_CFG_BLK_TAG,
|
||||||
|
.version = 0,
|
||||||
|
.readSampleClkSrc = 1,
|
||||||
|
.csHoldTime = 3,
|
||||||
|
.csSetupTime = 3,
|
||||||
|
.deviceModeCfgEnable = 1,
|
||||||
|
.deviceModeSeq = {.seqNum = 1, .seqId = 2},
|
||||||
|
.deviceModeArg = 0x0740,
|
||||||
|
.configCmdEnable = 0,
|
||||||
|
.deviceType = 0x1,
|
||||||
|
.sflashPadType = 4,
|
||||||
|
.serialClkFreq = 4,
|
||||||
|
.sflashA1Size = 0x4000000U,
|
||||||
|
.sflashA2Size = 0,
|
||||||
|
.sflashB1Size = 0,
|
||||||
|
.sflashB2Size = 0,
|
||||||
|
.lookupTable =
|
||||||
|
{
|
||||||
|
[0] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0xEB,
|
||||||
|
MG_RADDR_SDR, MG_FLEXSPI_4PAD, 0x18),
|
||||||
|
[1] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_DUMMY_SDR, MG_FLEXSPI_4PAD, 0x06,
|
||||||
|
MG_READ_SDR, MG_FLEXSPI_4PAD, 0x04),
|
||||||
|
[4 * 1 + 0] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x05,
|
||||||
|
MG_READ_SDR, MG_FLEXSPI_1PAD, 0x04),
|
||||||
|
[4 * 2 + 0] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x01,
|
||||||
|
MG_WRITE_SDR, MG_FLEXSPI_1PAD, 0x02),
|
||||||
|
[4 * 3 + 0] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x06,
|
||||||
|
MG_STOP_EXE, MG_FLEXSPI_1PAD, 0x00),
|
||||||
|
[4 * 5 + 0] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x20,
|
||||||
|
MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18),
|
||||||
|
[4 * 8 + 0] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x52,
|
||||||
|
MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18),
|
||||||
|
[4 * 9 + 0] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x02,
|
||||||
|
MG_RADDR_SDR, MG_FLEXSPI_1PAD, 0x18),
|
||||||
|
[4 * 9 + 1] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_WRITE_SDR, MG_FLEXSPI_1PAD, 0x00,
|
||||||
|
MG_STOP_EXE, MG_FLEXSPI_1PAD, 0x00),
|
||||||
|
[4 * 11 + 0] =
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CMD_SDR, MG_FLEXSPI_1PAD, 0x60,
|
||||||
|
MG_STOP_EXE, MG_FLEXSPI_1PAD, 0x00),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.pageSize = 0x100,
|
||||||
|
.sectorSize = 0x1000,
|
||||||
|
.ipcmdSerialClkFreq = 0,
|
||||||
|
.blockSize = 0x8000,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MG_FLEXSPI_NOR_INSTANCE 0
|
||||||
|
#define MG_ROMAPI_ADDRESS 0x13030000U
|
||||||
|
#define flexspi_nor \
|
||||||
|
((struct mg_flexspi_nor_driver_interface *) (( \
|
||||||
|
(uint32_t *) MG_ROMAPI_ADDRESS)[5]))
|
||||||
|
|
||||||
|
MG_IRAM static bool flash_page_start(volatile uint32_t *dst) {
|
||||||
|
char *base = (char *) s_mg_flash_frdm.start,
|
||||||
|
*end = base + s_mg_flash_frdm.size;
|
||||||
|
volatile char *p = (char *) dst;
|
||||||
|
return p >= base && p < end && ((p - base) % s_mg_flash_frdm.secsz) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_IRAM static int flexspi_nor_get_config(
|
||||||
|
struct mg_flexspi_nor_config *config) {
|
||||||
|
uint32_t option = 0xc0000004;
|
||||||
|
return flexspi_nor->get_config(MG_FLEXSPI_NOR_INSTANCE, config, &option);
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_IRAM static int flash_init(void) {
|
||||||
|
static bool initialized = false;
|
||||||
|
if (!initialized) {
|
||||||
|
struct mg_flexspi_nor_config config;
|
||||||
|
memset(&config, 0, sizeof(config));
|
||||||
|
flexspi_nor->set_clock_source(0);
|
||||||
|
flexspi_nor->config_clock(MG_FLEXSPI_NOR_INSTANCE, 1, 0);
|
||||||
|
if (flexspi_nor->init(MG_FLEXSPI_NOR_INSTANCE, &default_config)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
flexspi_nor_get_config(&config);
|
||||||
|
if (flexspi_nor->init(MG_FLEXSPI_NOR_INSTANCE, &config)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_IRAM static bool flash_erase(struct mg_flexspi_nor_config *config,
|
||||||
|
void *addr) {
|
||||||
|
if (flash_page_start(addr) == false) {
|
||||||
|
MG_ERROR(("%p is not on a sector boundary", addr));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *dst = (void *) ((char *) addr - (char *) s_mg_flash_frdm.start);
|
||||||
|
bool ok = (flexspi_nor->erase_sector(MG_FLEXSPI_NOR_INSTANCE, config,
|
||||||
|
(uint32_t) dst) == 0);
|
||||||
|
MG_INFO(("Sector starting at %p erasure: %s", addr, ok ? "ok" : "fail"));
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_IRAM bool mg_frdm_swap(void) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_IRAM static void flash_wait(void) {
|
||||||
|
while ((*((volatile uint32_t *) (MG_FLEXSPI_BASE + 0xE0)) & MG_BIT(1)) == 0)
|
||||||
|
(void) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool s_flash_irq_disabled;
|
||||||
|
|
||||||
|
MG_IRAM static bool mg_frdm_write(void *addr, const void *buf, size_t len) {
|
||||||
|
struct mg_flexspi_nor_config config;
|
||||||
|
bool ok = false;
|
||||||
|
MG_ARM_DISABLE_IRQ();
|
||||||
|
if (flash_init() != 0) goto fwxit;
|
||||||
|
if (flexspi_nor_get_config(&config) != 0) goto fwxit;
|
||||||
|
if ((len % s_mg_flash_frdm.align) != 0) {
|
||||||
|
MG_ERROR(("%lu is not aligned to %lu", len, s_mg_flash_frdm.align));
|
||||||
|
goto fwxit;
|
||||||
|
}
|
||||||
|
if ((char *) addr < (char *) s_mg_flash_frdm.start) {
|
||||||
|
MG_ERROR(("Invalid flash write address: %p", addr));
|
||||||
|
goto fwxit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *dst = (uint32_t *) addr;
|
||||||
|
uint32_t *src = (uint32_t *) buf;
|
||||||
|
uint32_t *end = (uint32_t *) ((char *) buf + len);
|
||||||
|
ok = true;
|
||||||
|
|
||||||
|
while (ok && src < end) {
|
||||||
|
if (flash_page_start(dst) && flash_erase(&config, dst) == false) {
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t dst_ofs = (uint32_t) dst - (uint32_t) s_mg_flash_frdm.start;
|
||||||
|
if ((char *) buf >= (char *) s_mg_flash_frdm.start &&
|
||||||
|
(char *) buf <
|
||||||
|
(char *) (s_mg_flash_frdm.start + s_mg_flash_frdm.size)) {
|
||||||
|
// If we copy from FLASH to FLASH, then we first need to copy the source
|
||||||
|
// to RAM
|
||||||
|
size_t tmp_buf_size = s_mg_flash_frdm.align / sizeof(uint32_t);
|
||||||
|
uint32_t tmp[tmp_buf_size];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < tmp_buf_size; i++) {
|
||||||
|
flash_wait();
|
||||||
|
tmp[i] = src[i];
|
||||||
|
}
|
||||||
|
status = flexspi_nor->page_program(MG_FLEXSPI_NOR_INSTANCE, &config,
|
||||||
|
(uint32_t) dst_ofs, tmp, false);
|
||||||
|
} else {
|
||||||
|
status = flexspi_nor->page_program(MG_FLEXSPI_NOR_INSTANCE, &config,
|
||||||
|
(uint32_t) dst_ofs, src, false);
|
||||||
|
}
|
||||||
|
src = (uint32_t *) ((char *) src + s_mg_flash_frdm.align);
|
||||||
|
dst = (uint32_t *) ((char *) dst + s_mg_flash_frdm.align);
|
||||||
|
if (status != 0) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MG_INFO(("Flash write %lu bytes @ %p: %s.", len, dst, ok ? "ok" : "fail"));
|
||||||
|
fwxit:
|
||||||
|
if (!s_flash_irq_disabled) MG_ARM_ENABLE_IRQ();
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
// just overwrite instead of swap
|
||||||
|
MG_IRAM static void single_bank_swap(char *p1, char *p2, size_t s, size_t ss) {
|
||||||
|
// no stdlib calls here
|
||||||
|
for (size_t ofs = 0; ofs < s; ofs += ss) {
|
||||||
|
mg_frdm_write(p1 + ofs, p2 + ofs, ss);
|
||||||
|
}
|
||||||
|
*(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mg_ota_begin(size_t new_firmware_size) {
|
||||||
|
return mg_ota_flash_begin(new_firmware_size, &s_mg_flash_frdm);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mg_ota_write(const void *buf, size_t len) {
|
||||||
|
return mg_ota_flash_write(buf, len, &s_mg_flash_frdm);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mg_ota_end(void) {
|
||||||
|
if (mg_ota_flash_end(&s_mg_flash_frdm)) {
|
||||||
|
if (0) { // is_dualbank()
|
||||||
|
// TODO(): no devices so far
|
||||||
|
*(volatile unsigned long *) 0xe000ed0c = 0x5fa0004;
|
||||||
|
} else {
|
||||||
|
// Swap partitions. Pray power does not go away
|
||||||
|
MG_INFO(("Swapping partitions, size %u (%u sectors)",
|
||||||
|
s_mg_flash_frdm.size,
|
||||||
|
s_mg_flash_frdm.size / s_mg_flash_frdm.secsz));
|
||||||
|
MG_INFO(("Do NOT power off..."));
|
||||||
|
mg_log_level = MG_LL_NONE;
|
||||||
|
s_flash_irq_disabled = true;
|
||||||
|
// Runs in RAM, will reset when finished
|
||||||
|
single_bank_swap(
|
||||||
|
(char *) s_mg_flash_frdm.start,
|
||||||
|
(char *) s_mg_flash_frdm.start + s_mg_flash_frdm.size / 2,
|
||||||
|
s_mg_flash_frdm.size / 2, s_mg_flash_frdm.secsz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+197
-28
@@ -13,18 +13,26 @@ static bool mg_imxrt_swap(void);
|
|||||||
#elif MG_OTA == MG_OTA_RT1064
|
#elif MG_OTA == MG_OTA_RT1064
|
||||||
#define MG_IMXRT_FLASH_START 0x70000000
|
#define MG_IMXRT_FLASH_START 0x70000000
|
||||||
#define FLEXSPI_NOR_INSTANCE 1
|
#define FLEXSPI_NOR_INSTANCE 1
|
||||||
#else // RT1170
|
#else // RT1170
|
||||||
#define MG_IMXRT_FLASH_START 0x30000000
|
#define MG_IMXRT_FLASH_START 0x30000000
|
||||||
#define FLEXSPI_NOR_INSTANCE 1
|
#define FLEXSPI_NOR_INSTANCE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MG_OTA == MG_OTA_RT1050
|
||||||
|
#define MG_IMXRT_SECTOR_SIZE (256 * 1024)
|
||||||
|
#define MG_IMXRT_PAGE_SIZE 512
|
||||||
|
#else
|
||||||
|
#define MG_IMXRT_SECTOR_SIZE (4 * 1024)
|
||||||
|
#define MG_IMXRT_PAGE_SIZE 256
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO(): fill at init, support more devices in a dynamic way
|
// TODO(): fill at init, support more devices in a dynamic way
|
||||||
// TODO(): then, check alignment is <= 256, see Wizard's #251
|
// TODO(): then, check alignment is <= 256, see Wizard's #251
|
||||||
static struct mg_flash s_mg_flash_imxrt = {
|
static struct mg_flash s_mg_flash_imxrt = {
|
||||||
(void *) MG_IMXRT_FLASH_START, // Start,
|
(void *) MG_IMXRT_FLASH_START, // Start,
|
||||||
4 * 1024 * 1024, // Size, 4mb
|
4 * 1024 * 1024, // Size, 4mb
|
||||||
4 * 1024, // Sector size, 4k
|
MG_IMXRT_SECTOR_SIZE, // Sector size
|
||||||
256, // Align,
|
MG_IMXRT_PAGE_SIZE, // Align
|
||||||
mg_imxrt_write,
|
mg_imxrt_write,
|
||||||
mg_imxrt_swap,
|
mg_imxrt_swap,
|
||||||
};
|
};
|
||||||
@@ -106,8 +114,10 @@ struct mg_flexspi_nor_config {
|
|||||||
#define MG_CMD_DDR 0x21
|
#define MG_CMD_DDR 0x21
|
||||||
#define MG_DUMMY_SDR 0x0C
|
#define MG_DUMMY_SDR 0x0C
|
||||||
#define MG_DUMMY_DDR 0x2C
|
#define MG_DUMMY_DDR 0x2C
|
||||||
|
#define MG_DUMMY_RWDS_DDR 0x2D
|
||||||
#define MG_RADDR_SDR 0x02
|
#define MG_RADDR_SDR 0x02
|
||||||
#define MG_RADDR_DDR 0x22
|
#define MG_RADDR_DDR 0x22
|
||||||
|
#define MG_CADDR_DDR 0x23
|
||||||
#define MG_READ_SDR 0x09
|
#define MG_READ_SDR 0x09
|
||||||
#define MG_READ_DDR 0x29
|
#define MG_READ_DDR 0x29
|
||||||
#define MG_WRITE_SDR 0x08
|
#define MG_WRITE_SDR 0x08
|
||||||
@@ -141,6 +151,131 @@ struct mg_flexspi_nor_config {
|
|||||||
MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
|
MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MG_FLEXSPI_HYPER_LUT \
|
||||||
|
{ \
|
||||||
|
[0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xA0, MG_RADDR_DDR, \
|
||||||
|
MG_FLEXSPI_8PAD, 0x18), \
|
||||||
|
[1] = MG_FLEXSPI_LUT_SEQ(MG_CADDR_DDR, MG_FLEXSPI_8PAD, 0x10, \
|
||||||
|
MG_DUMMY_DDR, MG_FLEXSPI_8PAD, 0x0C), \
|
||||||
|
[2] = MG_FLEXSPI_LUT_SEQ(MG_READ_DDR, MG_FLEXSPI_8PAD, 0x04, MG_STOP, \
|
||||||
|
MG_FLEXSPI_1PAD, 0x0), \
|
||||||
|
[4 * 1 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 1 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 1 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
|
||||||
|
[4 * 1 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x70), \
|
||||||
|
[4 * 2 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xA0, \
|
||||||
|
MG_RADDR_DDR, MG_FLEXSPI_8PAD, 0x18), \
|
||||||
|
[4 * 2 + 1] = \
|
||||||
|
MG_FLEXSPI_LUT_SEQ(MG_CADDR_DDR, MG_FLEXSPI_8PAD, 0x10, \
|
||||||
|
MG_DUMMY_RWDS_DDR, MG_FLEXSPI_8PAD, 0x0B), \
|
||||||
|
[4 * 2 + 2] = MG_FLEXSPI_LUT_SEQ(MG_READ_DDR, MG_FLEXSPI_8PAD, 0x4, \
|
||||||
|
MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
|
||||||
|
[4 * 3 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 3 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 3 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
|
||||||
|
[4 * 3 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 4 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 4 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
|
||||||
|
[4 * 4 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x02), \
|
||||||
|
[4 * 4 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
|
||||||
|
[4 * 5 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 5 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 5 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
|
||||||
|
[4 * 5 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x80), \
|
||||||
|
[4 * 6 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 6 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 6 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
|
||||||
|
[4 * 6 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 7 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 7 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
|
||||||
|
[4 * 7 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x02), \
|
||||||
|
[4 * 7 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
|
||||||
|
[4 * 8 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_RADDR_DDR, MG_FLEXSPI_8PAD, 0x18), \
|
||||||
|
[4 * 8 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CADDR_DDR, MG_FLEXSPI_8PAD, 0x10, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 8 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x30, \
|
||||||
|
MG_STOP, MG_FLEXSPI_1PAD, 0x0), \
|
||||||
|
[4 * 9 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 9 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 9 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
|
||||||
|
[4 * 9 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xA0), \
|
||||||
|
[4 * 10 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_RADDR_DDR, MG_FLEXSPI_8PAD, 0x18), \
|
||||||
|
[4 * 10 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CADDR_DDR, MG_FLEXSPI_8PAD, 0x10, \
|
||||||
|
MG_WRITE_DDR, MG_FLEXSPI_8PAD, 0x80), \
|
||||||
|
[4 * 11 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 11 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 11 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
|
||||||
|
[4 * 11 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x80), \
|
||||||
|
[4 * 12 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 12 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 12 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
|
||||||
|
[4 * 12 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 13 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 13 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
|
||||||
|
[4 * 13 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x02), \
|
||||||
|
[4 * 13 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x55), \
|
||||||
|
[4 * 14 + 0] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0), \
|
||||||
|
[4 * 14 + 1] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0xAA), \
|
||||||
|
[4 * 14 + 2] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x05), \
|
||||||
|
[4 * 14 + 3] = MG_FLEXSPI_LUT_SEQ(MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x0, \
|
||||||
|
MG_CMD_DDR, MG_FLEXSPI_8PAD, 0x10), \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MG_LUT_CUSTOM_SEQ \
|
||||||
|
{ \
|
||||||
|
{.seqNum = 0, .seqId = 0, .reserved = 0}, \
|
||||||
|
{.seqNum = 2, .seqId = 1, .reserved = 0}, \
|
||||||
|
{.seqNum = 2, .seqId = 3, .reserved = 0}, \
|
||||||
|
{.seqNum = 4, .seqId = 5, .reserved = 0}, \
|
||||||
|
{.seqNum = 2, .seqId = 9, .reserved = 0}, \
|
||||||
|
{.seqNum = 4, .seqId = 11, .reserved = 0}, \
|
||||||
|
}
|
||||||
|
|
||||||
#define MG_FLEXSPI_LUT_OPERAND0(x) (((uint32_t) (((uint32_t) (x)))) & 0xFFU)
|
#define MG_FLEXSPI_LUT_OPERAND0(x) (((uint32_t) (((uint32_t) (x)))) & 0xFFU)
|
||||||
#define MG_FLEXSPI_LUT_NUM_PADS0(x) \
|
#define MG_FLEXSPI_LUT_NUM_PADS0(x) \
|
||||||
(((uint32_t) (((uint32_t) (x)) << 8U)) & 0x300U)
|
(((uint32_t) (((uint32_t) (x)) << 8U)) & 0x300U)
|
||||||
@@ -153,8 +288,8 @@ struct mg_flexspi_nor_config {
|
|||||||
#define MG_FLEXSPI_LUT_OPCODE1(x) \
|
#define MG_FLEXSPI_LUT_OPCODE1(x) \
|
||||||
(((uint32_t) (((uint32_t) (x)) << 26U)) & 0xFC000000U)
|
(((uint32_t) (((uint32_t) (x)) << 26U)) & 0xFC000000U)
|
||||||
|
|
||||||
#if MG_OTA == MG_OTA_RT1020
|
#if MG_OTA == MG_OTA_RT1020 || MG_OTA == MG_OTA_RT1050
|
||||||
// RT102X boards support ROM API version 1.4
|
// RT102X and RT105x boards support ROM API version 1.4
|
||||||
struct mg_flexspi_nor_driver_interface {
|
struct mg_flexspi_nor_driver_interface {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
int (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
|
int (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
|
||||||
@@ -212,10 +347,10 @@ struct mg_flexspi_nor_driver_interface {
|
|||||||
uint32_t address);
|
uint32_t address);
|
||||||
void (*hw_reset)(uint32_t instance, uint32_t resetLogic);
|
void (*hw_reset)(uint32_t instance, uint32_t resetLogic);
|
||||||
int (*wait_busy)(uint32_t instance, struct mg_flexspi_nor_config *config,
|
int (*wait_busy)(uint32_t instance, struct mg_flexspi_nor_config *config,
|
||||||
bool isParallelMode, uint32_t address);
|
bool isParallelMode, uint32_t address);
|
||||||
int (*set_clock_source)(uint32_t instance, uint32_t clockSrc);
|
int (*set_clock_source)(uint32_t instance, uint32_t clockSrc);
|
||||||
void (*config_clock)(uint32_t instance, uint32_t freqOption,
|
void (*config_clock)(uint32_t instance, uint32_t freqOption,
|
||||||
uint32_t sampleClkMode);
|
uint32_t sampleClkMode);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -234,33 +369,67 @@ struct mg_flexspi_nor_driver_interface {
|
|||||||
static bool s_flash_irq_disabled;
|
static bool s_flash_irq_disabled;
|
||||||
|
|
||||||
MG_IRAM static bool flash_page_start(volatile uint32_t *dst) {
|
MG_IRAM static bool flash_page_start(volatile uint32_t *dst) {
|
||||||
char *base = (char *) s_mg_flash_imxrt.start, *end = base + s_mg_flash_imxrt.size;
|
char *base = (char *) s_mg_flash_imxrt.start,
|
||||||
|
*end = base + s_mg_flash_imxrt.size;
|
||||||
volatile char *p = (char *) dst;
|
volatile char *p = (char *) dst;
|
||||||
return p >= base && p < end && ((p - base) % s_mg_flash_imxrt.secsz) == 0;
|
return p >= base && p < end && ((p - base) % s_mg_flash_imxrt.secsz) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: the get_config function below works both for RT1020 and 1060
|
#if MG_OTA == MG_OTA_RT1050
|
||||||
// must reside in RAM, as flash will be erased
|
// Configuration for Hyper flash memory
|
||||||
static struct mg_flexspi_nor_config default_config = {
|
static struct mg_flexspi_nor_config default_config = {
|
||||||
.memConfig = {.tag = MG_FLEXSPI_CFG_BLK_TAG,
|
.memConfig =
|
||||||
.version = MG_FLEXSPI_CFG_BLK_VERSION,
|
{
|
||||||
.readSampleClkSrc = 1, // ReadSampleClk_LoopbackFromDqsPad
|
.tag = MG_FLEXSPI_CFG_BLK_TAG,
|
||||||
.csHoldTime = 3,
|
.version = MG_FLEXSPI_CFG_BLK_VERSION,
|
||||||
.csSetupTime = 3,
|
.readSampleClkSrc = 3, // ReadSampleClk_LoopbackFromDqsPad
|
||||||
.controllerMiscOption = MG_BIT(4),
|
.csHoldTime = 3,
|
||||||
.deviceType = 1, // serial NOR
|
.csSetupTime = 3,
|
||||||
.sflashPadType = 4,
|
.columnAddressWidth = 3u,
|
||||||
.serialClkFreq = 7, // 133MHz
|
.controllerMiscOption =
|
||||||
.sflashA1Size = 8 * 1024 * 1024,
|
MG_BIT(6) | MG_BIT(4) | MG_BIT(3) | MG_BIT(0),
|
||||||
.lookupTable = MG_FLEXSPI_QSPI_LUT},
|
.deviceType = 1, // serial NOR
|
||||||
.pageSize = 256,
|
.sflashPadType = 8,
|
||||||
.sectorSize = 4 * 1024,
|
.serialClkFreq = 7, // 133MHz
|
||||||
.ipcmdSerialClkFreq = 1,
|
.sflashA1Size = 64 * 1024 * 1024,
|
||||||
.blockSize = 64 * 1024,
|
.dataValidTime = {15, 0},
|
||||||
.isUniformBlockSize = false
|
.busyOffset = 15,
|
||||||
};
|
.busyBitPolarity = 1,
|
||||||
|
.lutCustomSeqEnable = 0x1,
|
||||||
|
.lookupTable = MG_FLEXSPI_HYPER_LUT,
|
||||||
|
.lutCustomSeq = MG_LUT_CUSTOM_SEQ,
|
||||||
|
},
|
||||||
|
.pageSize = 512,
|
||||||
|
.sectorSize = 256 * 1024,
|
||||||
|
.ipcmdSerialClkFreq = 1,
|
||||||
|
.serialNorType = 1u,
|
||||||
|
.blockSize = 256 * 1024,
|
||||||
|
.isUniformBlockSize = true};
|
||||||
|
#else
|
||||||
|
// Note: this QSPI configuration works for RTs supporting QSPI
|
||||||
|
// Configuration for QSPI memory
|
||||||
|
static struct mg_flexspi_nor_config default_config = {
|
||||||
|
.memConfig = {.tag = MG_FLEXSPI_CFG_BLK_TAG,
|
||||||
|
.version = MG_FLEXSPI_CFG_BLK_VERSION,
|
||||||
|
.readSampleClkSrc = 1, // ReadSampleClk_LoopbackFromDqsPad
|
||||||
|
.csHoldTime = 3,
|
||||||
|
.csSetupTime = 3,
|
||||||
|
.controllerMiscOption = MG_BIT(4),
|
||||||
|
.deviceType = 1, // serial NOR
|
||||||
|
.sflashPadType = 4,
|
||||||
|
.serialClkFreq = 7, // 133MHz
|
||||||
|
.sflashA1Size = 8 * 1024 * 1024,
|
||||||
|
.lookupTable = MG_FLEXSPI_QSPI_LUT},
|
||||||
|
.pageSize = 256,
|
||||||
|
.sectorSize = 4 * 1024,
|
||||||
|
.ipcmdSerialClkFreq = 1,
|
||||||
|
.blockSize = 64 * 1024,
|
||||||
|
.isUniformBlockSize = false};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// must reside in RAM, as flash will be erased
|
||||||
MG_IRAM static int flexspi_nor_get_config(
|
MG_IRAM static int flexspi_nor_get_config(
|
||||||
struct mg_flexspi_nor_config **config) {
|
struct mg_flexspi_nor_config **config) {
|
||||||
*config = &default_config;
|
*config = &default_config;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
// timestamp in milliseconds since connection init time.
|
// timestamp in milliseconds since connection init time.
|
||||||
//
|
//
|
||||||
// Test (run in two separate terminals):
|
// Test (run in two separate terminals):
|
||||||
// make -C examples/http-server/ CFLAGS_EXTRA=-DMG_ENABLE_PROFILE=1
|
// make -C tutorials/http/http-server/ CFLAGS_EXTRA=-DMG_ENABLE_PROFILE=1
|
||||||
// curl localhost:8000
|
// curl localhost:8000
|
||||||
// Output:
|
// Output:
|
||||||
// 1ea1f1e7 2 net.c:150:mg_close_conn 3 profile:
|
// 1ea1f1e7 2 net.c:150:mg_close_conn 3 profile:
|
||||||
|
|||||||
+8
-12
@@ -173,15 +173,11 @@ void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data,
|
|||||||
mg_sha256_final(dst, &ctx);
|
mg_sha256_final(dst, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=====================================
|
#define rotr64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
||||||
// TODO: rename macros
|
#define ep064(x) (rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39))
|
||||||
#define ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
#define ep164(x) (rotr64(x, 14) ^ rotr64(x, 18) ^ rotr64(x, 41))
|
||||||
#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
|
#define sig064(x) (rotr64(x, 1) ^ rotr64(x, 8) ^ ((x) >> 7))
|
||||||
#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
#define sig164(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ ((x) >> 6))
|
||||||
#define EP0(x) (ROTR64(x, 28) ^ ROTR64(x, 34) ^ ROTR64(x, 39))
|
|
||||||
#define EP1(x) (ROTR64(x, 14) ^ ROTR64(x, 18) ^ ROTR64(x, 41))
|
|
||||||
#define SIG0(x) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ ((x) >> 7))
|
|
||||||
#define SIG1(x) (ROTR64(x, 19) ^ ROTR64(x, 61) ^ ((x) >> 6))
|
|
||||||
|
|
||||||
static const uint64_t mg_sha256_k2[80] = {
|
static const uint64_t mg_sha256_k2[80] = {
|
||||||
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
|
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
|
||||||
@@ -223,7 +219,7 @@ static void mg_sha384_transform(mg_sha384_ctx *ctx, const uint8_t data[]) {
|
|||||||
((uint64_t) data[j + 4] << 24) | ((uint64_t) data[j + 5] << 16) |
|
((uint64_t) data[j + 4] << 24) | ((uint64_t) data[j + 5] << 16) |
|
||||||
((uint64_t) data[j + 6] << 8) | ((uint64_t) data[j + 7]);
|
((uint64_t) data[j + 6] << 8) | ((uint64_t) data[j + 7]);
|
||||||
for (; i < 80; ++i)
|
for (; i < 80; ++i)
|
||||||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
m[i] = sig164(m[i - 2]) + m[i - 7] + sig064(m[i - 15]) + m[i - 16];
|
||||||
|
|
||||||
a = ctx->state[0];
|
a = ctx->state[0];
|
||||||
b = ctx->state[1];
|
b = ctx->state[1];
|
||||||
@@ -235,8 +231,8 @@ static void mg_sha384_transform(mg_sha384_ctx *ctx, const uint8_t data[]) {
|
|||||||
h = ctx->state[7];
|
h = ctx->state[7];
|
||||||
|
|
||||||
for (i = 0; i < 80; ++i) {
|
for (i = 0; i < 80; ++i) {
|
||||||
uint64_t t1 = h + EP1(e) + CH(e, f, g) + mg_sha256_k2[i] + m[i];
|
uint64_t t1 = h + ep164(e) + ch(e, f, g) + mg_sha256_k2[i] + m[i];
|
||||||
uint64_t t2 = EP0(a) + MAJ(a, b, c);
|
uint64_t t2 = ep064(a) + maj(a, b, c);
|
||||||
h = g;
|
h = g;
|
||||||
g = f;
|
g = f;
|
||||||
f = e;
|
f = e;
|
||||||
|
|||||||
+23
-4
@@ -128,7 +128,7 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
|
MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
|
||||||
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
|
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
|
||||||
if (MG_SOCK_RESET(n)) return MG_IO_RESET; // MbedTLS, see #1507
|
if (MG_SOCK_RESET(n)) return MG_IO_RESET; // MbedTLS, see #1507
|
||||||
if (n <= 0) return MG_IO_ERR;
|
if (n <= 0) return MG_IO_ERR;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -176,6 +176,25 @@ static void mg_set_non_blocking_mode(MG_SOCKET_TYPE fd) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mg_multicast_add(struct mg_connection *c, char *ip);
|
||||||
|
void mg_multicast_add(struct mg_connection *c, char *ip) {
|
||||||
|
#if MG_ENABLE_RL
|
||||||
|
#error UNSUPPORTED
|
||||||
|
#elif MG_ENABLE_FREERTOS_TCP
|
||||||
|
// TODO(): prvAllowIPPacketIPv4()
|
||||||
|
#else
|
||||||
|
// lwIP, Unix, Windows, Zephyr(, AzureRTOS ?)
|
||||||
|
#if MG_ENABLE_LWIP && !LWIP_IGMP
|
||||||
|
MG_ERROR(("LWIP_IGMP not defined, no multicast support"));
|
||||||
|
#else
|
||||||
|
struct ip_mreq mreq;
|
||||||
|
mreq.imr_multiaddr.s_addr = inet_addr(ip);
|
||||||
|
mreq.imr_interface.s_addr = mg_htonl(INADDR_ANY);
|
||||||
|
setsockopt(FD(c), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool mg_open_listener(struct mg_connection *c, const char *url) {
|
bool mg_open_listener(struct mg_connection *c, const char *url) {
|
||||||
MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
|
MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
@@ -250,7 +269,7 @@ static long recv_raw(struct mg_connection *c, void *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
|
MG_VERBOSE(("%lu %ld %d", c->id, n, MG_SOCK_ERR(n)));
|
||||||
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
|
if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
|
||||||
if (MG_SOCK_RESET(n)) return MG_IO_RESET; // MbedTLS, see #1507
|
if (MG_SOCK_RESET(n)) return MG_IO_RESET; // MbedTLS, see #1507
|
||||||
if (n <= 0) return MG_IO_ERR;
|
if (n <= 0) return MG_IO_ERR;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -287,11 +306,11 @@ static void read_conn(struct mg_connection *c) {
|
|||||||
}
|
}
|
||||||
// there can still be > 16K from last iteration, always mg_tls_recv()
|
// there can still be > 16K from last iteration, always mg_tls_recv()
|
||||||
m = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len);
|
m = c->is_tls_hs ? (long) MG_IO_WAIT : mg_tls_recv(c, buf, len);
|
||||||
if (n == MG_IO_ERR || n == MG_IO_RESET) { // Windows, see #3031
|
if (n == MG_IO_ERR || n == MG_IO_RESET) { // Windows, see #3031
|
||||||
if (c->rtls.len == 0 || m < 0) {
|
if (c->rtls.len == 0 || m < 0) {
|
||||||
// Close only when we have fully drained both rtls and TLS buffers
|
// Close only when we have fully drained both rtls and TLS buffers
|
||||||
c->is_closing = 1; // or there's nothing we can do about it.
|
c->is_closing = 1; // or there's nothing we can do about it.
|
||||||
m = MG_IO_ERR;
|
if (m < 0) m = MG_IO_ERR; // but return last record data, see #3104
|
||||||
} else { // see #2885
|
} else { // see #2885
|
||||||
// TLS buffer is capped to max record size, even though, there can
|
// TLS buffer is capped to max record size, even though, there can
|
||||||
// be more than one record, give TLS a chance to process them.
|
// be more than one record, give TLS a chance to process them.
|
||||||
|
|||||||
Loaded 100 of 2789 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user