source: roaraudio/roard/req.c @ 1900:cc3ed982fabd

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

set defaults on MIDI streams, don't use bits=8 on midi streams

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