Compare commits

...

8 commits

Author SHA1 Message Date
Vinzenz Schroeter 70cf6116cb build all variations in CI to keep track of what works
Some checks failed
Rust / build-gnu-apt (pull_request) Successful in 4m15s
Rust / build-musl-beta (pull_request) Failing after 51s
Rust / build-size-gnu-unstable (pull_request) Successful in 1m13s
Rust / build-size-musl-unstable (pull_request) Failing after 48s
2025-05-04 11:32:18 +02:00
Vinzenz Schroeter 388f3289b3 a bunch of options for the Makefile 2025-05-04 11:32:18 +02:00
Vinzenz Schroeter a1d40e3049 update to released servicepoint version 2025-05-04 11:32:18 +02:00
Vinzenz Schroeter 7859a61443 features, cargo fmt 2025-05-04 11:32:18 +02:00
Vinzenz Schroeter 1b007e59fb add functions to convert containers directly into packet 2025-05-04 11:32:18 +02:00
Vinzenz Schroeter 3f0075493d heap_remove, sp_brightness_grid_into_packet 2025-05-04 11:32:17 +02:00
Vinzenz Schroeter 709468c835 add command code constants, send header 2025-05-04 11:32:17 +02:00
Vinzenz Schroeter 372cb450f2 translate announce and brightness tester examples 2025-05-04 11:32:17 +02:00
20 changed files with 746 additions and 296 deletions

View file

@ -13,32 +13,77 @@ env:
RUSTFLAGS: "-Dwarnings" RUSTFLAGS: "-Dwarnings"
jobs: jobs:
build: build-gnu-apt:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Update repos - name: Update repos
run: sudo apt-get update -qq run: sudo apt-get update -qq
- name: Install rust toolchain - name: Install toolchain
run: sudo apt-get install -qy cargo rust-clippy run: sudo apt-get install -qy cargo rust-clippy liblzma-dev gcc make pkgconf
- name: install lzma
run: sudo apt-get install -qy liblzma-dev
- name: install gcc
run: sudo apt-get install -qy gcc make
- name: Run Clippy - name: Run Clippy
run: cargo clippy run: cargo clippy
- name: build
run: cargo build
- name: generate bindings - name: generate bindings
run: ./generate-binding.sh run: ./generate-binding.sh
- name: check that generated files did not change - name: check that generated files did not change
run: output=$(git status --porcelain) && [ -z "$output" ] run: output=$(git status --porcelain) && [ -z "$output" ]
- name: build - name: build example -- glibc release
run: cargo build run: cd example && make clean && make TARGET=aarch64-unknown-linux-gnu PROFILE=release
- name: build example -- glibc debug
run: cd example && make clean && make TARGET=aarch64-unknown-linux-gnu PROFILE=debug
- name: build example # this _should_ have been -stable, but there is a bug when running in the container ("Invalid cross-device link")
run: cd example && make build-musl-beta:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update repos
run: sudo apt-get update -qq
- name: Install toolchain
run: sudo apt-get install -qy liblzma-dev gcc make pkgconf musl-dev musl-tools rustup
- name: install rust target
run: rustup default beta && rustup target add aarch64-unknown-linux-musl && rustup component add rust-src && rustup update
- name: build example -- musl release
run: cd example && make clean && make TARGET=aarch64-unknown-linux-musl PROFILE=release MUSL=1 CARGO="rustup run beta cargo"
- name: build example -- musl debug
run: cd example && make clean && make TARGET=aarch64-unknown-linux-musl PROFILE=debug MUSL=1 CARGO="rustup run beta cargo"
build-size-gnu-unstable:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update repos
run: sudo apt-get update -qq
- name: Install toolchain
run: sudo apt-get install -qy liblzma-dev gcc make pkgconf rustup
- name: install rust targets
run: rustup toolchain install nightly -t aarch64-unknown-linux-gnu -c rust-src --no-self-update
- name: build example -- glibc size-optimized
run: cd example && make clean && make TARGET=aarch64-unknown-linux-gnu PROFILE=size-optimized CARGO="rustup run nightly cargo"
build-size-musl-unstable:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update repos
run: sudo apt-get update -qq
- name: Install toolchain
run: sudo apt-get install -qy liblzma-dev gcc make pkgconf musl-dev musl-tools rustup
- name: install rust targets
run: rustup toolchain install nightly -t aarch64-unknown-linux-musl -c rust-src --no-self-update
- name: build example -- musl size-optimized
run: cd example && make clean && make TARGET=aarch64-unknown-linux-musl PROFILE=size-optimized MUSL=1 LTO=1 CARGO="rustup run nightly cargo"

202
Cargo.lock generated
View file

