diff options
| author | lonkaars <loek@pipeframe.xyz> | 2022-12-12 13:57:33 +0100 | 
|---|---|---|
| committer | lonkaars <loek@pipeframe.xyz> | 2022-12-12 13:57:33 +0100 | 
| commit | 61dd8a5ee66734dfd53ee9be725c9e71fd8d5414 (patch) | |
| tree | da896421d93baa3a80a7c6ebb3a16fc25138516f /shared | |
| parent | 8c21a929d06ed108b0e64f3892d036cd4cd67e51 (diff) | |
implement DYN_MEMBER_SIZEOF macro correctly and implement cd_cmd_response_sizeof
Diffstat (limited to 'shared')
| -rw-r--r-- | shared/bin.c | 8 | ||||
| -rw-r--r-- | shared/bin.h | 16 | ||||
| -rw-r--r-- | shared/protocol-tests/ping-response.bin | bin | 0 -> 10 bytes | |||
| -rw-r--r-- | shared/protocol.c | 32 | 
4 files changed, 51 insertions, 5 deletions
| diff --git a/shared/bin.c b/shared/bin.c index fdceb30..875d013 100644 --- a/shared/bin.c +++ b/shared/bin.c @@ -65,6 +65,14 @@ uint16_t cd_bin_hton16(uint16_t h16) {  uint32_t cd_bin_ntoh32(uint32_t n32) { return cd_bin_hton32(n32); }  uint16_t cd_bin_ntoh16(uint16_t n16) { return cd_bin_hton16(n16); } +uint32_t cd_bin_ntohd(uint8_t* n, size_t s) { return cd_bin_htond(n, s); } + +uint32_t cd_bin_htond(uint8_t* h, size_t s) { +	if (s == sizeof(uint8_t)) return *h; +	else if (s == sizeof(uint16_t)) return cd_bin_hton16(*(uint16_t*) h); +	else if (s == sizeof(uint32_t)) return cd_bin_hton32(*(uint32_t*) h); +	else return 0; +}  cd_s_bin *cd_bin_s_alloc(uint16_t bytes, uint8_t *data) {  	cd_s_bin *temp = malloc(sizeof(cd_s_bin) + sizeof(uint8_t) * bytes); diff --git a/shared/bin.h b/shared/bin.h index 35d2bc4..0e16ec0 100644 --- a/shared/bin.h +++ b/shared/bin.h @@ -10,6 +10,7 @@   */  #include <stdint.h> +#include <malloc.h>  #ifdef __cplusplus  extern "C" { @@ -50,6 +51,21 @@ uint32_t cd_bin_ntoh32(uint32_t n32);  /** @brief convert 16-bit value from network (big-endian) to host endian */  uint16_t cd_bin_ntoh16(uint16_t n16); +/** + * @brief convert (8*s)-bit value from network (big-endian) to host endian + * (dynamic size) + * + * @param n  pointer to number + * @param s  size of number in bytes + *  + * @return 32-bit integer regardless of `s` + * + * this function is exclusively used by the CD_DYN_MEMBER_SIZEOF macro in + * shared/protocol.c + */ +uint32_t cd_bin_ntohd(uint8_t* n, size_t s); +uint32_t cd_bin_htond(uint8_t* h, size_t s); +  /** @brief replace 32-bit value from host endian to network (big-endian) */  void cd_bin_repl_hton32(uint32_t *h32);  /** @brief replace 16-bit value from host endian to network (big-endian) */ diff --git a/shared/protocol-tests/ping-response.bin b/shared/protocol-tests/ping-response.binBinary files differ new file mode 100644 index 0000000..6067349 --- /dev/null +++ b/shared/protocol-tests/ping-response.bin diff --git a/shared/protocol.c b/shared/protocol.c index 474398a..1d66f17 100644 --- a/shared/protocol.c +++ b/shared/protocol.c @@ -1,3 +1,5 @@ +#include <stddef.h> +  #include "protocol.h"  #ifdef __cplusplus @@ -16,13 +18,33 @@ size_t cd_cmd_sizeof(uint8_t data[CD_SERIAL_READ_BUFFER_SIZE], uint8_t data_leng  	return length;  } -#define CD_DYN_MEMBER_SIZEOF(struct_t, length_byte, trailing_type)                                 \ -	sizeof(struct_t) +                                                                             \ -		(data->bytes > length_byte ? (sizeof(trailing_type) * data->data[length_byte]) : 0) +/** + * @brief macro to calculate size of message based on struct with member to + * indicate length of dynamic (last) field + * + * @param data  cd_s_bin pointer to currently received data + * @param struct_t  message struct + * @param length_field  struct field with dynamic length + * + * @return size_t with calculated size + * + * equivalent c code: + * + * size_t size = sizeof(struct_t); + * size_t dyn_member_offset = offsetof(struct_t, length_field); + * size_t dyn_member_size = sizeof(((struct_t*)0)->length_field); + * if (data->bytes >= (dyn_member_offset + dyn_member_size)) + *     size += cd_bin_ntohd(&data->data[dyn_member_offset], dyn_member_size); + * return size; + */ +#define CD_DYN_MEMBER_SIZEOF(data, struct_t, length_field) \ +	sizeof(struct_t) + ( \ +	(data->bytes >= (offsetof(struct_t, length_field) + sizeof(((struct_t*)0)->length_field))) ? \ +		(cd_bin_ntohd(&data->data[offsetof(struct_t, length_field)], sizeof(((struct_t*)0)->length_field))) :\ +		0);  size_t cd_cmd_response_sizeof(cd_s_bin* data) { -	(void) data; // unused variable TODO: implement this -	return 0; +	return CD_DYN_MEMBER_SIZEOF(data, cd_s_cmd_response, response_size);  }  #ifdef __cplusplus |