source: roaraudio/roard/req.c @ 3745:fbebbe3f0522

Last change on this file since 3745:fbebbe3f0522 was 3745:fbebbe3f0522, checked in by phi, 14 years ago

corrected ,

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