features, cargo fmt

This commit is contained in:
Vinzenz Schroeter 2025-04-12 22:32:27 +02:00
commit 8ea511a33a
9 changed files with 25 additions and 15 deletions

View file

@ -26,8 +26,9 @@ git = "https://git.berlin.ccc.de/servicepoint/servicepoint/"
branch = "next"
[features]
full = ["servicepoint/all_compressions", "servicepoint/default"]
default = ["full"]
protocol_udp = ["servicepoint/protocol_udp"]
all_compressions = ["servicepoint/all_compressions"]
default = ["all_compressions", "servicepoint/default", "protocol_udp"]
[lints.rust]
missing-docs = "warn"

View file

@ -3,6 +3,7 @@ CARGO := rustup run nightly cargo
TARGET := x86_64-unknown-linux-musl
PROFILE := size-optimized
FEATURES := protocol_udp
THIS_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
REPO_ROOT := $(THIS_DIR)/..
@ -22,6 +23,7 @@ RUSTFLAGS := -Zlocation-detail=none \
CARGOFLAGS := --manifest-path=$(REPO_ROOT)/Cargo.toml \
--profile=$(PROFILE) \
--no-default-features \
--features=$(FEATURES) \
--target=$(TARGET) \
-Zbuild-std="core,std,alloc,proc_macro,panic_abort" \
-Zbuild-std-features="panic_immediate_abort" \
@ -53,7 +55,7 @@ _programs := $(basename $(_c_src))
_bins := $(addprefix out/, $(_programs))
_unstripped_bins := $(addsuffix _unstripped, $(_bins))
_run_programs := $(addprefix run_, $(_programs))
_rs_src := $(wildcard ../src/**.rs) ../Cargo.lock
_rs_src := $(wildcard ../src/**.rs) ../Cargo.lock ../Cargo.toml ../cbindgen.toml
all: $(_bins)

View file

@ -1,6 +1,8 @@
use crate::byte_slice::ByteSlice;
use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, SPBitVec};
use servicepoint::{Bitmap, BitmapCommand, CompressionCode, DataRef, Grid, Origin, Packet};
use servicepoint::{
Bitmap, BitmapCommand, CompressionCode, DataRef, Grid, Origin, Packet,
};
use std::ptr::NonNull;
/// Creates a new [Bitmap] with the specified dimensions.
@ -210,7 +212,7 @@ pub unsafe extern "C" fn sp_bitmap_into_packet(
bitmap: NonNull<Bitmap>,
x: usize,
y: usize,
compression: CompressionCode
compression: CompressionCode,
) -> *mut Packet {
let bitmap = unsafe { heap_remove(bitmap) };
match Packet::try_from(BitmapCommand {

View file

@ -1,5 +1,7 @@
use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
use servicepoint::{BinaryOperation, BitVecCommand, BitVecU8Msb0, CompressionCode, Packet};
use servicepoint::{
BinaryOperation, BitVecCommand, BitVecU8Msb0, CompressionCode, Packet,
};
use std::ptr::NonNull;
/// A vector of bits
@ -157,7 +159,7 @@ pub unsafe extern "C" fn sp_bitvec_into_packet(
bitvec: NonNull<SPBitVec>,
offset: usize,
operation: BinaryOperation,
compression: CompressionCode
compression: CompressionCode,
) -> *mut Packet {
let bitvec = unsafe { heap_remove(bitvec) }.0;
match Packet::try_from(BitVecCommand {

View file

@ -1,3 +0,0 @@
mod typed;
pub use typed::*;

View file

@ -1,5 +1,7 @@
use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice};
use servicepoint::{Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet};
use servicepoint::{
Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet,
};
use std::ptr::NonNull;
/// Creates a new [Cp437Grid] with the specified dimensions.

View file

@ -30,22 +30,26 @@ pub use crate::bitvec::*;
pub use crate::brightness_grid::*;
pub use crate::byte_slice::*;
pub use crate::char_grid::*;
pub use crate::commands::*;
pub use crate::connection::*;
pub use crate::cp437_grid::*;
pub use crate::packet::*;
pub use servicepoint::CommandCode;
use std::ptr::NonNull;
pub use typed_command::*;
mod bitmap;
mod bitvec;
mod brightness_grid;
mod byte_slice;
mod char_grid;
mod commands;
mod connection;
mod cp437_grid;
mod packet;
mod typed_command;
#[cfg(feature = "protocol_udp")]
mod udp;
#[cfg(feature = "protocol_udp")]
pub use udp::*;
use std::time::Duration;

201
src/typed_command.rs Normal file
View file

@ -0,0 +1,201 @@
use crate::{heap_drop, heap_move, heap_move_nonnull, SPBitVec};
use servicepoint::{
BinaryOperation, Bitmap, Brightness, BrightnessGrid, CharGrid,
CompressionCode, Cp437Grid, GlobalBrightnessCommand, Packet, TypedCommand,
};
use std::ptr::NonNull;
/// Tries to turn a [Packet] into a [TypedCommand].
///
/// The packet is deallocated in the process.
///
/// Returns: pointer to new [TypedCommand] instance or NULL if parsing failed.
#[no_mangle]
pub unsafe extern "C" fn sp_command_try_from_packet(
packet: NonNull<Packet>,
) -> *mut TypedCommand {
let packet = *unsafe { Box::from_raw(packet.as_ptr()) };
match servicepoint::TypedCommand::try_from(packet) {
Err(_) => std::ptr::null_mut(),
Ok(command) => heap_move(command),
}
}
/// Clones a [TypedCommand] instance.
///
/// returns: new [TypedCommand] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_command_clone(
command: NonNull<TypedCommand>,
) -> NonNull<TypedCommand> {
heap_move_nonnull(unsafe { command.as_ref().clone() })
}
/// Set all pixels to the off state.
///
/// Does not affect brightness.
///
/// Returns: a new [servicepoint::Command::Clear] instance.
///
/// # Examples
///
/// ```C
/// sp_udp_send_command(connection, sp_command_clear());
/// ```
#[no_mangle]
pub unsafe extern "C" fn sp_command_clear() -> NonNull<TypedCommand> {
heap_move_nonnull(servicepoint::ClearCommand.into())
}
/// Kills the udp daemon on the display, which usually results in a restart.
///
/// Please do not send this in your normal program flow.
///
/// Returns: a new [servicepoint::Command::HardReset] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_command_hard_reset() -> NonNull<TypedCommand> {
heap_move_nonnull(servicepoint::HardResetCommand.into())
}
/// A yet-to-be-tested command.
///
/// Returns: a new [servicepoint::Command::FadeOut] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_command_fade_out() -> NonNull<TypedCommand> {
heap_move_nonnull(servicepoint::FadeOutCommand.into())
}
/// Set the brightness of all tiles to the same value.
///
/// Returns: a new [servicepoint::Command::Brightness] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_command_global_brightness(
brightness: Brightness,
) -> NonNull<TypedCommand> {
heap_move_nonnull(GlobalBrightnessCommand::from(brightness).into())
}
/// Set the brightness of individual tiles in a rectangular area of the display.
///
/// The passed [BrightnessGrid] gets consumed.
///
/// Returns: a new [servicepoint::Command::CharBrightness] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_command_brightness_grid(
x: usize,
y: usize,
grid: NonNull<BrightnessGrid>,
) -> NonNull<TypedCommand> {
let grid = unsafe { *Box::from_raw(grid.as_ptr()) };
let result = servicepoint::BrightnessGridCommand {
origin: servicepoint::Origin::new(x, y),
grid,
}
.into();
heap_move_nonnull(result)
}
/// Set pixel data starting at the pixel offset on screen.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The [`BinaryOperation`] will be applied on the display comparing old and sent bit.
///
/// `new_bit = old_bit op sent_bit`
///
/// For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels.
///
/// The contained [`BitVecU8Msb0`] is always uncompressed.
#[no_mangle]
pub unsafe extern "C" fn sp_command_bitvec(
offset: usize,
bit_vec: NonNull<SPBitVec>,
compression: CompressionCode,
operation: BinaryOperation,
) -> *mut TypedCommand {
let bit_vec = unsafe { *Box::from_raw(bit_vec.as_ptr()) };
let command = servicepoint::BitVecCommand {
offset,
operation,
bitvec: bit_vec.0,
compression,
}
.into();
heap_move(command)
}
/// Show codepage 437 encoded text on the screen.
///
/// The passed [Cp437Grid] gets consumed.
///
/// Returns: a new [servicepoint::Cp437GridCommand] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_command_cp437_grid(
x: usize,
y: usize,
grid: NonNull<Cp437Grid>,
) -> NonNull<TypedCommand> {
let grid = *unsafe { Box::from_raw(grid.as_ptr()) };
let result = servicepoint::Cp437GridCommand {
origin: servicepoint::Origin::new(x, y),
grid,
}
.into();
heap_move_nonnull(result)
}
/// Show UTF-8 encoded text on the screen.
///
/// The passed [CharGrid] gets consumed.
///
/// Returns: a new [servicepoint::CharGridCommand] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_command_char_grid(
x: usize,
y: usize,
grid: NonNull<CharGrid>,
) -> NonNull<TypedCommand> {
let grid = unsafe { *Box::from_raw(grid.as_ptr()) };
let result = servicepoint::CharGridCommand {
origin: servicepoint::Origin::new(x, y),
grid,
}
.into();
heap_move_nonnull(result)
}
/// Sets a window of pixels to the specified values.
///
/// The passed [Bitmap] gets consumed.
///
/// Returns: a new [servicepoint::BitmapCommand] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_command_bitmap(
x: usize,
y: usize,
bitmap: NonNull<Bitmap>,
compression: CompressionCode,
) -> *mut TypedCommand {
let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) };
let command = servicepoint::BitmapCommand {
origin: servicepoint::Origin::new(x, y),
bitmap,
compression,
}
.into();
heap_move(command)
}
/// Deallocates a [TypedCommand].
///
/// # Examples
///
/// ```C
/// TypedCommand c = sp_command_clear();
/// sp_command_free(c);
/// ```
#[no_mangle]
pub unsafe extern "C" fn sp_command_free(command: NonNull<TypedCommand>) {
unsafe { heap_drop(command) }
}

119
src/udp.rs Normal file
View file

@ -0,0 +1,119 @@
use crate::{heap_drop, heap_move, heap_remove};
use servicepoint::{Connection, Header, Packet, TypedCommand, UdpConnection};
use std::ffi::{c_char, CStr};
use std::net::{Ipv4Addr, SocketAddrV4};
use std::ptr::NonNull;
/// Creates a new instance of [UdpConnection].
///
/// returns: NULL if connection fails, or connected instance
///
/// # Examples
///
/// ```C
/// UdpConnection connection = sp_udp_open("172.23.42.29:2342");
/// if (connection != NULL)
/// sp_udp_send_command(connection, sp_command_clear());
/// ```
#[no_mangle]
pub unsafe extern "C" fn sp_udp_open(
host: NonNull<c_char>,
) -> *mut UdpConnection {
let host = unsafe { CStr::from_ptr(host.as_ptr()) }
.to_str()
.expect("Bad encoding");
let connection = match UdpConnection::open(host) {
Err(_) => return std::ptr::null_mut(),
Ok(value) => value,
};
heap_move(connection)
}
/// Creates a new instance of [UdpConnection].
///
/// returns: NULL if connection fails, or connected instance
///
/// # Examples
///
/// ```C
/// UdpConnection connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
/// if (connection != NULL)
/// sp_udp_send_command(connection, sp_command_clear());
/// ```
#[no_mangle]
pub unsafe extern "C" fn sp_udp_open_ipv4(
ip1: u8,
ip2: u8,
ip3: u8,
ip4: u8,
port: u16,
) -> *mut UdpConnection {
let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port);
let connection = match UdpConnection::open(addr) {
Err(_) => return std::ptr::null_mut(),
Ok(value) => value,
};
heap_move(connection)
}
/// Sends a [Packet] to the display using the [UdpConnection].
///
/// The passed `packet` gets consumed.
///
/// returns: true in case of success
#[no_mangle]
pub unsafe extern "C" fn sp_udp_send_packet(
connection: NonNull<UdpConnection>,
packet: NonNull<Packet>,
) -> bool {
let packet = unsafe { heap_remove(packet) };
unsafe { connection.as_ref().send(packet) }.is_ok()
}
/// Sends a [TypedCommand] to the display using the [UdpConnection].
///
/// The passed `command` gets consumed.
///
/// returns: true in case of success
///
/// # Examples
///
/// ```C
/// sp_udp_send_command(connection, sp_command_brightness(5));
/// ```
#[no_mangle]
pub unsafe extern "C" fn sp_udp_send_command(
connection: NonNull<UdpConnection>,
command: NonNull<TypedCommand>,
) -> bool {
let command = unsafe { heap_remove(command) };
unsafe { connection.as_ref().send(command) }.is_ok()
}
/// 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<UdpConnection>,
header: Header,
) -> bool {
let packet = Packet {
header,
payload: vec![],
};
unsafe { udp_connection.as_ref() }.send(packet).is_ok()
}
/// Closes and deallocates a [UdpConnection].
#[no_mangle]
pub unsafe extern "C" fn sp_udp_free(connection: NonNull<UdpConnection>) {
unsafe { heap_drop(connection) }
}