source: roaraudio/roard/req.c @ 1907:3be1f0e73ed2

Last change on this file since 1907:3be1f0e73ed2 was 1907:3be1f0e73ed2, checked in by phi, 15 years ago

try to set dir again

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