@ -49,19 +49,20 @@ dependencies = [
[[package]] [[package]]
name = "anstyle-wincon" name = "anstyle-wincon"
version = "3.0.6" version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"once_cell",
"windows-sys", "windows-sys",
] ]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.7.0" version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]] [[package]]
name = "bitvec" name = "bitvec"
@ -77,22 +78,20 @@ dependencies = [
[[package]] [[package]]
name = "bzip2" name = "bzip2"
version = "0.5.0" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bafdbf26611df8c14810e268ddceda071c297570a5fb360ceddf617fe417ef58" checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47"
dependencies = [ dependencies = [
"bzip2-sys", "bzip2-sys",
"libc",
] ]
[[package]] [[package]]
name = "bzip2-sys" name = "bzip2-sys"
version = "0.1.11+1.0.8" version = "0.1.13+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"
dependencies = [ dependencies = [
"cc", "cc",
"libc",
"pkg-config", "pkg-config",
] ]
@ -117,9 +116,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.9" version = "1.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
dependencies = [ dependencies = [
"jobserver", "jobserver",
"libc", "libc",
@ -134,18 +133,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.26" version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
] ]
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.26" version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -176,15 +175,15 @@ dependencies = [
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.10" version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys", "windows-sys",
@ -198,9 +197,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.35" version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
@ -214,20 +213,21 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.15" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"r-efi",
"wasi", "wasi",
] ]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.15.2" version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
[[package]] [[package]]
name = "heck" name = "heck"
@ -237,9 +237,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.7.0" version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown",
@ -253,36 +253,37 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.14" version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.32" version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
dependencies = [ dependencies = [
"getrandom",
"libc", "libc",
] ]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.169" version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.15" version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.22" version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]] [[package]]
name = "memchr" name = "memchr"
@ -292,43 +293,49 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.2" version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
dependencies = [ dependencies = [
"adler2", "adler2",
] ]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.20.2" version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.31" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.93" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.38" version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]] [[package]]
name = "radium" name = "radium"
version = "0.7.0" version = "0.7.0"
@ -347,9 +354,9 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.43" version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"errno", "errno",
@ -360,24 +367,24 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.18" version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.217" version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.217" version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -386,9 +393,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.135" version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
@ -407,8 +414,9 @@ dependencies = [
[[package]] [[package]]
name = "servicepoint" name = "servicepoint"
version = "0.13.2" version = "0.14.0"
source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint/?branch=next#531d4e6b4a368dc126cab9dc12b64d2ca8a81694" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce70bae3641ccafdeb9832ac367efd51243e0708ef35151ad8c2c4ee578aa4a"
dependencies = [ dependencies = [
"bitvec", "bitvec",
"bzip2", "bzip2",
@ -442,9 +450,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.96" version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -459,11 +467,10 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.15.0" version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [ dependencies = [
"cfg-if",
"fastrand", "fastrand",
"getrandom", "getrandom",
"once_cell", "once_cell",
@ -473,18 +480,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.11" version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "2.0.11" version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -493,9 +500,9 @@ dependencies = [
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.8.19" version = "0.8.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
@ -505,31 +512,38 @@ dependencies = [
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.8" version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
dependencies = [ dependencies = [
"serde", "serde",
] ]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.22" version = "0.22.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"toml_write",
"winnow", "winnow",
] ]
[[package]] [[package]]
name = "unicode-ident" name = "toml_write"
version = "1.0.14" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]] [[package]]
name = "utf8parse" name = "utf8parse"
@ -545,9 +559,12 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
@ -624,13 +641,22 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.6.24" version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
[[package]] [[package]]
name = "wyz" name = "wyz"
version = "0.5.1" version = "0.5.1"
@ -642,27 +668,27 @@ dependencies = [
[[package]] [[package]]
name = "zstd" name = "zstd"
version = "0.13.2" version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
dependencies = [ dependencies = [
"zstd-safe", "zstd-safe",
] ]
[[package]] [[package]]
name = "zstd-safe" name = "zstd-safe"
version = "7.2.1" version = "7.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
dependencies = [ dependencies = [
"zstd-sys", "zstd-sys",
] ]
[[package]] [[package]]
name = "zstd-sys" name = "zstd-sys"
version = "2.0.13+zstd.1.5.6" version = "2.0.15+zstd.1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237"
dependencies = [ dependencies = [
"cc", "cc",
"pkg-config", "pkg-config",

View file

@ -19,20 +19,20 @@ cbindgen = "0.28.0"
[dependencies.servicepoint] [dependencies.servicepoint]
package = "servicepoint" package = "servicepoint"
version = "0.13.2" version = "0.14.0"
default-features = false default-features = false
features = ["protocol_udp"]
git = "https://git.berlin.ccc.de/servicepoint/servicepoint/"
branch = "next"
[features] [features]
full = ["servicepoint/all_compressions", "servicepoint/default"] all_compressions = ["servicepoint/all_compressions"]
default = ["full"] default = ["all_compressions", "servicepoint/default"]
[lints.rust] [lints.rust]
missing-docs = "warn" missing-docs = "warn"
unsafe_op_in_unsafe_fn = "warn" unsafe_op_in_unsafe_fn = "warn"
[lints.clippy]
missing_safety_doc = "allow"
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true

View file

@ -1,33 +1,42 @@
CC := gcc CARGO ?= cargo
CARGO := rustup run nightly cargo STRIP ?= strip
FEATURES := ""
THIS_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) THIS_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
REPO_ROOT := $(THIS_DIR)/.. REPO_ROOT := $(realpath $(THIS_DIR)/..)
RUST_TARGET_DIR := $(REPO_ROOT)/target/x86_64-unknown-linux-musl/size-optimized export SERVICEPOINT_HEADER_OUT := $(REPO_ROOT)/include
RUSTFLAGS := -Zlocation-detail=none \ override CFG_MUSL := $(if $(CFG_MUSL),$(CFG_MUSL),$(if $(MUSL),$(MUSL),0))
-Zfmt-debug=none \ override CFG_PROFILE := $(if $(CFG_PROFILE),$(CFG_PROFILE),$(if $(PROFILE),$(PROFILE),release))
-C linker=musl-gcc \
-C link-arg=-s \
-C link-arg=--gc-sections \
-C link-arg=-z,norelro \
-C link-arg=--hash-style=gnu \
--crate-type=staticlib \
-C panic=abort
CARGOFLAGS := --manifest-path=$(REPO_ROOT)/Cargo.toml \ CCFLAGS += -Wall -fwhole-program -fPIE -pie
--profile=size-optimized \
--no-default-features \
--target=x86_64-unknown-linux-musl \
-Zbuild-std="core,std,alloc,proc_macro,panic_abort" \
-Zbuild-std-features="panic_immediate_abort" \
CCFLAGS := -static -Os \ STRIPFLAGS := -s --strip-unneeded -R .comment -R .gnu.version -R .note -R .note.gnu.build-id -R .note.ABI-tag
-ffunction-sections -fdata-sections \
ifeq ($(CFG_MUSL), 1)
TARGET ?= x86_64-unknown-linux-musl
CC ?= musl-gcc
CCFLAGS += -static -lservicepoint_binding_c
RUSTFLAGS += --crate-type=staticlib -Ctarget-feature=-crt-static
else
TARGET ?= x86_64-unknown-linux-gnu
CC ?= gcc
#CCFLAGS += -shared
CCFLAGS += -Wl,-Bstatic -lservicepoint_binding_c -Wl,-Bdynamic
endif
#ifeq ($(CFG_PROFILE), size-optimized)
# CCFLAGS += -nodefaultlibs -lc
#endif
RUST_TARGET_DIR := $(REPO_ROOT)/target/$(TARGET)/$(CFG_PROFILE)
OUT_DIR := $(realpath $(THIS_DIR)/out/)
ifeq ($(CFG_PROFILE), size-optimized)
CARGO_PROFILE := size-optimized
CCFLAGS += -Oz \
-fwrapv -fomit-frame-pointer -fno-stack-protector\ -fwrapv -fomit-frame-pointer -fno-stack-protector\
-fwhole-program \
-nodefaultlibs -lservicepoint_binding_c -lc \
-Wl,--gc-sections \
-fno-unroll-loops \ -fno-unroll-loops \
-fno-unwind-tables -fno-asynchronous-unwind-tables \ -fno-unwind-tables -fno-asynchronous-unwind-tables \
-fmerge-all-constants \ -fmerge-all-constants \
@ -36,45 +45,85 @@ CCFLAGS := -static -Os \
-fvisibility=hidden \ -fvisibility=hidden \
-Bsymbolic \ -Bsymbolic \
-Wl,--exclude-libs,ALL \ -Wl,--exclude-libs,ALL \
-fno-ident -fno-ident \
#-fuse-ld=gold \
-fno-exceptions -fno-exceptions
#-Wl,--icf=all \ CARGOFLAGS += -Zbuild-std="core,std,alloc,proc_macro,panic_abort" \
-Zbuild-std-features="panic_immediate_abort"
RUSTFLAGS += -Zlocation-detail=none \
-Zfmt-debug=none \
-C link-arg=-z,norelro \
-C panic=abort
#-C link-arg=--hash-style=gnu
else ifeq ($(CFG_PROFILE), release)
CARGO_PROFILE := release
CCFLAGS += -O2
else ifeq ($(CFG_PROFILE), debug)
CCFLAGS += -Og
CARGO_PROFILE := dev
else
CFG_PROFILE := $(error "PROFILE has to be set to one of: debug, release, size-optimized")
endif
export SERVICEPOINT_HEADER_OUT := $(REPO_ROOT)/include CARGOFLAGS += --manifest-path=$(REPO_ROOT)/Cargo.toml \
--profile=$(CARGO_PROFILE) \
--no-default-features \
--features=$(FEATURES) \
--target=$(TARGET)
build: out/example ifneq ($(CFG_PROFILE), debug)
CCFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections
RUSTFLAGS += -C link-arg=-s -C link-arg=-Wl,--gc-sections
endif
clean: ifeq ($(LTO), 1)
rm -r out || true CCFLAGS += -flto
rm include/servicepoint.h || true endif
_c_src := $(wildcard ./src/*.c)
_programs := $(basename $(notdir $(_c_src)))
_bins := $(addprefix out/, $(_programs))
_unstripped_bins := $(addsuffix _unstripped, $(_bins))
_run_programs := $(addprefix run_, $(_programs))
_rs_src := $(wildcard ../src/**.rs) ../Cargo.lock ../Cargo.toml ../cbindgen.toml
_sp_artifacts := $(SERVICEPOINT_HEADER_OUT)/servicepoint.h $(RUST_TARGET_DIR)/libservicepoint_binding_c.a $(RUST_TARGET_DIR)/libservicepoint_binding_c.so
all: $(_bins)
clean: clean-c clean-rust
clean-c:
rm -r $(OUT_DIR) || true
clean-rust:
rm $(SERVICEPOINT_HEADER_OUT)/servicepoint.h || true
cargo clean cargo clean
run: out/example .PHONY: all clean sizes $(_run_programs) clean-c clean-rust
out/example
PHONY: build clean dependencies run $(_unstripped_bins): out/%_unstripped: src/%.c $(SERVICEPOINT_HEADER_OUT)/servicepoint.h $(_sp_artifacts)
out/example_unstripped: dependencies main.c
mkdir -p out || true mkdir -p out || true
${CC} main.c \ ${CC} $< \
-I $(SERVICEPOINT_HEADER_OUT) \ -I $(SERVICEPOINT_HEADER_OUT) \
-L $(RUST_TARGET_DIR) \ -L $(RUST_TARGET_DIR) \
$(CCFLAGS) \ $(CCFLAGS) \
-o out/example_unstripped -o $@
out/example: out/example_unstripped
strip -s --strip-unneeded \
-R .comment -R .gnu.version -R .comment -R .note -R .note.gnu.build-id -R .note.ABI-tag \
out/example_unstripped \
-o out/example
dependencies: FORCE $(_bins): out/%: out/%_unstripped
mkdir -p include || true $(STRIP) $(STRIPFLAGS) $^ -o $@
# generate servicepoint header and binary to link against
$(_sp_artifacts): $(_rs_src)
mkdir -p $(SERVICEPOINT_HEADER_OUT) || true
# generate servicepoint header and library to link against
${CARGO} rustc $(CARGOFLAGS) -- $(RUSTFLAGS) ${CARGO} rustc $(CARGOFLAGS) -- $(RUSTFLAGS)
analyze-size: out/example_unstripped $(_run_programs): run_%: out/% FORCE
nm --print-size --size-sort --reverse-sort --radix=d --demangle out/example_unstripped \ ./$<
sizes: $(_bins)
ls -lB out
analyze-size: out/$(BIN)_unstripped
nm --print-size --size-sort --reverse-sort --radix=d --demangle $(OUT_DIR)/$(BIN)_unstripped \
| awk '{size=$$2+0; print size "\t" $$4}' \ | awk '{size=$$2+0; print size "\t" $$4}' \
| less | less

View file

@ -1,28 +0,0 @@
#include <stdio.h>
#include "servicepoint.h"
int main(void) {
UdpConnection *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
if (connection == NULL)
return 1;
Bitmap *pixels = sp_bitmap_new(PIXEL_WIDTH, PIXEL_HEIGHT);
if (pixels == NULL)
return 1;
sp_bitmap_fill(pixels, true);
TypedCommand *command = sp_command_bitmap(0, 0, pixels, COMPRESSION_CODE_UNCOMPRESSED);
if (command == NULL)
return 1;
Packet *packet = sp_packet_from_command(command);
Header *header = sp_packet_get_header(packet);
//printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d);
sp_udp_send_packet(connection, packet);
sp_udp_free(connection);
return 0;
}

37
example/src/announce.c Normal file
View file

@ -0,0 +1,37 @@
#include <stdio.h>
#include "servicepoint.h"
int main(void) {
printf("test\n");
UdpSocket *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
//UdpSocket *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
if (connection == NULL)
return 1;
sp_udp_send_header(connection, (Header) {.command_code = COMMAND_CODE_CLEAR});
CharGrid *grid = sp_char_grid_new(5, 2);
if (grid == NULL)
return 1;
sp_char_grid_set(grid, 0, 0, 'H');
sp_char_grid_set(grid, 1, 0, 'e');
sp_char_grid_set(grid, 2, 0, 'l');
sp_char_grid_set(grid, 3, 0, 'l');
sp_char_grid_set(grid, 4, 0, 'o');
sp_char_grid_set(grid, 0, 1, 'W');
sp_char_grid_set(grid, 1, 1, 'o');
sp_char_grid_set(grid, 2, 1, 'r');
sp_char_grid_set(grid, 3, 1, 'l');
sp_char_grid_set(grid, 4, 1, 'd');
Packet *packet = sp_char_grid_into_packet(grid, 0, 0);
if (packet == NULL)
return 1;
sp_udp_send_packet(connection, packet);
sp_udp_free(connection);
return 0;
}

View file

@ -0,0 +1,30 @@
#include "servicepoint.h"
int main(void) {
UdpSocket *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
//UdpSocket *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
if (connection == NULL)
return -1;
Bitmap *all_on = sp_bitmap_new_max_sized();
sp_bitmap_fill(all_on, true);
Packet *packet = sp_bitmap_into_packet(all_on, 0, 0, COMPRESSION_CODE_UNCOMPRESSED);
if (packet == NULL)
return -1;
sp_udp_send_packet(connection, packet);
BrightnessGrid *grid = sp_brightness_grid_new(TILE_WIDTH, TILE_HEIGHT);
ByteSlice slice = sp_brightness_grid_unsafe_data_ref(grid);
for (size_t index = 0; index < slice.length; index++) {
slice.start[index] = (uint8_t) (index % ((size_t) Brightness_MAX));
}
packet = sp_brightness_grid_into_packet(grid, 0, 0);
sp_udp_send_packet(connection, packet);
sp_udp_free(connection);
return 0;
}

View file

@ -0,0 +1,25 @@
#include "servicepoint.h"
int main(void) {
UdpSocket *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
if (connection == NULL)
return 1;
Bitmap *pixels = sp_bitmap_new(PIXEL_WIDTH, PIXEL_HEIGHT);
if (pixels == NULL)
return 1;
sp_bitmap_fill(pixels, true);
Packet *packet = sp_bitmap_into_packet(pixels, 0, 0, COMPRESSION_CODE_UNCOMPRESSED);
if (packet == NULL)
return 1;
Header *header = sp_packet_get_header(packet);
// printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d);
sp_udp_send_packet(connection, packet);
sp_udp_free(connection);
return 0;
}

View file

@ -36,10 +36,11 @@
buildInputs = with pkgs; [ buildInputs = with pkgs; [
xe xe
xz xz
libgcc #libgcc
#glibc.static #glibc
musl pkgsStatic.musl
libunwind # libunwind
]; ];
nativeBuildInputs = with pkgs; [ nativeBuildInputs = with pkgs; [
@ -57,12 +58,14 @@
]; ];
}) })
gcc gcc
gdb
pkgsStatic.gcc
gnumake gnumake
pkg-config pkg-config
]; ];
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; #RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
CARGO = "rustup run nightly cargo";
}; };
} }
); );

View file

@ -95,6 +95,36 @@ enum BinaryOperation
typedef uint8_t BinaryOperation; typedef uint8_t BinaryOperation;
#endif // __cplusplus #endif // __cplusplus
/**
* The u16 command codes used for the [Command]s.
*/
enum CommandCode
#ifdef __cplusplus
: uint16_t
#endif // __cplusplus
{
COMMAND_CODE_CLEAR = 2,
COMMAND_CODE_CP437_DATA = 3,
COMMAND_CODE_CHAR_BRIGHTNESS = 5,
COMMAND_CODE_BRIGHTNESS = 7,
COMMAND_CODE_HARD_RESET = 11,
COMMAND_CODE_FADE_OUT = 13,
COMMAND_CODE_BITMAP_LEGACY = 16,
COMMAND_CODE_BITMAP_LINEAR = 18,
COMMAND_CODE_BITMAP_LINEAR_WIN_UNCOMPRESSED = 19,
COMMAND_CODE_BITMAP_LINEAR_AND = 20,
COMMAND_CODE_BITMAP_LINEAR_OR = 21,
COMMAND_CODE_BITMAP_LINEAR_XOR = 22,
COMMAND_CODE_BITMAP_LINEAR_WIN_ZLIB = 23,
COMMAND_CODE_BITMAP_LINEAR_WIN_BZIP2 = 24,
COMMAND_CODE_BITMAP_LINEAR_WIN_LZMA = 25,
COMMAND_CODE_UTF8_DATA = 32,
COMMAND_CODE_BITMAP_LINEAR_WIN_ZSTD = 26,
};
#ifndef __cplusplus
typedef uint16_t CommandCode;
#endif // __cplusplus
/** /**
* Specifies the kind of compression to use. Availability depends on features. * Specifies the kind of compression to use. Availability depends on features.
* *
@ -196,13 +226,9 @@ typedef struct SPBitVec SPBitVec;
typedef struct TypedCommand TypedCommand; typedef struct TypedCommand TypedCommand;
/** /**
* A connection using the UDP protocol. * This is a type only used by cbindgen to have a type for pointers.
*
* Use this when sending commands directly to the display.
*
* Requires the feature "`protocol_udp`" which is enabled by default.
*/ */
typedef struct UdpConnection UdpConnection; typedef struct UdpSocket UdpSocket;
/** /**
* A 2D grid of values. * A 2D grid of values.
@ -268,7 +294,7 @@ typedef struct {
* grid.set(1, 1, Brightness::MIN); * grid.set(1, 1, Brightness::MIN);
* *
* # let connection = FakeConnection; * # let connection = FakeConnection;
* connection.send(BrightnessGridCommand { * connection.send_command(BrightnessGridCommand {
* origin: Origin::new(3, 7), * origin: Origin::new(3, 7),
* grid * grid
* }).unwrap() * }).unwrap()
@ -288,7 +314,7 @@ typedef ValueGrid_Brightness BrightnessGrid;
* *
* let b = Brightness::try_from(7).unwrap(); * let b = Brightness::try_from(7).unwrap();
* # let connection = FakeConnection; * # let connection = FakeConnection;
* let result = connection.send(GlobalBrightnessCommand::from(b)); * let result = connection.send_command(GlobalBrightnessCommand::from(b));
* ``` * ```
*/ */
typedef uint8_t Brightness; typedef uint8_t Brightness;
@ -317,7 +343,7 @@ typedef uint8_t Brightness;
* *
* # let connection = FakeConnection; * # let connection = FakeConnection;
* let command = CharGridCommand { origin: Origin::ZERO, grid }; * let command = CharGridCommand { origin: Origin::ZERO, grid };
* connection.send(command).unwrap() * connection.send_command(command).unwrap()
* ``` * ```
*/ */
typedef ValueGrid_char CharGrid; typedef ValueGrid_char CharGrid;
@ -425,6 +451,18 @@ size_t sp_bitmap_height(Bitmap */*notnull*/ bitmap);
*/ */
SPBitVec */*notnull*/ sp_bitmap_into_bitvec(Bitmap */*notnull*/ bitmap); SPBitVec */*notnull*/ sp_bitmap_into_bitvec(Bitmap */*notnull*/ bitmap);
/**
* Creates a [BitmapCommand] and immediately turns that into a [Packet].
*
* The provided [Bitmap] gets consumed.
*
* Returns NULL in case of an error.
*/
Packet *sp_bitmap_into_packet(Bitmap */*notnull*/ bitmap,
size_t x,
size_t y,
CompressionCode compression);
/** /**
* Loads a [Bitmap] with the specified dimensions from the provided data. * Loads a [Bitmap] with the specified dimensions from the provided data.
* *
@ -550,6 +588,18 @@ void sp_bitvec_free(SPBitVec */*notnull*/ bit_vec);
*/ */
bool sp_bitvec_get(SPBitVec */*notnull*/ bit_vec, size_t index); bool sp_bitvec_get(SPBitVec */*notnull*/ bit_vec, size_t index);
/**
* Creates a [BitVecCommand] and immediately turns that into a [Packet].
*
* The provided [SPBitVec] gets consumed.
*
* Returns NULL in case of an error.
*/
Packet *sp_bitvec_into_packet(SPBitVec */*notnull*/ bitvec,
size_t offset,
BinaryOperation operation,
CompressionCode compression);
/** /**
* Returns true if length is 0. * Returns true if length is 0.
* *
@ -665,9 +715,22 @@ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ brightness_grid,
*/ */
size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ brightness_grid); size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ brightness_grid);
/**
* Creates a [BrightnessGridCommand] and immediately turns that into a [Packet].
*
* The provided [BrightnessGrid] gets consumed.
*
* Returns NULL in case of an error.
*/
Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid,
size_t x,
size_t y);
/** /**
* Loads a [BrightnessGrid] with the specified dimensions from the provided data. * Loads a [BrightnessGrid] with the specified dimensions from the provided data.
* *
* Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN].
*
* returns: new [BrightnessGrid] instance, or NULL in case of an error. * returns: new [BrightnessGrid] instance, or NULL in case of an error.
*/ */
BrightnessGrid *sp_brightness_grid_load(size_t width, BrightnessGrid *sp_brightness_grid_load(size_t width,
@ -681,7 +744,7 @@ BrightnessGrid *sp_brightness_grid_load(size_t width,
* *
* # Examples * # Examples
* ```C * ```C
* UdpConnection connection = sp_connection_open("127.0.0.1:2342"); * UdpConnection connection = sp_udp_open("127.0.0.1:2342");
* if (connection == NULL) * if (connection == NULL)
* return 1; * return 1;
* *
@ -690,7 +753,7 @@ BrightnessGrid *sp_brightness_grid_load(size_t width,
* sp_brightness_grid_set(grid, 1, 1, 10); * sp_brightness_grid_set(grid, 1, 1, 10);
* *
* TypedCommand command = sp_command_char_brightness(grid); * TypedCommand command = sp_command_char_brightness(grid);
* sp_connection_free(connection); * sp_udp_free(connection);
* ``` * ```
*/ */
BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height);
@ -782,6 +845,17 @@ uint32_t sp_char_grid_get(CharGrid */*notnull*/ char_grid, size_t x, size_t y);
*/ */
size_t sp_char_grid_height(CharGrid */*notnull*/ char_grid); size_t sp_char_grid_height(CharGrid */*notnull*/ char_grid);
/**
* Creates a [CharGridCommand] and immediately turns that into a [Packet].
*
* The provided [CharGrid] gets consumed.
*
* Returns NULL in case of an error.
*/
Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid,
size_t x,
size_t y);
/** /**
* Loads a [CharGrid] with the specified dimensions from the provided data. * Loads a [CharGrid] with the specified dimensions from the provided data.
* *
@ -897,7 +971,7 @@ TypedCommand */*notnull*/ sp_command_char_grid(size_t x,
* # Examples * # Examples
* *
* ```C * ```C
* sp_connection_send_command(connection, sp_command_clear()); * sp_udp_send_command(connection, sp_command_clear());
* ``` * ```
*/ */
TypedCommand */*notnull*/ sp_command_clear(void); TypedCommand */*notnull*/ sp_command_clear(void);
@ -1009,6 +1083,17 @@ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ cp437_grid,
*/ */
size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ cp437_grid); size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ cp437_grid);
/**
* Creates a [Cp437GridCommand] and immediately turns that into a [Packet].
*
* The provided [Cp437Grid] gets consumed.
*
* Returns NULL in case of an error.
*/
Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid,
size_t x,
size_t y);
/** /**
* Loads a [Cp437Grid] with the specified dimensions from the provided data. * Loads a [Cp437Grid] with the specified dimensions from the provided data.
*/ */
@ -1120,10 +1205,18 @@ void sp_packet_set_payload(Packet */*notnull*/ packet, ByteSlice data);
*/ */
Packet *sp_packet_try_load(ByteSlice data); Packet *sp_packet_try_load(ByteSlice data);
/**
* Converts u16 into [CommandCode].
*
* If the provided value is not valid, false is returned and result is not changed.
*/
bool sp_u16_to_command_code(uint16_t code,
CommandCode *result);
/** /**
* Closes and deallocates a [UdpConnection]. * Closes and deallocates a [UdpConnection].
*/ */
void sp_udp_free(UdpConnection */*notnull*/ connection); void sp_udp_free(UdpSocket */*notnull*/ connection);
/** /**
* Creates a new instance of [UdpConnection]. * Creates a new instance of [UdpConnection].
@ -1133,12 +1226,12 @@ void sp_udp_free(UdpConnection */*notnull*/ connection);
* # Examples * # Examples
* *
* ```C * ```C
* UdpConnection connection = sp_connection_open("172.23.42.29:2342"); * UdpConnection connection = sp_udp_open("172.23.42.29:2342");
* if (connection != NULL) * if (connection != NULL)
* sp_connection_send_command(connection, sp_command_clear()); * sp_udp_send_command(connection, sp_command_clear());
* ``` * ```
*/ */
UdpConnection *sp_udp_open(char */*notnull*/ host); UdpSocket *sp_udp_open(char */*notnull*/ host);
/** /**
* Creates a new instance of [UdpConnection]. * Creates a new instance of [UdpConnection].
@ -1148,12 +1241,12 @@ UdpConnection *sp_udp_open(char */*notnull*/ host);
* # Examples * # Examples
* *
* ```C * ```C
* UdpConnection connection = sp_connection_open_ipv4(172, 23, 42, 29, 2342); * UdpConnection connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
* if (connection != NULL) * if (connection != NULL)
* sp_connection_send_command(connection, sp_command_clear()); * sp_udp_send_command(connection, sp_command_clear());
* ``` * ```
*/ */
UdpConnection *sp_udp_open_ipv4(uint8_t ip1, UdpSocket *sp_udp_open_ipv4(uint8_t ip1,
uint8_t ip2, uint8_t ip2,
uint8_t ip3, uint8_t ip3,
uint8_t ip4, uint8_t ip4,
@ -1169,13 +1262,25 @@ UdpConnection *sp_udp_open_ipv4(uint8_t ip1,
* # Examples * # Examples
* *
* ```C * ```C
* sp_connection_send_command(connection, sp_command_clear()); * sp_udp_send_command(connection, sp_command_brightness(5));
* sp_connection_send_command(connection, sp_command_brightness(5));
* ``` * ```
*/ */
bool sp_udp_send_command(UdpConnection */*notnull*/ connection, bool sp_udp_send_command(UdpSocket */*notnull*/ connection,
TypedCommand */*notnull*/ command); TypedCommand */*notnull*/ command);
/**
* Sends a [Header] to the display using the [UdpConnection].
*
* returns: true in case of success
*
* # Examples
*
* ```C
* sp_udp_send_header(connection, sp_command_brightness(5));
* ```
*/
bool sp_udp_send_header(UdpSocket */*notnull*/ udp_connection, Header header);
/** /**
* Sends a [Packet] to the display using the [UdpConnection]. * Sends a [Packet] to the display using the [UdpConnection].
* *
@ -1183,7 +1288,7 @@ bool sp_udp_send_command(UdpConnection */*notnull*/ connection,
* *
* returns: true in case of success * returns: true in case of success
*/ */
bool sp_udp_send_packet(UdpConnection */*notnull*/ connection, bool sp_udp_send_packet(UdpSocket */*notnull*/ connection,
Packet */*notnull*/ packet); Packet */*notnull*/ packet);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -1,6 +1,8 @@
use crate::byte_slice::ByteSlice; use crate::byte_slice::ByteSlice;
use crate::{heap_drop, heap_move, heap_move_nonnull, SPBitVec}; use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, SPBitVec};
use servicepoint::{Bitmap, DataRef, Grid}; use servicepoint::{
Bitmap, BitmapCommand, CompressionCode, DataRef, Grid, Origin, Packet,
};
use std::ptr::NonNull; use std::ptr::NonNull;
/// Creates a new [Bitmap] with the specified dimensions. /// Creates a new [Bitmap] with the specified dimensions.
@ -78,7 +80,7 @@ pub unsafe extern "C" fn sp_bitmap_from_bitvec(
width: usize, width: usize,
bitvec: NonNull<SPBitVec>, bitvec: NonNull<SPBitVec>,
) -> *mut Bitmap { ) -> *mut Bitmap {
let bitvec = unsafe { *Box::from_raw(bitvec.as_ptr()) }; let bitvec = unsafe { heap_remove(bitvec) };
if let Ok(bitmap) = Bitmap::from_bitvec(width, bitvec.0) { if let Ok(bitmap) = Bitmap::from_bitvec(width, bitvec.0) {
heap_move(bitmap) heap_move(bitmap)
} else { } else {
@ -196,6 +198,29 @@ pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref(
pub unsafe extern "C" fn sp_bitmap_into_bitvec( pub unsafe extern "C" fn sp_bitmap_into_bitvec(
bitmap: NonNull<Bitmap>, bitmap: NonNull<Bitmap>,
) -> NonNull<SPBitVec> { ) -> NonNull<SPBitVec> {
let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) }; let bitmap = unsafe { heap_remove(bitmap) };
heap_move_nonnull(SPBitVec(bitmap.into())) heap_move_nonnull(SPBitVec(bitmap.into()))
} }
/// Creates a [BitmapCommand] and immediately turns that into a [Packet].
///
/// The provided [Bitmap] gets consumed.
///
/// Returns NULL in case of an error.
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_into_packet(
bitmap: NonNull<Bitmap>,
x: usize,
y: usize,
compression: CompressionCode,
) -> *mut Packet {
let bitmap = unsafe { heap_remove(bitmap) };
match Packet::try_from(BitmapCommand {
bitmap,
origin: Origin::new(x, y),
compression,
}) {
Ok(packet) => heap_move(packet),
Err(_) => std::ptr::null_mut(),
}
}

View file

@ -1,5 +1,5 @@
use crate::{heap_drop, heap_move_nonnull, ByteSlice}; use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
use servicepoint::BitVecU8Msb0; use servicepoint::{BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Packet};
use std::ptr::NonNull; use std::ptr::NonNull;
/// A vector of bits /// A vector of bits
@ -10,7 +10,7 @@ use std::ptr::NonNull;
/// sp_bitvec_set(vec, 5, true); /// sp_bitvec_set(vec, 5, true);
/// sp_bitvec_free(vec); /// sp_bitvec_free(vec);
/// ``` /// ```
pub struct SPBitVec(pub(crate) BitVecU8Msb0); pub struct SPBitVec(pub(crate) DisplayBitVec);
impl Clone for SPBitVec { impl Clone for SPBitVec {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -31,7 +31,7 @@ impl Clone for SPBitVec {
/// - when `size` is not divisible by 8. /// - when `size` is not divisible by 8.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull<SPBitVec> { pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull<SPBitVec> {
heap_move_nonnull(SPBitVec(BitVecU8Msb0::repeat(false, size))) heap_move_nonnull(SPBitVec(DisplayBitVec::repeat(false, size)))
} }
/// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance.
@ -40,7 +40,7 @@ pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull<SPBitVec> {
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_bitvec_load(data: ByteSlice) -> NonNull<SPBitVec> { pub unsafe extern "C" fn sp_bitvec_load(data: ByteSlice) -> NonNull<SPBitVec> {
let data = unsafe { data.as_slice() }; let data = unsafe { data.as_slice() };
heap_move_nonnull(SPBitVec(BitVecU8Msb0::from_slice(data))) heap_move_nonnull(SPBitVec(DisplayBitVec::from_slice(data)))
} }
/// Clones a [SPBitVec]. /// Clones a [SPBitVec].
@ -146,3 +146,27 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref(
) -> ByteSlice { ) -> ByteSlice {
unsafe { ByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) } unsafe { ByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) }
} }
/// Creates a [BitVecCommand] and immediately turns that into a [Packet].
///
/// The provided [SPBitVec] gets consumed.
///
/// Returns NULL in case of an error.
#[no_mangle]
pub unsafe extern "C" fn sp_bitvec_into_packet(
bitvec: NonNull<SPBitVec>,
offset: usize,
operation: BinaryOperation,
compression: CompressionCode,
) -> *mut Packet {
let bitvec = unsafe { heap_remove(bitvec) }.0;
match Packet::try_from(BitVecCommand {
bitvec,
offset,
operation,
compression,
}) {
Ok(packet) => heap_move(packet),
Err(_) => std::ptr::null_mut(),
}
}

View file

@ -1,5 +1,8 @@
use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
use servicepoint::{Brightness, BrightnessGrid, ByteGrid, DataRef, Grid}; use servicepoint::{
Brightness, BrightnessGrid, BrightnessGridCommand, ByteGrid, DataRef, Grid,
Origin, Packet,
};
use std::mem::transmute; use std::mem::transmute;
use std::ptr::NonNull; use std::ptr::NonNull;
@ -9,7 +12,7 @@ use std::ptr::NonNull;
/// ///
/// # Examples /// # Examples
/// ```C /// ```C
/// UdpConnection connection = sp_connection_open("127.0.0.1:2342"); /// UdpConnection connection = sp_udp_open("127.0.0.1:2342");
/// if (connection == NULL) /// if (connection == NULL)
/// return 1; /// return 1;
/// ///
@ -18,7 +21,7 @@ use std::ptr::NonNull;
/// sp_brightness_grid_set(grid, 1, 1, 10); /// sp_brightness_grid_set(grid, 1, 1, 10);
/// ///
/// TypedCommand command = sp_command_char_brightness(grid); /// TypedCommand command = sp_command_char_brightness(grid);
/// sp_connection_free(connection); /// sp_udp_free(connection);
/// ``` /// ```
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_new( pub unsafe extern "C" fn sp_brightness_grid_new(
@ -167,5 +170,28 @@ pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref(
const _: () = assert!(size_of::<Brightness>() == 1); const _: () = assert!(size_of::<Brightness>() == 1);
let data = unsafe { (*brightness_grid.as_ptr()).data_ref_mut() }; let data = unsafe { (*brightness_grid.as_ptr()).data_ref_mut() };
unsafe { ByteSlice::from_slice(transmute(data)) } unsafe {
ByteSlice::from_slice(transmute::<&mut [Brightness], &mut [u8]>(data))
}
}
/// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet].
///
/// The provided [BrightnessGrid] gets consumed.
///
/// Returns NULL in case of an error.
#[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_into_packet(
grid: NonNull<BrightnessGrid>,
x: usize,
y: usize,
) -> *mut Packet {
let grid = unsafe { heap_remove(grid) };
match Packet::try_from(BrightnessGridCommand {
grid,
origin: Origin::new(x, y),
}) {
Ok(packet) => heap_move(packet),
Err(_) => std::ptr::null_mut(),
}
} }

View file

@ -24,7 +24,7 @@ impl ByteSlice {
unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) } unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) }
} }
pub(crate) unsafe fn as_slice_mut(&self) -> &mut [u8] { pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe { unsafe {
std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length) std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length)
} }

