source: roaraudio/roard/req.c @ 3928:6e8e191af6a7

Last change on this file since 3928:6e8e191af6a7 was 3928:6e8e191af6a7, checked in by phi, 14 years ago

fixed exec of ready stream bug :)

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