source: roaraudio/roard/req.c @ 3737:e79803f4911d

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

added clients_new_from_fh(), converted some code to use the function

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