source: roaraudio/roard/req.c @ 1848:eaba1872ebfd

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

start of midi clock bridge

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