source: roaraudio/libroarlight/roardmx.c @ 5924:1488a53c9a47

Last change on this file since 5924:1488a53c9a47 was 5924:1488a53c9a47, checked in by phi, 11 years ago

improve the RoarDMX code a bit: cleanup and better error handling.

File size: 5.6 KB
Line 
1//roardmx.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2013
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
31int roar_roardmx_message_new (struct roar_roardmx_message * mes) {
32 BCHK(mes);
33
34 memset(mes, 0, sizeof(struct roar_roardmx_message));
35
36 mes->version = ROAR_ROARDMX_VERSION;
37
38 return 0;
39}
40
41// low level:
42//int roar_roardmx_message_set_flag(struct roar_roardmx_message * mes, unsigned char   flag);
43//int roar_roardmx_message_set_len (struct roar_roardmx_message * mes, size_t          type);
44//int roar_roardmx_message_get_data(struct roar_roardmx_message * mes, unsigned char ** data);
45
46// medium level:
47int roar_roardmx_message_set_type(struct roar_roardmx_message * mes, unsigned char   type) {
48 BCHK(mes);
49
50 // check if type contains non-type bits.
51 if ( (type | ROAR_ROARDMX_MASK_TYPE) - ROAR_ROARDMX_MASK_TYPE ) {
52  roar_err_set(ROAR_ERROR_INVAL);
53  return -1;
54 }
55
56 mes->type = type;
57
58 return 0;
59}
60
61int roar_roardmx_message_get_flag(struct roar_roardmx_message * mes, unsigned char * flag) {
62 BCHK(mes);
63
64 *flag = mes->flags;
65
66 return 0;
67}
68
69int roar_roardmx_message_get_type(struct roar_roardmx_message * mes, unsigned char * type) {
70 BCHK(mes);
71
72 *type = mes->type;
73
74 return 0;
75}
76
77int roar_roardmx_message_get_len (struct roar_roardmx_message * mes, size_t        * length) {
78 BCHK(mes);
79
80 *length = mes->length;
81
82 return 0;
83}
84
85
86// IO:
87int roar_roardmx_message_send(struct roar_roardmx_message * mes, struct roar_vio_calls * vio) {
88 BCHK(mes);
89 BCHK(vio);
90
91 if ( mes->length > ROAR_ROARDMX_DATA_LENGTH ) { // this is very fatal!
92  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL);
93  roar_err_set(ROAR_ERROR_FAULT);
94  return -1;
95 }
96
97 mes->data[0] =  mes->version;
98 mes->data[1] = (mes->flags & ROAR_ROARDMX_MASK_FLAGS) |
99                (mes->type  & ROAR_ROARDMX_MASK_TYPE ) ;
100
101 mes->data[2] = mes->length;
102
103 return roar_vio_write(vio, mes->data, mes->length + 3) == (ssize_t)(mes->length + 3) ? 0 : -1;
104}
105
106int roar_roardmx_message_recv(struct roar_roardmx_message * mes, struct roar_vio_calls * vio) {
107 BCHK(mes);
108 BCHK(vio);
109
110 if ( roar_roardmx_message_new(mes) == -1 )
111  return -1;
112
113 if ( roar_vio_read(vio, mes->data, 3) != 3 )
114  return -1;
115
116 mes->version = mes->data[0];
117
118 if ( mes->version != ROAR_ROARDMX_VERSION ) {
119  roar_err_set(ROAR_ERROR_NSVERSION);
120  return -1;
121 }
122
123 mes->flags  = mes->data[1] & ROAR_ROARDMX_MASK_FLAGS;
124 mes->type   = mes->data[1] & ROAR_ROARDMX_MASK_TYPE;
125
126 mes->length = mes->data[2];
127
128 if ( roar_vio_read(vio, &(mes->data[3]), mes->length) != (ssize_t)mes->length )
129  return -1;
130
131 return 0;
132}
133
134// Data/high level:
135// * *:
136int roar_roardmx_message_add_chanval(struct roar_roardmx_message * mes, uint16_t channel, unsigned char val) {
137 register uint16_t * chan;
138
139 BCHK(mes);
140
141 switch (mes->type) {
142  case ROAR_ROARDMX_TYPE_SSET:
143  case ROAR_ROARDMX_TYPE_INC8S:
144   break;
145  default:
146    roar_err_set(ROAR_ERROR_TYPEMM);
147    return -1;
148   break;
149 }
150
151 if ( (mes->length + 3) > ROAR_ROARDMX_DATA_LENGTH ) { // message would be to long
152  roar_err_set(ROAR_ERROR_NOSPC);
153  return -1;
154 }
155
156 chan = (uint16_t *) &(mes->data[mes->length + 3]);
157
158 *chan = ROAR_HOST2NET16(channel);
159
160 mes->data[mes->length + 2 + 3] = val;
161
162 mes->length += 3;
163
164 return 0;
165}
166
167int roar_roardmx_message_get_chanval(struct roar_roardmx_message * mes, uint16_t * channel, unsigned char * val, int index) {
168 register uint16_t * chan;
169
170 BCHK(mes);
171
172 if ( index < 0 ) {
173  roar_err_set(ROAR_ERROR_INVAL);
174  return -1;
175 }
176
177 if ( mes->version != ROAR_ROARDMX_VERSION ) {
178  roar_err_set(ROAR_ERROR_NSVERSION);
179  return -1;
180 }
181
182 switch (mes->type) {
183  case ROAR_ROARDMX_TYPE_SSET:
184  case ROAR_ROARDMX_TYPE_INC8S:
185    if ( index >= (ROAR_ROARDMX_DATA_LENGTH/3) )
186     return -1;
187
188    *val     = mes->data[3 * index + 2 + 3];
189    chan     = (uint16_t *) &(mes->data[3 + 3 * index]);
190    *channel = ROAR_NET2HOST16(*chan);
191    return 0;
192   break;
193 }
194
195 roar_err_set(ROAR_ERROR_NSTYPE);
196 return -1;
197}
198
199int roar_roardmx_message_numchannels(struct roar_roardmx_message * mes) {
200 BCHK(mes);
201
202 if ( mes->version != ROAR_ROARDMX_VERSION ) {
203  roar_err_set(ROAR_ERROR_NSVERSION);
204  return -1;
205 }
206
207 switch (mes->type) {
208  case ROAR_ROARDMX_TYPE_SSET:
209  case ROAR_ROARDMX_TYPE_INC8S:
210    return mes->length /  3;
211   break;
212  case ROAR_ROARDMX_TYPE_IPO1:
213    return mes->length /  6;
214   break;
215  case ROAR_ROARDMX_TYPE_IPO4:
216    return mes->length / 12;
217   break;
218  case ROAR_ROARDMX_TYPE_RANGESET:
219    return mes->length /  5;
220   break;
221  case ROAR_ROARDMX_TYPE_EVENT:
222  case ROAR_ROARDMX_TYPE_CONTROL:
223    return 0;
224   break;
225 }
226
227 roar_err_set(ROAR_ERROR_NSTYPE);
228 return -1;
229}
230
231// * SSET:
232int roar_roardmx_message_new_sset   (struct roar_roardmx_message * mes) {
233 if ( roar_roardmx_message_new(mes) == -1 )
234  return -1;
235
236 mes->type = ROAR_ROARDMX_TYPE_SSET;
237
238 return 0;
239}
240
241//ll
Note: See TracBrowser for help on using the repository browser.