source: roaraudio/roard/req.c @ 4343:a67cbb88fbe0

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

added support for wait command

File size: 34.0 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
[4298]28static void * _dataspace(struct roar_message * mes, char ** data, uint32_t flags[2], size_t len) {
29 if ( len <= LIBROAR_BUFFER_MSGDATA )
30  return mes->data;
31
32 if ( *data != NULL )
33  free(*data);
34
35 *data = malloc(len);
36
37 ROAR_DBG("_dataspace(mes=%p, data=%p, flags=%p, len=%llu): *data=%p", mes, data, flags, (long long unsigned int)len, *data);
38
39 if ( *data == NULL )
40  return NULL;
41
42 flags[1] |= COMMAND_FLAG_OUT_LONGDATA;
43
44 return *data;
45}
46
[3926]47int req_on_noop        (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]48 mes->cmd     = ROAR_CMD_OK;
[3741]49 mes->pos     = g_pos;
[0]50 mes->datalen = 0;
51 return 0;
52}
53
[3926]54int req_on_identify    (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]55 struct roar_client * c;
56 int max_len;
57
58 if ( mes->datalen < 1 )
59  return -1;
60
61 clients_get(client, &c);
62
63 if ( mes->data[0] == 1 ) {
[436]64  if ( c->pid == -1 ) {
65   c->pid       = ROAR_NET2HOST32(*(uint32_t*)((mes->data)+1));
[443]66   ROAR_DBG("req_on_identify(): new PID: c->pid = %i", c->pid);
[436]67  }
[0]68
[443]69  ROAR_DBG("req_on_identify(): final PID: c->pid = %i", c->pid);
70
[0]71  max_len = (mes->datalen - 5) < (ROAR_BUFFER_NAME-1) ? (mes->datalen - 5) : (ROAR_BUFFER_NAME-1);
72
73  strncpy(c->name, mes->data + 5, max_len);
74  c->name[max_len] = 0;
75
76  mes->cmd     = ROAR_CMD_OK;
[3741]77  mes->pos     = g_pos;
[0]78  mes->datalen = 0;
79
80  ROAR_DBG("req_on_identify(*): client=%i, pid=%i", client, c->pid);
81  ROAR_DBG("req_on_identify(*) = 0");
82  return 0;
83 }
84
85 return -1;
86}
87
[3926]88int req_on_auth        (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]89 // TODO: add code to support some auth.
90 mes->cmd     = ROAR_CMD_OK;
[3741]91 mes->pos     = g_pos;
[0]92 mes->datalen = 0;
93 return 0;
94}
95
96
[3926]97int req_on_whoami      (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[1162]98 mes->cmd     = ROAR_CMD_OK;
[3741]99 mes->pos     = g_pos;
[1162]100 mes->datalen = 1;
101 mes->data[0] = client;
102 return 0;
103}
104
105
[3926]106int req_on_new_stream  (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]107 int stream;
108 struct roar_stream * s;
[1812]109 struct roar_stream * source_stream;
[1809]110 struct roar_audio_info * info;
[1812]111 struct roar_audio_info * source_info;
[0]112
[1904]113 ROAR_DBG("req_on_new_stream(client=%i, ...): creating stream...", client);
[0]114 if ((stream = streams_new()) == -1 )
115  return -1;
116
[4236]117 ROAR_DBG("req_on_new_stream(client=%i, ...): stream=%i", client, stream);
118
[1904]119 ROAR_DBG("req_on_new_stream(client=%i, ...): getting stream...", client);
[0]120 if ( streams_get(stream, (struct roar_stream_server **)&s) == -1 ) {
121  streams_delete(stream);
122  return -1;
123 }
124
[1904]125 ROAR_DBG("req_on_new_stream(client=%i, ...): set client of stream...", client);
[0]126 if ( client_stream_add(client, stream) == -1 ) {
127  streams_delete(stream);
128  return -1;
129 }
130
[1904]131 ROAR_DBG("req_on_new_stream(client=%i, ...): loading stream from message...", client);
[0]132 if ( roar_stream_m2s(s, mes) == -1 ) {
133  streams_delete(stream);
134  return -1;
135 }
136
[1904]137 ROAR_DBG("req_on_new_stream(client=%i, ...): setting id and codec of stream...", client);
[486]138 ROAR_STREAM(s)->id = stream; // roar_stream_m2s() resets this
[539]139 ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM(s)->info.codec;
[486]140
[1904]141 ROAR_DBG("req_on_new_stream(client=%i, ...): setting direction stream...", client);
[1900]142 // int streams_set_dir    (int id, int dir, int defaults)
143 if ( streams_set_dir(stream, ROAR_STREAM(s)->dir, 1) == -1 ) {
144  streams_delete(stream);
145  return -1;
146 }
147
[1904]148 ROAR_DBG("req_on_new_stream(client=%i, ...): setting up direction specific stream settings...", client);
[1809]149 switch (ROAR_STREAM(s)->dir) {
150  case ROAR_DIR_LIGHT_IN:
151  case ROAR_DIR_LIGHT_OUT:
[2497]152#ifndef ROAR_WITHOUT_DCOMP_LIGHT
[1809]153    info = &(ROAR_STREAM(s)->info);
154
155    info->channels = 0;
156    info->bits     = 0;
157    info->rate     = 0;
[2497]158#else
159    streams_delete(stream);
160    return -1;
161#endif
[1809]162
163   break;
[1848]164  case ROAR_DIR_MIDI_IN:
165  case ROAR_DIR_MIDI_OUT:
[2497]166#ifndef ROAR_WITHOUT_DCOMP_MIDI
[1848]167    info = &(ROAR_STREAM(s)->info);
168
[2402]169    info->channels = ROAR_MIDI_CHANNELS_DEFAULT;
170    info->bits     = ROAR_MIDI_BITS;
171    info->rate     = 0;
[2497]172#else
173    streams_delete(stream);
174    return -1;
175#endif
[1848]176
177   break;
178
[2250]179  case ROAR_DIR_RAW_IN:
[2497]180#ifndef ROAR_WITHOUT_DCOMP_RAW
[2250]181    if ( ROAR_STREAM(s)->pos_rel_id == -1     ||
182         ROAR_STREAM(s)->pos_rel_id == stream ||
183         streams_get_dir(ROAR_STREAM(s)->pos_rel_id) != ROAR_DIR_RAW_OUT
184       ) {
185     ROAR_STREAM(s)->pos_rel_id = -1; // force this here as it will try to delete itself while deleting
186                                      // in case rel_id == stream
187     streams_delete(stream);
188     return -1;
189    }
[2497]190#else
191  case ROAR_DIR_RAW_OUT:
192    streams_delete(stream);
193    return -1;
194#endif
[2250]195
196   break;
[1812]197  case ROAR_DIR_THRU:
[1815]198
199    if ( ROAR_STREAM(s)->pos_rel_id == -1 || ROAR_STREAM(s)->pos_rel_id == stream ) {
[1861]200     ROAR_STREAM(s)->pos_rel_id = -1; // force this here as it will try to delete itself while deleting
201                                      // in case rel_id == stream
[1815]202     streams_delete(stream);
203     return -1;
204    }
205
[1812]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
211    info        = &(ROAR_STREAM(s)->info);
212    source_info = &(ROAR_STREAM(source_stream)->info);
213
214    info->channels = source_info->channels;
215    info->bits     = source_info->bits;
216    info->rate     = source_info->rate;
217    info->codec    = source_info->codec;
[1840]218    ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM_SERVER(source_stream)->codec_orgi;
[1812]219
220   break;
[3672]221  case ROAR_DIR_FILTER:
222    info        = &(ROAR_STREAM(s)->info);
223
224    if ( ROAR_STREAM(s)->pos_rel_id == -1 ) {
225     source_info = g_sa;
226    } else {
227     if ( streams_get(ROAR_STREAM(s)->pos_rel_id, (struct roar_stream_server **)&source_stream) == -1 ) {
228      streams_delete(stream);
229      return -1;
230     }
231     source_info = &(ROAR_STREAM(source_stream)->info);
232    }
233
234    if ( info->channels != source_info->channels || info->bits != source_info->bits ||
235         info->codec    != source_info->codec    || info->rate != source_info->rate ) {
236     // the stream parameters don't match the one of the stream being filtered.
237     // -> delete and reject the stream.
238     streams_delete(stream);
239     return -1;
240    }
241   break;
[1809]242 }
243
[4236]244 ROAR_DBG("req_on_new_stream(client=%i, ...): returning (OK, stream=%i)...", client, stream);
[1904]245
[0]246 mes->cmd     = ROAR_CMD_OK;
247 mes->stream  = stream;
248 mes->datalen = 0;
249
250 return 0;
251}
252
[3926]253int req_on_exec_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]254 int r;
255
[1904]256 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): execing stream", client, mes->stream);
257
[3928]258
259 if ( streams_is_ready(mes->stream) ) {
260  flags[1] |= COMMAND_FLAG_OUT_CLOSECON;
261 } else {
262  if ( (r = client_stream_exec(client, mes->stream)) == -1 )
263   return -1;
264 }
[0]265
[1904]266 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
[0]267 mes->cmd     = ROAR_CMD_OK;
268 mes->datalen = 0;
269
270 return 0;
271}
272
[3926]273int req_on_con_stream  (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[77]274 char   host[80] = {0};
275 int    port = 0;
276 int    type;
277 int    fh;
278 int    len;
279
280 if ( mes->datalen < 4 )
281  return -1;
282
283 if ( *(mes->data) != 0 )
284  return -1;
285
[80]286 if ( mes->datalen > 80 ) // we do not support long messages here
287  return -1;
288
[77]289 type = (unsigned)mes->data[1];
[79]290 port = ROAR_NET2HOST16(((uint16_t*)mes->data)[1]);
[77]291
[80]292 len = mes->datalen - 4;
[77]293
[84]294 strncpy(host, &(mes->data[4]), len);
[77]295 host[len] = 0;
296
297 if ( type > ROAR_SOCKET_TYPE_MAX )
298  return -1;
299
300 if ( type == ROAR_SOCKET_TYPE_FILE ) // disabled because of security resons
301  return -1;
302
303 if ( type == ROAR_SOCKET_TYPE_FORK ) // why should we connect to ourself?
304  return -1;
305
[525]306 ROAR_DBG("req_on_con_stream(*): CONNECT(type=%i, host='%s', port=%i)", type, host, port);
307
[77]308 if ( (fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port)) == -1 )
309  return -1;
310
[78]311 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
312  close(fh);
313  return 1;
314 }
315
[757]316 mes->datalen = 0;
317 mes->cmd     = ROAR_CMD_OK;
318
[78]319 return 0;
[757]320}
321
[3926]322int req_on_passfh      (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[3714]323 int sock = clients_get_fh(client);
[3720]324 int16_t * d = (int16_t*)mes->data;
[3732]325 struct roard_listen * lsock;
326 int listening;
[757]327 int fh;
[3714]328 int i;
[757]329
[4236]330 ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...) = ?", client, mes->stream);
331
[4255]332 if ( (fh = roar_socket_recv_fh(sock, NULL, NULL)) == -1 ) {
333  ROAR_WARN("req_on_passfh(client=%i, mes={stream=%i,...},...): was unabled to get filehandle from remote end. bad.", client, mes->stream);
334  ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (ERROR)...", client, mes->stream);
[757]335  return -1;
[4255]336 }
[757]337
[4236]338 ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): fh=%i", client, mes->stream, fh);
339
[3723]340 if ( mes->stream != -1 ) { // stream pass:
[4236]341  ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): This is a stream passfh", client, mes->stream);
342
[3714]343  if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
344   close(fh);
[4236]345   ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (ERROR)...", client, mes->stream);
[4235]346   return -1;
[3714]347  }
348
[4236]349  ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
350
[3714]351  mes->datalen = 0;
352  mes->cmd     = ROAR_CMD_OK;
353
354  return 0;
[757]355 }
356
[3714]357// non-stream pass:
358
[4236]359 ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): This is a client passfh", client, mes->stream);
360
[3714]361/*
[3745]362 0: Version,   16
363 1: Flags,     16
364 2: Protocol,  16
365 3: Byteorder, 16
[3714]366 Options...
367*/
368
369 if ( mes->datalen < 4*2 )
370  return -1;
371
372 for (i = 0; i < 4; i++) {
373  d[i] = ROAR_NET2HOST16(d[i]);
374 }
375
376 if ( d[0] != 0 ) // version
377  return -1;
378
[3732]379 listening = d[1] & ROAR_CLIENTPASS_FLAG_LISTEN;
380
381 if ( listening )
382  d[1] -= ROAR_CLIENTPASS_FLAG_LISTEN;
383
[3714]384 if ( d[1] != 0 ) // flags
385  return -1;
386
[3732]387 if ( listening ) {
[3734]388  if ( get_listen(&lsock, NULL) == -1 ) {
389   close(fh);
[3732]390   return -1;
[3734]391  }
[3714]392
[3802]393  roar_vio_open_fh_socket(&(lsock->sock), fh);
394  lsock->used   = 1;
[3732]395  lsock->proto  = d[2];
396 } else {
[3737]397  if ( clients_new_from_fh(fh, d[2], d[3], 1) == -1 )
[3732]398   return -1;
[3729]399 }
400
[4236]401 ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
402
[78]403 mes->datalen = 0;
404 mes->cmd     = ROAR_CMD_OK;
[757]405
[3720]406 return 0;
[77]407}
408
[1493]409#ifdef ROAR_SUPPORT_META
[3926]410int req_on_set_meta    (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[92]411 int type;
412 int mode;
413 int namelen, vallen;
[99]414 char   val[255+1];
[92]415 char   name[ROAR_META_MAX_NAMELEN+1];
416
417 if ( mes->datalen < 3 )
418  return -1;
419
420 if ( mes->data[0] != 0 ) // version
421  return -1;
422
423 mode = (unsigned) mes->data[1];
424 type = (unsigned) mes->data[2];
425
[99]426 ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type);
427
[92]428 if ( mode == ROAR_META_MODE_CLEAR ) {
429  stream_meta_clear(mes->stream);
430  mes->datalen = 0;
431  mes->cmd     = ROAR_CMD_OK;
432  return 0;
433 } else if ( mode == ROAR_META_MODE_DELETE ) { // unsuppoerted at the moment
[1038]434  return -1;
435 } else if ( mode == ROAR_META_MODE_FINALIZE ) {
436  stream_meta_finalize(mes->stream);
437  mes->datalen = 0;
438  mes->cmd     = ROAR_CMD_OK;
439  return 0;
[92]440 } else if ( mode == ROAR_META_MODE_SET || mode == ROAR_META_MODE_ADD ) {
441  if ( mes->datalen < 5 )
442   return -1;
443
444  namelen = (unsigned) mes->data[3];
445  vallen  = (unsigned) mes->data[4];
446
[99]447  ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen);
448
[92]449  if ( mes->datalen < (5 + namelen + vallen) )
450   return -1;
451
452  if ( namelen > ROAR_META_MAX_NAMELEN )
453   return -1;
454
455  strncpy(name, &(mes->data[5]), namelen);
456  name[namelen] = 0;
457
[99]458  if ( vallen > 255 )
[92]459   return -1;
460
461  strncpy(val, &(mes->data[5+namelen]), vallen);
462  val[vallen] = 0;
463
464  if ( mode == ROAR_META_MODE_SET ) {
465   if ( stream_meta_set(mes->stream, type, name, val) == -1 )
466    return -1;
467  } else {
468   if ( stream_meta_add(mes->stream, type, name, val) == -1 )
469    return -1;
470  }
471
472  mes->datalen = 0;
473  mes->cmd     = ROAR_CMD_OK;
474  return 0;
475 } else { // unknown mode!
476  return -1;
477 }
478
[0]479 return -1;
480}
481
[3926]482int req_on_get_meta    (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[101]483 int vallen;
484 int type;
[107]485 char val[LIBROAR_BUFFER_MSGDATA-1];
[101]486
487 if ( mes->datalen != 2 )
488  return -1;
489
490 if ( mes->data[0] != 0 ) // version
491  return -1;
492
493 type = (unsigned) mes->data[1];
494
495 if ( stream_meta_get(mes->stream, type, NULL, val, LIBROAR_BUFFER_MSGDATA-2) == -1 )
496  return -1;
497
498 vallen = strlen(val);
499
500 mes->cmd     = ROAR_CMD_OK;
501 mes->datalen = 2 + vallen;
502
503 mes->data[0] = 0;
504 mes->data[1] = (unsigned char) vallen;
505
[107]506 val[vallen] = 0;
507
508 strncpy(&(mes->data[2]), val, vallen+1);
[101]509
510 return 0;
[100]511}
[0]512
[3926]513int req_on_list_meta   (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[113]514 int i;
515 int len = 0;
516 int types[ROAR_META_MAX_PER_STREAM];
517
518 if ( mes->datalen != 1 )
519  return -1;
520
521 if ( mes->data[0] != 0 ) // version
522  return -1;
523
524 if ( (len = stream_meta_list(mes->stream, types, ROAR_META_MAX_PER_STREAM)) == -1 )
525  return -1;
526
527 mes->cmd     = ROAR_CMD_OK;
528 mes->datalen = 1 + len;
529 mes->data[0] = 0;
530
531 for (i = 0; i < len; i++)
532  mes->data[i+1] = types[i];
533
534 return 0;
535}
[1493]536#endif
[113]537
[3926]538int req_on_server_oinfo    (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]539 struct roar_stream s;
540//ROAR_DIR_OUTPUT
541
[966]542 memset(&s, 0, sizeof(struct roar_stream));
[964]543
[977]544 s.dir           = ROAR_DIR_MIXING;
[0]545 s.pos_rel_id    = -1;
546 s.info.rate     = g_sa->rate;
547 s.info.bits     = g_sa->bits;
548 s.info.channels = g_sa->channels;
549 s.info.codec    = g_sa->codec;
[977]550 s.pos           = g_pos;
[0]551
552 if ( roar_stream_s2m(&s, mes) == -1 )
553  return -1;
554
555 mes->cmd = ROAR_CMD_OK;
556
557 return 0;
558}
559
560
[3926]561int req_on_get_standby (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[3741]562 mes->cmd     = ROAR_CMD_OK;
563 mes->pos     = g_pos;
[0]564 mes->datalen = 2;
565
566 *((uint16_t*)mes->data) = ROAR_HOST2NET16((unsigned) g_standby);
567
568 return 0;
569}
570
[3926]571int req_on_set_standby (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]572 if ( mes->datalen != 2 )
573  return -1;
574
575 g_standby = ROAR_NET2HOST16(*((uint16_t*)mes->data));
576
577 mes->cmd     = ROAR_CMD_OK;
[3741]578 mes->pos     = g_pos;
[0]579 mes->datalen = 0;
580
581 return 0;
582}
583
[3926]584int req_on_exit      (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[575]585 int term = 0;
586
587 if ( mes->datalen == 1 )
588  term = mes->data[0];
589
[0]590 mes->cmd     = ROAR_CMD_OK;
[3741]591 mes->pos     = g_pos;
[0]592 mes->datalen = 0;
593
[576]594 ROAR_DBG("req_on_exit(*): term=%i", term);
595
[575]596 if ( term ) {
597  cleanup_listen_socket(1);
598 } else {
599  alive = 0;
600 }
[0]601
602 return 0;
603}
604
[3926]605int req_on_list_clients(int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]606 unsigned char filter, cmp;
607 uint32_t id;
608 int clients[ROAR_CLIENTS_MAX];
609 int i, c = 0;
610
611 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
612  return -1;
613
614 // TODO: add code to support filter
615 if ( filter != ROAR_CTL_FILTER_ANY )
616  return -1;
617
618 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
619  if ( g_clients[i] != NULL ) {
620   clients[c++] = i;
621  }
622 }
623
624 roar_ctl_ia2m(mes, clients, c);
625
626 mes->cmd = ROAR_CMD_OK;
627
628 return 0;
629}
[3926]630int req_on_list_streams(int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]631 unsigned char filter, cmp;
632 uint32_t id;
633 int streams[ROAR_STREAMS_MAX];
634 int i, c = 0;
[4333]635 int match;
[0]636
637 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
638  return -1;
639
[4333]640 for (i = 0; i < ROAR_STREAMS_MAX; i++) {
641  if ( g_streams[i] == NULL )
642   continue;
643
644  match = 0;
[0]645
[4333]646  switch (filter) {
647   case ROAR_CTL_FILTER_ANY:
648     match = 1;
649    break;
650   case ROAR_CTL_FILTER_DIR:
651     match = roar_filter_match(cmp, id, ROAR_STREAM(g_streams[i])->dir);
652    break;
653   default: // unsupported filter...
654     return -1;
655    break;
656  }
657
658  if ( match )
[0]659   streams[c++] = i;
660 }
661
662 roar_ctl_ia2m(mes, streams, c);
663
664 mes->cmd = ROAR_CMD_OK;
665
666 return 0;
667}
668
[3926]669int req_on_get_client  (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]670 struct roar_client * c;
671
672 if ( mes->datalen != 1 )
673  return -1;
674
675 if ( clients_get(mes->data[0], &c) == -1 )
676  return -1;
677
678 mes->cmd = ROAR_CMD_OK;
679
680 return roar_ctl_c2m(mes, c);
681}
682
[3926]683int req_on_get_stream  (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]684 struct roar_stream_server * s;
685
686 if ( mes->datalen != 1 )
687  return -1;
688
689 if ( streams_get(mes->data[0], &s) == -1 )
690  return -1;
691
692 mes->cmd = ROAR_CMD_OK;
[465]693 mes->stream = mes->data[0];
[0]694
695 return roar_stream_s2m(ROAR_STREAM(s), mes);
696}
697
[3926]698int req_on_get_stream_para (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[465]699 struct roar_stream * s;
[963]700 struct roar_stream_server * ss;
[465]701 struct roar_audio_info * audio_info;
[4277]702 struct roar_stream_ltm * ltm;
703 uint16_t * d  = (uint16_t *) mes->data;
704 int64_t * d64 = ( int64_t *) mes->data;
705 int64_t * d64ptr;
706 int i, h, k;
[1842]707 char * str;
[4277]708 size_t needed;
709 int test, bits;
[465]710
[4279]711 ROAR_DBG("req_on_get_stream_para(client=%i, mes=%p{.stream=%i, .datalen=%i,...}, data=%p, flags=%p) = ?", client, mes, (int)mes->stream, (int)mes->datalen, data, flags);
712
[4280]713 if ( mes->datalen < 4 )
[465]714  return -1;
715
[4281]716 for (i = 0; i < 2; i++) {
[465]717  d[i] = ROAR_NET2HOST16(d[i]);
718 }
719
[1842]720 if ( d[0] != 0 ) {
[4066]721  ROAR_WARN("req_on_get_stream_para(*): unsupported command version: %i, %i", (int)d[0], (int)d[1]);
[465]722  return -1;
723 }
724
[1842]725 switch (d[1]) {
726  case ROAR_STREAM_PARA_INFO:
727    if ( streams_get(mes->stream, &ss) == -1 ) {
728     ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream);
729     return -1;
730    }
731
732    if ( streams_calc_delay(mes->stream) == -1 ) {
733     ROAR_WARN("req_on_get_stream_para(*): can not calc delay for stream %i", mes->stream);
734    }
735
736    s = ROAR_STREAM(ss);
[465]737
[1842]738    audio_info = &(s->info);
739
[3630]740    mes->datalen = 2*12;
[1842]741
[3213]742    d[ 2] = ROAR_OUTPUT_CALC_OUTBUFSIZE(audio_info);
743    d[ 3] = ss->pre_underruns;
744    d[ 4] = ss->post_underruns;
745    d[ 5] = ss->codec_orgi;
746    d[ 6] = (ss->flags & 0xFFFF) | (ss->primary ? ROAR_FLAG_PRIMARY : 0) | (ss->driver_id != -1 ? ROAR_FLAG_OUTPUT : 0);
747    d[ 7] = ss->delay/1000;
748    d[ 8] = ss->state;
749    d[ 9] = (ss->flags & 0xFFFF0000) >> 16;
750    d[10] = ss->mixer_stream;
[3630]751    d[11] = ss->role;
[1842]752
753    ROAR_DBG("req_on_get_stream_para(*): ss->driver_id=%i", ss->driver_id);
754
755    ROAR_DBG("req_on_get_stream_para(*): delay=%i, send delay=%i", ss->delay, d[7]);
[465]756
[1842]757    for (i = 0; i < mes->datalen/2; i++) {
758     d[i] = ROAR_HOST2NET16(d[i]);
759    }
[1156]760
[1842]761    mes->pos = s->pos;
762   break;
763
764  case ROAR_STREAM_PARA_NAME:
765   str = streams_get_name(mes->stream);
766
767   if ( str == NULL )
768    return -1;
[1151]769
[1842]770    mes->datalen = 4 + strlen(str);
771
772    if ( mes->datalen > LIBROAR_BUFFER_MSGDATA )
773     return -1;
774
775    strncpy(((char*)&(mes->data))+4, str, mes->datalen);
776
777    d[0] = ROAR_HOST2NET16(d[0]);
778    d[1] = ROAR_HOST2NET16(d[1]);
779   break;
780
[3539]781  case ROAR_STREAM_PARA_CHANMAP:
782    if ( streams_get(mes->stream, &ss) == -1 ) {
783     ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream);
784     return -1;
785    }
786
787    s = ROAR_STREAM(ss);
788
789    memcpy(&(mes->data[4]), ss->chanmap.in, s->info.channels);
790    mes->datalen = 2*2 + s->info.channels;
791
792    d[0] = ROAR_HOST2NET16(d[0]);
793    d[1] = ROAR_HOST2NET16(d[1]);
794   break;
795
[4277]796  case ROAR_STREAM_PARA_LTM:
[4279]797    ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM request...", client);
798
[4281]799    if ( mes->datalen < (6 * 2) ) {
800     ROAR_ERR("req_on_get_stream_para(client=%i, ...): LTM request of client is corruped: message too short", client);
[4277]801     return -1;
[4281]802    }
[4277]803
804    for (i = 2; i < mes->datalen/2; i++) {
805     d[i] = ROAR_NET2HOST16(d[i]);
806    }
807
[4281]808    if ( d[2] != ROAR_LTM_SST_GET_RAW ) {
809     ROAR_ERR("req_on_get_stream_para(client=%i, ...): LTM request of client is corruped: unknown LTM subtype: %i", client, (int)d[2]);
[4277]810     return -1;
[4281]811    }
[4277]812
[4279]813    ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM request of type GET_RAW", client);
814
[4277]815    test = d[5];
816    bits = 0;
817    while (test) {
818     if ( test & 0x1 )
819      bits++;
820
821     test >>= 1;
822    }
823
824    needed = 0;
825
826    if ( mes->stream == -1 ) {
[4279]827     ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM multi-stream request...", client);
828
[4277]829     for (i = 6; i < mes->datalen/2; i++) {
[4289]830      if ( (ltm = streams_ltm_get(d[i], d[5], d[3])) == NULL )
[4277]831       return -1;
832
833      needed += ltm->channels;
834     }
835    } else {
[4279]836     ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM single-stream request for stream %i...", client, mes->stream);
[4289]837     if ( (ltm = streams_ltm_get(mes->stream, d[5], d[3])) == NULL )
[4277]838      return -1;
839
840     needed = ltm->channels;
841    }
842
843    needed *= bits;
844
845    needed += mes->stream == -1 ? (mes->datalen/2) - 6 : 1;
846
[4279]847    ROAR_DBG("req_on_get_stream_para(client=%i, ...): data size for answer is %i 64 bit sub-packets", client, (int)needed);
848
[4298]849    ROAR_DBG("req_on_get_stream_para(client=%i, ...): mes->datalen=%i, data=%p{%p}", client, (int)mes->datalen, data, *data);
850    d64 = _dataspace(mes, data, flags, needed * 8);
851    ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data);
[4277]852
853    if ( (d = roar_mm_malloc(mes->datalen)) == NULL )
854     return -1;
855
[4298]856    ROAR_DBG("req_on_get_stream_para(client=%i, ...): d=%p, data=%p{%p}", client, d, data, *data);
857
858
859    ROAR_DBG("req_on_get_stream_para(client=%i, ...): mes->datalen=%i, data=%p{%p}", client, (int)mes->datalen, data, *data);
860    ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data);
[4277]861    memcpy(d, mes->data, mes->datalen);
[4298]862    ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data);
[4277]863
[4291]864    d64ptr = d64;
[4277]865
[4298]866    ROAR_DBG("req_on_get_stream_para(client=%i, ...): mes->datalen=%i, data=%p{%p}", client, (int)mes->datalen, data, *data);
867    ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data);
868
[4277]869    if ( mes->stream == -1 ) {
870     for (i = 6; i < mes->datalen/2; i++) {
[4298]871      ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data);
872
[4289]873      if ( (ltm = streams_ltm_get(d[i], d[5], d[3])) == NULL )
[4277]874       return -1;
875
876      *d64ptr = ltm->channels & 0xFFFF;
877       d64ptr++;
878
879      for (h = 0; h < ltm->channels; h++) {
880       for (k = 0; k < ROAR_LTM_MTBITS; k++) {
881        if ( d[5] & (1<<k) ) {
882         switch (1<<k) {
883          case ROAR_LTM_MT_RMS:
884            *d64ptr = ltm->cur[h].rms;
885           break;
886          default:
887            ROAR_ERR("req_on_get_stream_para(client=%i, ...): client requets unknown MT for LTM: bit %i", client, k);
888         }
889         d64ptr++;
890        }
891       }
892      }
893     }
894    } else {
[4289]895     if ( (ltm = streams_ltm_get(mes->stream, d[5], d[3])) == NULL )
[4277]896      return -1;
897
898     *d64ptr = ltm->channels & 0xFFFF;
899      d64ptr++;
900
901     for (h = 0; h < ltm->channels; h++) {
902      for (k = 0; k < ROAR_LTM_MTBITS; k++) {
903       if ( d[5] & (1<<k) ) {
904        switch (1<<k) {
905         case ROAR_LTM_MT_RMS:
906           *d64ptr = ltm->cur[h].rms;
[4287]907           ROAR_DBG("req_on_get_stream_para(client=%i, ...): rms=%lli to %p", client, (long long int)*d64ptr, d64ptr);
[4277]908          break;
909         default:
910           ROAR_ERR("req_on_get_stream_para(client=%i, ...): client requets unknown MT for LTM: bit %i", client, k);
911        }
912        d64ptr++;
913       }
914      }
915     }
916    }
917
[4298]918    ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data);
919
[4277]920    roar_mm_free(d);
921
922    for (i = 0; i < needed; i++) {
923     d64[i] = ROAR_HOST2NET64(d64[i]);
924    }
925
926    mes->datalen = needed * 8;
[4283]927    ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM d64=%p, d64ptr=%p", client, d64, d64ptr);
[4279]928    ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM final message has %i byte of data", client, (int)mes->datalen);
[4298]929    ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data);
[4279]930    ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM GET_RAW request: OK. returning...", client);
[4277]931   break;
932
[1842]933  default:
934    ROAR_WARN("req_on_get_stream_para(*): unsupported command: %i", d[1]);
935    return -1;
[465]936 }
937
[4279]938 ROAR_DBG("req_on_get_stream_para(client=%i, mes=%p{.stream=%i, .datalen=%i,...}, data=%p, flags=%p) = 0 // returning OK", client, mes, (int)mes->stream, (int)mes->datalen, data, flags);
[465]939 mes->cmd = ROAR_CMD_OK;
940 return 0;
941}
942
[3926]943int req_on_set_stream_para (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[1043]944 uint16_t * d = (uint16_t *) mes->data;
945 int i;
946
[3542]947 if ( mes->datalen < 2*2 )
[1043]948  return -1;
949
[3542]950 for (i = 0; i < 2; i++) {
[1043]951  d[i] = ROAR_NET2HOST16(d[i]);
952 }
953
[3542]954 if ( d[0] != 0 )
[1043]955  return -1;
[3542]956
957 switch (d[1]) {
958  case ROAR_STREAM_PARA_FLAGS:
959    if ( mes->datalen != 2*4 )
960     return -1;
961
962    d[2] = ROAR_NET2HOST16(d[2]);
963    d[3] = ROAR_NET2HOST16(d[3]);
964
965    ROAR_DBG("req_on_set_stream_para(*): request seems to be valid");
966
967    if ( d[2] == ROAR_RESET_FLAG ) {
968     if ( streams_reset_flag(mes->stream, d[3]) == -1 )
969      return -1;
970    } else {
971     if ( streams_set_flag(mes->stream, d[3]) == -1 )
972      return -1;
973    }
974   break;
975  case ROAR_STREAM_PARA_CHANMAP:
976    if ( streams_set_map(mes->stream, &(mes->data[4]), mes->datalen - 4) == -1 )
977     return -1;
978   break;
[3696]979  case ROAR_STREAM_PARA_ROLE:
980    if ( mes->datalen != 2*3 )
981     return -1;
982
983    d[2] = ROAR_NET2HOST16(d[2]);
984
985    if ( streams_set_role(mes->stream, d[2]) == -1 )
986     return -1;
987   break;
[4272]988  case ROAR_STREAM_PARA_LTM:
[4277]989    if ( mes->datalen < (6 * 2) )
990     return -1;
991
[4272]992    for (i = 2; i < mes->datalen/2; i++) {
993     d[i] = ROAR_NET2HOST16(d[i]);
994    }
995
[4273]996    if ( mes->stream == -1 ) {
997     for (i = 6; i < mes->datalen/2; i++)
998      if ( streams_ltm_ctl(d[i], d[5], d[3], d[2]) == -1 )
999       return -1;
1000    } else {
1001     if ( streams_ltm_ctl(mes->stream, d[5], d[3], d[2]) == -1 )
1002      return -1;
1003    }
[4272]1004   break;
[3542]1005  default:
1006    ROAR_WARN("req_on_set_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
1007    return -1;
1008   break;
[1043]1009 }
1010
1011 mes->cmd     = ROAR_CMD_OK;
1012 mes->datalen = 0;
1013
[3542]1014 return 0;
[1043]1015}
1016
[3926]1017int req_on_kick (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[4330]1018 struct roar_stream_server * ss;
[17]1019 uint16_t * info = (uint16_t *) mes->data;
[4329]1020 int is_stream = 0;
[0]1021
1022 if ( mes->datalen != 4 )
1023  return -1;
1024
[251]1025 info[0] = ROAR_NET2HOST16(info[0]);
1026 info[1] = ROAR_NET2HOST16(info[1]);
1027
[4329]1028 switch (info[0]) {
1029  case ROAR_OT_CLIENT:
1030    clients_delete(info[1]);
1031   break;
1032  case ROAR_OT_STREAM:
1033    is_stream = 1;
1034   break;
1035  case ROAR_OT_SOURCE:
1036    if ( streams_get_flag(info[1], ROAR_FLAG_SOURCE) != 1 )
1037     return -1;
1038    is_stream = 1;
1039   break;
1040  case ROAR_OT_OUTPUT:
[4330]1041    if ( streams_get(info[1], &ss) == -1 )
1042     return -1;
1043
1044    if ( ss->driver_id == -1 )
1045     return -1;
1046
1047    is_stream = 1;
1048   break;
1049  case ROAR_OT_MIXER:
1050    if ( streams_get(info[1], &ss) == -1 )
[4329]1051     return -1;
[4330]1052
1053    if ( ROAR_STREAM(ss)->dir != ROAR_DIR_MIXING )
1054     return -1;
1055
1056    is_stream = 1;
1057   break;
1058  case ROAR_OT_BRIDGE:
1059    if ( streams_get(info[1], &ss) == -1 )
1060     return -1;
1061
1062    if ( ROAR_STREAM(ss)->dir != ROAR_DIR_BRIDGE )
1063     return -1;
1064
[4329]1065    is_stream = 1;
1066   break;
1067  default:
1068/* TODO: those types should be handled, too:
1069#define ROAR_OT_SAMPLE    4
1070#define ROAR_OT_LISTEN    8
1071#define ROAR_OT_ACTION    9
1072#define ROAR_OT_MSGQUEUE 10
1073#define ROAR_OT_MSGBUS   11
1074*/
1075    return -1;
1076   break;
1077 }
1078
1079 if ( is_stream ) {
[2952]1080  if ( streams_get_flag(info[1], ROAR_FLAG_IMMUTABLE) == 1 )
1081   return -1;
1082
[0]1083  streams_delete(info[1]);
1084 }
1085
1086 mes->cmd     = ROAR_CMD_OK;
1087 mes->datalen = 0;
1088
1089 return 0;
1090}
1091
[3926]1092int req_on_attach      (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[769]1093 uint16_t * info = (uint16_t *) mes->data;
1094
1095 if ( mes->datalen < 6 )
1096  return -1;
1097
1098 info[0] = ROAR_NET2HOST16(info[0]);
1099 info[1] = ROAR_NET2HOST16(info[1]);
1100 info[2] = ROAR_NET2HOST16(info[2]);
1101
1102 if ( info[0] != 0 )
1103  return -1;
1104
1105 if ( info[1] == ROAR_ATTACH_SIMPLE ) {
1106  if ( client_stream_move(info[2], mes->stream) == -1 )
1107   return -1;
1108 } else {
1109  return -1;
1110 }
1111
1112 mes->cmd     = ROAR_CMD_OK;
1113 mes->datalen = 0;
1114
1115 return 0;
[768]1116}
1117
[3926]1118int req_on_set_vol (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[3530]1119 struct roar_stream_server * s;
[17]1120 uint16_t * info = (uint16_t *) mes->data;
[3530]1121 uint16_t   version;
1122 uint16_t   scale = 65535;
[17]1123 int stream;
1124 int i;
1125 int chans;
1126
1127 ROAR_DBG("req_on_set_vol(*) = ?");
1128 ROAR_DBG("req_on_set_vol(*): mes->datalen=%i", mes->datalen);
1129
1130 if ( mes->datalen < (4*2) )
1131  return -1;
1132
[3530]1133 version = ROAR_NET2HOST16(info[0]);
1134 ROAR_DBG("req_on_set_vol(*): version=%i", (int)version);
[17]1135
[3530]1136 switch (version) {
1137  case 0:
1138    stream = ROAR_NET2HOST16(info[1]);
1139   break;
1140  case 1:
1141    stream = mes->stream;
1142    scale  = ROAR_NET2HOST16(info[1]);
1143   break;
1144  default:
1145    return -1;
1146   break;
1147 }
[17]1148 ROAR_DBG("req_on_set_vol(*): stream=%i", stream);
1149
[3561]1150 if ( scale == 0 )
1151  return -1;
1152
[17]1153 // TODO: change this code.
1154 //       we should not directly change the stream object but use some stream_*()-func
1155 //       for that job.
1156
1157 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
1158  return -1;
1159
1160 s = g_streams[stream];
1161
1162 if ( s == NULL )
1163  return -1;
1164
1165 ROAR_DBG("req_on_set_vol(*): s=%p", s);
1166
[252]1167 info[2] = ROAR_NET2HOST16(info[2]);
1168
[17]1169 if ( info[2] == ROAR_SET_VOL_ALL ) {
1170  chans = (mes->datalen/2) - 3;
1171  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ALL, channes=%i", chans);
1172
1173  if ( chans >= ROAR_MAX_CHANNELS )
1174   return -1;
1175
[18]1176  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
1177
[17]1178  for (i = 0; i < chans; i++) {
[252]1179   s->mixer.mixer[i] = ROAR_NET2HOST16(info[i+3]);
1180   ROAR_DBG("req_on_set_vol(*): channel %i: %i", i, ROAR_NET2HOST16(info[i+3]));
[17]1181  }
1182
[3530]1183  s->mixer.scale = scale;
1184
[17]1185  ROAR_DBG("req_on_set_vol(*): mixer changed!");
1186
1187 } else if ( info[2] == ROAR_SET_VOL_ONE ) {
1188  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ONE");
[252]1189  if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS )
[17]1190   return -1;
1191
[252]1192  s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]);
[3530]1193
1194  s->mixer.scale = scale;
[17]1195 } else {
1196  return -1;
1197 }
1198
[1590]1199 if ( streams_set_mixer(stream) == -1 )
1200  return -1;
1201
[17]1202 mes->cmd     = ROAR_CMD_OK;
1203 mes->datalen = 0;
1204
1205 return 0;
1206}
[0]1207
[3926]1208int req_on_get_vol (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[23]1209 uint16_t * info = (uint16_t *) mes->data;
[3529]1210 uint16_t   version = -1;
[23]1211 int stream;
1212 struct roar_stream_server * s;
1213 int i;
1214 int chans;
1215
1216 ROAR_DBG("req_on_get_vol(*) = ?");
1217 ROAR_DBG("req_on_get_vol(*): mes->datalen=%i", mes->datalen);
1218
[3529]1219 if ( mes->datalen < 2 ) {
[23]1220  return -1;
[3529]1221 }
1222
1223 version = ROAR_NET2HOST16(info[0]);
1224
1225 switch (version) {
1226  case 0:
1227    if ( mes->datalen < (2*2) )
1228     return -1;
[23]1229
[3529]1230    stream = ROAR_NET2HOST16(info[1]);
1231   break;
1232  case 1:
1233    stream = mes->stream;
1234   break;
1235  default:
1236    return -1;
1237   break;
1238 }
[23]1239
1240 ROAR_DBG("req_on_get_vol(*): stream=%i", stream);
1241
1242 // TODO: change this code.
1243 //       we should not directly change the stream object but use some stream_*()-func
1244 //       for that job.
1245
1246 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
1247  return -1;
1248
1249 s = g_streams[stream];
1250
1251 if ( s == NULL )
1252  return -1;
1253
1254 ROAR_DBG("req_on_get_vol(*): s=%p", s);
1255
1256 // ok, we have everything
1257
[3529]1258 info[0] = ROAR_HOST2NET16(version);
1259
1260 switch (version) {
1261  case 0:
1262    info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
1263
1264    for (i = 0; i < chans; i++)
1265     info[2+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
[23]1266
[3529]1267     mes->datalen = (2 + chans)*2;
1268   break;
1269  case 1:
1270    info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
1271    info[2] = ROAR_HOST2NET16(s->mixer.scale);
1272    info[3] = ROAR_HOST2NET16(s->mixer.rpg_mul);
1273    info[4] = ROAR_HOST2NET16(s->mixer.rpg_div);
[23]1274
[3529]1275    for (i = 0; i < chans; i++)
1276     info[5+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
1277
1278     mes->datalen = (5 + chans)*2;
1279   break;
1280  default:
1281    return -1;
1282   break;
1283 }
1284
[23]1285 mes->cmd = ROAR_CMD_OK;
1286
1287 return 0;
1288}
1289
[3926]1290int req_on_add_data (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[0]1291 struct roar_buffer * b;
1292 char               * buf;
1293
[3764]1294 if ( roar_buffer_new_data(&b, mes->datalen, (void **)&buf) == -1 ) {
[0]1295  ROAR_ERR("req_on_add_data(*): Can not alloc buffer space!");
1296  ROAR_DBG("req_on_add_data(*) = -1");
1297  return -1;
1298 }
1299
1300 if ( data == NULL ) {
1301  memcpy(buf, mes->data, mes->datalen);
1302 } else {
[3926]1303  memcpy(buf, *data, mes->datalen);
[0]1304 }
1305
1306 if ( stream_add_buffer(mes->stream, b) == -1 ) {
1307  roar_buffer_free(b);
1308  return -1;
1309 }
1310
[498]1311 mes->cmd     = ROAR_CMD_OK_STOP;
[0]1312 mes->datalen = 0;
1313
1314 return 0;
1315}
1316
[3926]1317int req_on_beep        (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
[3575]1318 struct roar_beep bs;
1319 int16_t * info = (int16_t*)mes->data;
1320 int stream;
1321
1322 memset(&bs, 0, sizeof(bs));
1323
1324 if ( mes->datalen > 0 ) {
1325  if ( mes->datalen < 2 )
1326   return -1;
1327
1328  if ( ROAR_NET2HOST16(info[0]) != 0 ) /* version */
1329   return -1;
1330
1331  if ( mes->datalen != 8*2 )
1332   return -1;
1333
1334  bs.vol  = ROAR_NET2HOST16(info[1]);
1335  bs.time = ROAR_NET2HOST16(info[2]);
1336  bs.freq = ROAR_NET2HOST16(info[3]);
1337  bs.type = ROAR_NET2HOST16(info[4]);
1338  bs.x    = ROAR_NET2HOST16(info[5]);
1339  bs.y    = ROAR_NET2HOST16(info[6]);
1340  bs.z    = ROAR_NET2HOST16(info[7]);
1341 }
1342
1343 if ( (stream = beep_start(client, &bs)) == -1 )
1344  return -1;
1345
1346 mes->stream  = stream;
1347 mes->cmd     = ROAR_CMD_OK_STOP;
1348 mes->datalen = 0;
1349
1350 return 0;
[3574]1351}
1352
[4343]1353int req_on_wait        (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) {
1354 uint16_t * u16 = (uint16_t*)mes->data;
1355 struct roar_event events[4];
1356 size_t left, tmp;
1357 size_t num = 0;
1358 void * vp = mes->data;
1359
1360 vp += 4;
1361
1362 // check for complet header...
1363 if ( mes->datalen < 4 )
1364  return -1;
1365
1366 u16[0] = ROAR_NET2HOST16(u16[0]);
1367 u16[1] = ROAR_NET2HOST16(u16[1]);
1368
1369 // do we support version and flags?
1370 if ( u16[0] != 0 || u16[1] != 0 )
1371  return -1;
1372
1373 memset(events, 0, sizeof(events));
1374
1375 left = mes->datalen - 4;
1376
1377 while (left) {
1378  tmp = left;
1379  if ( roar_event_from_blob(&(events[num]), vp, &tmp) == -1 )
1380   return -1;
1381
1382  vp   += tmp;
1383  left -= tmp;
1384  num++;
1385 }
1386
1387 if ( clients_wait(client, events, num) == -1 )
1388  return -1;
1389
1390 flags[1] |= COMMAND_FLAG_OUT_NOSEND;
1391
1392 return 0;
1393}
1394
[0]1395//ll
Note: See TracBrowser for help on using the repository browser.