From 4713c80244fe1bc00da097eb27987e77c98601f0 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 13 Dec 2023 20:19:20 -0600 Subject: [PATCH] Feature: Add f_fss_simple_packet_encode() for encoding the Simple Packet header. --- level_0/f_fss/c/fss/simple_packet.c | 49 ++++++++++++ level_0/f_fss/c/fss/simple_packet.h | 30 ++++++++ level_0/f_fss/data/build/settings-tests | 2 +- .../tests/unit/c/test-fss-simple_packet_encode.c | 87 ++++++++++++++++++++++ .../tests/unit/c/test-fss-simple_packet_encode.h | 34 +++++++++ level_0/f_fss/tests/unit/c/test-fss.c | 3 + level_0/f_fss/tests/unit/c/test-fss.h | 1 + 7 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 level_0/f_fss/tests/unit/c/test-fss-simple_packet_encode.c create mode 100644 level_0/f_fss/tests/unit/c/test-fss-simple_packet_encode.h diff --git a/level_0/f_fss/c/fss/simple_packet.c b/level_0/f_fss/c/fss/simple_packet.c index e73cd30..fe03667 100644 --- a/level_0/f_fss/c/fss/simple_packet.c +++ b/level_0/f_fss/c/fss/simple_packet.c @@ -34,6 +34,55 @@ extern "C" { } #endif // _di_f_fss_simple_packet_destroy_ +#ifndef _di_f_fss_simple_packet_encode_ + f_status_t f_fss_simple_packet_encode(const uint8_t control, const uint32_t size, f_string_dynamic_t * const destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + { + const f_status_t status = f_memory_array_increase_by(F_fss_simple_packet_block_header_size_d, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); + if (F_status_is_error(status)) return status; + } + + destination->string[destination->used++] = (uint8_t) control; + + #ifdef _is_F_endian_little + // Big Endian. + if (control & F_fss_simple_packet_endian_d) { + destination->string[destination->used++] = ((uint8_t) size) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 8) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 16) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 24) & 0xff; + } + // Little Endian. + else { + destination->string[destination->used++] = (((uint8_t) size) >> 24) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 16) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 8) & 0xff; + destination->string[destination->used++] = ((uint8_t) size) & 0xff; + } + #else + // Big Endian. + if (control & F_fss_simple_packet_endian_d) { + destination->string[destination->used++] = (((uint8_t) size) >> 24) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 16) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 8) & 0xff; + destination->string[destination->used++] = ((uint8_t) size) & 0xff; + } + // Little Endian. + else { + destination->string[destination->used++] = ((uint8_t) size)) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 8) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 16) & 0xff; + destination->string[destination->used++] = (((uint8_t) size) >> 24) & 0xff; + } + #endif // _is_F_endian_little + + return F_okay; + } +#endif // _di_f_fss_simple_packet_encode_ + #ifndef _di_f_fss_simple_packet_extract_ f_status_t f_fss_simple_packet_extract(const f_string_static_t buffer, f_fss_simple_packet_t * const packet) { #ifndef _di_level_0_parameter_checking_ diff --git a/level_0/f_fss/c/fss/simple_packet.h b/level_0/f_fss/c/fss/simple_packet.h index 0a9257e..6f14c17 100644 --- a/level_0/f_fss/c/fss/simple_packet.h +++ b/level_0/f_fss/c/fss/simple_packet.h @@ -204,6 +204,7 @@ extern "C" { * * @param simple_packet * The FSS-000F (Simple Packet) to delete. + * Must not be NULL. * * @return * F_okay on success. @@ -225,6 +226,7 @@ extern "C" { * * @param simple_packet * The FSS-000F (Simple Packet) to destroy. + * Must not be NULL. * * @return * F_okay on success. @@ -242,6 +244,32 @@ extern "C" { #endif // _di_f_fss_simple_packet_destroy_ /** + * Encode the control and size parts of the FSS-000F (Simple Packet) packet structure into a string. + * + * This encodes only the header parts of the packet, which consists of the control block and the size block. + * + * @param control + * The bits to encode into the control block. + * @param size + * The size to encode into the size block. + * @param destination + * The string buffer to encode the packet parts into. + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_resize(). + * + * @see f_memory_array_resize() + */ +#ifndef _di_f_fss_simple_packet_encode_ + extern f_status_t f_fss_simple_packet_encode(const uint8_t control, const uint32_t size, f_string_dynamic_t * const destination); +#endif // _di_f_fss_simple_packet_encode_ + +/** * Extract the different parts of the FSS-000F (Simple Packet) string into a packet structure. * * The buffer is processed as binary data, therefore, NULL and other control data are considered valid data and are not ignored. @@ -252,6 +280,7 @@ extern "C" { * @param packet * The packet extracted from the given buffer, without doing anything to the payload. * The caller can allocate the payload and extract it at any time by just selecting the string from F_fss_simple_packet_block_header_size_d until at most F_fss_simple_packet_block_payload_size_d. + * Must not be NULL. * * @return * F_okay on success (The end of the Payload Block is assumed to be the remainder of the buffer or F_fss_simple_packet_block_payload_size_d, whichever is smaller). @@ -274,6 +303,7 @@ extern "C" { * This buffer is considered binary data and so any NULL found within is treated as a valid part of the buffer. * @param packet * The packet range extracted from the given buffer, with the payload being represented by a range. + * Must not be NULL. * * @return * F_okay on success (The end of the Payload Block is assumed to be the remainder of the buffer or F_fss_simple_packet_block_payload_size_d, whichever is smaller). diff --git a/level_0/f_fss/data/build/settings-tests b/level_0/f_fss/data/build/settings-tests index 18ed23a..3d3b51d 100644 --- a/level_0/f_fss/data/build/settings-tests +++ b/level_0/f_fss/data/build/settings-tests @@ -36,7 +36,7 @@ build_sources_program test-fss-set_delete.c test-fss-set_destroy.c build_sources_program test-fss-sets_delete_callback.c test-fss-sets_destroy_callback.c test-fss-setss_delete_callback.c test-fss-setss_destroy_callback.c build_sources_program test-fss-set_quote_delete.c test-fss-set_quote_destroy.c build_sources_program test-fss-set_quotes_delete_callback.c test-fss-set_quotes_destroy_callback.c test-fss-set_quotess_delete_callback.c test-fss-set_quotess_destroy_callback.c -build_sources_program test-fss-simple_packet_extract.c test-fss-simple_packet_extract_range.c +build_sources_program test-fss-simple_packet_encode.c test-fss-simple_packet_extract.c test-fss-simple_packet_extract_range.c build_sources_program test-fss-simple_packet_delete.c test-fss-simple_packet_destroy.c build_sources_program test-fss-simple_packets_delete_callback.c test-fss-simple_packets_destroy_callback.c test-fss-simple_packetss_delete_callback.c test-fss-simple_packetss_destroy_callback.c diff --git a/level_0/f_fss/tests/unit/c/test-fss-simple_packet_encode.c b/level_0/f_fss/tests/unit/c/test-fss-simple_packet_encode.c new file mode 100644 index 0000000..00d3d12 --- /dev/null +++ b/level_0/f_fss/tests/unit/c/test-fss-simple_packet_encode.c @@ -0,0 +1,87 @@ +#include "test-fss.h" +#include "test-fss-simple_packet_encode.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_fss_simple_packet_encode__parameter_checking(void **state) { + + { + const f_status_t status = f_fss_simple_packet_encode(0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_fss_simple_packet_encode__works_big_endian(void **state) { + + const f_char_t datas[3][5] = { + { 0x80, 0x05, 0x00, 0x00, 0x00 }, + { 0x80, 0x06, 0x00, 0x00, 0x00 }, + { 0x80, 0x07, 0x00, 0x00, 0x00 }, + }; + + const f_number_unsigned_t size[] = { + 5, + 6, + 7, + }; + + { + for (uint8_t i = 0; i < 3; ++i) { + + f_string_dynamic_t dynamic = f_string_dynamic_t_initialize; + + const f_status_t status = f_fss_simple_packet_encode(F_fss_simple_packet_endian_d, size[i], &dynamic); + + assert_int_equal(status, F_okay); + assert_int_equal(dynamic.string[0], datas[i][0]); + assert_int_equal(dynamic.string[1], datas[i][1]); + assert_int_equal(dynamic.string[2], datas[i][2]); + assert_int_equal(dynamic.string[3], datas[i][3]); + assert_int_equal(dynamic.string[4], datas[i][4]); + assert_int_equal(dynamic.used, F_fss_simple_packet_block_header_size_d); + + free(dynamic.string); + } // for + } +} + +void test__f_fss_simple_packet_encode__works_little_endian(void **state) { + + const f_char_t datas[3][5] = { + { 0x00, 0x00, 0x00, 0x00, 0x05 }, + { 0x00, 0x00, 0x00, 0x00, 0x06 }, + { 0x00, 0x00, 0x00, 0x00, 0x07 }, + }; + + const f_number_unsigned_t size[] = { + 5, + 6, + 7, + }; + + { + for (uint8_t i = 0; i < 3; ++i) { + + f_string_dynamic_t dynamic = f_string_dynamic_t_initialize; + + const f_status_t status = f_fss_simple_packet_encode(0, size[i], &dynamic); + + assert_int_equal(status, F_okay); + assert_int_equal(dynamic.string[0], datas[i][0]); + assert_int_equal(dynamic.string[1], datas[i][1]); + assert_int_equal(dynamic.string[2], datas[i][2]); + assert_int_equal(dynamic.string[3], datas[i][3]); + assert_int_equal(dynamic.string[4], datas[i][4]); + assert_int_equal(dynamic.used, F_fss_simple_packet_block_header_size_d); + + free(dynamic.string); + } // for + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_fss/tests/unit/c/test-fss-simple_packet_encode.h b/level_0/f_fss/tests/unit/c/test-fss-simple_packet_encode.h new file mode 100644 index 0000000..3aee967 --- /dev/null +++ b/level_0/f_fss/tests/unit/c/test-fss-simple_packet_encode.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: FSS + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the FSS project. + */ +#ifndef _TEST__F_fss__simple_packet_encode +#define _TEST__F_fss__simple_packet_encode + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_fss_simple_packet_encode() + */ +extern void test__f_fss_simple_packet_encode__parameter_checking(void **state); + +/** + * Test that the function works, with the control bit set to big endian. + * + * @see f_fss_simple_packet_encode() + */ +extern void test__f_fss_simple_packet_encode__works_big_endian(void **state); + +/** + * Test that the function works, with the control bit set to little endian. + * + * @see f_fss_simple_packet_encode() + */ +extern void test__f_fss_simple_packet_encode__works_little_endian(void **state); + +#endif // _TEST__F_fss__simple_packet_encode diff --git a/level_0/f_fss/tests/unit/c/test-fss.c b/level_0/f_fss/tests/unit/c/test-fss.c index cebf91d..950351b 100644 --- a/level_0/f_fss/tests/unit/c/test-fss.c +++ b/level_0/f_fss/tests/unit/c/test-fss.c @@ -129,11 +129,13 @@ int main(void) { cmocka_unit_test(test__f_fss_simple_packetss_delete_callback__works), cmocka_unit_test(test__f_fss_simple_packetss_destroy_callback__works), + cmocka_unit_test(test__f_fss_simple_packet_encode__works_little_endian), cmocka_unit_test(test__f_fss_simple_packet_extract__works_little_endian), cmocka_unit_test(test__f_fss_simple_packet_extract_range__works_little_endian), cmocka_unit_test(test__f_fss_simple_packet_extract__works_big_endian), cmocka_unit_test(test__f_fss_simple_packet_extract_range__works_big_endian), + cmocka_unit_test(test__f_fss_simple_packet_encode__works_big_endian), cmocka_unit_test(test__f_fss_simple_packet_extract__returns_packet_too_small), cmocka_unit_test(test__f_fss_simple_packet_extract_range__returns_packet_too_small), @@ -170,6 +172,7 @@ int main(void) { cmocka_unit_test(test__f_fss_simple_packet_delete__parameter_checking), cmocka_unit_test(test__f_fss_simple_packet_destroy__parameter_checking), + cmocka_unit_test(test__f_fss_simple_packet_encode__parameter_checking), cmocka_unit_test(test__f_fss_simple_packet_extract__parameter_checking), cmocka_unit_test(test__f_fss_simple_packet_extract_range__parameter_checking), diff --git a/level_0/f_fss/tests/unit/c/test-fss.h b/level_0/f_fss/tests/unit/c/test-fss.h index 8c0c0bd..5b7433a 100644 --- a/level_0/f_fss/tests/unit/c/test-fss.h +++ b/level_0/f_fss/tests/unit/c/test-fss.h @@ -67,6 +67,7 @@ #include "test-fss-set_quotes_destroy_callback.h" #include "test-fss-set_quotess_delete_callback.h" #include "test-fss-set_quotess_destroy_callback.h" +#include "test-fss-simple_packet_encode.h" #include "test-fss-simple_packet_extract.h" #include "test-fss-simple_packet_extract_range.h" #include "test-fss-simple_packet_delete.h" -- 1.8.3.1