source: roaraudio/roard/req.c @ 3744:d95dada255ec

Last change on this file since 3744:d95dada255ec was 3741:9792d9a5321c, checked in by phi, 14 years ago

return gpos as pos

File size: 24.6 KB
RevLine 
[668]1//req.c:
[486]2
[668]3/*
[3358]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2010
[668]5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[668]23 *
24 */
[0]25
26#include "roard.h"
27
28int req_on_noop        (int client, struct roar_message * mes, char * data) {
29 mes->cmd     = ROAR_CMD_OK;
[3741]30 mes->pos     = g_pos;
[0]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 ) {
[436]45  if ( c->pid == -1 ) {
46   c->pid       = ROAR_NET2HOST32(*(uint32_t*)((mes->data)+1));
[443]47   ROAR_DBG("req_on_identify(): new PID: c->pid = %i", c->pid);
[436]48  }
[0]49
[443]50  ROAR_DBG("req_on_identify(): final PID: c->pid = %i", c->pid);
51
[0]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;
[3741]58  mes->pos     = g_pos;
[0]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;
[3741]72 mes->pos     = g_pos;
[0]73 mes->datalen = 0;
74 return 0;
75}
76
77
[1162]78int req_on_whoami      (int client, struct roar_message * mes, char * data) {
79 mes->cmd     = ROAR_CMD_OK;
[3741]80 mes->pos     = g_pos;
[1162]81 mes->datalen = 1;
82 mes->data[0] = client;
83 return 0;
84}
85
86
[0]87int req_on_new_stream  (int client, struct roar_message * mes, char * data) {
88 int stream;
89 struct roar_stream * s;
[1812]90 struct roar_stream * source_stream;
[1809]91 struct roar_audio_info * info;
[1812]92 struct roar_audio_info * source_info;
[0]93
[1904]94 ROAR_DBG("req_on_new_stream(client=%i, ...): creating stream...", client);
[0]95 if ((stream = streams_new()) == -1 )
96  return -1;
97
[1904]98 ROAR_DBG("req_on_new_stream(client=%i, ...): getting stream...", client);
[0]99 if ( streams_get(stream, (struct roar_stream_server **)&s) == -1 ) {
100  streams_delete(stream);
101  return -1;
102 }
103
[1904]104 ROAR_DBG("req_on_new_stream(client=%i, ...): set client of stream...", client);
[0]105 if ( client_stream_add(client, stream) == -1 ) {
106  streams_delete(stream);
107  return -1;
108 }
109
[1904]110 ROAR_DBG("req_on_new_stream(client=%i, ...): loading stream from message...", client);
[0]111 if ( roar_stream_m2s(s, mes) == -1 ) {
112  streams_delete(stream);
113  return -1;
114 }
115
[1904]116 ROAR_DBG("req_on_new_stream(client=%i, ...): setting id and codec of stream...", client);
[486]117 ROAR_STREAM(s)->id = stream; // roar_stream_m2s() resets this
[539]118 ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM(s)->info.codec;
[486]119
[1904]120 ROAR_DBG("req_on_new_stream(client=%i, ...): setting direction stream...", client);
[1900]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
[1904]127 ROAR_DBG("req_on_new_stream(client=%i, ...): setting up direction specific stream settings...", client);
[1809]128 switch (ROAR_STREAM(s)->dir) {
129  case ROAR_DIR_LIGHT_IN:
130  case ROAR_DIR_LIGHT_OUT:
[2497]131#ifndef ROAR_WITHOUT_DCOMP_LIGHT
[1809]132    info = &(ROAR_STREAM(s)->info);
133
134    info->channels = 0;
135    info->bits     = 0;
136    info->rate     = 0;
[2497]137#else
138    streams_delete(stream);
139    return -1;
140#endif
[1809]141
142   break;
[1848]143  case ROAR_DIR_MIDI_IN:
144  case ROAR_DIR_MIDI_OUT:
[2497]145#ifndef ROAR_WITHOUT_DCOMP_MIDI
[1848]146    info = &(ROAR_STREAM(s)->info);
147
[2402]148    info->channels = ROAR_MIDI_CHANNELS_DEFAULT;
149    info->bits     = ROAR_MIDI_BITS;
150    info->rate     = 0;
[2497]151#else
152    streams_delete(stream);
153    return -1;
154#endif
[1848]155
156   break;
157
[2250]158  case ROAR_DIR_RAW_IN:
[2497]159#ifndef ROAR_WITHOUT_DCOMP_RAW
[2250]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    }
[2497]169#else
170  case ROAR_DIR_RAW_OUT:
171    streams_delete(stream);
172    return -1;
173#endif
[2250]174
175   break;
[1812]176  case ROAR_DIR_THRU:
[1815]177
178    if ( ROAR_STREAM(s)->pos_rel_id == -1 || ROAR_STREAM(s)->pos_rel_id == stream ) {
[1861]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
[1815]181     streams_delete(stream);
182     return -1;
183    }
184
[1812]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;
[1840]197    ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM_SERVER(source_stream)->codec_orgi;
[1812]198
199   break;
[3672]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;
[1809]221 }
222
[1904]223 ROAR_DBG("req_on_new_stream(client=%i, ...): returning (OK)...", client);
224
[0]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
[1904]235 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): execing stream", client, mes->stream);
236
[0]237 if ( (r = client_stream_exec(client, mes->stream)) == -1 )
238  return -1;
239
[1904]240 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
[0]241 mes->cmd     = ROAR_CMD_OK;
242 mes->datalen = 0;
243
244 return 0;
245}
246
[77]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
[80]260 if ( mes->datalen > 80 ) // we do not support long messages here
261  return -1;
262
[77]263 type = (unsigned)mes->data[1];
[79]264 port = ROAR_NET2HOST16(((uint16_t*)mes->data)[1]);
[77]265
[80]266 len = mes->datalen - 4;
[77]267
[84]268 strncpy(host, &(mes->data[4]), len);
[77]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
[525]280 ROAR_DBG("req_on_con_stream(*): CONNECT(type=%i, host='%s', port=%i)", type, host, port);
281
[77]282 if ( (fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port)) == -1 )
283  return -1;
284
[78]285 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
286  close(fh);
287  return 1;
288 }
289
[757]290 mes->datalen = 0;
291 mes->cmd     = ROAR_CMD_OK;
292
[78]293 return 0;
[757]294}
295
296int req_on_passfh      (int client, struct roar_message * mes, char * data) {
[3714]297 int sock = clients_get_fh(client);
[3720]298 int16_t * d = (int16_t*)mes->data;
[3732]299 struct roard_listen * lsock;
300 int listening;
[757]301 int fh;
[3714]302 int i;
[757]303
304 if ( (fh = roar_socket_recv_fh(sock, NULL, NULL)) == -1 )
305  return -1;
306
[3723]307 if ( mes->stream != -1 ) { // stream pass:
[3714]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;
[757]317 }
318
[3714]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
[3732]339 listening = d[1] & ROAR_CLIENTPASS_FLAG_LISTEN;
340
341 if ( listening )
342  d[1] -= ROAR_CLIENTPASS_FLAG_LISTEN;
343
[3714]344 if ( d[1] != 0 ) // flags
345  return -1;
346
[3732]347 if ( listening ) {
[3734]348  if ( get_listen(&lsock, NULL) == -1 ) {
349   close(fh);
[3732]350   return -1;
[3734]351  }
[3714]352
[3732]353  lsock->socket = fh;
354  lsock->proto  = d[2];
355 } else {
[3737]356  if ( clients_new_from_fh(fh, d[2], d[3], 1) == -1 )
[3732]357   return -1;
[3729]358 }
359
[78]360 mes->datalen = 0;
361 mes->cmd     = ROAR_CMD_OK;
[757]362
[3720]363 return 0;
[77]364}
365
[1493]366#ifdef ROAR_SUPPORT_META
[0]367int req_on_set_meta    (int client, struct roar_message * mes, char * data) {
[92]368 int type;
369 int mode;
370 int namelen, vallen;
[99]371 char   val[255+1];
[92]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
[99]383 ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type);
384
[92]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
[1038]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;
[92]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
[99]404  ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen);
405
[92]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
[99]415  if ( vallen > 255 )
[92]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
[0]436 return -1;
437}
438
[100]439int req_on_get_meta    (int client, struct roar_message * mes, char * data) {
[101]440 int vallen;
441 int type;
[107]442 char val[LIBROAR_BUFFER_MSGDATA-1];
[101]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
[107]463 val[vallen] = 0;
464
465 strncpy(&(mes->data[2]), val, vallen+1);
[101]466
467 return 0;
[100]468}
[0]469
[113]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}
[1493]493#endif
[113]494
[0]495int req_on_server_oinfo    (int client, struct roar_message * mes, char * data) {
496 struct roar_stream s;
497//ROAR_DIR_OUTPUT
498
[966]499 memset(&s, 0, sizeof(struct roar_stream));
[964]500
[977]501 s.dir           = ROAR_DIR_MIXING;
[0]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;
[977]507 s.pos           = g_pos;
[0]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) {
[3741]519 mes->cmd     = ROAR_CMD_OK;
520 mes->pos     = g_pos;
[0]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;
[3741]535 mes->pos     = g_pos;
[0]536 mes->datalen = 0;
537
538 return 0;
539}
540
541int req_on_exit      (int client, struct roar_message * mes, char * data) {
[575]542 int term = 0;
543
544 if ( mes->datalen == 1 )
545  term = mes->data[0];
546
[0]547 mes->cmd     = ROAR_CMD_OK;
[3741]548 mes->pos     = g_pos;
[0]549 mes->datalen = 0;
550
[576]551 ROAR_DBG("req_on_exit(*): term=%i", term);
552
[575]553 if ( term ) {
554  cleanup_listen_socket(1);
555 } else {
556  alive = 0;
557 }
[0]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;
[465]637 mes->stream = mes->data[0];
[0]638
639 return roar_stream_s2m(ROAR_STREAM(s), mes);
640}
641
[465]642int req_on_get_stream_para (int client, struct roar_message * mes, char * data) {
643 struct roar_stream * s;
[963]644 struct roar_stream_server * ss;
[465]645 struct roar_audio_info * audio_info;
646 uint16_t * d = (uint16_t *) mes->data;
647 int i;
[1842]648 char * str;
[465]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
[1842]657 if ( d[0] != 0 ) {
[465]658  ROAR_WARN("req_on_get_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
659  return -1;
660 }
661
[1842]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);
[465]674
[1842]675    audio_info = &(s->info);
676
[3630]677    mes->datalen = 2*12;
[1842]678
[3213]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;
[3630]688    d[11] = ss->role;
[1842]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]);
[465]693
[1842]694    for (i = 0; i < mes->datalen/2; i++) {
695     d[i] = ROAR_HOST2NET16(d[i]);
696    }
[1156]697
[1842]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;
[1151]706
[1842]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
[3539]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
[1842]733  default:
734    ROAR_WARN("req_on_get_stream_para(*): unsupported command: %i", d[1]);
735    return -1;
[465]736 }
737
738 mes->cmd = ROAR_CMD_OK;
739 return 0;
740}
741
[1043]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
[3542]746 if ( mes->datalen < 2*2 )
[1043]747  return -1;
748
[3542]749 for (i = 0; i < 2; i++) {
[1043]750  d[i] = ROAR_NET2HOST16(d[i]);
751 }
752
[3542]753 if ( d[0] != 0 )
[1043]754  return -1;
[3542]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;
[3696]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;
[3542]787  default:
788    ROAR_WARN("req_on_set_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
789    return -1;
790   break;
[1043]791 }
792
793 mes->cmd     = ROAR_CMD_OK;
794 mes->datalen = 0;
795
[3542]796 return 0;
[1043]797}
798
[0]799int req_on_kick (int client, struct roar_message * mes, char * data) {
[17]800 uint16_t * info = (uint16_t *) mes->data;
[0]801
802 if ( mes->datalen != 4 )
803  return -1;
804
[251]805 info[0] = ROAR_NET2HOST16(info[0]);
806 info[1] = ROAR_NET2HOST16(info[1]);
807
[0]808 if ( info[0] == ROAR_OT_CLIENT ) {
809  clients_delete(info[1]);
810 } else if ( info[0] == ROAR_OT_STREAM ) {
[2952]811  if ( streams_get_flag(info[1], ROAR_FLAG_IMMUTABLE) == 1 )
812   return -1;
813
[0]814  streams_delete(info[1]);
[1111]815 } else if ( info[0] == ROAR_OT_SOURCE ) {
[2952]816  if ( streams_get_flag(info[1], ROAR_FLAG_IMMUTABLE) == 1 )
817   return -1;
818
[1111]819  if ( streams_get_flag(info[1], ROAR_FLAG_SOURCE) == 1 ) {
820   streams_delete(info[1]);
821  } else {
822   return -1;
823  }
[0]824 } else {
825  return -1;
826 }
827
828 mes->cmd     = ROAR_CMD_OK;
829 mes->datalen = 0;
830
831 return 0;
832}
833
[768]834int req_on_attach      (int client, struct roar_message * mes, char * data) {
[769]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;
[768]858}
859
[17]860int req_on_set_vol (int client, struct roar_message * mes, char * data) {
[3530]861 struct roar_stream_server * s;
[17]862 uint16_t * info = (uint16_t *) mes->data;
[3530]863 uint16_t   version;
864 uint16_t   scale = 65535;
[17]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
[3530]875 version = ROAR_NET2HOST16(info[0]);
876 ROAR_DBG("req_on_set_vol(*): version=%i", (int)version);
[17]877
[3530]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 }
[17]890 ROAR_DBG("req_on_set_vol(*): stream=%i", stream);
891
[3561]892 if ( scale == 0 )
893  return -1;
894
[17]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
[252]909 info[2] = ROAR_NET2HOST16(info[2]);
910
[17]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
[18]918  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
919
[17]920  for (i = 0; i < chans; i++) {
[252]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]));
[17]923  }
924
[3530]925  s->mixer.scale = scale;
926
[17]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");
[252]931  if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS )
[17]932   return -1;
933
[252]934  s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]);
[3530]935
936  s->mixer.scale = scale;
[17]937 } else {
938  return -1;
939 }
940
[1590]941 if ( streams_set_mixer(stream) == -1 )
942  return -1;
943
[17]944 mes->cmd     = ROAR_CMD_OK;
945 mes->datalen = 0;
946
947 return 0;
948}
[0]949
[23]950int req_on_get_vol (int client, struct roar_message * mes, char * data) {
951 uint16_t * info = (uint16_t *) mes->data;
[3529]952 uint16_t   version = -1;
[23]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
[3529]961 if ( mes->datalen < 2 ) {
[23]962  return -1;
[3529]963 }
964
965 version = ROAR_NET2HOST16(info[0]);
966
967 switch (version) {
968  case 0:
969    if ( mes->datalen < (2*2) )
970     return -1;
[23]971
[3529]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 }
[23]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
[3529]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]);
[23]1008
[3529]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);
[23]1016
[3529]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
[23]1027 mes->cmd = ROAR_CMD_OK;
1028
1029 return 0;
1030}
1031
[0]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
[498]1055 mes->cmd     = ROAR_CMD_OK_STOP;
[0]1056 mes->datalen = 0;
1057
1058 return 0;
1059}
1060
[3574]1061int req_on_beep        (int client, struct roar_message * mes, char * data) {
[3575]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;
[3574]1095}
1096
[0]1097//ll
Note: See TracBrowser for help on using the repository browser.