View file

@ -1,5 +1,5 @@
use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
use servicepoint::{CharGrid, Grid}; use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet};
use std::ptr::NonNull; use std::ptr::NonNull;
/// Creates a new [CharGrid] with the specified dimensions. /// Creates a new [CharGrid] with the specified dimensions.
@ -132,3 +132,24 @@ pub unsafe extern "C" fn sp_char_grid_height(
) -> usize { ) -> usize {
unsafe { char_grid.as_ref().height() } unsafe { char_grid.as_ref().height() }
} }
/// Creates a [CharGridCommand] and immediately turns that into a [Packet].
///
/// The provided [CharGrid] gets consumed.
///
/// Returns NULL in case of an error.
#[no_mangle]
pub unsafe extern "C" fn sp_char_grid_into_packet(
grid: NonNull<CharGrid>,
x: usize,
y: usize,
) -> *mut Packet {
let grid = unsafe { heap_remove(grid) };
match Packet::try_from(CharGridCommand {
grid,
origin: Origin::new(x, y),
}) {
Ok(packet) => heap_move(packet),
Err(_) => std::ptr::null_mut(),
}
}

View file

@ -1,5 +1,7 @@
use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
use servicepoint::{Cp437Grid, DataRef, Grid}; use servicepoint::{
Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet,
};
use std::ptr::NonNull; use std::ptr::NonNull;
/// Creates a new [Cp437Grid] with the specified dimensions. /// Creates a new [Cp437Grid] with the specified dimensions.
@ -132,3 +134,24 @@ pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref(
) -> ByteSlice { ) -> ByteSlice {
unsafe { ByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) } unsafe { ByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) }
} }
/// Creates a [Cp437GridCommand] and immediately turns that into a [Packet].
///
/// The provided [Cp437Grid] gets consumed.
///
/// Returns NULL in case of an error.
#[no_mangle]
pub unsafe extern "C" fn sp_cp437_grid_into_packet(
grid: NonNull<Cp437Grid>,
x: usize,
y: usize,
) -> *mut Packet {
let grid = unsafe { heap_remove(grid) };
match Packet::try_from(Cp437GridCommand {
grid,
origin: Origin::new(x, y),
}) {
Ok(packet) => heap_move(packet),
Err(_) => std::ptr::null_mut(),
}
}

