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
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
[1904]89 ROAR_DBG("req_on_new_stream(client=%i, ...): creating stream...", client);
[0]90 if ((stream = streams_new()) == -1 )
91  return -1;
92
[1904]93 ROAR_DBG("req_on_new_stream(client=%i, ...): getting stream...", client);
[0]94 if ( streams_get(stream, (struct roar_stream_server **)&s) == -1 ) {
95  streams_delete(stream);
96  return -1;
97 }
98
[1904]99 ROAR_DBG("req_on_new_stream(client=%i, ...): set client of stream...", client);
[0]100 if ( client_stream_add(client, stream) == -1 ) {
101  streams_delete(stream);
102  return -1;
103 }
104
[1904]105 ROAR_DBG("req_on_new_stream(client=%i, ...): loading stream from message...", client);
[0]106 if ( roar_stream_m2s(s, mes) == -1 ) {
107  streams_delete(stream);
108  return -1;
109 }
110
[1904]111 ROAR_DBG("req_on_new_stream(client=%i, ...): setting id and codec of stream...", client);
[486]112 ROAR_STREAM(s)->id = stream; // roar_stream_m2s() resets this
[539]113 ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM(s)->info.codec;
[486]114
[1904]115 ROAR_DBG("req_on_new_stream(client=%i, ...): setting direction stream...", client);
[1900]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
[1904]122 ROAR_DBG("req_on_new_stream(client=%i, ...): setting up direction specific stream settings...", client);
[1809]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;
[1848]133  case ROAR_DIR_MIDI_IN:
134  case ROAR_DIR_MIDI_OUT:
135    info = &(ROAR_STREAM(s)->info);
136
137    info->channels = 16;
[1900]138    info->bits     =  0;
[1848]139    info->rate     = MIDI_RATE;
140
141   break;
142
[1812]143  case ROAR_DIR_THRU:
[1815]144
145    if ( ROAR_STREAM(s)->pos_rel_id == -1 || ROAR_STREAM(s)->pos_rel_id == stream ) {
[1861]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
[1815]148     streams_delete(stream);
149     return -1;
150    }
151
[1812]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;
[1840]164    ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM_SERVER(source_stream)->codec_orgi;
[1812]165
166   break;
[1809]167 }
168
[1904]169 ROAR_DBG("req_on_new_stream(client=%i, ...): returning (OK)...", client);
170
[0]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
[1904]181 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): execing stream", client, mes->stream);
182
[0]183 if ( (r = client_stream_exec(client, mes->stream)) == -1 )
184  return -1;
185
[1904]186 ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream);
[0]187 mes->cmd     = ROAR_CMD_OK;
188 mes->datalen = 0;
189
190 return 0;
191}
192
[77]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
[80]206 if ( mes->datalen > 80 ) // we do not support long messages here
207  return -1;
208
[77]209 type = (unsigned)mes->data[1];
[79]210 port = ROAR_NET2HOST16(((uint16_t*)mes->data)[1]);
[77]211
[80]212 len = mes->datalen - 4;
[77]213
[84]214 strncpy(host, &(mes->data[4]), len);
[77]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
[525]226 ROAR_DBG("req_on_con_stream(*): CONNECT(type=%i, host='%s', port=%i)", type, host, port);
227
[77]228 if ( (fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port)) == -1 )
229  return -1;
230
[78]231 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
232  close(fh);
233  return 1;
234 }
235
[757]236 mes->datalen = 0;
237 mes->cmd     = ROAR_CMD_OK;
238
[78]239 return 0;
[757]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
[78]254
255 mes->datalen = 0;
256 mes->cmd     = ROAR_CMD_OK;
[757]257
258 return 0;
[77]259}
260
[1493]261#ifdef ROAR_SUPPORT_META
[0]262int req_on_set_meta    (int client, struct roar_message * mes, char * data) {
[92]263 int type;
264 int mode;
265 int namelen, vallen;
[99]266 char   val[255+1];
[92]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
[99]278 ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type);
279
[92]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
[1038]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;
[92]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
[99]299  ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen);
300
[92]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
[99]310  if ( vallen > 255 )
[92]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
[0]331 return -1;
332}
333
[100]334int req_on_get_meta    (int client, struct roar_message * mes, char * data) {
[101]335 int vallen;
336 int type;
[107]337 char val[LIBROAR_BUFFER_MSGDATA-1];
[101]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
[107]358 val[vallen] = 0;
359
360 strncpy(&(mes->data[2]), val, vallen+1);
[101]361
362 return 0;
[100]363}
[0]364
[113]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}
[1493]388#endif
[113]389
[0]390int req_on_server_oinfo    (int client, struct roar_message * mes, char * data) {
391 struct roar_stream s;
392//ROAR_DIR_OUTPUT
393
[966]394 memset(&s, 0, sizeof(struct roar_stream));
[964]395
[977]396 s.dir           = ROAR_DIR_MIXING;
[0]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;
[977]402 s.pos           = g_pos;
[0]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) {
[575]435 int term = 0;
436
437 if ( mes->datalen == 1 )
438  term = mes->data[0];
439
[0]440 mes->cmd     = ROAR_CMD_OK;
441 mes->datalen = 0;
442
[576]443 ROAR_DBG("req_on_exit(*): term=%i", term);
444
[575]445 if ( term ) {
446  cleanup_listen_socket(1);
447 } else {
448  alive = 0;
449 }
[0]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;
[465]529 mes->stream = mes->data[0];
[0]530
531 return roar_stream_s2m(ROAR_STREAM(s), mes);
532}
533
[465]534int req_on_get_stream_para (int client, struct roar_message * mes, char * data) {
535 struct roar_stream * s;
[963]536 struct roar_stream_server * ss;
[465]537 struct roar_audio_info * audio_info;
538 uint16_t * d = (uint16_t *) mes->data;
539 int i;
[1842]540 char * str;
[465]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
[1842]549 if ( d[0] != 0 ) {
[465]550  ROAR_WARN("req_on_get_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
551  return -1;
552 }
553
[1842]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);
[465]566
[1842]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]);
[465]581
[1842]582    for (i = 0; i < mes->datalen/2; i++) {
583     d[i] = ROAR_HOST2NET16(d[i]);
584    }
[1156]585
[1842]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;
[1151]594
[1842]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;
[465]609 }
610
611 mes->cmd = ROAR_CMD_OK;
612 return 0;
613}
614
[1043]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
[1842]626 if ( d[0] != 0 || d[1] != ROAR_STREAM_PARA_FLAGS ) {
[1043]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
[1044]634 ROAR_DBG("req_on_set_stream_para(*): request seems to be valid");
[1043]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
[0]645int req_on_kick (int client, struct roar_message * mes, char * data) {
[17]646 uint16_t * info = (uint16_t *) mes->data;
[0]647
648 if ( mes->datalen != 4 )
649  return -1;
650
[251]651 info[0] = ROAR_NET2HOST16(info[0]);
652 info[1] = ROAR_NET2HOST16(info[1]);
653
[0]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]);
[1111]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  }
[0]664 } else {
665  return -1;
666 }
667
668 mes->cmd     = ROAR_CMD_OK;
669 mes->datalen = 0;
670
671 return 0;
672}
673
[768]674int req_on_attach      (int client, struct roar_message * mes, char * data) {
[769]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;
[768]698}
699
[17]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
[252]716 stream = ROAR_NET2HOST16(info[1]);
[17]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
[252]733 info[2] = ROAR_NET2HOST16(info[2]);
734
[17]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
[18]742  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
743
[17]744  for (i = 0; i < chans; i++) {
[252]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]));
[17]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");
[252]753  if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS )
[17]754   return -1;
755
[252]756  s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]);
[17]757 } else {
758  return -1;
759 }
760
[1590]761 if ( streams_set_mixer(stream) == -1 )
762  return -1;
763
[17]764 mes->cmd     = ROAR_CMD_OK;
765 mes->datalen = 0;
766
767 return 0;
768}
[0]769
[23]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
[252]786 stream = ROAR_NET2HOST16(info[1]);
[23]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;
[252]806 info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
[23]807
808 for (i = 0; i < chans; i++)
[252]809  info[2+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
[23]810
811 mes->datalen = (2 + chans)*2;
812 mes->cmd = ROAR_CMD_OK;
813
814 return 0;
815}
816
[0]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
[498]840 mes->cmd     = ROAR_CMD_OK_STOP;
[0]841 mes->datalen = 0;
842
843 return 0;
844}
845
846//ll
Note: See TracBrowser for help on using the repository browser.