From c9d2479f5e04a35c4df4b15725541b29316a7f52 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 18 May 2025 11:20:57 +0200 Subject: [PATCH] sp_cmd_generic_try_from_packet return struct directly --- example/src/header_logger.c | 13 +++++++++++-- include/servicepoint.h | 4 +++- src/commands/generic_command.rs | 15 ++++++++++----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/example/src/header_logger.c b/example/src/header_logger.c index 97cd3dd..8f53be1 100644 --- a/example/src/header_logger.c +++ b/example/src/header_logger.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "servicepoint.h" #define DEFAULT_LISTEN_IP "127.0.0.1" @@ -63,14 +64,22 @@ int main(int argc, char **argv) { } struct Header *header = sp_packet_get_header(packet); + done = header->command_code == COMMAND_CODE_HARD_RESET; + ByteSlice payload = sp_packet_get_payload(packet); printf("Received packet: cc=%d, a=%d, b=%d, c=%d, d=%d, payload=%p (len %zu)\n", header->command_code, header->a, header->b, header->c, header->d, payload.start, payload.length); - done = header->command_code == COMMAND_CODE_HARD_RESET; - sp_packet_free(packet); + struct Command command = sp_cmd_generic_try_from_packet(packet); + if (command.tag == COMMAND_TAG_INVALID) { + printf("received invalid command\n"); + continue; + } + + sp_cmd_generic_free(command); } + close(udp_socket); exit(EXIT_SUCCESS); } diff --git a/include/servicepoint.h b/include/servicepoint.h index dec3af2..0fc72d5 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -1564,6 +1564,8 @@ struct Command sp_cmd_generic_clone(struct Command command); /** * Deallocates an [SPCommand]. * + * Commands with an invalid `tag` do not have to be freed as the `data` pointer should be null. + * * # Examples * * ```C @@ -1588,7 +1590,7 @@ struct Packet *sp_cmd_generic_into_packet(struct Command command); * * Returns: pointer to new [SPCommand] instance or NULL if parsing failed. */ -struct Command *sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet); +struct Command sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet); /** * Deallocates a [HardResetCommand]. diff --git a/src/commands/generic_command.rs b/src/commands/generic_command.rs index bdeab5e..851e897 100644 --- a/src/commands/generic_command.rs +++ b/src/commands/generic_command.rs @@ -74,10 +74,10 @@ impl SPCommand { #[no_mangle] pub unsafe extern "C" fn sp_cmd_generic_try_from_packet( packet: NonNull, -) -> *mut SPCommand { +) -> SPCommand { let packet = *unsafe { Box::from_raw(packet.as_ptr()) }; - heap_move_ok(servicepoint::TypedCommand::try_from(packet).map(|value| { - match value { + servicepoint::TypedCommand::try_from(packet) + .map(|value| match value { TypedCommand::Clear(clear) => SPCommand { tag: CommandTag::Clear, data: CommandUnion { @@ -139,8 +139,11 @@ pub unsafe extern "C" fn sp_cmd_generic_try_from_packet( bitmap_legacy: heap_move_nonnull(bitmap_legacy), }, }, - } - })) + }) + .unwrap_or_else(move |_| SPCommand { + tag: CommandTag::Invalid, + data: CommandUnion { null: null_mut() }, + }) } /// Clones an [SPCommand] instance. @@ -219,6 +222,8 @@ pub unsafe extern "C" fn sp_cmd_generic_clone(command: SPCommand) -> SPCommand { } /// Deallocates an [SPCommand]. +/// +/// Commands with an invalid `tag` do not have to be freed as the `data` pointer should be null. /// /// # Examples ///