View file

@ -9,7 +9,7 @@
//! #include "servicepoint.h" //! #include "servicepoint.h"
//! //!
//! int main(void) { //! int main(void) {
//! UdpConnection *connection = sp_connection_open("172.23.42.29:2342"); //! UdpConnection *connection = sp_udp_open("172.23.42.29:2342");
//! if (connection == NULL) //! if (connection == NULL)
//! return 1; //! return 1;
//! //!
@ -17,10 +17,10 @@
//! sp_bitmap_fill(pixels, true); //! sp_bitmap_fill(pixels, true);
//! //!
//! TypedCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); //! TypedCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed);
//! while (sp_connection_send_command(connection, sp_command_clone(command))); //! while (sp_udp_send_command(connection, sp_command_clone(command)));
//! //!
//! sp_command_free(command); //! sp_command_free(command);
//! sp_connection_free(connection); //! sp_udp_free(connection);
//! return 0; //! return 0;
//! } //! }
//! ``` //! ```
@ -30,21 +30,22 @@ pub use crate::bitvec::*;
pub use crate::brightness_grid::*; pub use crate::brightness_grid::*;
pub use crate::byte_slice::*; pub use crate::byte_slice::*;
pub use crate::char_grid::*; pub use crate::char_grid::*;
pub use crate::command::*;
pub use crate::connection::*;
pub use crate::cp437_grid::*; pub use crate::cp437_grid::*;
pub use crate::packet::*; pub use crate::packet::*;
pub use servicepoint::CommandCode;
use std::ptr::NonNull; use std::ptr::NonNull;
pub use crate::typed_command::*;
pub use crate::udp::*;
mod bitmap; mod bitmap;
mod bitvec; mod bitvec;
mod brightness_grid; mod brightness_grid;
mod byte_slice; mod byte_slice;
mod char_grid; mod char_grid;
mod command;
mod connection;
mod cp437_grid; mod cp437_grid;
mod packet; mod packet;
mod typed_command;
mod udp;
use std::time::Duration; use std::time::Duration;
@ -60,5 +61,12 @@ pub(crate) fn heap_move_nonnull<T>(x: T) -> NonNull<T> {
} }
pub(crate) unsafe fn heap_drop<T>(x: NonNull<T>) { pub(crate) unsafe fn heap_drop<T>(x: NonNull<T>) {
drop(unsafe { Box::from_raw(x.as_ptr()) }); drop(unsafe { heap_remove(x) });
} }
pub(crate) unsafe fn heap_remove<T>(x: NonNull<T>) -> T {
unsafe { *Box::from_raw(x.as_ptr()) }
}
/// This is a type only used by cbindgen to have a type for pointers.
pub struct UdpSocket;

