source: roaraudio/libroarlight/roardmx.c @ 6001:872d916b8ca0

Last change on this file since 6001:872d916b8ca0 was 6001:872d916b8ca0, checked in by phi, 10 years ago

added some support for CONTROL messages to libroarlight's RoarDMX support

File size: 21.4 KB
Line 
1//roardmx.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014
5 *
6 *  This file is part of libroardsp a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroardsp is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "libroarlight.h"
27
28// base(ic) check
29#define BCHK(x) if ( (x) == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; }
30
31// database access:
32static const struct {
33 const int id;
34 const char * const name;
35} __eventnames[] = {
36//$ grep '^#define ROAR_ROARDMX_EVENT_' roardmx.h | cut -d ' ' -f2 | while read line; do name=`echo $line | cut -d_ -f4 | tr A-Z a-z`; for suffix in beat off on hold; do printf " {%-56s \"%s\"},\n" "$line|ROAR_ROARDMX_ETYPE_`tr a-z A-Z <<<$suffix`," $name-$suffix; done; printf " {%-56s \"%s\"},\n" $line, $name; done
37 {ROAR_ROARDMX_EVENT_NONE|ROAR_ROARDMX_ETYPE_BEAT,         "none-beat"},
38 {ROAR_ROARDMX_EVENT_NONE|ROAR_ROARDMX_ETYPE_OFF,          "none-off"},
39 {ROAR_ROARDMX_EVENT_NONE|ROAR_ROARDMX_ETYPE_ON,           "none-on"},
40 {ROAR_ROARDMX_EVENT_NONE|ROAR_ROARDMX_ETYPE_HOLD,         "none-hold"},
41 {ROAR_ROARDMX_EVENT_NONE,                                 "none"},
42 {ROAR_ROARDMX_EVENT_STEP|ROAR_ROARDMX_ETYPE_BEAT,         "step-beat"},
43 {ROAR_ROARDMX_EVENT_STEP|ROAR_ROARDMX_ETYPE_OFF,          "step-off"},
44 {ROAR_ROARDMX_EVENT_STEP|ROAR_ROARDMX_ETYPE_ON,           "step-on"},
45 {ROAR_ROARDMX_EVENT_STEP|ROAR_ROARDMX_ETYPE_HOLD,         "step-hold"},
46 {ROAR_ROARDMX_EVENT_STEP,                                 "step"},
47 {ROAR_ROARDMX_EVENT_TAP|ROAR_ROARDMX_ETYPE_BEAT,          "tap-beat"},
48 {ROAR_ROARDMX_EVENT_TAP|ROAR_ROARDMX_ETYPE_OFF,           "tap-off"},
49 {ROAR_ROARDMX_EVENT_TAP|ROAR_ROARDMX_ETYPE_ON,            "tap-on"},
50 {ROAR_ROARDMX_EVENT_TAP|ROAR_ROARDMX_ETYPE_HOLD,          "tap-hold"},
51 {ROAR_ROARDMX_EVENT_TAP,                                  "tap"},
52 {ROAR_ROARDMX_EVENT_BEAT|ROAR_ROARDMX_ETYPE_BEAT,         "beat-beat"},
53 {ROAR_ROARDMX_EVENT_BEAT|ROAR_ROARDMX_ETYPE_OFF,          "beat-off"},
54 {ROAR_ROARDMX_EVENT_BEAT|ROAR_ROARDMX_ETYPE_ON,           "beat-on"},
55 {ROAR_ROARDMX_EVENT_BEAT|ROAR_ROARDMX_ETYPE_HOLD,         "beat-hold"},
56 {ROAR_ROARDMX_EVENT_BEAT,                                 "beat"},
57 {ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_BEAT,     "blackout-beat"},
58 {ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_OFF,      "blackout-off"},
59 {ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_ON,       "blackout-on"},
60 {ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_HOLD,     "blackout-hold"},
61 {ROAR_ROARDMX_EVENT_BLACKOUT,                             "blackout"},
62 {ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_BEAT,       "fullon-beat"},
63 {ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_OFF,        "fullon-off"},
64 {ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_ON,         "fullon-on"},
65 {ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_HOLD,       "fullon-hold"},
66 {ROAR_ROARDMX_EVENT_FULLON,                               "fullon"},
67 {ROAR_ROARDMX_EVENT_FLASH|ROAR_ROARDMX_ETYPE_BEAT,        "flash-beat"},
68 {ROAR_ROARDMX_EVENT_FLASH|ROAR_ROARDMX_ETYPE_OFF,         "flash-off"},
69 {ROAR_ROARDMX_EVENT_FLASH|ROAR_ROARDMX_ETYPE_ON,          "flash-on"},
70 {ROAR_ROARDMX_EVENT_FLASH|ROAR_ROARDMX_ETYPE_HOLD,        "flash-hold"},
71 {ROAR_ROARDMX_EVENT_FLASH,                                "flash"},
72 {ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_BEAT,       "strobe-beat"},
73 {ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_OFF,        "strobe-off"},
74 {ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_ON,         "strobe-on"},
75 {ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_HOLD,       "strobe-hold"},
76 {ROAR_ROARDMX_EVENT_STROBE,                               "strobe"},
77 {ROAR_ROARDMX_EVENT_STROBEREADY|ROAR_ROARDMX_ETYPE_BEAT,  "strobeready-beat"},
78 {ROAR_ROARDMX_EVENT_STROBEREADY|ROAR_ROARDMX_ETYPE_OFF,   "strobeready-off"},
79 {ROAR_ROARDMX_EVENT_STROBEREADY|ROAR_ROARDMX_ETYPE_ON,    "strobeready-on"},
80 {ROAR_ROARDMX_EVENT_STROBEREADY|ROAR_ROARDMX_ETYPE_HOLD,  "strobeready-hold"},
81 {ROAR_ROARDMX_EVENT_STROBEREADY,                          "strobeready"},
82 {ROAR_ROARDMX_EVENT_STROBELOAD|ROAR_ROARDMX_ETYPE_BEAT,   "strobeload-beat"},
83 {ROAR_ROARDMX_EVENT_STROBELOAD|ROAR_ROARDMX_ETYPE_OFF,    "strobeload-off"},
84 {ROAR_ROARDMX_EVENT_STROBELOAD|ROAR_ROARDMX_ETYPE_ON,     "strobeload-on"},
85 {ROAR_ROARDMX_EVENT_STROBELOAD|ROAR_ROARDMX_ETYPE_HOLD,   "strobeload-hold"},
86 {ROAR_ROARDMX_EVENT_STROBELOAD,                           "strobeload"},
87 {ROAR_ROARDMX_EVENT_FOG|ROAR_ROARDMX_ETYPE_BEAT,          "fog-beat"},
88 {ROAR_ROARDMX_EVENT_FOG|ROAR_ROARDMX_ETYPE_OFF,           "fog-off"},
89 {ROAR_ROARDMX_EVENT_FOG|ROAR_ROARDMX_ETYPE_ON,            "fog-on"},
90 {ROAR_ROARDMX_EVENT_FOG|ROAR_ROARDMX_ETYPE_HOLD,          "fog-hold"},
91 {ROAR_ROARDMX_EVENT_FOG,                                  "fog"},
92 {ROAR_ROARDMX_EVENT_FOGREADY|ROAR_ROARDMX_ETYPE_BEAT,     "fogready-beat"},
93 {ROAR_ROARDMX_EVENT_FOGREADY|ROAR_ROARDMX_ETYPE_OFF,      "fogready-off"},
94 {ROAR_ROARDMX_EVENT_FOGREADY|ROAR_ROARDMX_ETYPE_ON,       "fogready-on"},
95 {ROAR_ROARDMX_EVENT_FOGREADY|ROAR_ROARDMX_ETYPE_HOLD,     "fogready-hold"},
96 {ROAR_ROARDMX_EVENT_FOGREADY,                             "fogready"},
97 {ROAR_ROARDMX_EVENT_FOGHEAT|ROAR_ROARDMX_ETYPE_BEAT,      "fogheat-beat"},
98 {ROAR_ROARDMX_EVENT_FOGHEAT|ROAR_ROARDMX_ETYPE_OFF,       "fogheat-off"},
99 {ROAR_ROARDMX_EVENT_FOGHEAT|ROAR_ROARDMX_ETYPE_ON,        "fogheat-on"},
100 {ROAR_ROARDMX_EVENT_FOGHEAT|ROAR_ROARDMX_ETYPE_HOLD,      "fogheat-hold"},
101 {ROAR_ROARDMX_EVENT_FOGHEAT,                              "fogheat"},
102
103 // User Defined events:
104 {ROAR_ROARDMX_EVENT_USER0,                                "user0"},
105 {ROAR_ROARDMX_EVENT_USER1|ROAR_ROARDMX_ETYPE_BEAT,        "user1-beat"},
106 {ROAR_ROARDMX_EVENT_USER1|ROAR_ROARDMX_ETYPE_OFF,         "user1-off"},
107 {ROAR_ROARDMX_EVENT_USER1|ROAR_ROARDMX_ETYPE_ON,          "user1-on"},
108 {ROAR_ROARDMX_EVENT_USER1|ROAR_ROARDMX_ETYPE_HOLD,        "user1-hold"},
109 {ROAR_ROARDMX_EVENT_USER1,                                "user1"},
110 {ROAR_ROARDMX_EVENT_USER2|ROAR_ROARDMX_ETYPE_BEAT,        "user2-beat"},
111 {ROAR_ROARDMX_EVENT_USER2|ROAR_ROARDMX_ETYPE_OFF,         "user2-off"},
112 {ROAR_ROARDMX_EVENT_USER2|ROAR_ROARDMX_ETYPE_ON,          "user2-on"},
113 {ROAR_ROARDMX_EVENT_USER2|ROAR_ROARDMX_ETYPE_HOLD,        "user2-hold"},
114 {ROAR_ROARDMX_EVENT_USER2,                                "user2"},
115 {ROAR_ROARDMX_EVENT_USER3|ROAR_ROARDMX_ETYPE_BEAT,        "user3-beat"},
116 {ROAR_ROARDMX_EVENT_USER3|ROAR_ROARDMX_ETYPE_OFF,         "user3-off"},
117 {ROAR_ROARDMX_EVENT_USER3|ROAR_ROARDMX_ETYPE_ON,          "user3-on"},
118 {ROAR_ROARDMX_EVENT_USER3|ROAR_ROARDMX_ETYPE_HOLD,        "user3-hold"},
119 {ROAR_ROARDMX_EVENT_USER3,                                "user3"},
120 {ROAR_ROARDMX_EVENT_USER4|ROAR_ROARDMX_ETYPE_BEAT,        "user4-beat"},
121 {ROAR_ROARDMX_EVENT_USER4|ROAR_ROARDMX_ETYPE_OFF,         "user4-off"},
122 {ROAR_ROARDMX_EVENT_USER4|ROAR_ROARDMX_ETYPE_ON,          "user4-on"},
123 {ROAR_ROARDMX_EVENT_USER4|ROAR_ROARDMX_ETYPE_HOLD,        "user4-hold"},
124 {ROAR_ROARDMX_EVENT_USER4,                                "user4"},
125 {ROAR_ROARDMX_EVENT_USER5|ROAR_ROARDMX_ETYPE_BEAT,        "user5-beat"},
126 {ROAR_ROARDMX_EVENT_USER5|ROAR_ROARDMX_ETYPE_OFF,         "user5-off"},
127 {ROAR_ROARDMX_EVENT_USER5|ROAR_ROARDMX_ETYPE_ON,          "user5-on"},
128 {ROAR_ROARDMX_EVENT_USER5|ROAR_ROARDMX_ETYPE_HOLD,        "user5-hold"},
129 {ROAR_ROARDMX_EVENT_USER5,                                "user5"},
130 {ROAR_ROARDMX_EVENT_USER6|ROAR_ROARDMX_ETYPE_BEAT,        "user6-beat"},
131 {ROAR_ROARDMX_EVENT_USER6|ROAR_ROARDMX_ETYPE_OFF,         "user6-off"},
132 {ROAR_ROARDMX_EVENT_USER6|ROAR_ROARDMX_ETYPE_ON,          "user6-on"},
133 {ROAR_ROARDMX_EVENT_USER6|ROAR_ROARDMX_ETYPE_HOLD,        "user6-hold"},
134 {ROAR_ROARDMX_EVENT_USER6,                                "user6"},
135 {ROAR_ROARDMX_EVENT_USER7|ROAR_ROARDMX_ETYPE_BEAT,        "user7-beat"},
136 {ROAR_ROARDMX_EVENT_USER7|ROAR_ROARDMX_ETYPE_OFF,         "user7-off"},
137 {ROAR_ROARDMX_EVENT_USER7|ROAR_ROARDMX_ETYPE_ON,          "user7-on"},
138 {ROAR_ROARDMX_EVENT_USER7|ROAR_ROARDMX_ETYPE_HOLD,        "user7-hold"},
139 {ROAR_ROARDMX_EVENT_USER7,                                "user7"},
140 {ROAR_ROARDMX_EVENT_USER8|ROAR_ROARDMX_ETYPE_BEAT,        "user8-beat"},
141 {ROAR_ROARDMX_EVENT_USER8|ROAR_ROARDMX_ETYPE_OFF,         "user8-off"},
142 {ROAR_ROARDMX_EVENT_USER8|ROAR_ROARDMX_ETYPE_ON,          "user8-on"},
143 {ROAR_ROARDMX_EVENT_USER8|ROAR_ROARDMX_ETYPE_HOLD,        "user8-hold"},
144 {ROAR_ROARDMX_EVENT_USER8,                                "user8"},
145 {ROAR_ROARDMX_EVENT_USER9|ROAR_ROARDMX_ETYPE_BEAT,        "user9-beat"},
146 {ROAR_ROARDMX_EVENT_USER9|ROAR_ROARDMX_ETYPE_OFF,         "user9-off"},
147 {ROAR_ROARDMX_EVENT_USER9|ROAR_ROARDMX_ETYPE_ON,          "user9-on"},
148 {ROAR_ROARDMX_EVENT_USER9|ROAR_ROARDMX_ETYPE_HOLD,        "user9-hold"},
149 {ROAR_ROARDMX_EVENT_USER9,                                "user9"},
150 {ROAR_ROARDMX_EVENT_USER10|ROAR_ROARDMX_ETYPE_BEAT,       "user10-beat"},
151 {ROAR_ROARDMX_EVENT_USER10|ROAR_ROARDMX_ETYPE_OFF,        "user10-off"},
152 {ROAR_ROARDMX_EVENT_USER10|ROAR_ROARDMX_ETYPE_ON,         "user10-on"},
153 {ROAR_ROARDMX_EVENT_USER10|ROAR_ROARDMX_ETYPE_HOLD,       "user10-hold"},
154 {ROAR_ROARDMX_EVENT_USER10,                               "user10"},
155 {ROAR_ROARDMX_EVENT_USER11|ROAR_ROARDMX_ETYPE_BEAT,       "user11-beat"},
156 {ROAR_ROARDMX_EVENT_USER11|ROAR_ROARDMX_ETYPE_OFF,        "user11-off"},
157 {ROAR_ROARDMX_EVENT_USER11|ROAR_ROARDMX_ETYPE_ON,         "user11-on"},
158 {ROAR_ROARDMX_EVENT_USER11|ROAR_ROARDMX_ETYPE_HOLD,       "user11-hold"},
159 {ROAR_ROARDMX_EVENT_USER11,                               "user11"},
160 {ROAR_ROARDMX_EVENT_USER12|ROAR_ROARDMX_ETYPE_BEAT,       "user12-beat"},
161 {ROAR_ROARDMX_EVENT_USER12|ROAR_ROARDMX_ETYPE_OFF,        "user12-off"},
162 {ROAR_ROARDMX_EVENT_USER12|ROAR_ROARDMX_ETYPE_ON,         "user12-on"},
163 {ROAR_ROARDMX_EVENT_USER12|ROAR_ROARDMX_ETYPE_HOLD,       "user12-hold"},
164 {ROAR_ROARDMX_EVENT_USER12,                               "user12"},
165 {ROAR_ROARDMX_EVENT_USER13|ROAR_ROARDMX_ETYPE_BEAT,       "user13-beat"},
166 {ROAR_ROARDMX_EVENT_USER13|ROAR_ROARDMX_ETYPE_OFF,        "user13-off"},
167 {ROAR_ROARDMX_EVENT_USER13|ROAR_ROARDMX_ETYPE_ON,         "user13-on"},
168 {ROAR_ROARDMX_EVENT_USER13|ROAR_ROARDMX_ETYPE_HOLD,       "user13-hold"},
169 {ROAR_ROARDMX_EVENT_USER13,                               "user13"},
170 {ROAR_ROARDMX_EVENT_USER14|ROAR_ROARDMX_ETYPE_BEAT,       "user14-beat"},
171 {ROAR_ROARDMX_EVENT_USER14|ROAR_ROARDMX_ETYPE_OFF,        "user14-off"},
172 {ROAR_ROARDMX_EVENT_USER14|ROAR_ROARDMX_ETYPE_ON,         "user14-on"},
173 {ROAR_ROARDMX_EVENT_USER14|ROAR_ROARDMX_ETYPE_HOLD,       "user14-hold"},
174 {ROAR_ROARDMX_EVENT_USER14,                               "user14"},
175 {ROAR_ROARDMX_EVENT_USER15|ROAR_ROARDMX_ETYPE_BEAT,       "user15-beat"},
176 {ROAR_ROARDMX_EVENT_USER15|ROAR_ROARDMX_ETYPE_OFF,        "user15-off"},
177 {ROAR_ROARDMX_EVENT_USER15|ROAR_ROARDMX_ETYPE_ON,         "user15-on"},
178 {ROAR_ROARDMX_EVENT_USER15|ROAR_ROARDMX_ETYPE_HOLD,       "user15-hold"},
179 {ROAR_ROARDMX_EVENT_USER15,                               "user15"}
180};
181
182int roar_roardmx_str2event(const char * event) {
183 size_t i;
184
185 if ( event == NULL ) {
186  roar_err_set(ROAR_ERROR_FAULT);
187  return -1;
188 }
189
190 for (i = 0; i < (sizeof(__eventnames)/sizeof(*__eventnames)); i++)
191  if ( !strcasecmp(event, __eventnames[i].name) )
192   return __eventnames[i].id;
193
194 roar_err_set(ROAR_ERROR_NOENT);
195 return -1;
196}
197
198const char * roar_roardmx_event2str(const int event) {
199 size_t i;
200
201 for (i = 0; i < (sizeof(__eventnames)/sizeof(*__eventnames)); i++)
202  if ( __eventnames[i].id == event )
203   return __eventnames[i].name;
204
205 roar_err_set(ROAR_ERROR_NOENT);
206 return NULL;
207}
208
209// generic things:
210int roar_roardmx_message_new (struct roar_roardmx_message * mes) {
211 BCHK(mes);
212
213 memset(mes, 0, sizeof(struct roar_roardmx_message));
214
215 mes->version = ROAR_ROARDMX_VERSION;
216
217 return 0;
218}
219
220// low level:
221//int roar_roardmx_message_set_flag(struct roar_roardmx_message * mes, unsigned char   flag);
222//int roar_roardmx_message_set_len (struct roar_roardmx_message * mes, size_t          type);
223//int roar_roardmx_message_get_data(struct roar_roardmx_message * mes, unsigned char ** data);
224
225// medium level:
226int roar_roardmx_message_set_type(struct roar_roardmx_message * mes, unsigned char   type) {
227 BCHK(mes);
228
229 // check if type contains non-type bits.
230 if ( (type | ROAR_ROARDMX_MASK_TYPE) - ROAR_ROARDMX_MASK_TYPE ) {
231  roar_err_set(ROAR_ERROR_INVAL);
232  return -1;
233 }
234
235 mes->type = type;
236
237 return 0;
238}
239
240int roar_roardmx_message_get_flag(struct roar_roardmx_message * mes, unsigned char * flag) {
241 BCHK(mes);
242
243 *flag = mes->flags;
244
245 return 0;
246}
247
248int roar_roardmx_message_get_type(struct roar_roardmx_message * mes, unsigned char * type) {
249 BCHK(mes);
250
251 *type = mes->type;
252
253 return 0;
254}
255
256int roar_roardmx_message_get_len (struct roar_roardmx_message * mes, size_t        * length) {
257 BCHK(mes);
258
259 *length = mes->length;
260
261 return 0;
262}
263
264
265// IO:
266int roar_roardmx_message_send(struct roar_roardmx_message * mes, struct roar_vio_calls * vio) {
267 BCHK(mes);
268 BCHK(vio);
269
270 if ( mes->length > ROAR_ROARDMX_DATA_LENGTH ) { // this is very fatal!
271  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL);
272  roar_err_set(ROAR_ERROR_FAULT);
273  return -1;
274 }
275
276 mes->data[0] =  mes->version;
277 mes->data[1] = (mes->flags & ROAR_ROARDMX_MASK_FLAGS) |
278                (mes->type  & ROAR_ROARDMX_MASK_TYPE ) ;
279
280 mes->data[2] = mes->length;
281
282 return roar_vio_write(vio, mes->data, mes->length + 3) == (ssize_t)(mes->length + 3) ? 0 : -1;
283}
284
285int roar_roardmx_message_recv(struct roar_roardmx_message * mes, struct roar_vio_calls * vio) {
286 BCHK(mes);
287 BCHK(vio);
288
289 if ( roar_roardmx_message_new(mes) == -1 )
290  return -1;
291
292 if ( roar_vio_read(vio, mes->data, 3) != 3 )
293  return -1;
294
295 mes->version = mes->data[0];
296
297 if ( mes->version != ROAR_ROARDMX_VERSION ) {
298  roar_err_set(ROAR_ERROR_NSVERSION);
299  return -1;
300 }
301
302 mes->flags  = mes->data[1] & ROAR_ROARDMX_MASK_FLAGS;
303 mes->type   = mes->data[1] & ROAR_ROARDMX_MASK_TYPE;
304
305 mes->length = mes->data[2];
306
307 if ( roar_vio_read(vio, &(mes->data[3]), mes->length) != (ssize_t)mes->length )
308  return -1;
309
310 return 0;
311}
312
313// Data/high level:
314// * *:
315int roar_roardmx_message_add_chanval(struct roar_roardmx_message * mes, uint16_t channel, unsigned char val) {
316 register uint16_t * chan;
317
318 BCHK(mes);
319
320 switch (mes->type) {
321  case ROAR_ROARDMX_TYPE_SSET:
322  case ROAR_ROARDMX_TYPE_INC8S:
323   break;
324  default:
325    roar_err_set(ROAR_ERROR_TYPEMM);
326    return -1;
327   break;
328 }
329
330 if ( (mes->length + 3) > ROAR_ROARDMX_DATA_LENGTH ) { // message would be to long
331  roar_err_set(ROAR_ERROR_NOSPC);
332  return -1;
333 }
334
335 chan = (uint16_t *) &(mes->data[mes->length + 3]);
336
337 *chan = ROAR_HOST2NET16(channel);
338
339 mes->data[mes->length + 2 + 3] = val;
340
341 mes->length += 3;
342
343 return 0;
344}
345
346int roar_roardmx_message_get_chanval(struct roar_roardmx_message * mes, uint16_t * channel, unsigned char * val, int index) {
347 register uint16_t * chan;
348
349 BCHK(mes);
350
351 if ( index < 0 ) {
352  roar_err_set(ROAR_ERROR_INVAL);
353  return -1;
354 }
355
356 if ( mes->version != ROAR_ROARDMX_VERSION ) {
357  roar_err_set(ROAR_ERROR_NSVERSION);
358  return -1;
359 }
360
361 switch (mes->type) {
362  case ROAR_ROARDMX_TYPE_SSET:
363  case ROAR_ROARDMX_TYPE_INC8S:
364    if ( index >= (ROAR_ROARDMX_DATA_LENGTH/3) )
365     return -1;
366
367    *val     = mes->data[3 * index + 2 + 3];
368    chan     = (uint16_t *) &(mes->data[3 + 3 * index]);
369    *channel = ROAR_NET2HOST16(*chan);
370    return 0;
371   break;
372 }
373
374 roar_err_set(ROAR_ERROR_NSTYPE);
375 return -1;
376}
377
378int roar_roardmx_message_numchannels(struct roar_roardmx_message * mes) {
379 BCHK(mes);
380
381 if ( mes->version != ROAR_ROARDMX_VERSION ) {
382  roar_err_set(ROAR_ERROR_NSVERSION);
383  return -1;
384 }
385
386 switch (mes->type) {
387  case ROAR_ROARDMX_TYPE_SSET:
388  case ROAR_ROARDMX_TYPE_INC8S:
389    return mes->length /  3;
390   break;
391  case ROAR_ROARDMX_TYPE_IPO1:
392    return mes->length /  6;
393   break;
394  case ROAR_ROARDMX_TYPE_IPO4:
395    return mes->length / 12;
396   break;
397  case ROAR_ROARDMX_TYPE_RANGESET:
398    return mes->length /  5;
399   break;
400  case ROAR_ROARDMX_TYPE_EVENT:
401  case ROAR_ROARDMX_TYPE_CONTROL:
402    return 0;
403   break;
404 }
405
406 roar_err_set(ROAR_ERROR_NSTYPE);
407 return -1;
408}
409
410// * SSET:
411int roar_roardmx_message_new_sset   (struct roar_roardmx_message * mes) {
412 BCHK(mes);
413
414 if ( roar_roardmx_message_new(mes) == -1 )
415  return -1;
416
417 mes->type = ROAR_ROARDMX_TYPE_SSET;
418
419 return 0;
420}
421
422// * IPO1:
423// Not yet supported.
424// * IPO4:
425// Not yet supported.
426// * INC8S:
427// Not yet supported.
428// * RANGESET:
429int roar_roardmx_message_new_rangeset(struct roar_roardmx_message * mes) {
430 BCHK(mes);
431
432 if ( roar_roardmx_message_new(mes) == -1 )
433  return -1;
434
435 mes->type = ROAR_ROARDMX_TYPE_RANGESET;
436
437 return 0;
438}
439
440int roar_roardmx_message_add_rangeval(struct roar_roardmx_message * mes, uint16_t   start, uint16_t   end, unsigned char   val) {
441 register uint8_t * p;
442
443 BCHK(mes);
444
445 if ( mes->type != ROAR_ROARDMX_TYPE_RANGESET ) {
446  roar_err_set(ROAR_ERROR_TYPEMM);
447  return -1;
448 }
449
450 if ( (mes->length + 5) > ROAR_ROARDMX_DATA_LENGTH ) { // message would be to long
451  roar_err_set(ROAR_ERROR_NOSPC);
452  return -1;
453 }
454
455 if ( start > end ) {
456  roar_err_set(ROAR_ERROR_RANGE);
457  return -1;
458 }
459
460 p = mes->data + 3 + mes->length;
461
462 p[0] = (start & 0xFF00) >> 8;
463 p[1] = (start & 0x00FF);
464 p[2] = (end   & 0xFF00) >> 8;
465 p[3] = (end   & 0x00FF);
466 p[4] = val;
467
468 mes->length += 5;
469
470 return 0;
471}
472
473int roar_roardmx_message_get_rangeval(struct roar_roardmx_message * mes, uint16_t * start, uint16_t * end, unsigned char * val, int index) {
474 register uint8_t * p;
475 register uint16_t v;
476
477 BCHK(mes);
478
479 if ( index < 0 ) {
480  roar_err_set(ROAR_ERROR_INVAL);
481  return -1;
482 }
483
484 if ( mes->version != ROAR_ROARDMX_VERSION ) {
485  roar_err_set(ROAR_ERROR_NSVERSION);
486  return -1;
487 }
488
489 if ( mes->type != ROAR_ROARDMX_TYPE_RANGESET ) {
490  roar_err_set(ROAR_ERROR_TYPEMM);
491  return -1;
492 }
493
494 if ( (((size_t)index + 1) * 5) > mes->length ) {
495  ROAR_DBG("roar_roardmx_message_get_rangeval(mes=%p{.length=%i, ...}, start=%p, end=%p, val=%p, index=%i) = ?", mes, (int)mes->length, start, end, val, index);
496  roar_err_set(ROAR_ERROR_NOENT);
497  return -1;
498 }
499
500 p = mes->data + 3 + index * 5;
501
502 v   = *(p++);
503 v <<= 8;
504 v  += *(p++);
505 *start = v;
506
507 v   = *(p++);
508 v <<= 8;
509 v  += *(p++);
510 *end = v;
511
512 *val = *p;
513
514 return 0;
515}
516
517// * EVENT:
518int roar_roardmx_message_new_event(struct roar_roardmx_message * mes) {
519 BCHK(mes);
520
521 if ( roar_roardmx_message_new(mes) == -1 )
522  return -1;
523
524 mes->type = ROAR_ROARDMX_TYPE_EVENT;
525
526 return 0;
527}
528
529int roar_roardmx_message_add_events(struct roar_roardmx_message * mes, const uint8_t * events, size_t len) {
530 BCHK(mes);
531
532 if ( mes->type != ROAR_ROARDMX_TYPE_EVENT ) {
533  roar_err_set(ROAR_ERROR_TYPEMM);
534  return -1;
535 }
536
537 if ( (mes->length + len) > ROAR_ROARDMX_DATA_LENGTH ) { // message would be to long
538  roar_err_set(ROAR_ERROR_NOSPC);
539  return -1;
540 }
541
542 memcpy(mes->data + 3 + mes->length, events, len);
543 mes->length += len;
544
545 return 0;
546}
547
548int roar_roardmx_message_get_events(struct roar_roardmx_message * mes, const uint8_t ** events, size_t * len) {
549 BCHK(mes);
550
551 if ( mes->type != ROAR_ROARDMX_TYPE_EVENT ) {
552  roar_err_set(ROAR_ERROR_TYPEMM);
553  return -1;
554 }
555
556 *events = (const uint8_t *)(mes->data + 3);
557 *len    = mes->length;
558
559 return 0;
560}
561
562// * CONTROL:
563static inline int roar_roardmx_message_new_control(struct roar_roardmx_message * mes, uint8_t subcommand) {
564 BCHK(mes);
565
566 if ( roar_roardmx_message_new(mes) == -1 )
567  return -1;
568
569 mes->type = ROAR_ROARDMX_TYPE_CONTROL;
570 mes->data[3] = 0; // version
571 mes->data[4] = subcommand;
572 mes->length  = 2;
573
574 return 0;
575}
576
577int roar_roardmx_message_new_version(struct roar_roardmx_message * mes, uint8_t version) {
578 BCHK(mes);
579
580 if ( version != (uint8_t)0 ) {
581  roar_err_set(ROAR_ERROR_NSVERSION);
582  return -1;
583 }
584
585 if ( roar_roardmx_message_new_control(mes, ROAR_ROARDMX_CTL_VERSION) == -1 )
586  return -1;
587
588 mes->data[5] = version;
589 mes->length  = 3;
590
591 return 0;
592}
593
594int roar_roardmx_message_new_sync(struct roar_roardmx_message * mes, uint8_t flags) {
595 BCHK(mes);
596
597 if ( roar_roardmx_message_new_control(mes, ROAR_ROARDMX_CTL_VERSION) == -1 )
598  return -1;
599
600 mes->data[5] = flags;
601 mes->length  = 3;
602
603 return 0;
604}
605
606int roar_roardmx_message_get_subcommand(struct roar_roardmx_message * mes) {
607 BCHK(mes);
608
609 if ( mes->type != ROAR_ROARDMX_TYPE_CONTROL ) {
610  roar_err_set(ROAR_ERROR_TYPEMM);
611  return -1;
612 }
613
614 if ( mes->length < 2 ) {
615  roar_err_set(ROAR_ERROR_PROTO);
616  return -1;
617 }
618
619 if ( mes->data[3] != 0 ) {
620  roar_err_set(ROAR_ERROR_NSVERSION);
621  return -1;
622 }
623
624 return mes->data[4];
625}
626
627static inline int roar_roardmx_message_get_ctl_byte5(struct roar_roardmx_message * mes, uint8_t subtype) {
628 BCHK(mes);
629
630 if ( mes->type != ROAR_ROARDMX_TYPE_CONTROL ) {
631  roar_err_set(ROAR_ERROR_TYPEMM);
632  return -1;
633 }
634
635 if ( roar_roardmx_message_get_subcommand(mes) != (int)(unsigned)subtype ) {
636  roar_err_set(ROAR_ERROR_TYPEMM);
637  return -1;
638 }
639
640 return mes->data[5];
641}
642
643int roar_roardmx_message_get_ctl_version(struct roar_roardmx_message * mes) {
644 return roar_roardmx_message_get_ctl_byte5(mes, ROAR_ROARDMX_CTL_VERSION);
645}
646
647int roar_roardmx_message_get_ctl_flags(struct roar_roardmx_message * mes) {
648 return roar_roardmx_message_get_ctl_byte5(mes, ROAR_ROARDMX_CTL_SYNC);
649}
650
651//ll
Note: See TracBrowser for help on using the repository browser.