aboutsummaryrefslogtreecommitdiffstats
path: root/libradharc.c
blob: 32b47d9d80b1ae749404a45bb6cd206cfa55bb90 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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 *);