Compare commits
10 Commits
b1ee067789
...
9e48a99318
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e48a99318 | |||
| ede4100286 | |||
| 5921f67307 | |||
| bed46623de | |||
| 0054237bb8 | |||
| 0a19e56497 | |||
| 574236eff6 | |||
| 00ef9237fc | |||
| c1f48c8809 | |||
| 69e05023b0 |
243
Cargo.lock
generated
243
Cargo.lock
generated
|
|
@ -133,6 +133,19 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-compat"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1ba85bc55464dcbf728b56d97e119d673f4cf9062be330a9a26f3acf504a590"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"once_cell",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-executor"
|
name = "async-executor"
|
||||||
version = "1.14.0"
|
version = "1.14.0"
|
||||||
|
|
@ -527,7 +540,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
|
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
@ -567,8 +580,18 @@ version = "0.10.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
|
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core 0.10.2",
|
||||||
"darling_macro",
|
"darling_macro 0.10.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core 0.21.3",
|
||||||
|
"darling_macro 0.21.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -585,17 +608,41 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_macro"
|
name = "darling_macro"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
|
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core 0.10.2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core 0.21.3",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "defmt"
|
name = "defmt"
|
||||||
version = "0.3.100"
|
version = "0.3.100"
|
||||||
|
|
@ -698,7 +745,7 @@ version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0"
|
checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling 0.10.2",
|
||||||
"derive_builder_core",
|
"derive_builder_core",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -711,7 +758,7 @@ version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef"
|
checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling 0.10.2",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
|
|
@ -749,6 +796,29 @@ dependencies = [
|
||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "domain"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f7ff15f82df7d5086fb15dfc1c1e96598a6ded9829840a9bcfa1fa3ccd8d01d"
|
||||||
|
dependencies = [
|
||||||
|
"domain-macros",
|
||||||
|
"heapless 0.8.0",
|
||||||
|
"octseq",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "domain-macros"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d1a6796ad411f6812d691955066ad27450196bfb181bb91b66a643cc3e8f5b7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ecdsa"
|
name = "ecdsa"
|
||||||
version = "0.16.9"
|
version = "0.16.9"
|
||||||
|
|
@ -762,6 +832,47 @@ dependencies = [
|
||||||
"signature",
|
"signature",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "edge-mdns"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73e6e268ceceab96a31eeefb7fc4afbb8f005313de23944a0ecb10a20f382193"
|
||||||
|
dependencies = [
|
||||||
|
"domain 0.11.1",
|
||||||
|
"edge-nal",
|
||||||
|
"embassy-futures",
|
||||||
|
"embassy-sync",
|
||||||
|
"embassy-time",
|
||||||
|
"heapless 0.9.3",
|
||||||
|
"log",
|
||||||
|
"rand_core 0.9.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "edge-nal"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3c7d7163586cb9d457a34561a644aa957ce870226729bf6c9c8beeaead7e0d8"
|
||||||
|
dependencies = [
|
||||||
|
"embassy-time",
|
||||||
|
"embedded-io-async 0.7.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "edge-nal-std"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4af3f481df81463ca9a1bdb5adda6ecb956b1e4efacb29dab1835194479cdbc8"
|
||||||
|
dependencies = [
|
||||||
|
"async-io",
|
||||||
|
"edge-nal",
|
||||||
|
"embedded-io-async 0.7.0",
|
||||||
|
"futures-lite",
|
||||||
|
"heapless 0.9.3",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
|
|
@ -781,7 +892,7 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
"group",
|
"group",
|
||||||
"hkdf",
|
"hkdf",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"sec1",
|
"sec1",
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
|
|
@ -807,7 +918,7 @@ checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"critical-section",
|
"critical-section",
|
||||||
"embedded-io-async",
|
"embedded-io-async 0.6.1",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"heapless 0.8.0",
|
"heapless 0.8.0",
|
||||||
|
|
@ -881,13 +992,28 @@ version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-io-async"
|
name = "embedded-io-async"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f"
|
checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"embedded-io",
|
"embedded-io 0.6.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io-async"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0"
|
||||||
|
dependencies = [
|
||||||
|
"embedded-io 0.7.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -917,6 +1043,27 @@ dependencies = [
|
||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumset"
|
||||||
|
version = "1.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "839c4174b41e75c8f7306110b2c51996a293b8d1d850edd529011841d9fede7d"
|
||||||
|
dependencies = [
|
||||||
|
"enumset_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumset_derive"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4bd536557b58c682b217b8fb199afdff47cd3eff260623f19e77074eb073d63a"
|
||||||
|
dependencies = [
|
||||||
|
"darling 0.21.3",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_filter"
|
name = "env_filter"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
@ -989,7 +1136,7 @@ version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
|
checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1114,7 +1261,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ff",
|
"ff",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1877,8 +2024,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
|
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha 0.3.1",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1888,7 +2035,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.9.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1900,6 +2057,12 @@ dependencies = [
|
||||||
"getrandom 0.2.17",
|
"getrandom 0.2.17",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.12.3"
|
version = "1.12.3"
|
||||||
|
|
@ -1942,7 +2105,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rs-matter"
|
name = "rs-matter"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "git+https://git.fishmt.net/nakajima/rs-matter?branch=bluez-ios-reconnect#fe15e0cd698e49969abf42329966a70ffdfb8576"
|
source = "git+https://git.fishmt.net/nakajima/rs-matter?branch=bluez-ios-reconnect#e44e9e3debaf74e18f827ca163daf6fe03c7410f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"async-channel",
|
"async-channel",
|
||||||
|
|
@ -1956,7 +2119,7 @@ dependencies = [
|
||||||
"defmt 0.3.100",
|
"defmt 0.3.100",
|
||||||
"der",
|
"der",
|
||||||
"digest",
|
"digest",
|
||||||
"domain",
|
"domain 0.10.4",
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
"either",
|
"either",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
|
|
@ -1981,7 +2144,7 @@ dependencies = [
|
||||||
"primeorder",
|
"primeorder",
|
||||||
"qrcodegen-no-heap",
|
"qrcodegen-no-heap",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"rs-matter-codegen",
|
"rs-matter-codegen",
|
||||||
"rs-matter-macros",
|
"rs-matter-macros",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
|
|
@ -2004,7 +2167,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rs-matter-codegen"
|
name = "rs-matter-codegen"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.fishmt.net/nakajima/rs-matter?branch=bluez-ios-reconnect#fe15e0cd698e49969abf42329966a70ffdfb8576"
|
source = "git+https://git.fishmt.net/nakajima/rs-matter?branch=bluez-ios-reconnect#e44e9e3debaf74e18f827ca163daf6fe03c7410f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"convert_case",
|
"convert_case",
|
||||||
"miette",
|
"miette",
|
||||||
|
|
@ -2023,7 +2186,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rs-matter-macros"
|
name = "rs-matter-macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.fishmt.net/nakajima/rs-matter?branch=bluez-ios-reconnect#fe15e0cd698e49969abf42329966a70ffdfb8576"
|
source = "git+https://git.fishmt.net/nakajima/rs-matter?branch=bluez-ios-reconnect#e44e9e3debaf74e18f827ca163daf6fe03c7410f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -2031,6 +2194,29 @@ dependencies = [
|
||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rs-matter-stack"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "git+https://git.fishmt.net/nakajima/rs-matter-stack?branch=master#0a022bb2ac686707c3f5a84a790b1c3430b500ce"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.11.1",
|
||||||
|
"cfg-if",
|
||||||
|
"edge-mdns",
|
||||||
|
"edge-nal",
|
||||||
|
"edge-nal-std",
|
||||||
|
"embassy-futures",
|
||||||
|
"embassy-sync",
|
||||||
|
"embassy-time",
|
||||||
|
"enumset",
|
||||||
|
"heapless 0.8.0",
|
||||||
|
"log",
|
||||||
|
"rand_chacha 0.9.0",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
"rand_core 0.9.5",
|
||||||
|
"rs-matter",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.27"
|
version = "0.1.27"
|
||||||
|
|
@ -2199,7 +2385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2224,6 +2410,15 @@ version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_cell"
|
||||||
|
version = "2.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23"
|
||||||
|
dependencies = [
|
||||||
|
"portable-atomic",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
|
|
@ -2394,17 +2589,17 @@ checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toes-matter"
|
name = "toes-matter"
|
||||||
version = "0.1.12"
|
version = "0.1.17"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-io",
|
"async-compat",
|
||||||
"embassy-futures",
|
|
||||||
"embassy-time",
|
|
||||||
"embassy-time-queue-utils",
|
"embassy-time-queue-utils",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand",
|
||||||
"rs-matter",
|
"rs-matter",
|
||||||
|
"rs-matter-stack",
|
||||||
|
"static_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
29
Cargo.toml
29
Cargo.toml
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "toes-matter"
|
name = "toes-matter"
|
||||||
version = "0.1.12"
|
version = "0.1.17"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
@ -20,13 +20,13 @@ required-features = ["device"]
|
||||||
[features]
|
[features]
|
||||||
default = ["device"]
|
default = ["device"]
|
||||||
device = [
|
device = [
|
||||||
"dep:async-io",
|
"dep:async-compat",
|
||||||
"dep:embassy-futures",
|
|
||||||
"dep:embassy-time",
|
|
||||||
"dep:embassy-time-queue-utils",
|
"dep:embassy-time-queue-utils",
|
||||||
"dep:env_logger",
|
"dep:env_logger",
|
||||||
"dep:futures-lite",
|
"dep:futures-lite",
|
||||||
"dep:log",
|
"dep:log",
|
||||||
|
"dep:rs-matter-stack",
|
||||||
|
"dep:static_cell",
|
||||||
"rs-matter/log",
|
"rs-matter/log",
|
||||||
"rs-matter/os",
|
"rs-matter/os",
|
||||||
"rs-matter/rustcrypto",
|
"rs-matter/rustcrypto",
|
||||||
|
|
@ -35,17 +35,28 @@ device = [
|
||||||
"rs-matter/max-groups-per-fabric-12",
|
"rs-matter/max-groups-per-fabric-12",
|
||||||
"rs-matter/max-group-keys-per-fabric-2",
|
"rs-matter/max-group-keys-per-fabric-2",
|
||||||
"rs-matter/max-group-endpoints-per-fabric-3",
|
"rs-matter/max-group-endpoints-per-fabric-3",
|
||||||
|
"rs-matter-stack/log",
|
||||||
|
"rs-matter-stack/os",
|
||||||
|
"rs-matter-stack/std",
|
||||||
|
"rs-matter-stack/zbus",
|
||||||
|
"rs-matter-stack/max-sessions-32",
|
||||||
|
"rs-matter-stack/max-groups-per-fabric-12",
|
||||||
|
"rs-matter-stack/max-group-keys-per-fabric-2",
|
||||||
|
"rs-matter-stack/max-group-endpoints-per-fabric-3",
|
||||||
"zeroconf",
|
"zeroconf",
|
||||||
]
|
]
|
||||||
zeroconf = ["rs-matter/zeroconf"]
|
zeroconf = ["rs-matter/zeroconf", "rs-matter-stack/zeroconf"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-io = { version = "2", optional = true }
|
async-compat = { version = "0.2", optional = true }
|
||||||
embassy-futures = { version = "0.1", optional = true }
|
|
||||||
embassy-time = { version = "0.5", features = ["std"], optional = true }
|
|
||||||
embassy-time-queue-utils = { version = "0.3", features = ["generic-queue-64"], optional = true }
|
embassy-time-queue-utils = { version = "0.3", features = ["generic-queue-64"], optional = true }
|
||||||
env_logger = { version = "0.11", optional = true }
|
env_logger = { version = "0.11", optional = true }
|
||||||
futures-lite = { version = "2", optional = true }
|
futures-lite = { version = "2", optional = true }
|
||||||
log = { version = "0.4", optional = true }
|
log = { version = "0.4", optional = true }
|
||||||
rand = { version = "0.8", features = ["std", "std_rng"] }
|
rand = { version = "0.8", features = ["std", "std_rng"] }
|
||||||
rs-matter = { git = "https://git.fishmt.net/nakajima/rs-matter", branch = "bluez-ios-reconnect", default-features = false }
|
rs-matter = { version = "0.1", default-features = false }
|
||||||
|
rs-matter-stack = { git = "https://git.fishmt.net/nakajima/rs-matter-stack", branch = "master", default-features = false, optional = true }
|
||||||
|
static_cell = { version = "2.1", optional = true }
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
rs-matter = { git = "https://git.fishmt.net/nakajima/rs-matter", branch = "bluez-ios-reconnect" }
|
||||||
|
|
|
||||||
13
README.md
13
README.md
|
|
@ -1,23 +1,24 @@
|
||||||
# toes-matter
|
# toes-matter
|
||||||
|
|
||||||
Tiny facade around `rs-matter` for the Toes RGB light flow:
|
Tiny facade around `rs-matter-stack` for the Toes RGB light flow:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
use core::pin::pin;
|
||||||
|
|
||||||
fn main() -> toes_matter::Result<()> {
|
fn main() -> toes_matter::Result<()> {
|
||||||
env_logger::init_from_env(
|
env_logger::init_from_env(
|
||||||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||||
);
|
);
|
||||||
|
|
||||||
futures_lite::future::block_on(async {
|
let runtime = pin!(toes_matter::run());
|
||||||
toes_matter::generate_credentials("./creds").await?;
|
futures_lite::future::block_on(async_compat::Compat::new(runtime))
|
||||||
toes_matter::provision().await?;
|
|
||||||
toes_matter::listen().await
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`toes_matter::run()` handles both first-boot BLE/Wi-Fi commissioning and normal operational Matter traffic. The older `provision()` and `listen()` functions are kept as compatibility aliases for the same combined runtime.
|
||||||
|
|
||||||
## Runtime assumptions
|
## Runtime assumptions
|
||||||
|
|
||||||
- Linux + BlueZ on system D-Bus
|
- Linux + BlueZ on system D-Bus
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
use core::pin::pin;
|
||||||
|
|
||||||
fn main() -> toes_matter::Result<()> {
|
fn main() -> toes_matter::Result<()> {
|
||||||
env_logger::init_from_env(
|
env_logger::init_from_env(
|
||||||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||||
);
|
);
|
||||||
|
|
||||||
futures_lite::future::block_on(async {
|
futures_lite::future::block_on(toes_matter::generate_credentials("./creds"))?;
|
||||||
toes_matter::generate_credentials("./creds").await?;
|
|
||||||
toes_matter::provision().await?;
|
let runtime = pin!(toes_matter::run());
|
||||||
toes_matter::listen().await
|
futures_lite::future::block_on(async_compat::Compat::new(runtime))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
229
rebuild.sh
Executable file
229
rebuild.sh
Executable file
|
|
@ -0,0 +1,229 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
IMG="$HOME/Documents/toes-image-builder/toes-ubuntu-base.img"
|
||||||
|
USBBOOT="$HOME/apps/forks/usbboot"
|
||||||
|
PROVISION_SCRIPT="${PROVISION_SCRIPT:-$SCRIPT_DIR/scripts/provision-device.sh}"
|
||||||
|
PROVISION_DEVICE_ID="${PROVISION_DEVICE_ID:-${DEVICE_ID:-device-001}}"
|
||||||
|
DEFAULT_SERIAL_LOGIN="toes"
|
||||||
|
DEFAULT_SERIAL_PASSWORD="nicetrywiseguy"
|
||||||
|
REBOOT_SETTLE_SECS="${REBOOT_SETTLE_SECS:-45}"
|
||||||
|
SERIAL_BOOT_TIMEOUT_SECS="${SERIAL_BOOT_TIMEOUT_SECS:-180}"
|
||||||
|
|
||||||
|
list_external_disks() {
|
||||||
|
diskutil list external physical 2>/dev/null | awk '/^\/dev\/disk[0-9]+ / { sub("^/dev/", "", $1); print $1 }' | sort || true
|
||||||
|
}
|
||||||
|
|
||||||
|
disk_bytes() {
|
||||||
|
diskutil info "/dev/$1" | awk -F'[()]' '/Disk Size:/ { sub(/ Bytes.*/, "", $2); print $2; exit }'
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_serial_port() {
|
||||||
|
local pattern port
|
||||||
|
local -a matches
|
||||||
|
|
||||||
|
matches=()
|
||||||
|
for pattern in /dev/cu.usbserial\* /dev/cu.usbmodem\*; do
|
||||||
|
for port in $pattern; do
|
||||||
|
[[ -e "$port" ]] || continue
|
||||||
|
matches+=("$port")
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ${#matches[@]} == 1 )); then
|
||||||
|
printf '%s\n' "${matches[0]}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( ${#matches[@]} > 1 )); then
|
||||||
|
echo "multiple serial ports detected; set SERIAL_PORT to one of:" >&2
|
||||||
|
printf ' %s\n' "${matches[@]}" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
matches=()
|
||||||
|
for pattern in /dev/tty.usbserial\* /dev/tty.usbmodem\*; do
|
||||||
|
for port in $pattern; do
|
||||||
|
[[ -e "$port" ]] || continue
|
||||||
|
matches+=("$port")
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ${#matches[@]} == 1 )); then
|
||||||
|
printf '%s\n' "${matches[0]}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( ${#matches[@]} > 1 )); then
|
||||||
|
echo "multiple serial ports detected; set SERIAL_PORT to one of:" >&2
|
||||||
|
printf ' %s\n' "${matches[@]}" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_serial_port() {
|
||||||
|
local port status
|
||||||
|
|
||||||
|
if [[ -n "${SERIAL_PORT:-}" ]]; then
|
||||||
|
[[ -e "$SERIAL_PORT" ]] || { echo "serial port does not exist: $SERIAL_PORT" >&2; return 1; }
|
||||||
|
printf '%s\n' "$SERIAL_PORT"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if port="$(detect_serial_port)"; then
|
||||||
|
printf '%s\n' "$port"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
status=$?
|
||||||
|
if (( status == 1 )); then
|
||||||
|
echo "no serial port detected; set SERIAL_PORT=/dev/cu.*" >&2
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_serial_port() {
|
||||||
|
local timeout="$1"
|
||||||
|
local deadline=$((SECONDS + timeout))
|
||||||
|
local port status
|
||||||
|
|
||||||
|
if [[ -n "${SERIAL_PORT:-}" ]]; then
|
||||||
|
while (( SECONDS < deadline )); do
|
||||||
|
[[ -e "$SERIAL_PORT" ]] && { printf '%s\n' "$SERIAL_PORT"; return 0; }
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "timed out waiting for serial port: $SERIAL_PORT" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while (( SECONDS < deadline )); do
|
||||||
|
if port="$(detect_serial_port 2>/dev/null)"; then
|
||||||
|
printf '%s\n' "$port"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
status=$?
|
||||||
|
if (( status == 2 )); then
|
||||||
|
detect_serial_port >/dev/null || true
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "timed out waiting for serial port; set SERIAL_PORT=/dev/cu.*" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_rpiboot_mass_storage() {
|
||||||
|
pkill -f 'rpiboot.*mass-storage-gadget' 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
reboot_target_over_serial() {
|
||||||
|
local port="$1"
|
||||||
|
|
||||||
|
echo "Requesting target reboot over $port"
|
||||||
|
stty -f "$port" 115200 raw -echo clocal 2>/dev/null || true
|
||||||
|
{
|
||||||
|
sleep 0.2
|
||||||
|
printf '\r'
|
||||||
|
sleep 0.5
|
||||||
|
printf 'root\r'
|
||||||
|
sleep 0.5
|
||||||
|
printf '\r'
|
||||||
|
sleep 0.5
|
||||||
|
printf 'sync\r'
|
||||||
|
sleep 0.5
|
||||||
|
printf 'reboot -f\r'
|
||||||
|
} >"$port"
|
||||||
|
}
|
||||||
|
|
||||||
|
provision_device() {
|
||||||
|
local port="$1"
|
||||||
|
local provision_login="${SERIAL_LOGIN:-$DEFAULT_SERIAL_LOGIN}"
|
||||||
|
local provision_password="${SERIAL_PASSWORD:-$DEFAULT_SERIAL_PASSWORD}"
|
||||||
|
local provision_prompt="${SERIAL_PROMPT:-${provision_login}@}"
|
||||||
|
|
||||||
|
[[ -x "$PROVISION_SCRIPT" ]] || { echo "provision script is not executable: $PROVISION_SCRIPT" >&2; return 1; }
|
||||||
|
|
||||||
|
echo "Provisioning $PROVISION_DEVICE_ID over $port"
|
||||||
|
SERIAL_PORT="$port" \
|
||||||
|
SERIAL_LOGIN="$provision_login" \
|
||||||
|
SERIAL_PASSWORD="$provision_password" \
|
||||||
|
SERIAL_PROMPT="$provision_prompt" \
|
||||||
|
SERIAL_LOGIN_TIMEOUT_SECS="${SERIAL_LOGIN_TIMEOUT_SECS:-$SERIAL_BOOT_TIMEOUT_SECS}" \
|
||||||
|
"$PROVISION_SCRIPT" "$PROVISION_DEVICE_ID"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "${SKIP_BUILD:-0}" != 1 ]]; then
|
||||||
|
ssh toes-image-builder 'cd toes-image-builder && ./build.sh && cp build/toes-ubuntu-base.img /mnt/utm/toes-image-builder/'
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -f "$IMG" ]] || { echo "missing $IMG" >&2; exit 1; }
|
||||||
|
|
||||||
|
target="${DISK:-}"
|
||||||
|
if [[ -n "$target" ]]; then
|
||||||
|
target="${target#/dev/}"
|
||||||
|
target="${target#r}"
|
||||||
|
else
|
||||||
|
before="$(mktemp)"
|
||||||
|
after="$(mktemp)"
|
||||||
|
trap 'rm -f "$before" "$after"' EXIT
|
||||||
|
list_external_disks >"$before"
|
||||||
|
sudo "$USBBOOT/rpiboot" -d "$USBBOOT/mass-storage-gadget64"
|
||||||
|
|
||||||
|
for _ in {1..30}; do
|
||||||
|
list_external_disks >"$after"
|
||||||
|
new="$(comm -13 "$before" "$after")"
|
||||||
|
[[ -n "$new" ]] && { sleep 2; list_external_disks >"$after"; new="$(comm -13 "$before" "$after")"; break; }
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
[[ -n "${new:-}" ]] || { echo "no new disks" >&2; exit 1; }
|
||||||
|
|
||||||
|
echo "New disks:"
|
||||||
|
target_size=0
|
||||||
|
for disk in $new; do
|
||||||
|
bytes="$(disk_bytes "$disk")"
|
||||||
|
echo " /dev/$disk ${bytes:-?} bytes"
|
||||||
|
[[ "$bytes" =~ ^[0-9]+$ ]] && (( bytes > target_size )) && { target="$disk"; target_size="$bytes"; }
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ "${target:-}" =~ ^disk[0-9]+$ ]] || { echo "bad disk: ${target:-}" >&2; exit 1; }
|
||||||
|
|
||||||
|
target_size="$(disk_bytes "$target")"
|
||||||
|
image_size="$(stat -f %z "$IMG")"
|
||||||
|
[[ "$target_size" =~ ^[0-9]+$ ]] || { echo "could not size /dev/$target" >&2; exit 1; }
|
||||||
|
(( target_size >= image_size )) || { echo "/dev/$target is smaller than $IMG" >&2; exit 1; }
|
||||||
|
|
||||||
|
echo "Selected /dev/$target"
|
||||||
|
echo "Image: $IMG"
|
||||||
|
diskutil info "/dev/$target"
|
||||||
|
printf 'Type FLASH to erase /dev/%s: ' "$target"
|
||||||
|
read -r answer
|
||||||
|
[[ "$answer" == FLASH ]] || { echo "aborted"; exit 1; }
|
||||||
|
|
||||||
|
diskutil unmountDisk "/dev/$target"
|
||||||
|
sudo dd if="$IMG" of="/dev/r$target" bs=16m status=progress conv=fsync
|
||||||
|
sync
|
||||||
|
diskutil eject "/dev/$target"
|
||||||
|
|
||||||
|
if [[ "${SKIP_REBOOT:-0}" != 1 ]]; then
|
||||||
|
reboot_port="$(resolve_serial_port)"
|
||||||
|
stop_rpiboot_mass_storage
|
||||||
|
reboot_target_over_serial "$reboot_port"
|
||||||
|
echo "Waiting ${REBOOT_SETTLE_SECS}s for target to start booting..."
|
||||||
|
sleep "$REBOOT_SETTLE_SECS"
|
||||||
|
else
|
||||||
|
echo "Skipping target reboot because SKIP_REBOOT=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${SKIP_PROVISION:-0}" != 1 ]]; then
|
||||||
|
provision_port="$(wait_for_serial_port "$SERIAL_BOOT_TIMEOUT_SECS")"
|
||||||
|
provision_device "$provision_port"
|
||||||
|
else
|
||||||
|
echo "Skipping provisioning because SKIP_PROVISION=1"
|
||||||
|
fi
|
||||||
|
|
@ -110,6 +110,10 @@ impl Options {
|
||||||
|
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
match arg.as_str() {
|
match arg.as_str() {
|
||||||
|
"-V" | "--version" => {
|
||||||
|
println!("toes-matter-credentials {}", env!("CARGO_PKG_VERSION"));
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
"-h" | "--help" => {
|
"-h" | "--help" => {
|
||||||
print_usage();
|
print_usage();
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
|
|
@ -191,6 +195,7 @@ fn print_usage() {
|
||||||
--password PASS Serial login password [env: SERIAL_PASSWORD]\n\
|
--password PASS Serial login password [env: SERIAL_PASSWORD]\n\
|
||||||
--prompt PROMPT Shell prompt marker; may repeat [env: SERIAL_PROMPT]\n\
|
--prompt PROMPT Shell prompt marker; may repeat [env: SERIAL_PROMPT]\n\
|
||||||
--login-timeout-secs N Serial login timeout [default: 30, env: SERIAL_LOGIN_TIMEOUT_SECS]\n\
|
--login-timeout-secs N Serial login timeout [default: 30, env: SERIAL_LOGIN_TIMEOUT_SECS]\n\
|
||||||
|
-V, --version Show version\n\
|
||||||
-h, --help Show this help"
|
-h, --help Show this help"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,20 @@
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
use core::pin::pin;
|
||||||
|
|
||||||
fn main() -> toes_matter::Result<()> {
|
fn main() -> toes_matter::Result<()> {
|
||||||
|
if std::env::args()
|
||||||
|
.skip(1)
|
||||||
|
.any(|arg| matches!(arg.as_str(), "-V" | "--version"))
|
||||||
|
{
|
||||||
|
println!("toes-matter {}", env!("CARGO_PKG_VERSION"));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
env_logger::init_from_env(
|
env_logger::init_from_env(
|
||||||
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||||
);
|
);
|
||||||
|
|
||||||
futures_lite::future::block_on(async {
|
let runtime = pin!(toes_matter::run());
|
||||||
toes_matter::provision().await?;
|
futures_lite::future::block_on(async_compat::Compat::new(runtime))
|
||||||
toes_matter::listen().await
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
431
src/lib.rs
431
src/lib.rs
|
|
@ -5,70 +5,64 @@
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use core::pin::pin;
|
use core::pin::pin;
|
||||||
|
|
||||||
use std::net::UdpSocket;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use embassy_futures::select::{select, select4};
|
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
|
use static_cell::StaticCell;
|
||||||
|
|
||||||
use rs_matter::crypto::{default_crypto, Crypto};
|
use rs_matter_stack::ble::GattPeripheral;
|
||||||
use rs_matter::dm::clusters::app::level_control::LevelControlHooks;
|
use rs_matter_stack::matter as rs_matter;
|
||||||
use rs_matter::dm::clusters::app::on_off::OnOffHooks;
|
use rs_matter_stack::matter::crypto::{default_crypto, Crypto};
|
||||||
use rs_matter::dm::clusters::app::{level_control, on_off};
|
use rs_matter_stack::matter::dm::clusters::app::level_control::LevelControlHooks;
|
||||||
use rs_matter::dm::clusters::decl::color_control;
|
use rs_matter_stack::matter::dm::clusters::app::on_off::OnOffHooks;
|
||||||
use rs_matter::dm::clusters::decl::color_control::ClusterAsyncHandler as ColorControlHandler;
|
use rs_matter_stack::matter::dm::clusters::app::{level_control, on_off};
|
||||||
use rs_matter::dm::clusters::desc::{ClusterHandler as _, DescHandler};
|
use rs_matter_stack::matter::dm::clusters::decl::color_control;
|
||||||
use rs_matter::dm::clusters::dev_att::DeviceAttestation;
|
use rs_matter_stack::matter::dm::clusters::decl::color_control::ClusterAsyncHandler as ColorControlHandler;
|
||||||
use rs_matter::dm::clusters::net_comm::{
|
use rs_matter_stack::matter::dm::clusters::desc::{ClusterHandler as _, DescHandler};
|
||||||
NetCtl, NetCtlError, NetworkScanInfo, NetworkType, SharedNetworks, ThreadCapabilitiesBitmap,
|
use rs_matter_stack::matter::dm::clusters::dev_att::DeviceAttestation;
|
||||||
WiFiBandEnum, WirelessCreds,
|
use rs_matter_stack::matter::dm::clusters::gen_diag::{NetifDiag, NetifInfo};
|
||||||
|
use rs_matter_stack::matter::dm::clusters::net_comm::{
|
||||||
|
NetCtl, NetCtlError, NetworkScanInfo, NetworkType, ThreadCapabilitiesBitmap, WiFiBandEnum,
|
||||||
|
WirelessCreds,
|
||||||
};
|
};
|
||||||
use rs_matter::dm::clusters::wifi_diag::{
|
use rs_matter_stack::matter::dm::clusters::wifi_diag::{
|
||||||
SecurityTypeEnum, WiFiVersionEnum, WifiDiag, WirelessDiag,
|
SecurityTypeEnum, WiFiVersionEnum, WifiDiag, WirelessDiag,
|
||||||
};
|
};
|
||||||
use rs_matter::dm::devices::test::{DAC_PRIVKEY, TEST_DEV_ATT, TEST_DEV_COMM, TEST_DEV_DET};
|
use rs_matter_stack::matter::dm::devices::test::{
|
||||||
use rs_matter::dm::endpoints;
|
DAC_PRIVKEY, TEST_DEV_ATT, TEST_DEV_COMM, TEST_DEV_DET,
|
||||||
use rs_matter::dm::events::Events;
|
|
||||||
use rs_matter::dm::networks::unix::UnixNetifs;
|
|
||||||
use rs_matter::dm::networks::wireless::{NetCtlState, NetCtlWithStatusImpl, WifiNetworks};
|
|
||||||
use rs_matter::dm::networks::NetChangeNotif;
|
|
||||||
use rs_matter::dm::subscriptions::Subscriptions;
|
|
||||||
use rs_matter::dm::{
|
|
||||||
Async, Cluster, DataModel, Dataver, EmptyHandler, Endpoint, EpClMatcher, Node,
|
|
||||||
};
|
};
|
||||||
use rs_matter::error::{Error, ErrorCode};
|
use rs_matter_stack::matter::dm::networks::unix::UnixNetifs;
|
||||||
use rs_matter::pairing::qr::{no_optional_data, CommFlowType, QrPayload, QrTextType};
|
use rs_matter_stack::matter::dm::networks::NetChangeNotif;
|
||||||
use rs_matter::pairing::DiscoveryCapabilities;
|
use rs_matter_stack::matter::dm::{
|
||||||
use rs_matter::persist::{DirKvBlobStore, SharedKvBlobStore};
|
Async, Cluster, Dataver, EmptyHandler, Endpoint, EpClMatcher, Node,
|
||||||
use rs_matter::respond::DefaultResponder;
|
|
||||||
use rs_matter::sc::pase::{
|
|
||||||
Spake2pVerifierPassword, Spake2pVerifierPasswordRef, MAX_COMM_WINDOW_TIMEOUT_SECS,
|
|
||||||
};
|
};
|
||||||
use rs_matter::tlv::Nullable;
|
use rs_matter_stack::matter::error::{Error, ErrorCode};
|
||||||
use rs_matter::transport::network::btp::bluez;
|
use rs_matter_stack::matter::pairing::qr::{no_optional_data, CommFlowType, QrPayload};
|
||||||
use rs_matter::transport::network::btp::{AdvData, Btp};
|
use rs_matter_stack::matter::pairing::DiscoveryCapabilities;
|
||||||
use rs_matter::transport::network::mdns::zeroconf::ZeroconfMdnsResponder;
|
use rs_matter_stack::matter::persist::DirKvBlobStore;
|
||||||
use rs_matter::transport::network::wifi::wpa_supp::unix::DhClientCtl;
|
use rs_matter_stack::matter::sc::pase::{Spake2pVerifierPassword, Spake2pVerifierPasswordRef};
|
||||||
use rs_matter::transport::network::wifi::wpa_supp::WpaSuppCtl;
|
use rs_matter_stack::matter::tlv::Nullable;
|
||||||
use rs_matter::transport::network::{Address, ChainedNetwork};
|
use rs_matter_stack::matter::transport::network::btp::{AdvData, Btp};
|
||||||
use rs_matter::transport::MATTER_SOCKET_BIND_ADDR;
|
use rs_matter_stack::matter::transport::network::mdns::zeroconf::ZeroconfMdnsResponder;
|
||||||
use rs_matter::utils::select::Coalesce;
|
use rs_matter_stack::matter::transport::network::wifi::wpa_supp::unix::DhClientCtl;
|
||||||
use rs_matter::utils::storage::pooled::PooledBuffers;
|
use rs_matter_stack::matter::transport::network::wifi::wpa_supp::WpaSuppCtl;
|
||||||
use rs_matter::utils::sync::blocking::Mutex;
|
use rs_matter_stack::matter::utils::init::InitMaybeUninit;
|
||||||
use rs_matter::utils::sync::DynBase;
|
use rs_matter_stack::matter::utils::sync::blocking::Mutex;
|
||||||
use rs_matter::utils::zbus::Connection;
|
use rs_matter_stack::matter::utils::sync::DynBase;
|
||||||
use rs_matter::{clusters, devices, root_endpoint, with, BasicCommData, Matter, MATTER_PORT};
|
use rs_matter_stack::matter::utils::zbus::Connection;
|
||||||
|
use rs_matter_stack::matter::{clusters, devices, with, BasicCommData};
|
||||||
|
use rs_matter_stack::nal::std::Stack as StdNetStack;
|
||||||
|
use rs_matter_stack::wireless::{PreexistingWireless, WifiMatterStack};
|
||||||
|
|
||||||
pub type Result<T> = core::result::Result<T, Error>;
|
pub type Result<T> = core::result::Result<T, Error>;
|
||||||
|
|
||||||
const DEFAULT_CREDS_DIR: &str = "./creds";
|
const DEFAULT_CREDS_DIR: &str = "./creds";
|
||||||
const DEFAULT_WIFI_IFACE: &str = "wlan0";
|
const DEFAULT_WIFI_IFACE: &str = "wlan0";
|
||||||
const LIGHT_ENDPOINT_ID: u16 = 1;
|
const LIGHT_ENDPOINT_ID: u16 = 1;
|
||||||
const KV_BUF_SIZE: usize = 4096;
|
|
||||||
const BLE_SERVICE_NAME: &str = "TOES";
|
const BLE_SERVICE_NAME: &str = "TOES";
|
||||||
const COMMISSIONING_HANDOFF_SECS: u64 = 20;
|
const BUMP_SIZE: usize = 48_000;
|
||||||
|
|
||||||
const DEV_TYPE_EXTENDED_COLOR_LIGHT: rs_matter::dm::DeviceType = rs_matter::dm::DeviceType {
|
const DEV_TYPE_EXTENDED_COLOR_LIGHT: rs_matter::dm::DeviceType = rs_matter::dm::DeviceType {
|
||||||
dtype: 0x010d,
|
dtype: 0x010d,
|
||||||
|
|
@ -77,7 +71,7 @@ const DEV_TYPE_EXTENDED_COLOR_LIGHT: rs_matter::dm::DeviceType = rs_matter::dm::
|
||||||
|
|
||||||
const NODE: Node = Node {
|
const NODE: Node = Node {
|
||||||
endpoints: &[
|
endpoints: &[
|
||||||
root_endpoint!(wifi),
|
WifiMatterStack::<0, ()>::root_endpoint(),
|
||||||
Endpoint {
|
Endpoint {
|
||||||
id: LIGHT_ENDPOINT_ID,
|
id: LIGHT_ENDPOINT_ID,
|
||||||
device_types: devices!(DEV_TYPE_EXTENDED_COLOR_LIGHT),
|
device_types: devices!(DEV_TYPE_EXTENDED_COLOR_LIGHT),
|
||||||
|
|
@ -91,7 +85,9 @@ const NODE: Node = Node {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Runtime configuration used by [`provision_with_config`] and [`listen_with_config`].
|
static MATTER_STACK: StaticCell<WifiMatterStack<BUMP_SIZE, ()>> = StaticCell::new();
|
||||||
|
|
||||||
|
/// Runtime configuration used by [`run_with_config`].
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub creds_dir: PathBuf,
|
pub creds_dir: PathBuf,
|
||||||
|
|
@ -246,41 +242,78 @@ fn valid_setup_passcode(passcode: u32) -> bool {
|
||||||
(1..=99_999_998).contains(&passcode) && !INVALID.contains(&passcode)
|
(1..=99_999_998).contains(&passcode) && !INVALID.contains(&passcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provision this device over BLE Matter commissioning and Wi-Fi Network Commissioning.
|
/// Run the combined rs-matter-stack runtime.
|
||||||
///
|
///
|
||||||
/// Returns immediately if a fabric is already stored in the configured state dir.
|
/// This runtime handles both first-boot BLE/Wi-Fi commissioning and normal
|
||||||
/// Otherwise advertises over BlueZ, receives Wi-Fi credentials, connects the Wi-Fi
|
/// operational Matter traffic. It runs until the process is stopped or an
|
||||||
/// interface via wpa_supplicant, persists Matter state, then returns.
|
/// unrecoverable transport error is returned.
|
||||||
|
pub async fn run() -> Result<()> {
|
||||||
|
run_with_config(Config::from_env()).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn run_with_config(config: Config) -> Result<()> {
|
||||||
|
run_stack(config).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Legacy entrypoint kept for callers that used the earlier split API.
|
||||||
|
///
|
||||||
|
/// With `rs-matter-stack`, provisioning and listening are one runtime, so this
|
||||||
|
/// does not return after commissioning; it continues serving Matter traffic.
|
||||||
pub async fn provision() -> Result<()> {
|
pub async fn provision() -> Result<()> {
|
||||||
provision_with_config(Config::from_env()).await
|
info!("Starting combined Matter provisioning/listening runtime");
|
||||||
|
run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn provision_with_config(config: Config) -> Result<()> {
|
pub async fn provision_with_config(config: Config) -> Result<()> {
|
||||||
std::fs::create_dir_all(&config.state_dir)?;
|
info!("Starting combined Matter provisioning/listening runtime");
|
||||||
|
run_with_config(config).await
|
||||||
let connection = Connection::system().await?;
|
|
||||||
let net_ctl = PersistingWifiCtl::new(
|
|
||||||
WpaSuppCtl::new(
|
|
||||||
&connection,
|
|
||||||
&config.wifi_iface,
|
|
||||||
DhClientCtl::new(&config.wifi_iface, true),
|
|
||||||
),
|
|
||||||
&config.wifi_iface,
|
|
||||||
);
|
|
||||||
|
|
||||||
run_provision(&connection, net_ctl, &config).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Listen forever for Matter commands on the provisioned Wi-Fi/IP network.
|
/// Listen forever for Matter commands, opening BLE commissioning when needed.
|
||||||
///
|
///
|
||||||
/// RGB commands are applied by invoking `rgbled --order <RGBLED_ORDER|grb> <rrggbb>`.
|
/// RGB commands are applied by invoking `rgbled --order <RGBLED_ORDER|grb> <rrggbb>`.
|
||||||
pub async fn listen() -> Result<()> {
|
pub async fn listen() -> Result<()> {
|
||||||
listen_with_config(Config::from_env()).await
|
run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn listen_with_config(config: Config) -> Result<()> {
|
pub async fn listen_with_config(config: Config) -> Result<()> {
|
||||||
|
run_with_config(config).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run_stack(config: Config) -> Result<()> {
|
||||||
std::fs::create_dir_all(&config.state_dir)?;
|
std::fs::create_dir_all(&config.state_dir)?;
|
||||||
|
|
||||||
|
let comm = load_comm_data(&config)?;
|
||||||
|
let stack = MATTER_STACK
|
||||||
|
.uninit()
|
||||||
|
.init_with(WifiMatterStack::init_default(
|
||||||
|
&TEST_DEV_DET,
|
||||||
|
comm,
|
||||||
|
&TEST_DEV_ATT,
|
||||||
|
));
|
||||||
|
|
||||||
|
let crypto = default_crypto(rand::thread_rng(), DAC_PRIVKEY);
|
||||||
|
let mut rand = crypto.weak_rand()?;
|
||||||
|
|
||||||
|
let rgb_light = RgbLight::new(Dataver::new_rand(&mut rand), config.rgbled_order.clone());
|
||||||
|
let on_off =
|
||||||
|
on_off::OnOffHandler::new(Dataver::new_rand(&mut rand), LIGHT_ENDPOINT_ID, &rgb_light);
|
||||||
|
let level = level_control::LevelControlHandler::new(
|
||||||
|
Dataver::new_rand(&mut rand),
|
||||||
|
LIGHT_ENDPOINT_ID,
|
||||||
|
&rgb_light,
|
||||||
|
level_control::AttributeDefaults::default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
on_off.init(Some(&level));
|
||||||
|
level.init(Some(&on_off));
|
||||||
|
|
||||||
|
let handler = rgb_handler(&mut rand, &rgb_light, &on_off, &level);
|
||||||
|
|
||||||
|
let mut kv = DirKvBlobStore::new(config.state_dir.clone());
|
||||||
|
stack.startup(&crypto, &mut kv).await?;
|
||||||
|
let kv = stack.create_shared_kv(kv)?;
|
||||||
|
|
||||||
let connection = Connection::system().await?;
|
let connection = Connection::system().await?;
|
||||||
let net_ctl = PersistingWifiCtl::new(
|
let net_ctl = PersistingWifiCtl::new(
|
||||||
WpaSuppCtl::new(
|
WpaSuppCtl::new(
|
||||||
|
|
@ -291,201 +324,27 @@ pub async fn listen_with_config(config: Config) -> Result<()> {
|
||||||
&config.wifi_iface,
|
&config.wifi_iface,
|
||||||
);
|
);
|
||||||
|
|
||||||
run_listen(net_ctl, &config).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run_provision<N>(connection: &Connection, net_ctl: N, config: &Config) -> Result<()>
|
|
||||||
where
|
|
||||||
N: NetCtl + WifiDiag + NetChangeNotif,
|
|
||||||
{
|
|
||||||
let comm = load_comm_data(config)?;
|
|
||||||
let mut matter = Matter::new_default(&TEST_DEV_DET, comm.clone(), &TEST_DEV_ATT, MATTER_PORT);
|
|
||||||
let mut networks = WifiNetworks::<3>::new();
|
|
||||||
let mut events: Events = Events::new_default();
|
|
||||||
let mut kv_buf = [0_u8; KV_BUF_SIZE];
|
|
||||||
let mut kv = DirKvBlobStore::new(config.state_dir.clone());
|
|
||||||
|
|
||||||
matter.load_persist(&mut kv, &mut kv_buf).await?;
|
|
||||||
networks.load_persist(&mut kv, &mut kv_buf).await?;
|
|
||||||
events.load_persist(&mut kv, &mut kv_buf).await?;
|
|
||||||
|
|
||||||
if matter.is_commissioned() {
|
|
||||||
info!("Matter fabric already exists; skipping BLE provisioning");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let networks = SharedNetworks::new(networks);
|
|
||||||
let buffers = PooledBuffers::<10, _>::new(0);
|
|
||||||
let subscriptions: Subscriptions = Subscriptions::new();
|
|
||||||
let crypto = default_crypto(rand::thread_rng(), DAC_PRIVKEY);
|
|
||||||
let mut rand = crypto.rand()?;
|
|
||||||
|
|
||||||
let rgb_light = RgbLight::new(Dataver::new_rand(&mut rand), config.rgbled_order.clone());
|
|
||||||
let on_off =
|
|
||||||
on_off::OnOffHandler::new(Dataver::new_rand(&mut rand), LIGHT_ENDPOINT_ID, &rgb_light);
|
|
||||||
let level = level_control::LevelControlHandler::new(
|
|
||||||
Dataver::new_rand(&mut rand),
|
|
||||||
LIGHT_ENDPOINT_ID,
|
|
||||||
&rgb_light,
|
|
||||||
level_control::AttributeDefaults::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
on_off.init(Some(&level));
|
|
||||||
level.init(Some(&on_off));
|
|
||||||
|
|
||||||
let net_ctl_state = NetCtlState::new_with_mutex();
|
|
||||||
let net_ctl = NetCtlWithStatusImpl::new(&net_ctl_state, net_ctl);
|
|
||||||
|
|
||||||
let handler = rgb_handler(&mut rand, &rgb_light, &on_off, &level);
|
|
||||||
let dm = DataModel::new(
|
|
||||||
&matter,
|
|
||||||
&crypto,
|
|
||||||
&buffers,
|
|
||||||
&subscriptions,
|
|
||||||
&events,
|
|
||||||
(
|
|
||||||
NODE,
|
|
||||||
endpoints::with_wifi_sys(&true, &(), &UnixNetifs, &net_ctl, &net_ctl, rand, handler),
|
|
||||||
),
|
|
||||||
SharedKvBlobStore::new(kv, kv_buf.as_mut_slice()),
|
|
||||||
&networks,
|
|
||||||
);
|
|
||||||
|
|
||||||
let responder = DefaultResponder::new(&dm);
|
|
||||||
let mut respond = pin!(responder.run::<4, 4>());
|
|
||||||
let mut dm_job = pin!(dm.run());
|
|
||||||
|
|
||||||
matter.print_standard_qr_text(DiscoveryCapabilities::BLE)?;
|
|
||||||
matter.print_standard_qr_code(QrTextType::Unicode, DiscoveryCapabilities::BLE)?;
|
|
||||||
dm.open_basic_comm_window(MAX_COMM_WINDOW_TIMEOUT_SECS)?;
|
|
||||||
|
|
||||||
let btp = Btp::new();
|
|
||||||
|
|
||||||
let udp = async_io::Async::<UdpSocket>::bind(MATTER_SOCKET_BIND_ADDR)?;
|
|
||||||
let mut mdns_responder = ZeroconfMdnsResponder::new();
|
|
||||||
let mut mdns = pin!(mdns_responder.run(&matter));
|
|
||||||
|
|
||||||
let adv_data = AdvData::new(&TEST_DEV_DET, comm.discriminator);
|
|
||||||
let mut bluetooth = pin!(bluez::run_peripheral(
|
|
||||||
connection,
|
|
||||||
None,
|
|
||||||
BLE_SERVICE_NAME,
|
|
||||||
&adv_data,
|
|
||||||
&btp,
|
|
||||||
));
|
|
||||||
let mut transport = pin!(matter.run(
|
|
||||||
&crypto,
|
|
||||||
ChainedNetwork::new(Address::is_udp, &udp, &btp),
|
|
||||||
ChainedNetwork::new(Address::is_udp, &udp, &btp),
|
|
||||||
&udp,
|
|
||||||
));
|
|
||||||
info!("Running Matter over concurrent BLE commissioning and IP transport");
|
|
||||||
|
|
||||||
let mut commissioning_done_task = pin!(async {
|
|
||||||
NetCtlState::wait_prov_ready(&net_ctl_state, &btp).await;
|
|
||||||
info!("Wi-Fi credentials accepted; waiting for Matter fabric setup");
|
|
||||||
|
|
||||||
while !matter.is_commissioned() {
|
|
||||||
embassy_time::Timer::after_secs(1).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Matter fabric added; keeping BLE/IP commissioning transports alive for {}s handoff",
|
"Matter Network Commissioning will manage Wi-Fi interface {}",
|
||||||
COMMISSIONING_HANDOFF_SECS
|
config.wifi_iface
|
||||||
);
|
);
|
||||||
embassy_time::Timer::after_secs(COMMISSIONING_HANDOFF_SECS).await;
|
info!("Running Matter via rs-matter-stack with BLE name {BLE_SERVICE_NAME}");
|
||||||
|
|
||||||
Ok(())
|
let matter = pin!(stack.run_coex(
|
||||||
});
|
PreexistingWireless::new(
|
||||||
|
StdNetStack::new(),
|
||||||
let mut matter_tasks = pin!(select4(
|
PreferredNetifs::new(&config.wifi_iface),
|
||||||
&mut transport,
|
net_ctl,
|
||||||
&mut bluetooth,
|
ZeroconfMdnsResponder::new(),
|
||||||
&mut mdns,
|
ToesBluezGattPeripheral::new(&connection, None),
|
||||||
select(&mut respond, &mut dm_job).coalesce(),
|
|
||||||
)
|
|
||||||
.coalesce());
|
|
||||||
|
|
||||||
select(&mut matter_tasks, &mut commissioning_done_task)
|
|
||||||
.coalesce()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
matter.reset_transport()?;
|
|
||||||
|
|
||||||
info!("Matter provisioning completed; call toes_matter::listen().await next");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run_listen<N>(net_ctl: N, config: &Config) -> Result<()>
|
|
||||||
where
|
|
||||||
N: NetCtl + WifiDiag + NetChangeNotif,
|
|
||||||
{
|
|
||||||
let comm = load_comm_data(config)?;
|
|
||||||
let mut matter = Matter::new_default(&TEST_DEV_DET, comm, &TEST_DEV_ATT, MATTER_PORT);
|
|
||||||
let mut networks = WifiNetworks::<3>::new();
|
|
||||||
let mut events: Events = Events::new_default();
|
|
||||||
let mut kv_buf = [0_u8; KV_BUF_SIZE];
|
|
||||||
let mut kv = DirKvBlobStore::new(config.state_dir.clone());
|
|
||||||
|
|
||||||
matter.load_persist(&mut kv, &mut kv_buf).await?;
|
|
||||||
networks.load_persist(&mut kv, &mut kv_buf).await?;
|
|
||||||
events.load_persist(&mut kv, &mut kv_buf).await?;
|
|
||||||
|
|
||||||
if !matter.is_commissioned() {
|
|
||||||
warn!("Matter state is not commissioned; run toes_matter::provision().await first");
|
|
||||||
return Err(ErrorCode::InvalidState.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
let networks = SharedNetworks::new(networks);
|
|
||||||
let buffers = PooledBuffers::<10, _>::new(0);
|
|
||||||
let subscriptions: Subscriptions = Subscriptions::new();
|
|
||||||
let crypto = default_crypto(rand::thread_rng(), DAC_PRIVKEY);
|
|
||||||
let mut rand = crypto.rand()?;
|
|
||||||
|
|
||||||
let rgb_light = RgbLight::new(Dataver::new_rand(&mut rand), config.rgbled_order.clone());
|
|
||||||
let on_off =
|
|
||||||
on_off::OnOffHandler::new(Dataver::new_rand(&mut rand), LIGHT_ENDPOINT_ID, &rgb_light);
|
|
||||||
let level = level_control::LevelControlHandler::new(
|
|
||||||
Dataver::new_rand(&mut rand),
|
|
||||||
LIGHT_ENDPOINT_ID,
|
|
||||||
&rgb_light,
|
|
||||||
level_control::AttributeDefaults::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
on_off.init(Some(&level));
|
|
||||||
level.init(Some(&on_off));
|
|
||||||
|
|
||||||
let net_ctl_state = NetCtlState::new_with_mutex();
|
|
||||||
let net_ctl = NetCtlWithStatusImpl::new(&net_ctl_state, net_ctl);
|
|
||||||
|
|
||||||
let handler = rgb_handler(&mut rand, &rgb_light, &on_off, &level);
|
|
||||||
let dm = DataModel::new(
|
|
||||||
&matter,
|
|
||||||
&crypto,
|
|
||||||
&buffers,
|
|
||||||
&subscriptions,
|
|
||||||
&events,
|
|
||||||
(
|
|
||||||
NODE,
|
|
||||||
endpoints::with_wifi_sys(&false, &(), &UnixNetifs, &net_ctl, &net_ctl, rand, handler),
|
|
||||||
),
|
),
|
||||||
SharedKvBlobStore::new(kv, kv_buf.as_mut_slice()),
|
&crypto,
|
||||||
&networks,
|
(NODE, handler),
|
||||||
);
|
&kv,
|
||||||
|
(),
|
||||||
|
));
|
||||||
|
|
||||||
let responder = DefaultResponder::new(&dm);
|
matter.await
|
||||||
let mut respond = pin!(responder.run::<4, 4>());
|
|
||||||
let mut dm_job = pin!(dm.run());
|
|
||||||
let mut mdns_responder = ZeroconfMdnsResponder::new();
|
|
||||||
let mut mdns = pin!(mdns_responder.run(&matter));
|
|
||||||
|
|
||||||
let udp = async_io::Async::<UdpSocket>::bind(MATTER_SOCKET_BIND_ADDR)?;
|
|
||||||
let mut transport = pin!(matter.run(&crypto, &udp, &udp, &udp));
|
|
||||||
|
|
||||||
select4(&mut transport, &mut mdns, &mut respond, &mut dm_job)
|
|
||||||
.coalesce()
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rgb_handler<'a, OH, LH>(
|
fn rgb_handler<'a, OH, LH>(
|
||||||
|
|
@ -517,6 +376,62 @@ where
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ToesBluezGattPeripheral<'a> {
|
||||||
|
connection: &'a Connection,
|
||||||
|
adapter_name: Option<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToesBluezGattPeripheral<'a> {
|
||||||
|
const fn new(connection: &'a Connection, adapter_name: Option<&'a str>) -> Self {
|
||||||
|
Self {
|
||||||
|
connection,
|
||||||
|
adapter_name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GattPeripheral for ToesBluezGattPeripheral<'_> {
|
||||||
|
async fn run(&mut self, btp: &Btp, _service_name: &str, service_adv: &AdvData) -> Result<()> {
|
||||||
|
rs_matter::transport::network::btp::bluez::run_peripheral(
|
||||||
|
self.connection,
|
||||||
|
self.adapter_name,
|
||||||
|
BLE_SERVICE_NAME,
|
||||||
|
service_adv,
|
||||||
|
btp,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PreferredNetifs<'a> {
|
||||||
|
ifname: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PreferredNetifs<'a> {
|
||||||
|
const fn new(ifname: &'a str) -> Self {
|
||||||
|
Self { ifname }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DynBase for PreferredNetifs<'_> {}
|
||||||
|
|
||||||
|
impl NetifDiag for PreferredNetifs<'_> {
|
||||||
|
fn netifs(&self, f: &mut dyn FnMut(&NetifInfo) -> Result<()>) -> Result<()> {
|
||||||
|
UnixNetifs.netifs(&mut |netif| {
|
||||||
|
if netif.name == self.ifname {
|
||||||
|
f(netif)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetChangeNotif for PreferredNetifs<'_> {
|
||||||
|
async fn wait_changed(&self) {
|
||||||
|
UnixNetifs.wait_changed().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct PersistingWifiCtl<'a, C> {
|
struct PersistingWifiCtl<'a, C> {
|
||||||
inner: C,
|
inner: C,
|
||||||
ifname: &'a str,
|
ifname: &'a str,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user