source: roaraudio/roard/req.c @ 1811:1106ac98c209

Last change on this file since 1811:1106ac98c209 was 1809:4c4b1838d099, checked in by phi, 15 years ago

in case of light streams set ch/bits/rate to zero

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