source: roaraudio/roard/req.c @ 4283:27eefd9bc8e6

Last change on this file since 4283:27eefd9bc8e6 was 4283:27eefd9bc8e6, checked in by phi, 14 years ago

more debug lions

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