source: roaraudio/roard/req.c @ 1904:c2d7b0a826ef

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

added debug lions, commentedt seting of direction out for a moment

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