From 42a2a579628d4aa8153775cdcd894b8b5c80e7da Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 6 Feb 2025 20:08:50 +0100 Subject: m + libradharc for client-side protocol implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libradharc.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 libradharc.c (limited to 'libradharc.c') diff --git a/libradharc.c b/libradharc.c new file mode 100644 index 0000000..32b47d9 --- /dev/null +++ b/libradharc.c @@ -0,0 +1,171 @@ +/* See LICENSE file for copyright and license details. */ +#include "libradharc.h" +#include + + +int +libradharc_parse_response(const void *msg, size_t msglen, struct libradharc_response *response_out) +{ + const unsigned char *m = msg; + int enum_value; + int64_t i64; + int32_t i32; + + if (!msg || !msglen || !response_out) { + errno = EINVAL; + return -1; + } + + response_out->type = (enum libradharc_response_type)*m++; + msglen--; + + switch (response_out->type) { + case LIBRADHARC_RESPONSE_UNSUPPORTED: + case LIBRADHARC_RESPONSE_INVALID_REQUEST: + case LIBRADHARC_RESPONSE_ACK: + case LIBRADHARC_RESPONSE_ACK_NOOP: + case LIBRADHARC_RESPONSE_UNSET: + case LIBRADHARC_RESPONSE_YES: + case LIBRADHARC_RESPONSE_NO: + if (msglen) + goto ebadmsg; + break; + + case LIBRADHARC_RESPONSE_ERROR_STRING: + case LIBRADHARC_RESPONSE_SET_STRING: + if (!msglen || m[--msglen] || memchr(m, 0, msglen)) + goto ebadmsg; + response_out->value.string = (const char *)m; + break; + + case LIBRADHARC_RESPONSE_SET_TIME: + if (msglen != sizeof(i64) + sizeof(i32)) + goto ebadmsg; + memcpy(&i64, &m[0], sizeof(i64)); + memcpy(&i32, &m[sizeof(i64)], sizeof(i32)); + response_out->value.time.tv_sec = (time_t)i64; + response_out->value.time.tv_nsec = i32; + if (response_out->value.time.tv_sec < 0 || + response_out->value.time.tv_nsec < 0 || + response_out->value.time.tv_nsec >= 1000000000L) + goto ebadmsg; + break; + + case LIBRADHARC_RESPONSE_SET_REAL: + if (msglen != sizeof(response_out->value.real)) + goto ebadmsg; + goto raw; + + case LIBRADHARC_RESPONSE_SET_REAL_PAIR: + if (msglen != sizeof(response_out->value.real_pair)) + goto ebadmsg; + goto raw; + + case LIBRADHARC_RESPONSE_SET_SIGNED64: + if (msglen != sizeof(response_out->value.signed64)) + goto ebadmsg; + raw: + memcpy(&response_out->value, m, msglen); + break; + + case LIBRADHARC_RESPONSE_SET_ENUM: + if (msglen != sizeof(enum_value)) + goto ebadmsg; + memcpy(&enum_value, m, sizeof(enum_value)); + response_out->value.operation_mode = (enum libradharc_operation_mode)enum_value; /* any enum */ + break; + + default: + ebadmsg: + errno = EBADMSG; + return -1; + } + + return 0; +} + + +size_t +libradharc_format_request__n__(void *buffer, enum libradharc_request_type type, int what, size_t n, ...) +{ + char *buf = buffer;; + size_t off = 0; + const char *value; + size_t size; + va_list args; + va_start(args, n); + + if (buf) + buf[off] = (char)((n << 4) | type); + off++; + + if (buf) + buf[off] = (char)what; + off++; + + while (n--) { + value = va_arg(args, const char *); + size = va_arg(args, size_t); + if (buf) + memcpy(&buf[off], value, size); + off += size; + } + + va_end(args); + return off; +} + + +extern inline size_t libradharc_format_request__0__(void *, enum libradharc_request_type, int); +extern inline size_t libradharc_format_request__1__(void *, enum libradharc_request_type, int, const void *, size_t); +extern inline size_t libradharc_format_request__2__(void *, enum libradharc_request_type, int, const void *, size_t, + const void *, size_t); +extern inline size_t libradharc_format_request__3__(void *, enum libradharc_request_type, int, const void *, size_t, + const void *, size_t, const void *, size_t); + +extern inline size_t libradharc_format_get_request__0__(void *, enum libradharc_property ); +extern inline size_t libradharc_format_get_request__s__(void *, enum libradharc_property , const char *); +extern inline size_t libradharc_format_set_request__64i__(void *, enum libradharc_property, int64_t); +extern inline size_t libradharc_format_set_request__i__(void *, enum libradharc_property, int); +extern inline size_t libradharc_format_set_request__r__(void *, enum libradharc_property, double); +extern inline size_t libradharc_format_set_request__rt__(void *, enum libradharc_property, double, const struct timespec *); +extern inline size_t libradharc_format_set_request__rr__(void *, enum libradharc_property, double, double); +extern inline size_t libradharc_format_set_request__s__(void *, enum libradharc_property, const char *); +extern inline size_t libradharc_format_set_request__ss__(void *, enum libradharc_property, const char *, const char *); +extern inline size_t libradharc_format_set_request__t__(void *, enum libradharc_property, const struct timespec *); +extern inline size_t libradharc_format_unset_request__0__(void *, enum libradharc_property); +extern inline size_t libradharc_format_signal_request__0__(void *, int); +extern inline size_t libradharc_format_signal_request__t__(void *, int, const struct timespec *); + +extern inline size_t libradharc_format_set_request__rnt__(void *, enum libradharc_property, double, const struct timespec *); +extern inline size_t libradharc_format_set_request__sns__(void *, enum libradharc_property, const char *, const char *); +extern inline size_t libradharc_format_signal_request__nt__(void *, int, const struct timespec *); + +extern inline size_t libradharc_format_set_fade_in(void *, const struct timespec *); +extern inline size_t libradharc_format_get_fade_in(void *); +extern inline size_t libradharc_format_set_fade_out(void *, const struct timespec *); +extern inline size_t libradharc_format_get_fade_out(void *); +extern inline size_t libradharc_format_set_high_temperature(void *, double); +extern inline size_t libradharc_format_get_high_temperature(void *); +extern inline size_t libradharc_format_set_low_temperature(void *, double); +extern inline size_t libradharc_format_get_low_temperature(void *); +extern inline size_t libradharc_format_set_high_elevation(void *, double); +extern inline size_t libradharc_format_get_high_elevation(void *); +extern inline size_t libradharc_format_set_low_elevation(void *, double); +extern inline size_t libradharc_format_get_low_elevation(void *); +extern inline size_t libradharc_format_set_location(void *, double, double); +extern inline size_t libradharc_format_get_location(void *); +extern inline size_t libradharc_format_unset_location(void *); +extern inline size_t libradharc_format_set_operation_mode(void *, enum libradharc_operation_mode); +extern inline size_t libradharc_format_get_operation_mode(void *); +extern inline size_t libradharc_format_set_temperature(void *, double, const struct timespec *); +extern inline size_t libradharc_format_get_temperature(void *); +extern inline size_t libradharc_format_set_priority(void *, int64_t); +extern inline size_t libradharc_format_get_priority(void *); +extern inline size_t libradharc_format_set_vendor_option(void *, const char *, const char *); +extern inline size_t libradharc_format_get_vendor_option(void *, const char *); +extern inline size_t libradharc_format_get_status(void *); +extern inline size_t libradharc_format_smooth_terminate(void *, const struct timespec *); +extern inline size_t libradharc_format_freeze_terminate(void *); +extern inline size_t libradharc_format_disable(void *, const struct timespec *); +extern inline size_t libradharc_format_enable(void *, const struct timespec *); -- cgit v1.2.3-70-g09d2