/* 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 *);