source: roaraudio/roard/req.c @ 3802:958585351e28

Last change on this file since 3802:958585351e28 was 3802:958585351e28, checked in by phi, 14 years ago

converted listen socket handling mostly to VIOs

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