source: roaraudio/roard/req.c @ 3734:f0b2605ed0a4

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

close fh in case of error

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