source: roaraudio/roard/req.c @ 3685:cab6f9a5c647

Last change on this file since 3685:cab6f9a5c647 was 3672:af3bbd08fe6c, checked in by phi, 14 years ago

reject filter streams of wrong type (audio_info missmatch)

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