View file

@ -1,5 +1,5 @@
use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
use servicepoint::{Header, Packet, TypedCommand}; use servicepoint::{CommandCode, Header, Packet, TypedCommand};
use std::ptr::NonNull; use std::ptr::NonNull;
/// Turns a [TypedCommand] into a [Packet]. /// Turns a [TypedCommand] into a [Packet].
@ -10,7 +10,7 @@ use std::ptr::NonNull;
pub unsafe extern "C" fn sp_packet_from_command( pub unsafe extern "C" fn sp_packet_from_command(
command: NonNull<TypedCommand>, command: NonNull<TypedCommand>,
) -> *mut Packet { ) -> *mut Packet {
let command = unsafe { *Box::from_raw(command.as_ptr()) }; let command = unsafe { heap_remove(command) };
if let Ok(packet) = command.try_into() { if let Ok(packet) = command.try_into() {
heap_move(packet) heap_move(packet)
} else { } else {
@ -65,7 +65,7 @@ pub unsafe extern "C" fn sp_packet_get_header(
pub unsafe extern "C" fn sp_packet_get_payload( pub unsafe extern "C" fn sp_packet_get_payload(
packet: NonNull<Packet>, packet: NonNull<Packet>,
) -> ByteSlice { ) -> ByteSlice {
unsafe { ByteSlice::from_slice(&mut *(*packet.as_ptr()).payload) } unsafe { ByteSlice::from_slice(&mut (*packet.as_ptr()).payload) }
} }
/// Sets the payload of the provided packet to the provided data. /// Sets the payload of the provided packet to the provided data.
@ -87,7 +87,7 @@ pub unsafe extern "C" fn sp_packet_set_payload(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_packet_serialize_to( pub unsafe extern "C" fn sp_packet_serialize_to(
packet: NonNull<Packet>, packet: NonNull<Packet>,
buffer: ByteSlice, mut buffer: ByteSlice,
) { ) {
unsafe { unsafe {
packet.as_ref().serialize_to(buffer.as_slice_mut()); packet.as_ref().serialize_to(buffer.as_slice_mut());
@ -107,3 +107,22 @@ pub unsafe extern "C" fn sp_packet_clone(
pub unsafe extern "C" fn sp_packet_free(packet: NonNull<Packet>) { pub unsafe extern "C" fn sp_packet_free(packet: NonNull<Packet>) {
unsafe { heap_drop(packet) } unsafe { heap_drop(packet) }
} }
/// Converts u16 into [CommandCode].
///
/// If the provided value is not valid, false is returned and result is not changed.
#[no_mangle]
pub unsafe extern "C" fn sp_u16_to_command_code(
code: u16,
result: *mut CommandCode,
) -> bool {
match CommandCode::try_from(code) {
Ok(code) => {
unsafe {
*result = code;
}
true
}
Err(_) => false,
}
}

View file

@ -40,7 +40,7 @@ pub unsafe extern "C" fn sp_command_clone(
/// # Examples /// # Examples
/// ///
/// ```C /// ```C
/// sp_connection_send_command(connection, sp_command_clear()); /// sp_udp_send_command(connection, sp_command_clear());
/// ``` /// ```
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_command_clear() -> NonNull<TypedCommand> { pub unsafe extern "C" fn sp_command_clear() -> NonNull<TypedCommand> {
@ -115,10 +115,6 @@ pub unsafe extern "C" fn sp_command_bitvec(
operation: BinaryOperation, operation: BinaryOperation,
) -> *mut TypedCommand { ) -> *mut TypedCommand {
let bit_vec = unsafe { *Box::from_raw(bit_vec.as_ptr()) }; let bit_vec = unsafe { *Box::from_raw(bit_vec.as_ptr()) };
let compression = match compression.try_into() {
Ok(compression) => compression,
Err(_) => return std::ptr::null_mut(),
};
let command = servicepoint::BitVecCommand { let command = servicepoint::BitVecCommand {
offset, offset,
operation, operation,
@ -182,10 +178,6 @@ pub unsafe extern "C" fn sp_command_bitmap(
compression: CompressionCode, compression: CompressionCode,
) -> *mut TypedCommand { ) -> *mut TypedCommand {
let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) }; let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) };
let compression = match compression.try_into() {
Ok(compression) => compression,
Err(_) => return std::ptr::null_mut(),
};
let command = servicepoint::BitmapCommand { let command = servicepoint::BitmapCommand {
origin: servicepoint::Origin::new(x, y), origin: servicepoint::Origin::new(x, y),
bitmap, bitmap,

View file

@ -1,7 +1,7 @@
use crate::{heap_drop, heap_move}; use crate::{heap_drop, heap_move, heap_remove};
use servicepoint::{Connection, Packet, TypedCommand, UdpConnection}; use servicepoint::{Header, Packet, TypedCommand, UdpSocketExt};
use std::ffi::{c_char, CStr}; use std::ffi::{c_char, CStr};
use std::net::{Ipv4Addr, SocketAddrV4}; use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};
use std::ptr::NonNull; use std::ptr::NonNull;
/// Creates a new instance of [UdpConnection]. /// Creates a new instance of [UdpConnection].
@ -11,18 +11,18 @@ use std::ptr::NonNull;
/// # Examples /// # Examples
/// ///
/// ```C /// ```C
/// UdpConnection connection = sp_connection_open("172.23.42.29:2342"); /// UdpConnection connection = sp_udp_open("172.23.42.29:2342");
/// if (connection != NULL) /// if (connection != NULL)
/// sp_connection_send_command(connection, sp_command_clear()); /// sp_udp_send_command(connection, sp_command_clear());
/// ``` /// ```
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_udp_open( pub unsafe extern "C" fn sp_udp_open(
host: NonNull<c_char>, host: NonNull<c_char>,
) -> *mut UdpConnection { ) -> *mut UdpSocket {
let host = unsafe { CStr::from_ptr(host.as_ptr()) } let host = unsafe { CStr::from_ptr(host.as_ptr()) }
.to_str() .to_str()
.expect("Bad encoding"); .expect("Bad encoding");
let connection = match UdpConnection::open(host) { let connection = match UdpSocket::bind_connect(host) {
Err(_) => return std::ptr::null_mut(), Err(_) => return std::ptr::null_mut(),
Ok(value) => value, Ok(value) => value,
}; };
@ -37,9 +37,9 @@ pub unsafe extern "C" fn sp_udp_open(
/// # Examples /// # Examples
/// ///
/// ```C /// ```C
/// UdpConnection connection = sp_connection_open_ipv4(172, 23, 42, 29, 2342); /// UdpConnection connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
/// if (connection != NULL) /// if (connection != NULL)
/// sp_connection_send_command(connection, sp_command_clear()); /// sp_udp_send_command(connection, sp_command_clear());
/// ``` /// ```
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_udp_open_ipv4( pub unsafe extern "C" fn sp_udp_open_ipv4(
@ -48,9 +48,9 @@ pub unsafe extern "C" fn sp_udp_open_ipv4(
ip3: u8, ip3: u8,
ip4: u8, ip4: u8,
port: u16, port: u16,
) -> *mut UdpConnection { ) -> *mut UdpSocket {
let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port); let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port);
let connection = match UdpConnection::open(addr) { let connection = match UdpSocket::bind_connect(addr) {
Err(_) => return std::ptr::null_mut(), Err(_) => return std::ptr::null_mut(),
Ok(value) => value, Ok(value) => value,
}; };
@ -64,11 +64,11 @@ pub unsafe extern "C" fn sp_udp_open_ipv4(
/// returns: true in case of success /// returns: true in case of success
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_udp_send_packet( pub unsafe extern "C" fn sp_udp_send_packet(
connection: NonNull<UdpConnection>, connection: NonNull<UdpSocket>,
packet: NonNull<Packet>, packet: NonNull<Packet>,
) -> bool { ) -> bool {
let packet = unsafe { Box::from_raw(packet.as_ptr()) }; let packet = unsafe { heap_remove(packet) };
unsafe { connection.as_ref().send(*packet) }.is_ok() unsafe { connection.as_ref().send(&Vec::from(packet)) }.is_ok()
} }
/// Sends a [TypedCommand] to the display using the [UdpConnection]. /// Sends a [TypedCommand] to the display using the [UdpConnection].
@ -80,20 +80,40 @@ pub unsafe extern "C" fn sp_udp_send_packet(
/// # Examples /// # Examples
/// ///
/// ```C /// ```C
/// sp_connection_send_command(connection, sp_command_clear()); /// sp_udp_send_command(connection, sp_command_brightness(5));
/// sp_connection_send_command(connection, sp_command_brightness(5));
/// ``` /// ```
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_udp_send_command( pub unsafe extern "C" fn sp_udp_send_command(
connection: NonNull<UdpConnection>, connection: NonNull<UdpSocket>,
command: NonNull<TypedCommand>, command: NonNull<TypedCommand>,
) -> bool { ) -> bool {
let command = *unsafe { Box::from_raw(command.as_ptr()) }; let command = unsafe { heap_remove(command) };
unsafe { connection.as_ref().send(command) }.is_ok() unsafe { connection.as_ref().send_command(command) }.is_some()
}
/// Sends a [Header] to the display using the [UdpConnection].
///
/// returns: true in case of success
///
/// # Examples
///
/// ```C
/// sp_udp_send_header(connection, sp_command_brightness(5));
/// ```
#[no_mangle]
pub unsafe extern "C" fn sp_udp_send_header(
udp_connection: NonNull<UdpSocket>,
header: Header,
) -> bool {
let packet = Packet {
header,
payload: vec![],
};
unsafe { udp_connection.as_ref() }.send(&Vec::from(packet)).is_ok()
} }
/// Closes and deallocates a [UdpConnection]. /// Closes and deallocates a [UdpConnection].
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_udp_free(connection: NonNull<UdpConnection>) { pub unsafe extern "C" fn sp_udp_free(connection: NonNull<UdpSocket>) {
unsafe { heap_drop(connection) } unsafe { heap_drop(connection) }
} }