source: roaraudio/roard/req.c @ 1812:d46222e215af

Last change on this file since 1812:d46222e215af was 1812:d46222e215af, checked in by phi, 15 years ago

copy stream info from source stream in case of thru stream

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