source: roaraudio/roard/req.c @ 4236:1d583a76aa06

Last change on this file since 4236:1d583a76aa06 was 4236:1d583a76aa06, checked in by phi, 14 years ago

add more debug lions

File size: 26.1 KB
Line 
1//req.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2010
5 *
6 *  This file is part of roard 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 *  RoarAudio 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 "roard.h"
27
28int req_on_noop        (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
29 mes->cmd     = ROAR_CMD_OK;
30 mes->pos     = g_pos;
31 mes->datalen = 0;
32 return 0;
33}
34
35int req_on_identify    (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
36 struct roar_client * c;
37 int max_len;
38
39 if ( mes->datalen < 1 )
40  return -1;
41
42 clients_get(client, &c);
43
44 if ( mes->data[0] == 1 ) {
45  if ( c->pid == -1 ) {
46   c->pid       = ROAR_NET2HOST32(*(uint32_t*)((mes->data)+1));
47   ROAR_DBG("req_on_identify(): new PID: c->pid = %i", c->pid);
48  }
49
50  ROAR_DBG("req_on_identify(): final PID: c->pid = %i", c->pid);
51
52  max_len = (mes->datalen - 5) < (ROAR_BUFFER_NAME-1) ? (mes->datalen - 5) : (ROAR_BUFFER_NAME-1);
53
54  strncpy(c->name, mes->data + 5, max_len);
55  c->name[max_len] = 0;
56
57  mes->cmd     = ROAR_CMD_OK;
58  mes->pos     = g_pos;
59  mes->datalen = 0;
60
61  ROAR_DBG("req_on_identify(*): client=%i, pid=%i", client, c->pid);
62  ROAR_DBG("req_on_identify(*) = 0");
63  return 0;
64 }
65
66 return -1;
67}
68
69int req_on_auth        (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
70 // TODO: add code to support some auth.
71 mes->cmd     = ROAR_CMD_OK;
72 mes->pos     = g_pos;
73 mes->datalen = 0;
74 return 0;
75}
76
77
78int req_on_whoami      (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
79 mes->cmd     = ROAR_CMD_OK;
80 mes->pos     = g_pos;
81 mes->datalen = 1;
82 mes->data[0] = client;
83 return 0;
84}
85
86
87int req_on_new_stream  (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
88 int stream;
89 struct roar_stream * s;
90 struct roar_stream * source_stream;
91 struct roar_audio_info * info;
92 struct roar_audio_info * source_info;
93
94 ROAR_DBG("req_on_new_stream(client=%i, ...): creating stream...", client);
95 if ((stream = streams_new()) == -1 )
96  return -1;
97
98 ROAR_DBG("req_on_new_stream(client=%i, ...): stream=%i", client, stream);
99
100 ROAR_DBG("req_on_new_stream(client=%i, ...): getting stream...", client);
101 if ( streams_get(stream, (struct roar_stream_server **)&s) == -1 ) {
102  streams_delete(stream);
103  return -1;
104 }
105
106 ROAR_DBG("req_on_new_stream(client=%i, ...): set client of stream...", client);
107 if ( client_stream_add(client, stream) == -1 ) {
108  streams_delete(stream);
109  return -1;
110 }
111
112 ROAR_DBG("req_on_new_stream(client=%i, ...): loading stream from message...", client);
113 if ( roar_stream_m2s(s, mes) == -1 ) {
114  streams_delete(stream);
115  return -1;
116 }
117
118 ROAR_DBG("req_on_new_stream(client=%i, ...): setting id and codec of stream...", client);
119 ROAR_STREAM(s)->id = stream; // roar_stream_m2s() resets this
120 ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM(s)->info.codec;
121
122 ROAR_DBG("req_on_new_stream(client=%i, ...): setting direction stream...", client);
123 // int streams_set_dir    (int id, int dir, int defaults)
124 if ( streams_set_dir(stream, ROAR_STREAM(s)->dir, 1) == -1 ) {
125  streams_delete(stream);
126  return -1;
127 }
128
129 ROAR_DBG("req_on_new_stream(client=%i, ...): setting up direction specific stream settings...", client);
130 switch (ROAR_STREAM(s)->dir) {
131  case ROAR_DIR_LIGHT_IN:
132  case ROAR_DIR_LIGHT_OUT:
133#ifndef ROAR_WITHOUT_DCOMP_LIGHT
134    info = &(ROAR_STREAM(s)->info);
135
136    info->channels = 0;
137    info->bits     = 0;
138    info->rate     = 0;
139#else
140    streams_delete(stream);
141    return -1;
142#endif
143
144   break;
145  case ROAR_DIR_MIDI_IN:
146  case ROAR_DIR_MIDI_OUT:
147#ifndef ROAR_WITHOUT_DCOMP_MIDI
148    info = &(ROAR_STREAM(s)->info);
149
150    info->channels = ROAR_MIDI_CHANNELS_DEFAULT;
151    info->bits     = ROAR_MIDI_BITS;
152    info->rate     = 0;
153#else
154    streams_delete(stream);
155    return -1;
156#endif
157
158   break;
159
160  case ROAR_DIR_RAW_IN:
161#ifndef ROAR_WITHOUT_DCOMP_RAW
162    if ( ROAR_STREAM(s)->pos_rel_id == -1     ||
163         ROAR_STREAM(s)->pos_rel_id == stream ||
164         streams_get_dir(ROAR_STREAM(s)->pos_rel_id) != ROAR_DIR_RAW_OUT
165       ) {
166     ROAR_STREAM(s)->pos_rel_id = -1; // force this here as it will try to delete itself while deleting
167                                      // in case rel_id == stream
168     streams_delete(stream);
169     return -1;
170    }
171#else
172  case ROAR_DIR_RAW_OUT:
173    streams_delete(stream);
174    return -1;
175#endif
176
177   break;
178  case ROAR_DIR_THRU:
179
180    if ( ROAR_STREAM(s)->pos_rel_id == -1 || ROAR_STREAM(s)->pos_rel_id == stream ) {
181     ROAR_STREAM(s)->pos_rel_id = -1; // force this here as it will try to delete itself while deleting
182                                      // in case rel_id == stream
183     streams_delete(stream);
184     return -1;
185    }
186
187    if ( streams_get(ROAR_STREAM(s)->pos_rel_id, (struct roar_stream_server **)&source_stream) == -1 ) {
188     streams_delete(stream);
189     return -1;
190    }
191
192    info        = &(ROAR_STREAM(s)->info);
193    source_info = &(ROAR_STREAM(source_stream)->info);
194
195    info->channels = source_info->channels;
196    info->bits     = source_info->bits;
197    info->rate     = source_info->rate;
198    info->codec    = source_info->codec;
199    ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM_SERVER(source_stream)->codec_orgi;
200
201   break;
202  case ROAR_DIR_FILTER:
203    info        = &(ROAR_STREAM(s)->info);
204
205    if ( ROAR_STREAM(s)->pos_rel_id == -1 ) {
206     source_info = g_sa;
207    } else {
208     if ( streams_get(ROAR_STREAM(s)->pos_rel_id, (struct roar_stream_server **)&source_stream) == -1 ) {
209      streams_delete(stream);
210      return -1;
211     }
212     source_info = &(ROAR_STREAM(source_stream)->info);
213    }
214
215    if ( info->channels != source_info->channels || info->bits != source_info->bits ||
216         info->codec    != source_info->codec    || info->rate != source_info->rate ) {
217     // the stream parameters don't match the one of the stream being filtered.
218     // -> delete and reject the stream.
219     streams_delete(stream);
220     return -1;
221    }
222   break;
223 }
224
225 ROAR_DBG("req_on_new_stream(client=%i, ...): returning (OK, stream=%i)...", client, stream);
226
227 mes->cmd     = ROAR_CMD_OK;
228 mes->stream  = stream;
229 mes->datalen = 0;
230
231 return 0;
232}
233
234int req_on_exec_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
235 int r;
236
237 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): execing stream", client, mes->stream);
238
239
240 if ( streams_is_ready(mes->stream) ) {
241  flags[1] |= COMMAND_FLAG_OUT_CLOSECON;
242 } else {
243  if ( (r = client_stream_exec(client, mes->stream)) == -1 )
244   return -1;
245 }
246
247 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
248 mes->cmd     = ROAR_CMD_OK;
249 mes->datalen = 0;
250
251 return 0;
252}
253
254int req_on_con_stream  (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
255 char   host[80] = {0};
256 int    port = 0;
257 int    type;
258 int    fh;
259 int    len;
260
261 if ( mes->datalen < 4 )
262  return -1;
263
264 if ( *(mes->data) != 0 )
265  return -1;
266
267 if ( mes->datalen > 80 ) // we do not support long messages here
268  return -1;
269
270 type = (unsigned)mes->data[1];
271 port = ROAR_NET2HOST16(((uint16_t*)mes->data)[1]);
272
273 len = mes->datalen - 4;
274
275 strncpy(host, &(mes->data[4]), len);
276 host[len] = 0;
277
278 if ( type > ROAR_SOCKET_TYPE_MAX )
279  return -1;
280
281 if ( type == ROAR_SOCKET_TYPE_FILE ) // disabled because of security resons
282  return -1;
283
284 if ( type == ROAR_SOCKET_TYPE_FORK ) // why should we connect to ourself?
285  return -1;
286
287 ROAR_DBG("req_on_con_stream(*): CONNECT(type=%i, host='%s', port=%i)", type, host, port);
288
289 if ( (fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port)) == -1 )
290  return -1;
291
292 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
293  close(fh);
294  return 1;
295 }
296
297 mes->datalen = 0;
298 mes->cmd     = ROAR_CMD_OK;
299
300 return 0;
301}
302
303int req_on_passfh      (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
304 int sock = clients_get_fh(client);
305 int16_t * d = (int16_t*)mes->data;
306 struct roard_listen * lsock;
307 int listening;
308 int fh;
309 int i;
310
311 ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...) = ?", client, mes->stream);
312
313 if ( (fh = roar_socket_recv_fh(sock, NULL, NULL)) == -1 )
314  return -1;
315
316 ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): fh=%i", client, mes->stream, fh);
317
318 if ( mes->stream != -1 ) { // stream pass:
319  ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): This is a stream passfh", client, mes->stream);
320
321  if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
322   close(fh);
323   ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (ERROR)...", client, mes->stream);
324   return -1;
325  }
326
327  ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
328
329  mes->datalen = 0;
330  mes->cmd     = ROAR_CMD_OK;
331
332  return 0;
333 }
334
335// non-stream pass:
336
337 ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): This is a client passfh", client, mes->stream);
338
339/*
340 0: Version,   16
341 1: Flags,     16
342 2: Protocol,  16
343 3: Byteorder, 16
344 Options...
345*/
346
347 if ( mes->datalen < 4*2 )
348  return -1;
349
350 for (i = 0; i < 4; i++) {
351  d[i] = ROAR_NET2HOST16(d[i]);
352 }
353
354 if ( d[0] != 0 ) // version
355  return -1;
356
357 listening = d[1] & ROAR_CLIENTPASS_FLAG_LISTEN;
358
359 if ( listening )
360  d[1] -= ROAR_CLIENTPASS_FLAG_LISTEN;
361
362 if ( d[1] != 0 ) // flags
363  return -1;
364
365 if ( listening ) {
366  if ( get_listen(&lsock, NULL) == -1 ) {
367   close(fh);
368   return -1;
369  }
370
371  roar_vio_open_fh_socket(&(lsock->sock), fh);
372  lsock->used   = 1;
373  lsock->proto  = d[2];
374 } else {
375  if ( clients_new_from_fh(fh, d[2], d[3], 1) == -1 )
376   return -1;
377 }
378
379 ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
380
381 mes->datalen = 0;
382 mes->cmd     = ROAR_CMD_OK;
383
384 return 0;
385}
386
387#ifdef ROAR_SUPPORT_META
388int req_on_set_meta    (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
389 int type;
390 int mode;
391 int namelen, vallen;
392 char   val[255+1];
393 char   name[ROAR_META_MAX_NAMELEN+1];
394
395 if ( mes->datalen < 3 )
396  return -1;
397
398 if ( mes->data[0] != 0 ) // version
399  return -1;
400
401 mode = (unsigned) mes->data[1];
402 type = (unsigned) mes->data[2];
403
404 ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type);
405
406 if ( mode == ROAR_META_MODE_CLEAR ) {
407  stream_meta_clear(mes->stream);
408  mes->datalen = 0;
409  mes->cmd     = ROAR_CMD_OK;
410  return 0;
411 } else if ( mode == ROAR_META_MODE_DELETE ) { // unsuppoerted at the moment
412  return -1;
413 } else if ( mode == ROAR_META_MODE_FINALIZE ) {
414  stream_meta_finalize(mes->stream);
415  mes->datalen = 0;
416  mes->cmd     = ROAR_CMD_OK;
417  return 0;
418 } else if ( mode == ROAR_META_MODE_SET || mode == ROAR_META_MODE_ADD ) {
419  if ( mes->datalen < 5 )
420   return -1;
421
422  namelen = (unsigned) mes->data[3];
423  vallen  = (unsigned) mes->data[4];
424
425  ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen);
426
427  if ( mes->datalen < (5 + namelen + vallen) )
428   return -1;
429
430  if ( namelen > ROAR_META_MAX_NAMELEN )
431   return -1;
432
433  strncpy(name, &(mes->data[5]), namelen);
434  name[namelen] = 0;
435
436  if ( vallen > 255 )
437   return -1;
438
439  strncpy(val, &(mes->data[5+namelen]), vallen);
440  val[vallen] = 0;
441
442  if ( mode == ROAR_META_MODE_SET ) {
443   if ( stream_meta_set(mes->stream, type, name, val) == -1 )
444    return -1;
445  } else {
446   if ( stream_meta_add(mes->stream, type, name, val) == -1 )
447    return -1;
448  }
449
450  mes->datalen = 0;
451  mes->cmd     = ROAR_CMD_OK;
452  return 0;
453 } else { // unknown mode!
454  return -1;
455 }
456
457 return -1;
458}
459
460int req_on_get_meta    (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
461 int vallen;
462 int type;
463 char val[LIBROAR_BUFFER_MSGDATA-1];
464
465 if ( mes->datalen != 2 )
466  return -1;
467
468 if ( mes->data[0] != 0 ) // version
469  return -1;
470
471 type = (unsigned) mes->data[1];
472
473 if ( stream_meta_get(mes->stream, type, NULL, val, LIBROAR_BUFFER_MSGDATA-2) == -1 )
474  return -1;
475
476 vallen = strlen(val);
477
478 mes->cmd     = ROAR_CMD_OK;
479 mes->datalen = 2 + vallen;
480
481 mes->data[0] = 0;
482 mes->data[1] = (unsigned char) vallen;
483
484 val[vallen] = 0;
485
486 strncpy(&(mes->data[2]), val, vallen+1);
487
488 return 0;
489}
490
491int req_on_list_meta   (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
492 int i;
493 int len = 0;
494 int types[ROAR_META_MAX_PER_STREAM];
495
496 if ( mes->datalen != 1 )
497  return -1;
498
499 if ( mes->data[0] != 0 ) // version
500  return -1;
501
502 if ( (len = stream_meta_list(mes->stream, types, ROAR_META_MAX_PER_STREAM)) == -1 )
503  return -1;
504
505 mes->cmd     = ROAR_CMD_OK;
506 mes->datalen = 1 + len;
507 mes->data[0] = 0;
508
509 for (i = 0; i < len; i++)
510  mes->data[i+1] = types[i];
511
512 return 0;
513}
514#endif
515
516int req_on_server_oinfo    (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
517 struct roar_stream s;
518//ROAR_DIR_OUTPUT
519
520 memset(&s, 0, sizeof(struct roar_stream));
521
522 s.dir           = ROAR_DIR_MIXING;
523 s.pos_rel_id    = -1;
524 s.info.rate     = g_sa->rate;
525 s.info.bits     = g_sa->bits;
526 s.info.channels = g_sa->channels;
527 s.info.codec    = g_sa->codec;
528 s.pos           = g_pos;
529
530 if ( roar_stream_s2m(&s, mes) == -1 )
531  return -1;
532
533 mes->cmd = ROAR_CMD_OK;
534
535 return 0;
536}
537
538
539int req_on_get_standby (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
540 mes->cmd     = ROAR_CMD_OK;
541 mes->pos     = g_pos;
542 mes->datalen = 2;
543
544 *((uint16_t*)mes->data) = ROAR_HOST2NET16((unsigned) g_standby);
545
546 return 0;
547}
548
549int req_on_set_standby (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
550 if ( mes->datalen != 2 )
551  return -1;
552
553 g_standby = ROAR_NET2HOST16(*((uint16_t*)mes->data));
554
555 mes->cmd     = ROAR_CMD_OK;
556 mes->pos     = g_pos;
557 mes->datalen = 0;
558
559 return 0;
560}
561
562int req_on_exit      (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
563 int term = 0;
564
565 if ( mes->datalen == 1 )
566  term = mes->data[0];
567
568 mes->cmd     = ROAR_CMD_OK;
569 mes->pos     = g_pos;
570 mes->datalen = 0;
571
572 ROAR_DBG("req_on_exit(*): term=%i", term);
573
574 if ( term ) {
575  cleanup_listen_socket(1);
576 } else {
577  alive = 0;
578 }
579
580 return 0;
581}
582
583int req_on_list_clients(int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
584 unsigned char filter, cmp;
585 uint32_t id;
586 int clients[ROAR_CLIENTS_MAX];
587 int i, c = 0;
588
589 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
590  return -1;
591
592 // TODO: add code to support filter
593 if ( filter != ROAR_CTL_FILTER_ANY )
594  return -1;
595
596 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
597  if ( g_clients[i] != NULL ) {
598   clients[c++] = i;
599  }
600 }
601
602 roar_ctl_ia2m(mes, clients, c);
603
604 mes->cmd = ROAR_CMD_OK;
605
606 return 0;
607}
608int req_on_list_streams(int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
609 unsigned char filter, cmp;
610 uint32_t id;
611 int streams[ROAR_STREAMS_MAX];
612 int i, c = 0;
613
614 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
615  return -1;
616
617 // TODO: add code to support filter
618 if ( filter != ROAR_CTL_FILTER_ANY )
619  return -1;
620
621 for (i = 0; i < ROAR_STREAMS_MAX; i++) {
622  if ( g_streams[i] != NULL ) {
623   streams[c++] = i;
624  }
625 }
626
627 roar_ctl_ia2m(mes, streams, c);
628
629 mes->cmd = ROAR_CMD_OK;
630
631 return 0;
632}
633
634int req_on_get_client  (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
635 struct roar_client * c;
636
637 if ( mes->datalen != 1 )
638  return -1;
639
640 if ( clients_get(mes->data[0], &c) == -1 )
641  return -1;
642
643 mes->cmd = ROAR_CMD_OK;
644
645 return roar_ctl_c2m(mes, c);
646}
647
648int req_on_get_stream  (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
649 struct roar_stream_server * s;
650
651 if ( mes->datalen != 1 )
652  return -1;
653
654 if ( streams_get(mes->data[0], &s) == -1 )
655  return -1;
656
657 mes->cmd = ROAR_CMD_OK;
658 mes->stream = mes->data[0];
659
660 return roar_stream_s2m(ROAR_STREAM(s), mes);
661}
662
663int req_on_get_stream_para (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
664 struct roar_stream * s;
665 struct roar_stream_server * ss;
666 struct roar_audio_info * audio_info;
667 uint16_t * d = (uint16_t *) mes->data;
668 int i;
669 char * str;
670
671 if ( mes->datalen != 4 )
672  return -1;
673
674 for (i = 0; i < mes->datalen/2; i++) {
675  d[i] = ROAR_NET2HOST16(d[i]);
676 }
677
678 if ( d[0] != 0 ) {
679  ROAR_WARN("req_on_get_stream_para(*): unsupported command version: %i, %i", (int)d[0], (int)d[1]);
680  return -1;
681 }
682
683 switch (d[1]) {
684  case ROAR_STREAM_PARA_INFO:
685    if ( streams_get(mes->stream, &ss) == -1 ) {
686     ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream);
687     return -1;
688    }
689
690    if ( streams_calc_delay(mes->stream) == -1 ) {
691     ROAR_WARN("req_on_get_stream_para(*): can not calc delay for stream %i", mes->stream);
692    }
693
694    s = ROAR_STREAM(ss);
695
696    audio_info = &(s->info);
697
698    mes->datalen = 2*12;
699
700    d[ 2] = ROAR_OUTPUT_CALC_OUTBUFSIZE(audio_info);
701    d[ 3] = ss->pre_underruns;
702    d[ 4] = ss->post_underruns;
703    d[ 5] = ss->codec_orgi;
704    d[ 6] = (ss->flags & 0xFFFF) | (ss->primary ? ROAR_FLAG_PRIMARY : 0) | (ss->driver_id != -1 ? ROAR_FLAG_OUTPUT : 0);
705    d[ 7] = ss->delay/1000;
706    d[ 8] = ss->state;
707    d[ 9] = (ss->flags & 0xFFFF0000) >> 16;
708    d[10] = ss->mixer_stream;
709    d[11] = ss->role;
710
711    ROAR_DBG("req_on_get_stream_para(*): ss->driver_id=%i", ss->driver_id);
712
713    ROAR_DBG("req_on_get_stream_para(*): delay=%i, send delay=%i", ss->delay, d[7]);
714
715    for (i = 0; i < mes->datalen/2; i++) {
716     d[i] = ROAR_HOST2NET16(d[i]);
717    }
718
719    mes->pos = s->pos;
720   break;
721
722  case ROAR_STREAM_PARA_NAME:
723   str = streams_get_name(mes->stream);
724
725   if ( str == NULL )
726    return -1;
727
728    mes->datalen = 4 + strlen(str);
729
730    if ( mes->datalen > LIBROAR_BUFFER_MSGDATA )
731     return -1;
732
733    strncpy(((char*)&(mes->data))+4, str, mes->datalen);
734
735    d[0] = ROAR_HOST2NET16(d[0]);
736    d[1] = ROAR_HOST2NET16(d[1]);
737   break;
738
739  case ROAR_STREAM_PARA_CHANMAP:
740    if ( streams_get(mes->stream, &ss) == -1 ) {
741     ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream);
742     return -1;
743    }
744
745    s = ROAR_STREAM(ss);
746
747    memcpy(&(mes->data[4]), ss->chanmap.in, s->info.channels);
748    mes->datalen = 2*2 + s->info.channels;
749
750    d[0] = ROAR_HOST2NET16(d[0]);
751    d[1] = ROAR_HOST2NET16(d[1]);
752   break;
753
754  default:
755    ROAR_WARN("req_on_get_stream_para(*): unsupported command: %i", d[1]);
756    return -1;
757 }
758
759 mes->cmd = ROAR_CMD_OK;
760 return 0;
761}
762
763int req_on_set_stream_para (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
764 uint16_t * d = (uint16_t *) mes->data;
765 int i;
766
767 if ( mes->datalen < 2*2 )
768  return -1;
769
770 for (i = 0; i < 2; i++) {
771  d[i] = ROAR_NET2HOST16(d[i]);
772 }
773
774 if ( d[0] != 0 )
775  return -1;
776
777 switch (d[1]) {
778  case ROAR_STREAM_PARA_FLAGS:
779    if ( mes->datalen != 2*4 )
780     return -1;
781
782    d[2] = ROAR_NET2HOST16(d[2]);
783    d[3] = ROAR_NET2HOST16(d[3]);
784
785    ROAR_DBG("req_on_set_stream_para(*): request seems to be valid");
786
787    if ( d[2] == ROAR_RESET_FLAG ) {
788     if ( streams_reset_flag(mes->stream, d[3]) == -1 )
789      return -1;
790    } else {
791     if ( streams_set_flag(mes->stream, d[3]) == -1 )
792      return -1;
793    }
794   break;
795  case ROAR_STREAM_PARA_CHANMAP:
796    if ( streams_set_map(mes->stream, &(mes->data[4]), mes->datalen - 4) == -1 )
797     return -1;
798   break;
799  case ROAR_STREAM_PARA_ROLE:
800    if ( mes->datalen != 2*3 )
801     return -1;
802
803    d[2] = ROAR_NET2HOST16(d[2]);
804
805    if ( streams_set_role(mes->stream, d[2]) == -1 )
806     return -1;
807   break;
808  default:
809    ROAR_WARN("req_on_set_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
810    return -1;
811   break;
812 }
813
814 mes->cmd     = ROAR_CMD_OK;
815 mes->datalen = 0;
816
817 return 0;
818}
819
820int req_on_kick (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
821 uint16_t * info = (uint16_t *) mes->data;
822
823 if ( mes->datalen != 4 )
824  return -1;
825
826 info[0] = ROAR_NET2HOST16(info[0]);
827 info[1] = ROAR_NET2HOST16(info[1]);
828
829 if ( info[0] == ROAR_OT_CLIENT ) {
830  clients_delete(info[1]);
831 } else if ( info[0] == ROAR_OT_STREAM ) {
832  if ( streams_get_flag(info[1], ROAR_FLAG_IMMUTABLE) == 1 )
833   return -1;
834
835  streams_delete(info[1]);
836 } else if ( info[0] == ROAR_OT_SOURCE ) {
837  if ( streams_get_flag(info[1], ROAR_FLAG_IMMUTABLE) == 1 )
838   return -1;
839
840  if ( streams_get_flag(info[1], ROAR_FLAG_SOURCE) == 1 ) {
841   streams_delete(info[1]);
842  } else {
843   return -1;
844  }
845 } else {
846  return -1;
847 }
848
849 mes->cmd     = ROAR_CMD_OK;
850 mes->datalen = 0;
851
852 return 0;
853}
854
855int req_on_attach      (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
856 uint16_t * info = (uint16_t *) mes->data;
857
858 if ( mes->datalen < 6 )
859  return -1;
860
861 info[0] = ROAR_NET2HOST16(info[0]);
862 info[1] = ROAR_NET2HOST16(info[1]);
863 info[2] = ROAR_NET2HOST16(info[2]);
864
865 if ( info[0] != 0 )
866  return -1;
867
868 if ( info[1] == ROAR_ATTACH_SIMPLE ) {
869  if ( client_stream_move(info[2], mes->stream) == -1 )
870   return -1;
871 } else {
872  return -1;
873 }
874
875 mes->cmd     = ROAR_CMD_OK;
876 mes->datalen = 0;
877
878 return 0;
879}
880
881int req_on_set_vol (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
882 struct roar_stream_server * s;
883 uint16_t * info = (uint16_t *) mes->data;
884 uint16_t   version;
885 uint16_t   scale = 65535;
886 int stream;
887 int i;
888 int chans;
889
890 ROAR_DBG("req_on_set_vol(*) = ?");
891 ROAR_DBG("req_on_set_vol(*): mes->datalen=%i", mes->datalen);
892
893 if ( mes->datalen < (4*2) )
894  return -1;
895
896 version = ROAR_NET2HOST16(info[0]);
897 ROAR_DBG("req_on_set_vol(*): version=%i", (int)version);
898
899 switch (version) {
900  case 0:
901    stream = ROAR_NET2HOST16(info[1]);
902   break;
903  case 1:
904    stream = mes->stream;
905    scale  = ROAR_NET2HOST16(info[1]);
906   break;
907  default:
908    return -1;
909   break;
910 }
911 ROAR_DBG("req_on_set_vol(*): stream=%i", stream);
912
913 if ( scale == 0 )
914  return -1;
915
916 // TODO: change this code.
917 //       we should not directly change the stream object but use some stream_*()-func
918 //       for that job.
919
920 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
921  return -1;
922
923 s = g_streams[stream];
924
925 if ( s == NULL )
926  return -1;
927
928 ROAR_DBG("req_on_set_vol(*): s=%p", s);
929
930 info[2] = ROAR_NET2HOST16(info[2]);
931
932 if ( info[2] == ROAR_SET_VOL_ALL ) {
933  chans = (mes->datalen/2) - 3;
934  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ALL, channes=%i", chans);
935
936  if ( chans >= ROAR_MAX_CHANNELS )
937   return -1;
938
939  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
940
941  for (i = 0; i < chans; i++) {
942   s->mixer.mixer[i] = ROAR_NET2HOST16(info[i+3]);
943   ROAR_DBG("req_on_set_vol(*): channel %i: %i", i, ROAR_NET2HOST16(info[i+3]));
944  }
945
946  s->mixer.scale = scale;
947
948  ROAR_DBG("req_on_set_vol(*): mixer changed!");
949
950 } else if ( info[2] == ROAR_SET_VOL_ONE ) {
951  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ONE");
952  if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS )
953   return -1;
954
955  s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]);
956
957  s->mixer.scale = scale;
958 } else {
959  return -1;
960 }
961
962 if ( streams_set_mixer(stream) == -1 )
963  return -1;
964
965 mes->cmd     = ROAR_CMD_OK;
966 mes->datalen = 0;
967
968 return 0;
969}
970
971int req_on_get_vol (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
972 uint16_t * info = (uint16_t *) mes->data;
973 uint16_t   version = -1;
974 int stream;
975 struct roar_stream_server * s;
976 int i;
977 int chans;
978
979 ROAR_DBG("req_on_get_vol(*) = ?");
980 ROAR_DBG("req_on_get_vol(*): mes->datalen=%i", mes->datalen);
981
982 if ( mes->datalen < 2 ) {
983  return -1;
984 }
985
986 version = ROAR_NET2HOST16(info[0]);
987
988 switch (version) {
989  case 0:
990    if ( mes->datalen < (2*2) )
991     return -1;
992
993    stream = ROAR_NET2HOST16(info[1]);
994   break;
995  case 1:
996    stream = mes->stream;
997   break;
998  default:
999    return -1;
1000   break;
1001 }
1002
1003 ROAR_DBG("req_on_get_vol(*): stream=%i", stream);
1004
1005 // TODO: change this code.
1006 //       we should not directly change the stream object but use some stream_*()-func
1007 //       for that job.
1008
1009 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
1010  return -1;
1011
1012 s = g_streams[stream];
1013
1014 if ( s == NULL )
1015  return -1;
1016
1017 ROAR_DBG("req_on_get_vol(*): s=%p", s);
1018
1019 // ok, we have everything
1020
1021 info[0] = ROAR_HOST2NET16(version);
1022
1023 switch (version) {
1024  case 0:
1025    info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
1026
1027    for (i = 0; i < chans; i++)
1028     info[2+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
1029
1030     mes->datalen = (2 + chans)*2;
1031   break;
1032  case 1:
1033    info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
1034    info[2] = ROAR_HOST2NET16(s->mixer.scale);
1035    info[3] = ROAR_HOST2NET16(s->mixer.rpg_mul);
1036    info[4] = ROAR_HOST2NET16(s->mixer.rpg_div);
1037
1038    for (i = 0; i < chans; i++)
1039     info[5+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
1040
1041     mes->datalen = (5 + chans)*2;
1042   break;
1043  default:
1044    return -1;
1045   break;
1046 }
1047
1048 mes->cmd = ROAR_CMD_OK;
1049
1050 return 0;
1051}
1052
1053int req_on_add_data (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
1054 struct roar_buffer * b;
1055 char               * buf;
1056
1057 if ( roar_buffer_new_data(&b, mes->datalen, (void **)&buf) == -1 ) {
1058  ROAR_ERR("req_on_add_data(*): Can not alloc buffer space!");
1059  ROAR_DBG("req_on_add_data(*) = -1");
1060  return -1;
1061 }
1062
1063 if ( data == NULL ) {
1064  memcpy(buf, mes->data, mes->datalen);
1065 } else {
1066  memcpy(buf, *data, mes->datalen);
1067 }
1068
1069 if ( stream_add_buffer(mes->stream, b) == -1 ) {
1070  roar_buffer_free(b);
1071  return -1;
1072 }
1073
1074 mes->cmd     = ROAR_CMD_OK_STOP;
1075 mes->datalen = 0;
1076
1077 return 0;
1078}
1079
1080int req_on_beep        (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
1081 struct roar_beep bs;
1082 int16_t * info = (int16_t*)mes->data;
1083 int stream;
1084
1085 memset(&bs, 0, sizeof(bs));
1086
1087 if ( mes->datalen > 0 ) {
1088  if ( mes->datalen < 2 )
1089   return -1;
1090
1091  if ( ROAR_NET2HOST16(info[0]) != 0 ) /* version */
1092   return -1;
1093
1094  if ( mes->datalen != 8*2 )
1095   return -1;
1096
1097  bs.vol  = ROAR_NET2HOST16(info[1]);
1098  bs.time = ROAR_NET2HOST16(info[2]);
1099  bs.freq = ROAR_NET2HOST16(info[3]);
1100  bs.type = ROAR_NET2HOST16(info[4]);
1101  bs.x    = ROAR_NET2HOST16(info[5]);
1102  bs.y    = ROAR_NET2HOST16(info[6]);
1103  bs.z    = ROAR_NET2HOST16(info[7]);
1104 }
1105
1106 if ( (stream = beep_start(client, &bs)) == -1 )
1107  return -1;
1108
1109 mes->stream  = stream;
1110 mes->cmd     = ROAR_CMD_OK_STOP;
1111 mes->datalen = 0;
1112
1113 return 0;
1114}
1115
1116//ll
Note: See TracBrowser for help on using the repository browser.