source: roaraudio/roard/req.c @ 2250:1d6f167a7483

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

test pos_rel_id on new ROAR_DIR_RAW_IN streams

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