aboutsummaryrefslogblamecommitdiffstats
path: root/libradharc.c
blob: 32b47d9d80b1ae749404a45bb6cd206cfa55bb90 (plain) (tree)










































































































































































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