source: roaraudio/roard/req.c @ 3575:53cb52295b62

Last change on this file since 3575:53cb52295b62 was 3575:53cb52295b62, checked in by phi, 14 years ago

parse beep request

File size: 22.7 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;
30 mes->datalen = 0;
31 return 0;
32}
33
34int req_on_identify    (int client, struct roar_message * mes, char * data) {
35 struct roar_client * c;
36 int max_len;
37
38 if ( mes->datalen < 1 )
39  return -1;
40
41 clients_get(client, &c);
42
43 if ( mes->data[0] == 1 ) {
[436]44  if ( c->pid == -1 ) {
45   c->pid       = ROAR_NET2HOST32(*(uint32_t*)((mes->data)+1));
[443]46   ROAR_DBG("req_on_identify(): new PID: c->pid = %i", c->pid);
[436]47  }
[0]48
[443]49  ROAR_DBG("req_on_identify(): final PID: c->pid = %i", c->pid);
50
[0]51  max_len = (mes->datalen - 5) < (ROAR_BUFFER_NAME-1) ? (mes->datalen - 5) : (ROAR_BUFFER_NAME-1);
52
53  strncpy(c->name, mes->data + 5, max_len);
54  c->name[max_len] = 0;
55
56  mes->cmd     = ROAR_CMD_OK;
57  mes->datalen = 0;
58
59  ROAR_DBG("req_on_identify(*): client=%i, pid=%i", client, c->pid);
60  ROAR_DBG("req_on_identify(*) = 0");
61  return 0;
62 }
63
64 return -1;
65}
66
67int req_on_auth        (int client, struct roar_message * mes, char * data) {
68 // TODO: add code to support some auth.
69 mes->cmd     = ROAR_CMD_OK;
70 mes->datalen = 0;
71 return 0;
72}
73
74
[1162]75int req_on_whoami      (int client, struct roar_message * mes, char * data) {
76 mes->cmd     = ROAR_CMD_OK;
77 mes->datalen = 1;
78 mes->data[0] = client;
79 return 0;
80}
81
82
[0]83int req_on_new_stream  (int client, struct roar_message * mes, char * data) {
84 int stream;
85 struct roar_stream * s;
[1812]86 struct roar_stream * source_stream;
[1809]87 struct roar_audio_info * info;
[1812]88 struct roar_audio_info * source_info;
[0]89
[1904]90 ROAR_DBG("req_on_new_stream(client=%i, ...): creating stream...", client);
[0]91 if ((stream = streams_new()) == -1 )
92  return -1;
93
[1904]94 ROAR_DBG("req_on_new_stream(client=%i, ...): getting stream...", client);
[0]95 if ( streams_get(stream, (struct roar_stream_server **)&s) == -1 ) {
96  streams_delete(stream);
97  return -1;
98 }
99
[1904]100 ROAR_DBG("req_on_new_stream(client=%i, ...): set client of stream...", client);
[0]101 if ( client_stream_add(client, stream) == -1 ) {
102  streams_delete(stream);
103  return -1;
104 }
105
[1904]106 ROAR_DBG("req_on_new_stream(client=%i, ...): loading stream from message...", client);
[0]107 if ( roar_stream_m2s(s, mes) == -1 ) {
108  streams_delete(stream);
109  return -1;
110 }
111
[1904]112 ROAR_DBG("req_on_new_stream(client=%i, ...): setting id and codec of stream...", client);
[486]113 ROAR_STREAM(s)->id = stream; // roar_stream_m2s() resets this
[539]114 ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM(s)->info.codec;
[486]115
[1904]116 ROAR_DBG("req_on_new_stream(client=%i, ...): setting direction stream...", client);
[1900]117 // int streams_set_dir    (int id, int dir, int defaults)
118 if ( streams_set_dir(stream, ROAR_STREAM(s)->dir, 1) == -1 ) {
119  streams_delete(stream);
120  return -1;
121 }
122
[1904]123 ROAR_DBG("req_on_new_stream(client=%i, ...): setting up direction specific stream settings...", client);
[1809]124 switch (ROAR_STREAM(s)->dir) {
125  case ROAR_DIR_LIGHT_IN:
126  case ROAR_DIR_LIGHT_OUT:
[2497]127#ifndef ROAR_WITHOUT_DCOMP_LIGHT
[1809]128    info = &(ROAR_STREAM(s)->info);
129
130    info->channels = 0;
131    info->bits     = 0;
132    info->rate     = 0;
[2497]133#else
134    streams_delete(stream);
135    return -1;
136#endif
[1809]137
138   break;
[1848]139  case ROAR_DIR_MIDI_IN:
140  case ROAR_DIR_MIDI_OUT:
[2497]141#ifndef ROAR_WITHOUT_DCOMP_MIDI
[1848]142    info = &(ROAR_STREAM(s)->info);
143
[2402]144    info->channels = ROAR_MIDI_CHANNELS_DEFAULT;
145    info->bits     = ROAR_MIDI_BITS;
146    info->rate     = 0;
[2497]147#else
148    streams_delete(stream);
149    return -1;
150#endif
[1848]151
152   break;
153
[2250]154  case ROAR_DIR_RAW_IN:
[2497]155#ifndef ROAR_WITHOUT_DCOMP_RAW
[2250]156    if ( ROAR_STREAM(s)->pos_rel_id == -1     ||
157         ROAR_STREAM(s)->pos_rel_id == stream ||
158         streams_get_dir(ROAR_STREAM(s)->pos_rel_id) != ROAR_DIR_RAW_OUT
159       ) {
160     ROAR_STREAM(s)->pos_rel_id = -1; // force this here as it will try to delete itself while deleting
161                                      // in case rel_id == stream
162     streams_delete(stream);
163     return -1;
164    }
[2497]165#else
166  case ROAR_DIR_RAW_OUT:
167    streams_delete(stream);
168    return -1;
169#endif
[2250]170
171   break;
[1812]172  case ROAR_DIR_THRU:
[1815]173
174    if ( ROAR_STREAM(s)->pos_rel_id == -1 || ROAR_STREAM(s)->pos_rel_id == stream ) {
[1861]175     ROAR_STREAM(s)->pos_rel_id = -1; // force this here as it will try to delete itself while deleting
176                                      // in case rel_id == stream
[1815]177     streams_delete(stream);
178     return -1;
179    }
180
[1812]181    if ( streams_get(ROAR_STREAM(s)->pos_rel_id, (struct roar_stream_server **)&source_stream) == -1 ) {
182     streams_delete(stream);
183     return -1;
184    }
185
186    info        = &(ROAR_STREAM(s)->info);
187    source_info = &(ROAR_STREAM(source_stream)->info);
188
189    info->channels = source_info->channels;
190    info->bits     = source_info->bits;
191    info->rate     = source_info->rate;
192    info->codec    = source_info->codec;
[1840]193    ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM_SERVER(source_stream)->codec_orgi;
[1812]194
195   break;
[1809]196 }
197
[1904]198 ROAR_DBG("req_on_new_stream(client=%i, ...): returning (OK)...", client);
199
[0]200 mes->cmd     = ROAR_CMD_OK;
201 mes->stream  = stream;
202 mes->datalen = 0;
203
204 return 0;
205}
206
207int req_on_exec_stream (int client, struct roar_message * mes, char * data) {
208 int r;
209
[1904]210 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): execing stream", client, mes->stream);
211
[0]212 if ( (r = client_stream_exec(client, mes->stream)) == -1 )
213  return -1;
214
[1904]215 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
[0]216 mes->cmd     = ROAR_CMD_OK;
217 mes->datalen = 0;
218
219 return 0;
220}
221
[77]222int req_on_con_stream  (int client, struct roar_message * mes, char * data) {
223 char   host[80] = {0};
224 int    port = 0;
225 int    type;
226 int    fh;
227 int    len;
228
229 if ( mes->datalen < 4 )
230  return -1;
231
232 if ( *(mes->data) != 0 )
233  return -1;
234
[80]235 if ( mes->datalen > 80 ) // we do not support long messages here
236  return -1;
237
[77]238 type = (unsigned)mes->data[1];
[79]239 port = ROAR_NET2HOST16(((uint16_t*)mes->data)[1]);
[77]240
[80]241 len = mes->datalen - 4;
[77]242
[84]243 strncpy(host, &(mes->data[4]), len);
[77]244 host[len] = 0;
245
246 if ( type > ROAR_SOCKET_TYPE_MAX )
247  return -1;
248
249 if ( type == ROAR_SOCKET_TYPE_FILE ) // disabled because of security resons
250  return -1;
251
252 if ( type == ROAR_SOCKET_TYPE_FORK ) // why should we connect to ourself?
253  return -1;
254
[525]255 ROAR_DBG("req_on_con_stream(*): CONNECT(type=%i, host='%s', port=%i)", type, host, port);
256
[77]257 if ( (fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port)) == -1 )
258  return -1;
259
[78]260 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
261  close(fh);
262  return 1;
263 }
264
[757]265 mes->datalen = 0;
266 mes->cmd     = ROAR_CMD_OK;
267
[78]268 return 0;
[757]269}
270
271int req_on_passfh      (int client, struct roar_message * mes, char * data) {
272 int fh;
273 int sock = clients_get_fh(client);
274
275 if ( (fh = roar_socket_recv_fh(sock, NULL, NULL)) == -1 )
276  return -1;
277
278 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
279  close(fh);
280  return 1;
281 }
282
[78]283
284 mes->datalen = 0;
285 mes->cmd     = ROAR_CMD_OK;
[757]286
287 return 0;
[77]288}
289
[1493]290#ifdef ROAR_SUPPORT_META
[0]291int req_on_set_meta    (int client, struct roar_message * mes, char * data) {
[92]292 int type;
293 int mode;
294 int namelen, vallen;
[99]295 char   val[255+1];
[92]296 char   name[ROAR_META_MAX_NAMELEN+1];
297
298 if ( mes->datalen < 3 )
299  return -1;
300
301 if ( mes->data[0] != 0 ) // version
302  return -1;
303
304 mode = (unsigned) mes->data[1];
305 type = (unsigned) mes->data[2];
306
[99]307 ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type);
308
[92]309 if ( mode == ROAR_META_MODE_CLEAR ) {
310  stream_meta_clear(mes->stream);
311  mes->datalen = 0;
312  mes->cmd     = ROAR_CMD_OK;
313  return 0;
314 } else if ( mode == ROAR_META_MODE_DELETE ) { // unsuppoerted at the moment
[1038]315  return -1;
316 } else if ( mode == ROAR_META_MODE_FINALIZE ) {
317  stream_meta_finalize(mes->stream);
318  mes->datalen = 0;
319  mes->cmd     = ROAR_CMD_OK;
320  return 0;
[92]321 } else if ( mode == ROAR_META_MODE_SET || mode == ROAR_META_MODE_ADD ) {
322  if ( mes->datalen < 5 )
323   return -1;
324
325  namelen = (unsigned) mes->data[3];
326  vallen  = (unsigned) mes->data[4];
327
[99]328  ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen);
329
[92]330  if ( mes->datalen < (5 + namelen + vallen) )
331   return -1;
332
333  if ( namelen > ROAR_META_MAX_NAMELEN )
334   return -1;
335
336  strncpy(name, &(mes->data[5]), namelen);
337  name[namelen] = 0;
338
[99]339  if ( vallen > 255 )
[92]340   return -1;
341
342  strncpy(val, &(mes->data[5+namelen]), vallen);
343  val[vallen] = 0;
344
345  if ( mode == ROAR_META_MODE_SET ) {
346   if ( stream_meta_set(mes->stream, type, name, val) == -1 )
347    return -1;
348  } else {
349   if ( stream_meta_add(mes->stream, type, name, val) == -1 )
350    return -1;
351  }
352
353  mes->datalen = 0;
354  mes->cmd     = ROAR_CMD_OK;
355  return 0;
356 } else { // unknown mode!
357  return -1;
358 }
359
[0]360 return -1;
361}
362
[100]363int req_on_get_meta    (int client, struct roar_message * mes, char * data) {
[101]364 int vallen;
365 int type;
[107]366 char val[LIBROAR_BUFFER_MSGDATA-1];
[101]367
368 if ( mes->datalen != 2 )
369  return -1;
370
371 if ( mes->data[0] != 0 ) // version
372  return -1;
373
374 type = (unsigned) mes->data[1];
375
376 if ( stream_meta_get(mes->stream, type, NULL, val, LIBROAR_BUFFER_MSGDATA-2) == -1 )
377  return -1;
378
379 vallen = strlen(val);
380
381 mes->cmd     = ROAR_CMD_OK;
382 mes->datalen = 2 + vallen;
383
384 mes->data[0] = 0;
385 mes->data[1] = (unsigned char) vallen;
386
[107]387 val[vallen] = 0;
388
389 strncpy(&(mes->data[2]), val, vallen+1);
[101]390
391 return 0;
[100]392}
[0]393
[113]394int req_on_list_meta   (int client, struct roar_message * mes, char * data) {
395 int i;
396 int len = 0;
397 int types[ROAR_META_MAX_PER_STREAM];
398
399 if ( mes->datalen != 1 )
400  return -1;
401
402 if ( mes->data[0] != 0 ) // version
403  return -1;
404
405 if ( (len = stream_meta_list(mes->stream, types, ROAR_META_MAX_PER_STREAM)) == -1 )
406  return -1;
407
408 mes->cmd     = ROAR_CMD_OK;
409 mes->datalen = 1 + len;
410 mes->data[0] = 0;
411
412 for (i = 0; i < len; i++)
413  mes->data[i+1] = types[i];
414
415 return 0;
416}
[1493]417#endif
[113]418
[0]419int req_on_server_oinfo    (int client, struct roar_message * mes, char * data) {
420 struct roar_stream s;
421//ROAR_DIR_OUTPUT
422
[966]423 memset(&s, 0, sizeof(struct roar_stream));
[964]424
[977]425 s.dir           = ROAR_DIR_MIXING;
[0]426 s.pos_rel_id    = -1;
427 s.info.rate     = g_sa->rate;
428 s.info.bits     = g_sa->bits;
429 s.info.channels = g_sa->channels;
430 s.info.codec    = g_sa->codec;
[977]431 s.pos           = g_pos;
[0]432
433 if ( roar_stream_s2m(&s, mes) == -1 )
434  return -1;
435
436 mes->cmd = ROAR_CMD_OK;
437
438 return 0;
439}
440
441
442int req_on_get_standby (int client, struct roar_message * mes, char * data) {
443 mes->cmd = ROAR_CMD_OK;
444 mes->datalen = 2;
445
446 *((uint16_t*)mes->data) = ROAR_HOST2NET16((unsigned) g_standby);
447
448 return 0;
449}
450
451int req_on_set_standby (int client, struct roar_message * mes, char * data) {
452 if ( mes->datalen != 2 )
453  return -1;
454
455 g_standby = ROAR_NET2HOST16(*((uint16_t*)mes->data));
456
457 mes->cmd     = ROAR_CMD_OK;
458 mes->datalen = 0;
459
460 return 0;
461}
462
463int req_on_exit      (int client, struct roar_message * mes, char * data) {
[575]464 int term = 0;
465
466 if ( mes->datalen == 1 )
467  term = mes->data[0];
468
[0]469 mes->cmd     = ROAR_CMD_OK;
470 mes->datalen = 0;
471
[576]472 ROAR_DBG("req_on_exit(*): term=%i", term);
473
[575]474 if ( term ) {
475  cleanup_listen_socket(1);
476 } else {
477  alive = 0;
478 }
[0]479
480 return 0;
481}
482
483int req_on_list_clients(int client, struct roar_message * mes, char * data) {
484 unsigned char filter, cmp;
485 uint32_t id;
486 int clients[ROAR_CLIENTS_MAX];
487 int i, c = 0;
488
489 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
490  return -1;
491
492 // TODO: add code to support filter
493 if ( filter != ROAR_CTL_FILTER_ANY )
494  return -1;
495
496 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
497  if ( g_clients[i] != NULL ) {
498   clients[c++] = i;
499  }
500 }
501
502 roar_ctl_ia2m(mes, clients, c);
503
504 mes->cmd = ROAR_CMD_OK;
505
506 return 0;
507}
508int req_on_list_streams(int client, struct roar_message * mes, char * data) {
509 unsigned char filter, cmp;
510 uint32_t id;
511 int streams[ROAR_STREAMS_MAX];
512 int i, c = 0;
513
514 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
515  return -1;
516
517 // TODO: add code to support filter
518 if ( filter != ROAR_CTL_FILTER_ANY )
519  return -1;
520
521 for (i = 0; i < ROAR_STREAMS_MAX; i++) {
522  if ( g_streams[i] != NULL ) {
523   streams[c++] = i;
524  }
525 }
526
527 roar_ctl_ia2m(mes, streams, c);
528
529 mes->cmd = ROAR_CMD_OK;
530
531 return 0;
532}
533
534int req_on_get_client  (int client, struct roar_message * mes, char * data) {
535 struct roar_client * c;
536
537 if ( mes->datalen != 1 )
538  return -1;
539
540 if ( clients_get(mes->data[0], &c) == -1 )
541  return -1;
542
543 mes->cmd = ROAR_CMD_OK;
544
545 return roar_ctl_c2m(mes, c);
546}
547
548int req_on_get_stream  (int client, struct roar_message * mes, char * data) {
549 struct roar_stream_server * s;
550
551 if ( mes->datalen != 1 )
552  return -1;
553
554 if ( streams_get(mes->data[0], &s) == -1 )
555  return -1;
556
557 mes->cmd = ROAR_CMD_OK;
[465]558 mes->stream = mes->data[0];
[0]559
560 return roar_stream_s2m(ROAR_STREAM(s), mes);
561}
562
[465]563int req_on_get_stream_para (int client, struct roar_message * mes, char * data) {
564 struct roar_stream * s;
[963]565 struct roar_stream_server * ss;
[465]566 struct roar_audio_info * audio_info;
567 uint16_t * d = (uint16_t *) mes->data;
568 int i;
[1842]569 char * str;
[465]570
571 if ( mes->datalen != 4 )
572  return -1;
573
574 for (i = 0; i < mes->datalen/2; i++) {
575  d[i] = ROAR_NET2HOST16(d[i]);
576 }
577
[1842]578 if ( d[0] != 0 ) {
[465]579  ROAR_WARN("req_on_get_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
580  return -1;
581 }
582
[1842]583 switch (d[1]) {
584  case ROAR_STREAM_PARA_INFO:
585    if ( streams_get(mes->stream, &ss) == -1 ) {
586     ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream);
587     return -1;
588    }
589
590    if ( streams_calc_delay(mes->stream) == -1 ) {
591     ROAR_WARN("req_on_get_stream_para(*): can not calc delay for stream %i", mes->stream);
592    }
593
594    s = ROAR_STREAM(ss);
[465]595
[1842]596    audio_info = &(s->info);
597
[3213]598    mes->datalen = 2*11;
[1842]599
[3213]600    d[ 2] = ROAR_OUTPUT_CALC_OUTBUFSIZE(audio_info);
601    d[ 3] = ss->pre_underruns;
602    d[ 4] = ss->post_underruns;
603    d[ 5] = ss->codec_orgi;
604    d[ 6] = (ss->flags & 0xFFFF) | (ss->primary ? ROAR_FLAG_PRIMARY : 0) | (ss->driver_id != -1 ? ROAR_FLAG_OUTPUT : 0);
605    d[ 7] = ss->delay/1000;
606    d[ 8] = ss->state;
607    d[ 9] = (ss->flags & 0xFFFF0000) >> 16;
608    d[10] = ss->mixer_stream;
[1842]609
610    ROAR_DBG("req_on_get_stream_para(*): ss->driver_id=%i", ss->driver_id);
611
612    ROAR_DBG("req_on_get_stream_para(*): delay=%i, send delay=%i", ss->delay, d[7]);
[465]613
[1842]614    for (i = 0; i < mes->datalen/2; i++) {
615     d[i] = ROAR_HOST2NET16(d[i]);
616    }
[1156]617
[1842]618    mes->pos = s->pos;
619   break;
620
621  case ROAR_STREAM_PARA_NAME:
622   str = streams_get_name(mes->stream);
623
624   if ( str == NULL )
625    return -1;
[1151]626
[1842]627    mes->datalen = 4 + strlen(str);
628
629    if ( mes->datalen > LIBROAR_BUFFER_MSGDATA )
630     return -1;
631
632    strncpy(((char*)&(mes->data))+4, str, mes->datalen);
633
634    d[0] = ROAR_HOST2NET16(d[0]);
635    d[1] = ROAR_HOST2NET16(d[1]);
636   break;
637
[3539]638  case ROAR_STREAM_PARA_CHANMAP:
639    if ( streams_get(mes->stream, &ss) == -1 ) {
640     ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream);
641     return -1;
642    }
643
644    s = ROAR_STREAM(ss);
645
646    memcpy(&(mes->data[4]), ss->chanmap.in, s->info.channels);
647    mes->datalen = 2*2 + s->info.channels;
648
649    d[0] = ROAR_HOST2NET16(d[0]);
650    d[1] = ROAR_HOST2NET16(d[1]);
651   break;
652
[1842]653  default:
654    ROAR_WARN("req_on_get_stream_para(*): unsupported command: %i", d[1]);
655    return -1;
[465]656 }
657
658 mes->cmd = ROAR_CMD_OK;
659 return 0;
660}
661
[1043]662int req_on_set_stream_para (int client, struct roar_message * mes, char * data) {
663 uint16_t * d = (uint16_t *) mes->data;
664 int i;
665
[3542]666 if ( mes->datalen < 2*2 )
[1043]667  return -1;
668
[3542]669 for (i = 0; i < 2; i++) {
[1043]670  d[i] = ROAR_NET2HOST16(d[i]);
671 }
672
[3542]673 if ( d[0] != 0 )
[1043]674  return -1;
[3542]675
676 switch (d[1]) {
677  case ROAR_STREAM_PARA_FLAGS:
678    if ( mes->datalen != 2*4 )
679     return -1;
680
681    d[2] = ROAR_NET2HOST16(d[2]);
682    d[3] = ROAR_NET2HOST16(d[3]);
683
684    ROAR_DBG("req_on_set_stream_para(*): request seems to be valid");
685
686    if ( d[2] == ROAR_RESET_FLAG ) {
687     if ( streams_reset_flag(mes->stream, d[3]) == -1 )
688      return -1;
689    } else {
690     if ( streams_set_flag(mes->stream, d[3]) == -1 )
691      return -1;
692    }
693   break;
694  case ROAR_STREAM_PARA_CHANMAP:
695    if ( streams_set_map(mes->stream, &(mes->data[4]), mes->datalen - 4) == -1 )
696     return -1;
697   break;
698  default:
699    ROAR_WARN("req_on_set_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
700    return -1;
701   break;
[1043]702 }
703
704 mes->cmd     = ROAR_CMD_OK;
705 mes->datalen = 0;
706
[3542]707 return 0;
[1043]708}
709
[0]710int req_on_kick (int client, struct roar_message * mes, char * data) {
[17]711 uint16_t * info = (uint16_t *) mes->data;
[0]712
713 if ( mes->datalen != 4 )
714  return -1;
715
[251]716 info[0] = ROAR_NET2HOST16(info[0]);
717 info[1] = ROAR_NET2HOST16(info[1]);
718
[0]719 if ( info[0] == ROAR_OT_CLIENT ) {
720  clients_delete(info[1]);
721 } else if ( info[0] == ROAR_OT_STREAM ) {
[2952]722  if ( streams_get_flag(info[1], ROAR_FLAG_IMMUTABLE) == 1 )
723   return -1;
724
[0]725  streams_delete(info[1]);
[1111]726 } else if ( info[0] == ROAR_OT_SOURCE ) {
[2952]727  if ( streams_get_flag(info[1], ROAR_FLAG_IMMUTABLE) == 1 )
728   return -1;
729
[1111]730  if ( streams_get_flag(info[1], ROAR_FLAG_SOURCE) == 1 ) {
731   streams_delete(info[1]);
732  } else {
733   return -1;
734  }
[0]735 } else {
736  return -1;
737 }
738
739 mes->cmd     = ROAR_CMD_OK;
740 mes->datalen = 0;
741
742 return 0;
743}
744
[768]745int req_on_attach      (int client, struct roar_message * mes, char * data) {
[769]746 uint16_t * info = (uint16_t *) mes->data;
747
748 if ( mes->datalen < 6 )
749  return -1;
750
751 info[0] = ROAR_NET2HOST16(info[0]);
752 info[1] = ROAR_NET2HOST16(info[1]);
753 info[2] = ROAR_NET2HOST16(info[2]);
754
755 if ( info[0] != 0 )
756  return -1;
757
758 if ( info[1] == ROAR_ATTACH_SIMPLE ) {
759  if ( client_stream_move(info[2], mes->stream) == -1 )
760   return -1;
761 } else {
762  return -1;
763 }
764
765 mes->cmd     = ROAR_CMD_OK;
766 mes->datalen = 0;
767
768 return 0;
[768]769}
770
[17]771int req_on_set_vol (int client, struct roar_message * mes, char * data) {
[3530]772 struct roar_stream_server * s;
[17]773 uint16_t * info = (uint16_t *) mes->data;
[3530]774 uint16_t   version;
775 uint16_t   scale = 65535;
[17]776 int stream;
777 int i;
778 int chans;
779
780 ROAR_DBG("req_on_set_vol(*) = ?");
781 ROAR_DBG("req_on_set_vol(*): mes->datalen=%i", mes->datalen);
782
783 if ( mes->datalen < (4*2) )
784  return -1;
785
[3530]786 version = ROAR_NET2HOST16(info[0]);
787 ROAR_DBG("req_on_set_vol(*): version=%i", (int)version);
[17]788
[3530]789 switch (version) {
790  case 0:
791    stream = ROAR_NET2HOST16(info[1]);
792   break;
793  case 1:
794    stream = mes->stream;
795    scale  = ROAR_NET2HOST16(info[1]);
796   break;
797  default:
798    return -1;
799   break;
800 }
[17]801 ROAR_DBG("req_on_set_vol(*): stream=%i", stream);
802
[3561]803 if ( scale == 0 )
804  return -1;
805
[17]806 // TODO: change this code.
807 //       we should not directly change the stream object but use some stream_*()-func
808 //       for that job.
809
810 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
811  return -1;
812
813 s = g_streams[stream];
814
815 if ( s == NULL )
816  return -1;
817
818 ROAR_DBG("req_on_set_vol(*): s=%p", s);
819
[252]820 info[2] = ROAR_NET2HOST16(info[2]);
821
[17]822 if ( info[2] == ROAR_SET_VOL_ALL ) {
823  chans = (mes->datalen/2) - 3;
824  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ALL, channes=%i", chans);
825
826  if ( chans >= ROAR_MAX_CHANNELS )
827   return -1;
828
[18]829  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
830
[17]831  for (i = 0; i < chans; i++) {
[252]832   s->mixer.mixer[i] = ROAR_NET2HOST16(info[i+3]);
833   ROAR_DBG("req_on_set_vol(*): channel %i: %i", i, ROAR_NET2HOST16(info[i+3]));
[17]834  }
835
[3530]836  s->mixer.scale = scale;
837
[17]838  ROAR_DBG("req_on_set_vol(*): mixer changed!");
839
840 } else if ( info[2] == ROAR_SET_VOL_ONE ) {
841  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ONE");
[252]842  if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS )
[17]843   return -1;
844
[252]845  s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]);
[3530]846
847  s->mixer.scale = scale;
[17]848 } else {
849  return -1;
850 }
851
[1590]852 if ( streams_set_mixer(stream) == -1 )
853  return -1;
854
[17]855 mes->cmd     = ROAR_CMD_OK;
856 mes->datalen = 0;
857
858 return 0;
859}
[0]860
[23]861int req_on_get_vol (int client, struct roar_message * mes, char * data) {
862 uint16_t * info = (uint16_t *) mes->data;
[3529]863 uint16_t   version = -1;
[23]864 int stream;
865 struct roar_stream_server * s;
866 int i;
867 int chans;
868
869 ROAR_DBG("req_on_get_vol(*) = ?");
870 ROAR_DBG("req_on_get_vol(*): mes->datalen=%i", mes->datalen);
871
[3529]872 if ( mes->datalen < 2 ) {
[23]873  return -1;
[3529]874 }
875
876 version = ROAR_NET2HOST16(info[0]);
877
878 switch (version) {
879  case 0:
880    if ( mes->datalen < (2*2) )
881     return -1;
[23]882
[3529]883    stream = ROAR_NET2HOST16(info[1]);
884   break;
885  case 1:
886    stream = mes->stream;
887   break;
888  default:
889    return -1;
890   break;
891 }
[23]892
893 ROAR_DBG("req_on_get_vol(*): stream=%i", stream);
894
895 // TODO: change this code.
896 //       we should not directly change the stream object but use some stream_*()-func
897 //       for that job.
898
899 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
900  return -1;
901
902 s = g_streams[stream];
903
904 if ( s == NULL )
905  return -1;
906
907 ROAR_DBG("req_on_get_vol(*): s=%p", s);
908
909 // ok, we have everything
910
[3529]911 info[0] = ROAR_HOST2NET16(version);
912
913 switch (version) {
914  case 0:
915    info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
916
917    for (i = 0; i < chans; i++)
918     info[2+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
[23]919
[3529]920     mes->datalen = (2 + chans)*2;
921   break;
922  case 1:
923    info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
924    info[2] = ROAR_HOST2NET16(s->mixer.scale);
925    info[3] = ROAR_HOST2NET16(s->mixer.rpg_mul);
926    info[4] = ROAR_HOST2NET16(s->mixer.rpg_div);
[23]927
[3529]928    for (i = 0; i < chans; i++)
929     info[5+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
930
931     mes->datalen = (5 + chans)*2;
932   break;
933  default:
934    return -1;
935   break;
936 }
937
[23]938 mes->cmd = ROAR_CMD_OK;
939
940 return 0;
941}
942
[0]943int req_on_add_data (int client, struct roar_message * mes, char * data) {
944 struct roar_buffer * b;
945 char               * buf;
946
947 if ( roar_buffer_new(&b, mes->datalen) == -1 ) {
948  ROAR_ERR("req_on_add_data(*): Can not alloc buffer space!");
949  ROAR_DBG("req_on_add_data(*) = -1");
950  return -1;
951 }
952
953 roar_buffer_get_data(b, (void **)&buf);
954
955 if ( data == NULL ) {
956  memcpy(buf, mes->data, mes->datalen);
957 } else {
958  memcpy(buf, data, mes->datalen);
959 }
960
961 if ( stream_add_buffer(mes->stream, b) == -1 ) {
962  roar_buffer_free(b);
963  return -1;
964 }
965
[498]966 mes->cmd     = ROAR_CMD_OK_STOP;
[0]967 mes->datalen = 0;
968
969 return 0;
970}
971
[3574]972int req_on_beep        (int client, struct roar_message * mes, char * data) {
[3575]973 struct roar_beep bs;
974 int16_t * info = (int16_t*)mes->data;
975 int stream;
976
977 memset(&bs, 0, sizeof(bs));
978
979 if ( mes->datalen > 0 ) {
980  if ( mes->datalen < 2 )
981   return -1;
982
983  if ( ROAR_NET2HOST16(info[0]) != 0 ) /* version */
984   return -1;
985
986  if ( mes->datalen != 8*2 )
987   return -1;
988
989  bs.vol  = ROAR_NET2HOST16(info[1]);
990  bs.time = ROAR_NET2HOST16(info[2]);
991  bs.freq = ROAR_NET2HOST16(info[3]);
992  bs.type = ROAR_NET2HOST16(info[4]);
993  bs.x    = ROAR_NET2HOST16(info[5]);
994  bs.y    = ROAR_NET2HOST16(info[6]);
995  bs.z    = ROAR_NET2HOST16(info[7]);
996 }
997
998 if ( (stream = beep_start(client, &bs)) == -1 )
999  return -1;
1000
1001 mes->stream  = stream;
1002 mes->cmd     = ROAR_CMD_OK_STOP;
1003 mes->datalen = 0;
1004
1005 return 0;
[3574]1006}
1007
[0]1008//ll
Note: See TracBrowser for help on using the repository browser.