aboutsummaryrefslogtreecommitdiffstats
path: root/libradharc.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2025-02-06 20:08:50 +0100
committerMattias Andrée <m@maandree.se>2025-02-06 20:08:50 +0100
commit42a2a579628d4aa8153775cdcd894b8b5c80e7da (patch)
tree992dd3b057a7a18d2258b131c83ff56fd84587a8 /libradharc.c
parentm (diff)
downloadradharc-42a2a579628d4aa8153775cdcd894b8b5c80e7da.tar.gz
radharc-42a2a579628d4aa8153775cdcd894b8b5c80e7da.tar.bz2
radharc-42a2a579628d4aa8153775cdcd894b8b5c80e7da.tar.xz
m + libradharc for client-side protocol implementation
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libradharc.c')
-rw-r--r--libradharc.c171
1 files changed, 171 insertions, 0 deletions
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 <stdarg.h>
+
+
+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 *);