source: roaraudio/roard/req.c @ 1608:41f671214d02

Last change on this file since 1608:41f671214d02 was 1590:07fa8c4493e4, checked in by phi, 15 years ago

added first try of support for hwmixer flag

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