source: roaraudio/roard/req.c @ 496:a76b844d00c6

Last change on this file since 496:a76b844d00c6 was 496:a76b844d00c6, checked in by phi, 16 years ago

added support vor underrun vars to proto

File size: 12.4 KB
Line 
1
2
3#include "roard.h"
4
5int req_on_noop        (int client, struct roar_message * mes, char * data) {
6 mes->cmd     = ROAR_CMD_OK;
7 mes->datalen = 0;
8 return 0;
9}
10
11int req_on_identify    (int client, struct roar_message * mes, char * data) {
12 struct roar_client * c;
13 int max_len;
14
15 if ( mes->datalen < 1 )
16  return -1;
17
18 clients_get(client, &c);
19
20 if ( mes->data[0] == 1 ) {
21  if ( c->pid == -1 ) {
22   c->pid       = ROAR_NET2HOST32(*(uint32_t*)((mes->data)+1));
23   ROAR_DBG("req_on_identify(): new PID: c->pid = %i", c->pid);
24  }
25
26  ROAR_DBG("req_on_identify(): final PID: c->pid = %i", c->pid);
27
28  max_len = (mes->datalen - 5) < (ROAR_BUFFER_NAME-1) ? (mes->datalen - 5) : (ROAR_BUFFER_NAME-1);
29
30  strncpy(c->name, mes->data + 5, max_len);
31  c->name[max_len] = 0;
32
33  mes->cmd     = ROAR_CMD_OK;
34  mes->datalen = 0;
35
36  ROAR_DBG("req_on_identify(*): client=%i, pid=%i", client, c->pid);
37  ROAR_DBG("req_on_identify(*) = 0");
38  return 0;
39 }
40
41 return -1;
42}
43
44int req_on_auth        (int client, struct roar_message * mes, char * data) {
45 // TODO: add code to support some auth.
46 mes->cmd     = ROAR_CMD_OK;
47 mes->datalen = 0;
48 return 0;
49}
50
51
52int req_on_new_stream  (int client, struct roar_message * mes, char * data) {
53 int stream;
54 struct roar_stream * s;
55
56 if ((stream = streams_new()) == -1 )
57  return -1;
58
59 if ( streams_get(stream, (struct roar_stream_server **)&s) == -1 ) {
60  streams_delete(stream);
61  return -1;
62 }
63
64 if ( client_stream_add(client, stream) == -1 ) {
65  streams_delete(stream);
66  return -1;
67 }
68
69 if ( roar_stream_m2s(s, mes) == -1 ) {
70  streams_delete(stream);
71  return -1;
72 }
73
74 ROAR_STREAM(s)->id = stream; // roar_stream_m2s() resets this
75
76 mes->cmd     = ROAR_CMD_OK;
77 mes->stream  = stream;
78 mes->datalen = 0;
79
80 return 0;
81}
82
83int req_on_exec_stream (int client, struct roar_message * mes, char * data) {
84 int r;
85
86 if ( (r = client_stream_exec(client, mes->stream)) == -1 )
87  return -1;
88
89 mes->cmd     = ROAR_CMD_OK;
90 mes->datalen = 0;
91
92 return 0;
93}
94
95int req_on_con_stream  (int client, struct roar_message * mes, char * data) {
96 char   host[80] = {0};
97 int    port = 0;
98 int    type;
99 int    fh;
100 int    len;
101
102 if ( mes->datalen < 4 )
103  return -1;
104
105 if ( *(mes->data) != 0 )
106  return -1;
107
108 if ( mes->datalen > 80 ) // we do not support long messages here
109  return -1;
110
111 type = (unsigned)mes->data[1];
112 port = ROAR_NET2HOST16(((uint16_t*)mes->data)[1]);
113
114 len = mes->datalen - 4;
115
116 strncpy(host, &(mes->data[4]), len);
117 host[len] = 0;
118
119 if ( type > ROAR_SOCKET_TYPE_MAX )
120  return -1;
121
122 if ( type == ROAR_SOCKET_TYPE_FILE ) // disabled because of security resons
123  return -1;
124
125 if ( type == ROAR_SOCKET_TYPE_FORK ) // why should we connect to ourself?
126  return -1;
127
128 if ( (fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port)) == -1 )
129  return -1;
130
131 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
132  close(fh);
133  return 1;
134 }
135
136 return 0;
137
138 mes->datalen = 0;
139 mes->cmd     = ROAR_CMD_OK;
140}
141
142
143int req_on_set_meta    (int client, struct roar_message * mes, char * data) {
144 int type;
145 int mode;
146 int namelen, vallen;
147 char   val[255+1];
148 char   name[ROAR_META_MAX_NAMELEN+1];
149
150 if ( mes->datalen < 3 )
151  return -1;
152
153 if ( mes->data[0] != 0 ) // version
154  return -1;
155
156 mode = (unsigned) mes->data[1];
157 type = (unsigned) mes->data[2];
158
159 ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type);
160
161 if ( mode == ROAR_META_MODE_CLEAR ) {
162  stream_meta_clear(mes->stream);
163  mes->datalen = 0;
164  mes->cmd     = ROAR_CMD_OK;
165  return 0;
166 } else if ( mode == ROAR_META_MODE_DELETE ) { // unsuppoerted at the moment
167 } else if ( mode == ROAR_META_MODE_SET || mode == ROAR_META_MODE_ADD ) {
168  if ( mes->datalen < 5 )
169   return -1;
170
171  namelen = (unsigned) mes->data[3];
172  vallen  = (unsigned) mes->data[4];
173
174  ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen);
175
176  if ( mes->datalen < (5 + namelen + vallen) )
177   return -1;
178
179  if ( namelen > ROAR_META_MAX_NAMELEN )
180   return -1;
181
182  strncpy(name, &(mes->data[5]), namelen);
183  name[namelen] = 0;
184
185  if ( vallen > 255 )
186   return -1;
187
188  strncpy(val, &(mes->data[5+namelen]), vallen);
189  val[vallen] = 0;
190
191  if ( mode == ROAR_META_MODE_SET ) {
192   if ( stream_meta_set(mes->stream, type, name, val) == -1 )
193    return -1;
194  } else {
195   if ( stream_meta_add(mes->stream, type, name, val) == -1 )
196    return -1;
197  }
198
199  mes->datalen = 0;
200  mes->cmd     = ROAR_CMD_OK;
201  return 0;
202 } else { // unknown mode!
203  return -1;
204 }
205
206 return -1;
207}
208
209int req_on_get_meta    (int client, struct roar_message * mes, char * data) {
210 int vallen;
211 int type;
212 char val[LIBROAR_BUFFER_MSGDATA-1];
213
214 if ( mes->datalen != 2 )
215  return -1;
216
217 if ( mes->data[0] != 0 ) // version
218  return -1;
219
220 type = (unsigned) mes->data[1];
221
222 if ( stream_meta_get(mes->stream, type, NULL, val, LIBROAR_BUFFER_MSGDATA-2) == -1 )
223  return -1;
224
225 vallen = strlen(val);
226
227 mes->cmd     = ROAR_CMD_OK;
228 mes->datalen = 2 + vallen;
229
230 mes->data[0] = 0;
231 mes->data[1] = (unsigned char) vallen;
232
233 val[vallen] = 0;
234
235 strncpy(&(mes->data[2]), val, vallen+1);
236
237 return 0;
238}
239
240int req_on_list_meta   (int client, struct roar_message * mes, char * data) {
241 int i;
242 int len = 0;
243 int types[ROAR_META_MAX_PER_STREAM];
244
245 if ( mes->datalen != 1 )
246  return -1;
247
248 if ( mes->data[0] != 0 ) // version
249  return -1;
250
251 if ( (len = stream_meta_list(mes->stream, types, ROAR_META_MAX_PER_STREAM)) == -1 )
252  return -1;
253
254 mes->cmd     = ROAR_CMD_OK;
255 mes->datalen = 1 + len;
256 mes->data[0] = 0;
257
258 for (i = 0; i < len; i++)
259  mes->data[i+1] = types[i];
260
261 return 0;
262}
263
264int req_on_server_oinfo    (int client, struct roar_message * mes, char * data) {
265 struct roar_stream s;
266//ROAR_DIR_OUTPUT
267
268 s.dir           = ROAR_DIR_OUTPUT;
269 s.pos_rel_id    = -1;
270 s.info.rate     = g_sa->rate;
271 s.info.bits     = g_sa->bits;
272 s.info.channels = g_sa->channels;
273 s.info.codec    = g_sa->codec;
274
275 if ( roar_stream_s2m(&s, mes) == -1 )
276  return -1;
277
278 mes->cmd = ROAR_CMD_OK;
279
280 return 0;
281}
282
283
284int req_on_get_standby (int client, struct roar_message * mes, char * data) {
285 mes->cmd = ROAR_CMD_OK;
286 mes->datalen = 2;
287
288 *((uint16_t*)mes->data) = ROAR_HOST2NET16((unsigned) g_standby);
289
290 return 0;
291}
292
293int req_on_set_standby (int client, struct roar_message * mes, char * data) {
294 if ( mes->datalen != 2 )
295  return -1;
296
297 g_standby = ROAR_NET2HOST16(*((uint16_t*)mes->data));
298
299 mes->cmd     = ROAR_CMD_OK;
300 mes->datalen = 0;
301
302 return 0;
303}
304
305int req_on_exit      (int client, struct roar_message * mes, char * data) {
306 mes->cmd     = ROAR_CMD_OK;
307 mes->datalen = 0;
308
309 alive = 0;
310
311 return 0;
312}
313
314int req_on_list_clients(int client, struct roar_message * mes, char * data) {
315 unsigned char filter, cmp;
316 uint32_t id;
317 int clients[ROAR_CLIENTS_MAX];
318 int i, c = 0;
319
320 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
321  return -1;
322
323 // TODO: add code to support filter
324 if ( filter != ROAR_CTL_FILTER_ANY )
325  return -1;
326
327 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
328  if ( g_clients[i] != NULL ) {
329   clients[c++] = i;
330  }
331 }
332
333 roar_ctl_ia2m(mes, clients, c);
334
335 mes->cmd = ROAR_CMD_OK;
336
337 return 0;
338}
339int req_on_list_streams(int client, struct roar_message * mes, char * data) {
340 unsigned char filter, cmp;
341 uint32_t id;
342 int streams[ROAR_STREAMS_MAX];
343 int i, c = 0;
344
345 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
346  return -1;
347
348 // TODO: add code to support filter
349 if ( filter != ROAR_CTL_FILTER_ANY )
350  return -1;
351
352 for (i = 0; i < ROAR_STREAMS_MAX; i++) {
353  if ( g_streams[i] != NULL ) {
354   streams[c++] = i;
355  }
356 }
357
358 roar_ctl_ia2m(mes, streams, c);
359
360 mes->cmd = ROAR_CMD_OK;
361
362 return 0;
363}
364
365int req_on_get_client  (int client, struct roar_message * mes, char * data) {
366 struct roar_client * c;
367
368 if ( mes->datalen != 1 )
369  return -1;
370
371 if ( clients_get(mes->data[0], &c) == -1 )
372  return -1;
373
374 mes->cmd = ROAR_CMD_OK;
375
376 return roar_ctl_c2m(mes, c);
377}
378
379int req_on_get_stream  (int client, struct roar_message * mes, char * data) {
380 struct roar_stream_server * s;
381
382 if ( mes->datalen != 1 )
383  return -1;
384
385 if ( streams_get(mes->data[0], &s) == -1 )
386  return -1;
387
388 mes->cmd = ROAR_CMD_OK;
389 mes->stream = mes->data[0];
390
391 return roar_stream_s2m(ROAR_STREAM(s), mes);
392}
393
394int req_on_get_stream_para (int client, struct roar_message * mes, char * data) {
395 struct roar_stream * s;
396 struct roar_audio_info * audio_info;
397 uint16_t * d = (uint16_t *) mes->data;
398 int i;
399
400 if ( mes->datalen != 4 )
401  return -1;
402
403 for (i = 0; i < mes->datalen/2; i++) {
404  d[i] = ROAR_NET2HOST16(d[i]);
405 }
406
407 if ( streams_get(mes->stream, (struct roar_stream_server **)&s) == -1 ) {
408  ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream);
409  return -1;
410 }
411
412 audio_info = &(s->info);
413
414 if ( d[0] != 0 || d[1] != 1 ) {
415  ROAR_WARN("req_on_get_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
416  return -1;
417 }
418
419 mes->datalen = 2*5;
420
421 d[2] = ROAR_OUTPUT_CALC_OUTBUFSIZE(audio_info);
422 d[3] = ROAR_STREAM_SERVER(s)->pre_underruns;
423 d[4] = ROAR_STREAM_SERVER(s)->post_underruns;
424
425 for (i = 0; i < mes->datalen/2; i++) {
426  d[i] = ROAR_HOST2NET16(d[i]);
427 }
428
429 mes->cmd = ROAR_CMD_OK;
430 return 0;
431}
432
433int req_on_kick (int client, struct roar_message * mes, char * data) {
434 uint16_t * info = (uint16_t *) mes->data;
435
436 if ( mes->datalen != 4 )
437  return -1;
438
439 info[0] = ROAR_NET2HOST16(info[0]);
440 info[1] = ROAR_NET2HOST16(info[1]);
441
442 if ( info[0] == ROAR_OT_CLIENT ) {
443  clients_delete(info[1]);
444 } else if ( info[0] == ROAR_OT_STREAM ) {
445  streams_delete(info[1]);
446 } else {
447  return -1;
448 }
449
450 mes->cmd     = ROAR_CMD_OK;
451 mes->datalen = 0;
452
453 return 0;
454}
455
456int req_on_set_vol (int client, struct roar_message * mes, char * data) {
457 uint16_t * info = (uint16_t *) mes->data;
458 int stream;
459 struct roar_stream_server * s;
460 int i;
461 int chans;
462
463 ROAR_DBG("req_on_set_vol(*) = ?");
464 ROAR_DBG("req_on_set_vol(*): mes->datalen=%i", mes->datalen);
465
466 if ( mes->datalen < (4*2) )
467  return -1;
468
469 if ( info[0] != 0 ) // version
470  return -1;
471
472 stream = ROAR_NET2HOST16(info[1]);
473 ROAR_DBG("req_on_set_vol(*): stream=%i", stream);
474
475 // TODO: change this code.
476 //       we should not directly change the stream object but use some stream_*()-func
477 //       for that job.
478
479 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
480  return -1;
481
482 s = g_streams[stream];
483
484 if ( s == NULL )
485  return -1;
486
487 ROAR_DBG("req_on_set_vol(*): s=%p", s);
488
489 info[2] = ROAR_NET2HOST16(info[2]);
490
491 if ( info[2] == ROAR_SET_VOL_ALL ) {
492  chans = (mes->datalen/2) - 3;
493  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ALL, channes=%i", chans);
494
495  if ( chans >= ROAR_MAX_CHANNELS )
496   return -1;
497
498  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
499
500  for (i = 0; i < chans; i++) {
501   s->mixer.mixer[i] = ROAR_NET2HOST16(info[i+3]);
502   ROAR_DBG("req_on_set_vol(*): channel %i: %i", i, ROAR_NET2HOST16(info[i+3]));
503  }
504
505  ROAR_DBG("req_on_set_vol(*): mixer changed!");
506
507 } else if ( info[2] == ROAR_SET_VOL_ONE ) {
508  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ONE");
509  if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS )
510   return -1;
511
512  s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]);
513 } else {
514  return -1;
515 }
516
517 mes->cmd     = ROAR_CMD_OK;
518 mes->datalen = 0;
519
520 return 0;
521}
522
523int req_on_get_vol (int client, struct roar_message * mes, char * data) {
524 uint16_t * info = (uint16_t *) mes->data;
525 int stream;
526 struct roar_stream_server * s;
527 int i;
528 int chans;
529
530 ROAR_DBG("req_on_get_vol(*) = ?");
531 ROAR_DBG("req_on_get_vol(*): mes->datalen=%i", mes->datalen);
532
533 if ( mes->datalen < (2*2) )
534  return -1;
535
536 if ( info[0] != 0 ) // version
537  return -1;
538
539 stream = ROAR_NET2HOST16(info[1]);
540 ROAR_DBG("req_on_get_vol(*): stream=%i", stream);
541
542 // TODO: change this code.
543 //       we should not directly change the stream object but use some stream_*()-func
544 //       for that job.
545
546 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
547  return -1;
548
549 s = g_streams[stream];
550
551 if ( s == NULL )
552  return -1;
553
554 ROAR_DBG("req_on_get_vol(*): s=%p", s);
555
556 // ok, we have everything
557
558 info[0] = 0;
559 info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
560
561 for (i = 0; i < chans; i++)
562  info[2+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
563
564 mes->datalen = (2 + chans)*2;
565 mes->cmd = ROAR_CMD_OK;
566
567 return 0;
568}
569
570int req_on_add_data (int client, struct roar_message * mes, char * data) {
571 struct roar_buffer * b;
572 char               * buf;
573
574 if ( roar_buffer_new(&b, mes->datalen) == -1 ) {
575  ROAR_ERR("req_on_add_data(*): Can not alloc buffer space!");
576  ROAR_DBG("req_on_add_data(*) = -1");
577  return -1;
578 }
579
580 roar_buffer_get_data(b, (void **)&buf);
581
582 if ( data == NULL ) {
583  memcpy(buf, mes->data, mes->datalen);
584 } else {
585  memcpy(buf, data, mes->datalen);
586 }
587
588 if ( stream_add_buffer(mes->stream, b) == -1 ) {
589  roar_buffer_free(b);
590  return -1;
591 }
592
593 mes->cmd     = ROAR_CMD_OK;
594 mes->datalen = 0;
595
596 return 0;
597}
598
599//ll
Note: See TracBrowser for help on using the repository browser.