source: roaraudio/libroarlight/roardmx.c @ 5961:06e7fd9e4c25

Last change on this file since 5961:06e7fd9e4c25 was 5961:06e7fd9e4c25, checked in by phi, 10 years ago

Updates of copyright and license headers

File size: 12.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
104int roar_roardmx_str2event(const char * event) {
105 size_t i;
106
107 if ( event == NULL ) {
108  roar_err_set(ROAR_ERROR_FAULT);
109  return -1;
110 }
111
112 for (i = 0; i < (sizeof(__eventnames)/sizeof(*__eventnames)); i++)
113  if ( !strcasecmp(event, __eventnames[i].name) )
114   return __eventnames[i].id;
115
116 roar_err_set(ROAR_ERROR_NOENT);
117 return -1;
118}
119
120const char * roar_roardmx_event2str(const int event) {
121 size_t i;
122
123 for (i = 0; i < (sizeof(__eventnames)/sizeof(*__eventnames)); i++)
124  if ( __eventnames[i].id == event )
125   return __eventnames[i].name;
126
127 roar_err_set(ROAR_ERROR_NOENT);
128 return NULL;
129}
130
131// generic things:
132int roar_roardmx_message_new (struct roar_roardmx_message * mes) {
133 BCHK(mes);
134
135 memset(mes, 0, sizeof(struct roar_roardmx_message));
136
137 mes->version = ROAR_ROARDMX_VERSION;
138
139 return 0;
140}
141
142// low level:
143//int roar_roardmx_message_set_flag(struct roar_roardmx_message * mes, unsigned char   flag);
144//int roar_roardmx_message_set_len (struct roar_roardmx_message * mes, size_t          type);
145//int roar_roardmx_message_get_data(struct roar_roardmx_message * mes, unsigned char ** data);
146
147// medium level:
148int roar_roardmx_message_set_type(struct roar_roardmx_message * mes, unsigned char   type) {
149 BCHK(mes);
150
151 // check if type contains non-type bits.
152 if ( (type | ROAR_ROARDMX_MASK_TYPE) - ROAR_ROARDMX_MASK_TYPE ) {
153  roar_err_set(ROAR_ERROR_INVAL);
154  return -1;
155 }
156
157 mes->type = type;
158
159 return 0;
160}
161
162int roar_roardmx_message_get_flag(struct roar_roardmx_message * mes, unsigned char * flag) {
163 BCHK(mes);
164
165 *flag = mes->flags;
166
167 return 0;
168}
169
170int roar_roardmx_message_get_type(struct roar_roardmx_message * mes, unsigned char * type) {
171 BCHK(mes);
172
173 *type = mes->type;
174
175 return 0;
176}
177
178int roar_roardmx_message_get_len (struct roar_roardmx_message * mes, size_t        * length) {
179 BCHK(mes);
180
181 *length = mes->length;
182
183 return 0;
184}
185
186
187// IO:
188int roar_roardmx_message_send(struct roar_roardmx_message * mes, struct roar_vio_calls * vio) {
189 BCHK(mes);
190 BCHK(vio);
191
192 if ( mes->length > ROAR_ROARDMX_DATA_LENGTH ) { // this is very fatal!
193  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL);
194  roar_err_set(ROAR_ERROR_FAULT);
195  return -1;
196 }
197
198 mes->data[0] =  mes->version;
199 mes->data[1] = (mes->flags & ROAR_ROARDMX_MASK_FLAGS) |
200                (mes->type  & ROAR_ROARDMX_MASK_TYPE ) ;
201
202 mes->data[2] = mes->length;
203
204 return roar_vio_write(vio, mes->data, mes->length + 3) == (ssize_t)(mes->length + 3) ? 0 : -1;
205}
206
207int roar_roardmx_message_recv(struct roar_roardmx_message * mes, struct roar_vio_calls * vio) {
208 BCHK(mes);
209 BCHK(vio);
210
211 if ( roar_roardmx_message_new(mes) == -1 )
212  return -1;
213
214 if ( roar_vio_read(vio, mes->data, 3) != 3 )
215  return -1;
216
217 mes->version = mes->data[0];
218
219 if ( mes->version != ROAR_ROARDMX_VERSION ) {
220  roar_err_set(ROAR_ERROR_NSVERSION);
221  return -1;
222 }
223
224 mes->flags  = mes->data[1] & ROAR_ROARDMX_MASK_FLAGS;
225 mes->type   = mes->data[1] & ROAR_ROARDMX_MASK_TYPE;
226
227 mes->length = mes->data[2];
228
229 if ( roar_vio_read(vio, &(mes->data[3]), mes->length) != (ssize_t)mes->length )
230  return -1;
231
232 return 0;
233}
234
235// Data/high level:
236// * *:
237int roar_roardmx_message_add_chanval(struct roar_roardmx_message * mes, uint16_t channel, unsigned char val) {
238 register uint16_t * chan;
239
240 BCHK(mes);
241
242 switch (mes->type) {
243  case ROAR_ROARDMX_TYPE_SSET:
244  case ROAR_ROARDMX_TYPE_INC8S:
245   break;
246  default:
247    roar_err_set(ROAR_ERROR_TYPEMM);
248    return -1;
249   break;
250 }
251
252 if ( (mes->length + 3) > ROAR_ROARDMX_DATA_LENGTH ) { // message would be to long
253  roar_err_set(ROAR_ERROR_NOSPC);
254  return -1;
255 }
256
257 chan = (uint16_t *) &(mes->data[mes->length + 3]);
258
259 *chan = ROAR_HOST2NET16(channel);
260
261 mes->data[mes->length + 2 + 3] = val;
262
263 mes->length += 3;
264
265 return 0;
266}
267
268int roar_roardmx_message_get_chanval(struct roar_roardmx_message * mes, uint16_t * channel, unsigned char * val, int index) {
269 register uint16_t * chan;
270
271 BCHK(mes);
272
273 if ( index < 0 ) {
274  roar_err_set(ROAR_ERROR_INVAL);
275  return -1;
276 }
277
278 if ( mes->version != ROAR_ROARDMX_VERSION ) {
279  roar_err_set(ROAR_ERROR_NSVERSION);
280  return -1;
281 }
282
283 switch (mes->type) {
284  case ROAR_ROARDMX_TYPE_SSET:
285  case ROAR_ROARDMX_TYPE_INC8S:
286    if ( index >= (ROAR_ROARDMX_DATA_LENGTH/3) )
287     return -1;
288
289    *val     = mes->data[3 * index + 2 + 3];
290    chan     = (uint16_t *) &(mes->data[3 + 3 * index]);
291    *channel = ROAR_NET2HOST16(*chan);
292    return 0;
293   break;
294 }
295
296 roar_err_set(ROAR_ERROR_NSTYPE);
297 return -1;
298}
299
300int roar_roardmx_message_numchannels(struct roar_roardmx_message * mes) {
301 BCHK(mes);
302
303 if ( mes->version != ROAR_ROARDMX_VERSION ) {
304  roar_err_set(ROAR_ERROR_NSVERSION);
305  return -1;
306 }
307
308 switch (mes->type) {
309  case ROAR_ROARDMX_TYPE_SSET:
310  case ROAR_ROARDMX_TYPE_INC8S:
311    return mes->length /  3;
312   break;
313  case ROAR_ROARDMX_TYPE_IPO1:
314    return mes->length /  6;
315   break;
316  case ROAR_ROARDMX_TYPE_IPO4:
317    return mes->length / 12;
318   break;
319  case ROAR_ROARDMX_TYPE_RANGESET:
320    return mes->length /  5;
321   break;
322  case ROAR_ROARDMX_TYPE_EVENT:
323  case ROAR_ROARDMX_TYPE_CONTROL:
324    return 0;
325   break;
326 }
327
328 roar_err_set(ROAR_ERROR_NSTYPE);
329 return -1;
330}
331
332// * SSET:
333int roar_roardmx_message_new_sset   (struct roar_roardmx_message * mes) {
334 BCHK(mes);
335
336 if ( roar_roardmx_message_new(mes) == -1 )
337  return -1;
338
339 mes->type = ROAR_ROARDMX_TYPE_SSET;
340
341 return 0;
342}
343
344// * IPO1:
345// Not yet supported.
346// * IPO4:
347// Not yet supported.
348// * INC8S:
349// Not yet supported.
350// * RANGESET:
351// Not yet supported.
352// * EVENT:
353int roar_roardmx_message_new_event(struct roar_roardmx_message * mes) {
354 BCHK(mes);
355
356 if ( roar_roardmx_message_new(mes) == -1 )
357  return -1;
358
359 mes->type = ROAR_ROARDMX_TYPE_EVENT;
360
361 return 0;
362}
363
364int roar_roardmx_message_add_events(struct roar_roardmx_message * mes, const uint8_t * events, size_t len) {
365 BCHK(mes);
366
367 if ( mes->type != ROAR_ROARDMX_TYPE_EVENT ) {
368  roar_err_set(ROAR_ERROR_TYPEMM);
369  return -1;
370 }
371
372 if ( (mes->length + len) > ROAR_ROARDMX_DATA_LENGTH ) { // message would be to long
373  roar_err_set(ROAR_ERROR_NOSPC);
374  return -1;
375 }
376
377 memcpy(mes->data + 3 + mes->length, events, len);
378 mes->length += len;
379
380 return 0;
381}
382
383int roar_roardmx_message_get_events(struct roar_roardmx_message * mes, const uint8_t ** events, size_t * len) {
384 BCHK(mes);
385
386 if ( mes->type != ROAR_ROARDMX_TYPE_EVENT ) {
387  roar_err_set(ROAR_ERROR_TYPEMM);
388  return -1;
389 }
390
391 *events = (const uint8_t *)(mes->data + 3);
392 *len    = mes->length;
393
394 return 0;
395}
396
397// * CONTROL:
398// Not yet supported.
399
400//ll
Note: See TracBrowser for help on using the repository browser.