source: roaraudio/roard/req.c @ 1861:1dc86f9cb367

Last change on this file since 1861:1dc86f9cb367 was 1861:1dc86f9cb367, checked in by phi, 15 years ago

do not delete yourself

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