source: roaraudio/roard/req.c @ 3213:da8251c98c0a

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

support to transpher mixer stream id

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