source: roaraudio/libroar/ctl.c @ 2615:a46baf00194c

Last change on this file since 2615:a46baf00194c was 2615:a46baf00194c, checked in by phi, 15 years ago

added roar_str2byteorder() and roar_byteorder2str()

File size: 11.3 KB
Line 
1//ctl.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *
6 *  This file is part of libroar 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 *  libroar 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, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "libroar.h"
36
37int roar_get_clientid  (struct roar_connection * con) {
38 struct roar_message mes;
39
40 memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy!
41
42 mes.cmd     = ROAR_CMD_WHOAMI;
43 mes.datalen = 0;
44
45 if ( roar_req(con, &mes, NULL) == -1 )
46  return -1;
47
48 if ( mes.cmd != ROAR_CMD_OK )
49  return -1;
50
51 if ( mes.datalen != 1 )
52  return -1;
53
54 return mes.data[0];
55}
56
57int roar_server_oinfo   (struct roar_connection * con, struct roar_stream * sa) {
58 struct roar_message mes;
59
60 memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy!
61
62 mes.cmd     = ROAR_CMD_SERVER_OINFO;
63 mes.datalen = 0;
64
65 if ( roar_req(con, &mes, NULL) == -1 )
66  return -1;
67
68 if ( mes.cmd != ROAR_CMD_OK )
69  return -1;
70
71 if ( roar_stream_m2s(sa, &mes) == -1 )
72  return -1;
73
74 return 0;
75}
76
77int roar_get_standby   (struct roar_connection * con) {
78 struct roar_message mes;
79
80 memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy!
81
82 mes.cmd = ROAR_CMD_GET_STANDBY;
83 mes.datalen = 0;
84
85 if ( roar_req(con, &mes, NULL) == -1 )
86  return -1;
87
88 if ( mes.cmd != ROAR_CMD_OK )
89  return -1;
90
91 return ROAR_NET2HOST16(*((uint16_t*)mes.data));
92}
93
94int roar_set_standby   (struct roar_connection * con, int state) {
95 struct roar_message mes;
96
97 memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy!
98
99 mes.cmd = ROAR_CMD_SET_STANDBY;
100 mes.datalen = 2;
101
102 *((uint16_t*)mes.data) = ROAR_HOST2NET16((unsigned) state);
103
104 if ( roar_req(con, &mes, NULL) == -1 )
105  return -1;
106
107 if ( mes.cmd != ROAR_CMD_OK )
108  return -1;
109
110 return 0;
111}
112
113int roar_exit   (struct roar_connection * con) {
114 return roar_terminate(con, 0);
115}
116
117int roar_terminate (struct roar_connection * con, int terminate) {
118 struct roar_message mes;
119
120 memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy!
121
122 mes.cmd     = ROAR_CMD_EXIT;
123 mes.datalen = 1;
124 mes.data[0] = terminate;
125
126 if ( roar_req(con, &mes, NULL) == -1 )
127  return -1;
128
129 if ( mes.cmd != ROAR_CMD_OK )
130  return -1;
131
132 return 0;
133}
134
135int roar_list         (struct roar_connection * con, int * items,   int max, int cmd) {
136 struct roar_message m;
137
138 memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy!
139
140 roar_ctl_f2m_any(&m);
141 m.cmd = cmd;
142
143 if ( roar_req(con, &m, NULL) == -1 )
144  return -1;
145
146 return roar_ctl_m2ia(&m, items, max);
147}
148
149int roar_get_client   (struct roar_connection * con, struct roar_client * client, int id) {
150 struct roar_message m;
151
152 memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy!
153
154 m.cmd     = ROAR_CMD_GET_CLIENT;
155 m.datalen = 1;
156 m.data[0] = id;
157
158 ROAR_DBG("roar_get_client(*): id = %i", id);
159
160 if ( roar_req(con, &m, NULL) == -1 )
161  return -1;
162
163 if ( m.cmd != ROAR_CMD_OK )
164  return -1;
165
166 ROAR_DBG("roar_get_client(*): got ok");
167
168 return roar_ctl_m2c(&m, client);
169}
170
171int roar_get_stream   (struct roar_connection * con, struct roar_stream * stream, int id) {
172 struct roar_message m;
173
174 memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy!
175
176 m.cmd     = ROAR_CMD_GET_STREAM;
177 m.datalen = 1;
178 m.data[0] = id;
179
180 roar_errno = ROAR_ERROR_UNKNOWN;
181
182 if ( roar_req(con, &m, NULL) == -1 ) {
183  roar_errno = ROAR_ERROR_PROTO;
184  return -1;
185 }
186
187 if ( m.cmd != ROAR_CMD_OK )
188  return -1;
189
190 return roar_stream_m2s(stream, &m);
191}
192
193int roar_kick         (struct roar_connection * con, int type, int id) {
194 struct roar_message m;
195 uint16_t * info = (uint16_t *) m.data;
196
197 memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy!
198
199 m.cmd     = ROAR_CMD_KICK;
200 m.datalen = 4;
201 info[0] = ROAR_HOST2NET16(type);
202 info[1] = ROAR_HOST2NET16(id);
203
204 if ( roar_req(con, &m, NULL) == -1 )
205  return -1;
206
207 if ( m.cmd != ROAR_CMD_OK )
208  return -1;
209
210 return 0;
211}
212
213int roar_set_vol      (struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int channels) {
214 struct roar_message m;
215 uint16_t * info = (uint16_t *) m.data;
216 int i;
217
218 memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy!
219
220 m.cmd     = ROAR_CMD_SET_VOL;
221 m.datalen = (3 + channels) * 2;
222 info[0] = 0;
223 info[1] = ROAR_HOST2NET16(id);
224 info[2] = ROAR_HOST2NET16(ROAR_SET_VOL_ALL);
225
226 for (i = 0; i < channels; i++)
227  info[i+3] = ROAR_HOST2NET16(mixer->mixer[i]);
228
229 if ( roar_req(con, &m, NULL) == -1 )
230  return -1;
231
232 if ( m.cmd != ROAR_CMD_OK )
233  return -1;
234
235 return 0;
236}
237
238int roar_get_vol      (struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int * channels) {
239 struct roar_message m;
240 uint16_t * info = (uint16_t *) m.data;
241 int i;
242
243 memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy!
244
245 m.cmd     = ROAR_CMD_GET_VOL;
246 m.datalen = 2*2;
247 info[0] = 0;
248 info[1] = ROAR_HOST2NET16(id);
249
250 if ( roar_req(con, &m, NULL) == -1 )
251  return -1;
252
253 if ( m.cmd != ROAR_CMD_OK )
254  return -1;
255
256 if ( info[0] != 0 )
257  return -1;
258
259 info[1] = ROAR_NET2HOST16(info[1]);
260
261 if ( channels != NULL )
262  *channels = info[1];
263
264 if ( info[1] > ROAR_MAX_CHANNELS )
265  return -1;
266
267 mixer->scale   = 65535;
268 mixer->rpg_mul = 1;
269 mixer->rpg_div = 1;
270
271 for (i = 0; i < info[1]; i++)
272  mixer->mixer[i] = ROAR_NET2HOST16(info[i+2]);
273
274 return 0;
275}
276
277// converts: *_m2*, *_*2m
278
279int roar_ctl_f2m      (struct roar_message * m, unsigned char   filter, unsigned char   cmp, uint32_t   id) {
280
281 m->datalen = 7;
282
283 m->data[0] = 0;
284 m->data[1] = filter;
285 m->data[2] = cmp;
286 *((uint32_t*)&(m->data[3])) = ROAR_HOST2NET32(id);
287
288 return 0;
289}
290int roar_ctl_m2f      (struct roar_message * m, unsigned char * filter, unsigned char * cmp, uint32_t * id) {
291
292 if ( m->datalen != 7 )
293  return -1;
294
295 if ( m->data[0] != 0 ) {
296  ROAR_ERR("roar_ctl_m2f(*): version %i not supported!", m->data[0]);
297  return -1;
298 }
299
300 *filter = m->data[1];
301 *cmp    = m->data[2];
302
303 *id = ROAR_NET2HOST32(*((uint32_t*)&(m->data[3])));
304
305 return 0;
306}
307
308int roar_ctl_ia2m     (struct roar_message * m, int * data, int len) {
309 int i;
310
311 if ( len > LIBROAR_BUFFER_MSGDATA )
312  return -1;
313
314 m->datalen = len;
315
316 for (i = 0; i < len; i++)
317  m->data[i] = data[i];
318
319 return 0;
320}
321int roar_ctl_m2ia     (struct roar_message * m, int * data, int len) {
322 int i;
323
324 if ( m->datalen > len )
325  return -1;
326
327 for (i = 0; i < m->datalen; i++)
328  data[i] = m->data[i];
329
330 return m->datalen;
331}
332
333int roar_ctl_c2m      (struct roar_message * m, struct roar_client * c) {
334 int cur = 0;
335 int h;
336 int i;
337 int max_len;
338 uint32_t pid;
339
340 if ( c == NULL )
341  return -1;
342
343 m->data[cur++] = 0;                       // 0: Version
344 m->data[cur++] = c->execed;               // 1: execed
345
346 h = 0;
347 for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) {
348  if ( c->streams[i] != -1 )
349   m->data[cur+1+h++] = c->streams[i];
350 }
351
352 m->data[cur++] = h;                       // 2: num of streams
353 cur += h;
354
355 max_len = strlen(c->name);
356
357 // TODO: add some code to check if this fits in the pkg
358 // NOTE: add this code after we are sure how long this pkg will be
359 //       and fully decieded about this function.
360
361 m->data[cur++] = max_len;
362
363 strncpy((m->data)+cur, c->name, max_len);
364
365 cur += max_len;
366
367 pid = ROAR_HOST2NET32(c->pid);
368 memcpy(&(m->data[cur]), &pid, 4);
369 cur += 4;
370
371 pid = ROAR_HOST2NET32(c->uid);
372 memcpy(&(m->data[cur]), &pid, 4);
373 cur += 4;
374
375 pid = ROAR_HOST2NET32(c->gid);
376 memcpy(&(m->data[cur]), &pid, 4);
377 cur += 4;
378
379 pid = ROAR_HOST2NET32(c->proto);
380 memcpy(&(m->data[cur]), &pid, 4);
381 cur += 4;
382
383 m->datalen = cur;
384
385 return 0;
386}
387
388int roar_ctl_m2c      (struct roar_message * m, struct roar_client * c) {
389 int i;
390 int cur;
391 uint32_t pid;
392
393 if ( m == NULL || c == NULL )
394  return -1;
395
396 if ( m->datalen == 0 )
397  return -1;
398
399 ROAR_DBG("roar_ctl_m2c(*): got data!, len = %i", m->datalen);
400
401 if ( m->data[0] != 0 ) {
402  ROAR_DBG("roar_ctl_m2c(*): wrong version!");
403  return -1;
404 }
405
406 if ( m->datalen < 3 )
407  return -1;
408
409 ROAR_DBG("roar_ctl_m2c(*): have usable data!");
410
411 c->execed = m->data[1];
412
413 for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++)
414  c->streams[i] = -1;
415
416 for (i = 0; i < m->data[2]; i++)
417  c->streams[i] = m->data[3+i];
418
419 cur = 3 + m->data[2];
420
421 strncpy(c->name, (m->data)+cur+1, m->data[cur]);
422 c->name[(int)m->data[cur]] = 0;
423
424 cur += m->data[cur] + 1;
425
426 memcpy(&pid, &(m->data[cur]), 4);
427 c->pid = ROAR_NET2HOST32(pid);
428 cur += 4;
429
430 memcpy(&pid, &(m->data[cur]), 4);
431 c->uid = ROAR_NET2HOST32(pid);
432 cur += 4;
433
434 memcpy(&pid, &(m->data[cur]), 4);
435 c->gid = ROAR_NET2HOST32(pid);
436 cur += 4;
437
438 if ( m->datalen >= cur+4 ) {
439  memcpy(&pid, &(m->data[cur]), 4);
440  c->proto = ROAR_NET2HOST32(pid);
441  cur += 4;
442 } else {
443  c->proto = ROAR_PROTO_NONE;
444 }
445
446 return 0;
447}
448
449int    roar_str2proto (char * proto) {
450 if ( !strcasecmp(proto, "roar") ) {
451  return ROAR_PROTO_ROARAUDIO;
452 } else if ( !strcasecmp(proto, "roaraudio") ) {
453  return ROAR_PROTO_ROARAUDIO;
454 } else if ( !strcasecmp(proto, "esd") ) {
455  return ROAR_PROTO_ESOUND;
456 } else if ( !strcasecmp(proto, "esound") ) {
457  return ROAR_PROTO_ESOUND;
458 }
459
460 return -1;
461}
462
463char * roar_proto2str (int    proto) {
464 switch (proto) {
465  case ROAR_PROTO_ROARAUDIO: return "RoarAudio"; break;
466  case ROAR_PROTO_ESOUND:    return "EsounD";    break;
467  default:
468    return "(unknown)";
469 }
470}
471
472int    roar_str2byteorder (char * byteorder) {
473 if (        !strcasecmp(byteorder, "le")            || !strcasecmp(byteorder, "little") ||
474             !strcasecmp(byteorder, "little endian") || !strcasecmp(byteorder, "1234")   ) {
475  return ROAR_BYTEORDER_LE;
476 } else if ( !strcasecmp(byteorder, "be")            || !strcasecmp(byteorder, "big")    ||
477             !strcasecmp(byteorder, "big endian")    || !strcasecmp(byteorder, "4321")   ) {
478  return ROAR_BYTEORDER_BE;
479 } else if ( !strcasecmp(byteorder, "pdp")           ||
480             !strcasecmp(byteorder, "pdp endian") ) {
481  return ROAR_BYTEORDER_PDP;
482 } else if ( !strcasecmp(byteorder, "network")       ||
483             !strcasecmp(byteorder, "network byteorder") ) {
484  return ROAR_BYTEORDER_NETWORK;
485 }
486
487 return -1;
488}
489
490char * roar_byteorder2str (int    byteorder) {
491 switch (byteorder) {
492  case ROAR_BYTEORDER_LE:      return "little endian"; break;
493  case ROAR_BYTEORDER_BE:      return "big endian";    break;
494  case ROAR_BYTEORDER_PDP:     return "pdp endian";    break;
495//  case ROAR_BYTEORDER_NETWORK: return "network";       break;
496  default:
497    return "(unknown)";
498 }
499}
500
501//ll
Note: See TracBrowser for help on using the repository browser.