From 5120e220ecfcb0a85a9a1f8a91a1a266ea630329 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 12 Apr 2025 12:05:19 +0200 Subject: [PATCH] functions for manipulating packets --- Cargo.lock | 2 +- example/main.c | 7 ++++++- include/servicepoint.h | 8 +++++++- src/bitmap.rs | 23 +++++++++++++---------- src/bitvec.rs | 6 +----- src/brightness_grid.rs | 7 ++----- src/byte_slice.rs | 19 +++++++++++++++++++ src/cp437_grid.rs | 6 +----- src/packet.rs | 40 +++++++++++++++++++++++++++++++--------- 9 files changed, 81 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9641466..c0b11c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "servicepoint" version = "0.13.2" -source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint/?branch=next#aafa2bc9f91c3ae7d88607bf545d9665d50fc0db" +source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint/?branch=next#971bee5065139f220022e8108cfaa9c263b8a8a0" dependencies = [ "bitvec", "bzip2", diff --git a/example/main.c b/example/main.c index 73f4726..388218e 100644 --- a/example/main.c +++ b/example/main.c @@ -16,7 +16,12 @@ int main(void) { if (command == NULL) return 1; - sp_connection_send_command(connection, command); + 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_connection_send_packet(connection, packet); sp_connection_free(connection); return 0; diff --git a/include/servicepoint.h b/include/servicepoint.h index 46fe3b8..1de6cc5 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -1908,7 +1908,11 @@ Packet *sp_packet_from_parts(Header header, const uint8_t *payload, size_t payload_len); -Header sp_packet_get_header(const Packet *packet); +Header *sp_packet_get_header(Packet *packet); + +SPByteSlice sp_packet_get_payload(Packet *packet); + +void sp_packet_set_payload(Packet *packet, SPByteSlice data); /** * Tries to load a [SPPacket] from the passed array with the specified length. @@ -1931,6 +1935,8 @@ Header sp_packet_get_header(const Packet *packet); Packet *sp_packet_try_load(const uint8_t *data, size_t length); +void sp_packet_write_to(const Packet *packet, SPByteSlice buffer); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/src/bitmap.rs b/src/bitmap.rs index 9a9f59a..1f6327f 100644 --- a/src/bitmap.rs +++ b/src/bitmap.rs @@ -18,7 +18,6 @@ use std::ptr::NonNull; use crate::byte_slice::SPByteSlice; - /// Creates a new [SPBitmap] with the specified dimensions. /// /// # Arguments @@ -63,7 +62,8 @@ pub unsafe extern "C" fn sp_bitmap_new( /// - the returned instance is freed in some way, either by using a consuming function or /// by explicitly calling [sp_bitmap_free]. #[no_mangle] -pub unsafe extern "C" fn sp_bitmap_new_screen_sized() -> NonNull { +pub unsafe extern "C" fn sp_bitmap_new_screen_sized( +) -> NonNull { let result = Box::new(servicepoint::Bitmap::max_sized()); NonNull::from(Box::leak(result)) } @@ -235,7 +235,10 @@ pub unsafe extern "C" fn sp_bitmap_set( /// - `bitmap` points to a valid [SPBitmap] /// - `bitmap` is not written to or read from concurrently #[no_mangle] -pub unsafe extern "C" fn sp_bitmap_fill(bitmap: *mut servicepoint::Bitmap, value: bool) { +pub unsafe extern "C" fn sp_bitmap_fill( + bitmap: *mut servicepoint::Bitmap, + value: bool, +) { assert!(!bitmap.is_null()); unsafe { (*bitmap).fill(value) }; } @@ -256,7 +259,9 @@ pub unsafe extern "C" fn sp_bitmap_fill(bitmap: *mut servicepoint::Bitmap, value /// /// - `bitmap` points to a valid [SPBitmap] #[no_mangle] -pub unsafe extern "C" fn sp_bitmap_width(bitmap: *const servicepoint::Bitmap) -> usize { +pub unsafe extern "C" fn sp_bitmap_width( + bitmap: *const servicepoint::Bitmap, +) -> usize { assert!(!bitmap.is_null()); unsafe { (*bitmap).width() } } @@ -277,7 +282,9 @@ pub unsafe extern "C" fn sp_bitmap_width(bitmap: *const servicepoint::Bitmap) -> /// /// - `bitmap` points to a valid [SPBitmap] #[no_mangle] -pub unsafe extern "C" fn sp_bitmap_height(bitmap: *const servicepoint::Bitmap) -> usize { +pub unsafe extern "C" fn sp_bitmap_height( + bitmap: *const servicepoint::Bitmap, +) -> usize { assert!(!bitmap.is_null()); unsafe { (*bitmap).height() } } @@ -300,9 +307,5 @@ pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref( bitmap: *mut servicepoint::Bitmap, ) -> SPByteSlice { assert!(!bitmap.is_null()); - let data = unsafe { (*bitmap).data_ref_mut() }; - SPByteSlice { - start: NonNull::new(data.as_mut_ptr_range().start).unwrap(), - length: data.len(), - } + unsafe { SPByteSlice::from_slice((*bitmap).data_ref_mut()) } } diff --git a/src/bitvec.rs b/src/bitvec.rs index 676e617..104ca27 100644 --- a/src/bitvec.rs +++ b/src/bitvec.rs @@ -275,9 +275,5 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( bit_vec: *mut SPBitVec, ) -> SPByteSlice { assert!(!bit_vec.is_null()); - let data = unsafe { (*bit_vec).0.as_raw_mut_slice() }; - SPByteSlice { - start: NonNull::new(data.as_mut_ptr_range().start).unwrap(), - length: data.len(), - } + unsafe { SPByteSlice::from_slice((*bit_vec).0.as_raw_mut_slice() ) } } diff --git a/src/brightness_grid.rs b/src/brightness_grid.rs index e1780f2..4620a7d 100644 --- a/src/brightness_grid.rs +++ b/src/brightness_grid.rs @@ -318,9 +318,6 @@ pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( assert_eq!(core::mem::size_of::(), 1); let data = unsafe { (*brightness_grid).data_ref_mut() }; // this assumes more about the memory layout than rust guarantees. yikes! - let data: &mut [u8] = unsafe { transmute(data) }; - SPByteSlice { - start: NonNull::new(data.as_mut_ptr_range().start).unwrap(), - length: data.len(), - } + unsafe { SPByteSlice::from_slice(transmute(data)) } + } diff --git a/src/byte_slice.rs b/src/byte_slice.rs index 678a5d7..6ac4df3 100644 --- a/src/byte_slice.rs +++ b/src/byte_slice.rs @@ -22,3 +22,22 @@ pub struct SPByteSlice { /// The amount of memory in bytes pub length: usize, } + +impl SPByteSlice { + pub(crate) unsafe fn as_slice(&self) -> &[u8] { + unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) } + } + + pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] { + unsafe { + std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length) + } + } + + pub(crate) unsafe fn from_slice(slice: &mut [u8]) -> Self { + Self { + start: NonNull::new(slice.as_mut_ptr()).unwrap(), + length: slice.len(), + } + } +} diff --git a/src/cp437_grid.rs b/src/cp437_grid.rs index e251d6f..eeb63eb 100644 --- a/src/cp437_grid.rs +++ b/src/cp437_grid.rs @@ -280,9 +280,5 @@ pub unsafe extern "C" fn sp_cp437_grid_height( pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( cp437_grid: *mut SPCp437Grid, ) -> SPByteSlice { - let data = unsafe { (*cp437_grid).0.data_ref_mut() }; - SPByteSlice { - start: NonNull::new(data.as_mut_ptr_range().start).unwrap(), - length: data.len(), - } + unsafe {SPByteSlice::from_slice((*cp437_grid).0.data_ref_mut()) } } diff --git a/src/packet.rs b/src/packet.rs index 199ce72..71bbbae 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -5,8 +5,9 @@ //! //! The raw packet -use std::ptr::NonNull; +use crate::SPByteSlice; use servicepoint::{Header, Packet, TypedCommand}; +use std::ptr::NonNull; /// Turns a [SPCommand] into a [SPPacket]. /// The [SPCommand] gets consumed. @@ -107,19 +108,40 @@ pub unsafe extern "C" fn sp_packet_from_parts( Vec::from(payload) }; - let packet = Box::new(Packet { - header, - payload, - }); + let packet = Box::new(Packet { header, payload }); NonNull::from(Box::leak(packet)) } #[no_mangle] -pub unsafe extern "C" fn sp_packet_get_header( - packet: *const Packet, -) -> Header { +pub unsafe extern "C" fn sp_packet_get_header(packet: *mut Packet) -> *mut Header { assert!(!packet.is_null()); - unsafe { (*packet).header } + &mut unsafe { (*packet).header } +} + +#[no_mangle] +pub unsafe extern "C" fn sp_packet_get_payload(packet: *mut Packet) -> SPByteSlice { + assert!(!packet.is_null()); + unsafe { SPByteSlice::from_slice(&mut *(*packet).payload) } +} + +#[no_mangle] +pub unsafe extern "C" fn sp_packet_set_payload(packet: *mut Packet, data: SPByteSlice) { + assert!(!packet.is_null()); + unsafe { + (*packet).payload = data.as_slice().to_vec() + } +} + +#[no_mangle] +pub unsafe extern "C" fn sp_packet_write_to( + packet: *const Packet, + mut buffer: SPByteSlice, +) { + assert!(!packet.is_null()); + + unsafe { + (*packet).serialize_to(buffer.as_slice_mut()); + } } /// Clones a [SPPacket].