10 Commits

Author SHA1 Message Date
71bf244140 chore(deps): update rust crate jiff to v0.2.23
Some checks failed
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Continuous Integration / Rust Checks (map[args:--all -- --check command:fmt]) (pull_request) Has been cancelled
Continuous Integration / Rust Checks (map[args:--all-features --workspace -- -D warnings command:clippy]) (pull_request) Has been cancelled
Continuous Integration / Rust Checks (map[args:--release command:build]) (pull_request) Has been cancelled
2026-03-20 00:28:12 +00:00
a56b9c6af3 doc: add new schema
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-19 21:14:20 +01:00
437f1db1c1 feat: additional documentation
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-18 23:30:00 +01:00
5c73b3a6fc feat: revert big buffer to smaller buffers
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-18 23:10:37 +01:00
2acfe93a47 feat: reduce some buffers size 2026-03-18 23:05:11 +01:00
d72ac39e6f feat: increase some buffers size
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-18 22:59:57 +01:00
cb1556b655 Merge branch 'master' of https://gitea.communiquons.org/pierre/MatrixThermalPrinter
All checks were successful
continuous-integration/drone/push Build is passing
2026-03-18 22:50:05 +01:00
e4a5a84481 feat: add certificate check 2026-03-18 22:49:50 +01:00
62e7a51e39 Merge pull request 'Configure Renovate' (#1) from renovate/configure into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #1
2026-03-18 21:06:20 +00:00
7d3a669021 Add renovate.json
Some checks failed
Continuous Integration / Rust Checks (map[args:--all -- --check command:fmt]) (pull_request) Has been cancelled
Continuous Integration / Rust Checks (map[args:--all-features --workspace -- -D warnings command:clippy]) (pull_request) Has been cancelled
Continuous Integration / Rust Checks (map[args:--release command:build]) (pull_request) Has been cancelled
2026-01-22 00:28:02 +00:00
8 changed files with 457 additions and 23 deletions

2
.gitignore vendored
View File

@@ -24,3 +24,5 @@ target/
# Ignore .DS_Store file in mac
**/.DS_Store
*.bkp

265
Cargo.lock generated
View File

@@ -96,6 +96,12 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
[[package]]
name = "bitfield"
version = "0.19.4"
@@ -229,6 +235,32 @@ dependencies = [
"cipher",
]
[[package]]
name = "curve25519-dalek"
version = "4.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [
"cfg-if",
"cpufeatures",
"curve25519-dalek-derive",
"digest",
"fiat-crypto",
"rustc_version",
"subtle",
]
[[package]]
name = "curve25519-dalek-derive"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.114",
]
[[package]]
name = "darling"
version = "0.20.11"
@@ -436,6 +468,27 @@ dependencies = [
"signature",
]
[[package]]
name = "ed25519"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
dependencies = [
"signature",
]
[[package]]
name = "ed25519-dalek"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
dependencies = [
"curve25519-dalek",
"ed25519",
"sha2",
"subtle",
]
[[package]]
name = "edge-http"
version = "0.7.0"
@@ -808,13 +861,14 @@ dependencies = [
[[package]]
name = "embedded-tls"
version = "0.19.0"
source = "git+https://github.com/drogue-iot/embedded-tls?rev=3b9a0951a256ce84c5dc6f4827a0d05466ab5e63#3b9a0951a256ce84c5dc6f4827a0d05466ab5e63"
source = "git+https://github.com/drogue-iot/embedded-tls?rev=bd13e11ce9c7605baf7018ef2b0f353ae6693016#bd13e11ce9c7605baf7018ef2b0f353ae6693016"
dependencies = [
"aes-gcm",
"const-oid 0.10.2",
"der 0.8.0",
"digest",
"ecdsa",
"ed25519-dalek",
"embedded-io 0.7.1",
"embedded-io-async 0.7.0",
"generic-array 0.14.7",
@@ -822,9 +876,11 @@ dependencies = [
"heapless 0.9.2",
"hkdf",
"hmac",
"log",
"p256",
"portable-atomic",
"rand_core 0.6.4",
"rsa",
"sha2",
"signature",
"typenum",
@@ -874,7 +930,7 @@ dependencies = [
"encoding_rs",
"hashbrown",
"log",
"spin",
"spin 0.10.0",
]
[[package]]
@@ -1197,6 +1253,12 @@ dependencies = [
"subtle",
]
[[package]]
name = "fiat-crypto"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
[[package]]
name = "fnv"
version = "1.0.7"
@@ -1567,9 +1629,9 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "jiff"
version = "0.2.20"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c867c356cc096b33f4981825ab281ecba3db0acefe60329f044c1789d94c6543"
checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359"
dependencies = [
"jiff-static",
"log",
@@ -1580,9 +1642,9 @@ dependencies = [
[[package]]
name = "jiff-static"
version = "0.2.20"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7946b4325269738f270bb55b3c19ab5c5040525f83fd625259422a9d25d9be5"
checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4"
dependencies = [
"jiff-tzdb",
"proc-macro2",
@@ -1592,9 +1654,18 @@ dependencies = [
[[package]]
name = "jiff-tzdb"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2"
checksum = "c900ef84826f1338a557697dc8fc601df9ca9af4ac137c7fb61d4c6f2dfd3076"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
dependencies = [
"spin 0.9.8",
]
[[package]]
name = "libc"
@@ -1602,6 +1673,12 @@ version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
[[package]]
name = "libm"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "linked_list_allocator"
version = "0.10.5"
@@ -1678,8 +1755,10 @@ dependencies = [
"jiff",
"log",
"num-traits",
"pem",
"percent-encoding",
"rand",
"rand 0.9.2",
"rand_core 0.6.4",
"serde",
"serde_json",
"sntpc",
@@ -1711,12 +1790,48 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
[[package]]
name = "num-bigint-dig"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7"
dependencies = [
"lazy_static",
"libm",
"num-integer",
"num-iter",
"num-traits",
"rand 0.8.5",
"smallvec",
"zeroize",
]
[[package]]
name = "num-conv"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
@@ -1724,6 +1839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
]
[[package]]
@@ -1759,6 +1875,15 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pem"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
dependencies = [
"base64 0.22.1",
]
[[package]]
name = "percent-encoding"
version = "2.3.2"
@@ -1777,6 +1902,27 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
"der 0.7.10",
"pkcs8",
"spki",
]
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der 0.7.10",
"spki",
]
[[package]]
name = "polyval"
version = "0.6.2"
@@ -1819,6 +1965,15 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "primeorder"
version = "0.13.6"
@@ -1861,6 +2016,16 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46b71a9d9206e8b46714c74255adcaea8b11e0350c1d8456165073c3f75fc81a"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"rand_chacha",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.2"
@@ -1870,6 +2035,16 @@ dependencies = [
"rand_core 0.9.5",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core 0.6.4",
]
[[package]]
name = "rand_core"
version = "0.6.4"
@@ -1963,6 +2138,36 @@ dependencies = [
"svgbobdoc",
]
[[package]]
name = "rsa"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
dependencies = [
"const-oid 0.9.6",
"digest",
"num-bigint-dig",
"num-integer",
"num-traits",
"pkcs1",
"pkcs8",
"rand_core 0.6.4",
"sha2",
"signature",
"spki",
"subtle",
"zeroize",
]
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustversion"
version = "1.0.22"
@@ -2000,6 +2205,12 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e896488941756e5de3ee8449495464dbbf2201c85d2d1ace47d4fb81c74b99ec"
[[package]]
name = "semver"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "serde"
version = "1.0.228"
@@ -2136,6 +2347,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0f368519fc6c85fc1afdb769fb5a51123f6158013e143656e25a3485a0d401c"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "spin"
version = "0.10.0"
@@ -2145,6 +2362,16 @@ dependencies = [
"lock_api",
]
[[package]]
name = "spki"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der 0.7.10",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.1"
@@ -2504,6 +2731,26 @@ dependencies = [
"synstructure",
]
[[package]]
name = "zerocopy"
version = "0.8.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.114",
]
[[package]]
name = "zerofrom"
version = "0.1.6"

View File

@@ -43,7 +43,8 @@ sntpc-net-embassy = { version = "0.8.0", features = ["ipv6"] }
jiff = { version = "0.2.20", default-features = false, features = ["static"] }
# HTTP client handling dependencies
embedded-tls = { git = "https://github.com/drogue-iot/embedded-tls", rev = "3b9a0951a256ce84c5dc6f4827a0d05466ab5e63", default-features = false, features = ["rustpki", "alloc"] }
embedded-tls = { git = "https://github.com/drogue-iot/embedded-tls", rev = "bd13e11ce9c7605baf7018ef2b0f353ae6693016", default-features = false, features = ["rustpki", "alloc", "log", "rsa", "ed25519"] }
pem = {version = "3.0.6", default-features = false}
edge-nal-embassy = "0.8.1"
edge-nal = { version = "0.6.0", default-features = false }
edge-http = { version = "0.7.0", features = ["io"], default-features = false }
@@ -55,6 +56,7 @@ escpos = { git = "https://github.com/pierre42100/escpos-rs", rev = "7499c2653a10
critical-section = "1.2.0"
rand = { version = "0.9.2", default-features = false }
rand_core = "0.6.4"
static_cell = "2.1.1"
embedded-hal-bus = { version = "0.3.0", features = ["async"] }
embedded-io-async = "0.7.0"

View File

@@ -6,7 +6,13 @@ Print your incoming Matrix messages using a thermal printer
### Hardware requirement
#### ESP32
TODO
This project rely on a ESP32-s3. For the sake of simplicity I used the most powerful one available: [ESP32 N16R8](https://fr.aliexpress.com/item/1005007319706057.html)
The network is assured by a [W5500 chip](https://www.lextronic.fr/module-ethernet-w5500-sbcusres1-78053.html)
Schematics:
![](./docs/schematics_bb.png)
#### Thermal printer
You will need a Thermal printer that support the `Epson's ESC/POS` protocol.
@@ -43,3 +49,10 @@ cargo build --release
```bash
cargo run --release
```
### Project configuration roadmap
* Setup Matrix and wanted bridgets
* Setup MatrixGW and connect it to matrix
* Connect and configure your thermal printer
* Create an API token on MatrixGW for the printer
* Access http://ESP_IP/ (username: `admin` / password: `admin`) to configure the ESP

91
docs/architecture.drawio Normal file

File diff suppressed because one or more lines are too long

3
renovate.json Normal file
View File

@@ -0,0 +1,3 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}

View File

@@ -1,9 +1,12 @@
use crate::config::AppConfig;
use crate::time_client::TimeClient;
use alloc::vec;
use alloc::vec::Vec;
use core::cell::UnsafeCell;
use core::net::SocketAddr;
use edge_nal::io::{ErrorKind, ErrorType};
use embedded_tls::{Aes128GcmSha256, TlsConfig, TlsConnection};
use embedded_tls::{Aes128GcmSha256, CryptoRng, TlsClock, TlsConfig, TlsConnection};
use rand_core::{Error, RngCore};
struct MyMut(UnsafeCell<bool>, UnsafeCell<Vec<u8>>);
@@ -70,6 +73,56 @@ impl<'c> AutoTlsConnector<'c> {
}
}
struct Provider<'a> {
rng: PseudoRng,
verifier: embedded_tls::pki::CertVerifier<'a, Aes128GcmSha256, TimeClient, 4096>,
}
impl TlsClock for TimeClient {
fn now() -> Option<u64> {
Some(TimeClient::get().current_time_sec())
}
}
struct PseudoRng;
impl CryptoRng for PseudoRng {}
impl RngCore for PseudoRng {
fn next_u32(&mut self) -> u32 {
esp_hal::rng::Rng::new().next_u32()
}
fn next_u64(&mut self) -> u64 {
esp_hal::rng::Rng::new().next_u64()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
esp_hal::rng::Rng::new().fill_bytes(dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
esp_hal::rng::Rng::new().try_fill_bytes(dest)
}
}
impl embedded_tls::CryptoProvider for Provider<'_> {
type CipherSuite = Aes128GcmSha256;
type Signature = &'static [u8];
fn rng(&mut self) -> impl embedded_tls::CryptoRngCore {
&mut self.rng
}
fn verifier(
&mut self,
) -> Result<&mut impl embedded_tls::TlsVerifier<Self::CipherSuite>, embedded_tls::TlsError>
{
Ok(&mut self.verifier)
}
}
impl<'c> edge_nal::TcpConnect for AutoTlsConnector<'c> {
type Error = EdgeNalTlsError;
type Socket<'a>
@@ -89,7 +142,27 @@ impl<'c> edge_nal::TcpConnect for AutoTlsConnector<'c> {
let (rbuf, wbuf) = tls_buf.split_at_mut(tls_buf.len() / 2);
let mut tls = TlsConnection::new(socket, rbuf, wbuf);
// TODO : verify peer certificate
let root_ca = AppConfig::use_conf(|c| pem::parse(&c.safe.root_ca));
match root_ca {
Ok(pem) => {
log::info!("Checking certificate using root CA provided in config...");
tls.open(embedded_tls::TlsContext::new(
&config,
Provider {
rng: PseudoRng,
verifier: embedded_tls::pki::CertVerifier::new(
embedded_tls::Certificate::X509(pem.contents()),
),
},
))
.await?;
}
Err(e) => {
log::error!(
"Failed to parse TLS certificate: {e} will not check certificate, this is unsecure!!!"
);
tls.open(embedded_tls::TlsContext::new(
&config,
@@ -98,6 +171,8 @@ impl<'c> edge_nal::TcpConnect for AutoTlsConnector<'c> {
),
))
.await?;
}
}
Ok(AutoTlsSocket::Tls(tls))
}

View File

@@ -108,7 +108,7 @@ impl CompleteMessage<'_> {
// Message date
printer
.justify(JustifyMode::CENTER)?
.bold(true)?
.bold(false)?
.size(1, 1)?
.writeln(
&self
@@ -144,8 +144,9 @@ impl CompleteMessage<'_> {
}) = &self.room_info
{
printer
.bold(false)?
.justify(JustifyMode::CENTER)?
.size(2, 2)?
.size(1, 1)?
.writeln(&deunicode::deunicode(room_name))?
.reset_size()?;
}