source: roaraudio/roard/req.c @ 525:57dc0b2f5ee6

Last change on this file since 525:57dc0b2f5ee6 was 525:57dc0b2f5ee6, checked in by phi, 16 years ago

added debug line for connect

File size: 12.5 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 ROAR_DBG("req_on_con_stream(*): CONNECT(type=%i, host='%s', port=%i)", type, host, port);
129
130 if ( (fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port)) == -1 )
131  return -1;
132
133 if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) {
134  close(fh);
135  return 1;
136 }
137
138 return 0;
139
140 mes->datalen = 0;
141 mes->cmd     = ROAR_CMD_OK;
142}
143
144
145int req_on_set_meta    (int client, struct roar_message * mes, char * data) {
146 int type;
147 int mode;
148 int namelen, vallen;
149 char   val[255+1];
150 char   name[ROAR_META_MAX_NAMELEN+1];
151
152 if ( mes->datalen < 3 )
153  return -1;
154
155 if ( mes->data[0] != 0 ) // version
156  return -1;
157
158 mode = (unsigned) mes->data[1];
159 type = (unsigned) mes->data[2];
160
161 ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type);
162
163 if ( mode == ROAR_META_MODE_CLEAR ) {
164  stream_meta_clear(mes->stream);
165  mes->datalen = 0;
166  mes->cmd     = ROAR_CMD_OK;
167  return 0;
168 } else if ( mode == ROAR_META_MODE_DELETE ) { // unsuppoerted at the moment
169 } else if ( mode == ROAR_META_MODE_SET || mode == ROAR_META_MODE_ADD ) {
170  if ( mes->datalen < 5 )
171   return -1;
172
173  namelen = (unsigned) mes->data[3];
174  vallen  = (unsigned) mes->data[4];
175
176  ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen);
177
178  if ( mes->datalen < (5 + namelen + vallen) )
179   return -1;
180
181  if ( namelen > ROAR_META_MAX_NAMELEN )
182   return -1;
183
184  strncpy(name, &(mes->data[5]), namelen);
185  name[namelen] = 0;
186
187  if ( vallen > 255 )
188   return -1;
189
190  strncpy(val, &(mes->data[5+namelen]), vallen);
191  val[vallen] = 0;
192
193  if ( mode == ROAR_META_MODE_SET ) {
194   if ( stream_meta_set(mes->stream, type, name, val) == -1 )
195    return -1;
196  } else {
197   if ( stream_meta_add(mes->stream, type, name, val) == -1 )
198    return -1;
199  }
200
201  mes->datalen = 0;
202  mes->cmd     = ROAR_CMD_OK;
203  return 0;
204 } else { // unknown mode!
205  return -1;
206 }
207
208 return -1;
209}
210
211int req_on_get_meta    (int client, struct roar_message * mes, char * data) {
212 int vallen;
213 int type;
214 char val[LIBROAR_BUFFER_MSGDATA-1];
215
216 if ( mes->datalen != 2 )
217  return -1;
218
219 if ( mes->data[0] != 0 ) // version
220  return -1;
221
222 type = (unsigned) mes->data[1];
223
224 if ( stream_meta_get(mes->stream, type, NULL, val, LIBROAR_BUFFER_MSGDATA-2) == -1 )
225  return -1;
226
227 vallen = strlen(val);
228
229 mes->cmd     = ROAR_CMD_OK;
230 mes->datalen = 2 + vallen;
231
232 mes->data[0] = 0;
233 mes->data[1] = (unsigned char) vallen;
234
235 val[vallen] = 0;
236
237 strncpy(&(mes->data[2]), val, vallen+1);
238
239 return 0;
240}
241
242int req_on_list_meta   (int client, struct roar_message * mes, char * data) {
243 int i;
244 int len = 0;
245 int types[ROAR_META_MAX_PER_STREAM];
246
247 if ( mes->datalen != 1 )
248  return -1;
249
250 if ( mes->data[0] != 0 ) // version
251  return -1;
252
253 if ( (len = stream_meta_list(mes->stream, types, ROAR_META_MAX_PER_STREAM)) == -1 )
254  return -1;
255
256 mes->cmd     = ROAR_CMD_OK;
257 mes->datalen = 1 + len;
258 mes->data[0] = 0;
259
260 for (i = 0; i < len; i++)
261  mes->data[i+1] = types[i];
262
263 return 0;
264}
265
266int req_on_server_oinfo    (int client, struct roar_message * mes, char * data) {
267 struct roar_stream s;
268//ROAR_DIR_OUTPUT
269
270 s.dir           = ROAR_DIR_OUTPUT;
271 s.pos_rel_id    = -1;
272 s.info.rate     = g_sa->rate;
273 s.info.bits     = g_sa->bits;
274 s.info.channels = g_sa->channels;
275 s.info.codec    = g_sa->codec;
276
277 if ( roar_stream_s2m(&s, mes) == -1 )
278  return -1;
279
280 mes->cmd = ROAR_CMD_OK;
281
282 return 0;
283}
284
285
286int req_on_get_standby (int client, struct roar_message * mes, char * data) {
287 mes->cmd = ROAR_CMD_OK;
288 mes->datalen = 2;
289
290 *((uint16_t*)mes->data) = ROAR_HOST2NET16((unsigned) g_standby);
291
292 return 0;
293}
294
295int req_on_set_standby (int client, struct roar_message * mes, char * data) {
296 if ( mes->datalen != 2 )
297  return -1;
298
299 g_standby = ROAR_NET2HOST16(*((uint16_t*)mes->data));
300
301 mes->cmd     = ROAR_CMD_OK;
302 mes->datalen = 0;
303
304 return 0;
305}
306
307int req_on_exit      (int client, struct roar_message * mes, char * data) {
308 mes->cmd     = ROAR_CMD_OK;
309 mes->datalen = 0;
310
311 alive = 0;
312
313 return 0;
314}
315
316int req_on_list_clients(int client, struct roar_message * mes, char * data) {
317 unsigned char filter, cmp;
318 uint32_t id;
319 int clients[ROAR_CLIENTS_MAX];
320 int i, c = 0;
321
322 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
323  return -1;
324
325 // TODO: add code to support filter
326 if ( filter != ROAR_CTL_FILTER_ANY )
327  return -1;
328
329 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
330  if ( g_clients[i] != NULL ) {
331   clients[c++] = i;
332  }
333 }
334
335 roar_ctl_ia2m(mes, clients, c);
336
337 mes->cmd = ROAR_CMD_OK;
338
339 return 0;
340}
341int req_on_list_streams(int client, struct roar_message * mes, char * data) {
342 unsigned char filter, cmp;
343 uint32_t id;
344 int streams[ROAR_STREAMS_MAX];
345 int i, c = 0;
346
347 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
348  return -1;
349
350 // TODO: add code to support filter
351 if ( filter != ROAR_CTL_FILTER_ANY )
352  return -1;
353
354 for (i = 0; i < ROAR_STREAMS_MAX; i++) {
355  if ( g_streams[i] != NULL ) {
356   streams[c++] = i;
357  }
358 }
359
360 roar_ctl_ia2m(mes, streams, c);
361
362 mes->cmd = ROAR_CMD_OK;
363
364 return 0;
365}
366
367int req_on_get_client  (int client, struct roar_message * mes, char * data) {
368 struct roar_client * c;
369
370 if ( mes->datalen != 1 )
371  return -1;
372
373 if ( clients_get(mes->data[0], &c) == -1 )
374  return -1;
375
376 mes->cmd = ROAR_CMD_OK;
377
378 return roar_ctl_c2m(mes, c);
379}
380
381int req_on_get_stream  (int client, struct roar_message * mes, char * data) {
382 struct roar_stream_server * s;
383
384 if ( mes->datalen != 1 )
385  return -1;
386
387 if ( streams_get(mes->data[0], &s) == -1 )
388  return -1;
389
390 mes->cmd = ROAR_CMD_OK;
391 mes->stream = mes->data[0];
392
393 return roar_stream_s2m(ROAR_STREAM(s), mes);
394}
395
396int req_on_get_stream_para (int client, struct roar_message * mes, char * data) {
397 struct roar_stream * s;
398 struct roar_audio_info * audio_info;
399 uint16_t * d = (uint16_t *) mes->data;
400 int i;
401
402 if ( mes->datalen != 4 )
403  return -1;
404
405 for (i = 0; i < mes->datalen/2; i++) {
406  d[i] = ROAR_NET2HOST16(d[i]);
407 }
408
409 if ( streams_get(mes->stream, (struct roar_stream_server **)&s) == -1 ) {
410  ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream);
411  return -1;
412 }
413
414 audio_info = &(s->info);
415
416 if ( d[0] != 0 || d[1] != 1 ) {
417  ROAR_WARN("req_on_get_stream_para(*): unsupported command version: %i, %i", d[0], d[1]);
418  return -1;
419 }
420
421 mes->datalen = 2*5;
422
423 d[2] = ROAR_OUTPUT_CALC_OUTBUFSIZE(audio_info);
424 d[3] = ROAR_STREAM_SERVER(s)->pre_underruns;
425 d[4] = ROAR_STREAM_SERVER(s)->post_underruns;
426
427 for (i = 0; i < mes->datalen/2; i++) {
428  d[i] = ROAR_HOST2NET16(d[i]);
429 }
430
431 mes->cmd = ROAR_CMD_OK;
432 return 0;
433}
434
435int req_on_kick (int client, struct roar_message * mes, char * data) {
436 uint16_t * info = (uint16_t *) mes->data;
437
438 if ( mes->datalen != 4 )
439  return -1;
440
441 info[0] = ROAR_NET2HOST16(info[0]);
442 info[1] = ROAR_NET2HOST16(info[1]);
443
444 if ( info[0] == ROAR_OT_CLIENT ) {
445  clients_delete(info[1]);
446 } else if ( info[0] == ROAR_OT_STREAM ) {
447  streams_delete(info[1]);
448 } else {
449  return -1;
450 }
451
452 mes->cmd     = ROAR_CMD_OK;
453 mes->datalen = 0;
454
455 return 0;
456}
457
458int req_on_set_vol (int client, struct roar_message * mes, char * data) {
459 uint16_t * info = (uint16_t *) mes->data;
460 int stream;
461 struct roar_stream_server * s;
462 int i;
463 int chans;
464
465 ROAR_DBG("req_on_set_vol(*) = ?");
466 ROAR_DBG("req_on_set_vol(*): mes->datalen=%i", mes->datalen);
467
468 if ( mes->datalen < (4*2) )
469  return -1;
470
471 if ( info[0] != 0 ) // version
472  return -1;
473
474 stream = ROAR_NET2HOST16(info[1]);
475 ROAR_DBG("req_on_set_vol(*): stream=%i", stream);
476
477 // TODO: change this code.
478 //       we should not directly change the stream object but use some stream_*()-func
479 //       for that job.
480
481 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
482  return -1;
483
484 s = g_streams[stream];
485
486 if ( s == NULL )
487  return -1;
488
489 ROAR_DBG("req_on_set_vol(*): s=%p", s);
490
491 info[2] = ROAR_NET2HOST16(info[2]);
492
493 if ( info[2] == ROAR_SET_VOL_ALL ) {
494  chans = (mes->datalen/2) - 3;
495  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ALL, channes=%i", chans);
496
497  if ( chans >= ROAR_MAX_CHANNELS )
498   return -1;
499
500  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
501
502  for (i = 0; i < chans; i++) {
503   s->mixer.mixer[i] = ROAR_NET2HOST16(info[i+3]);
504   ROAR_DBG("req_on_set_vol(*): channel %i: %i", i, ROAR_NET2HOST16(info[i+3]));
505  }
506
507  ROAR_DBG("req_on_set_vol(*): mixer changed!");
508
509 } else if ( info[2] == ROAR_SET_VOL_ONE ) {
510  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ONE");
511  if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS )
512   return -1;
513
514  s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]);
515 } else {
516  return -1;
517 }
518
519 mes->cmd     = ROAR_CMD_OK;
520 mes->datalen = 0;
521
522 return 0;
523}
524
525int req_on_get_vol (int client, struct roar_message * mes, char * data) {
526 uint16_t * info = (uint16_t *) mes->data;
527 int stream;
528 struct roar_stream_server * s;
529 int i;
530 int chans;
531
532 ROAR_DBG("req_on_get_vol(*) = ?");
533 ROAR_DBG("req_on_get_vol(*): mes->datalen=%i", mes->datalen);
534
535 if ( mes->datalen < (2*2) )
536  return -1;
537
538 if ( info[0] != 0 ) // version
539  return -1;
540
541 stream = ROAR_NET2HOST16(info[1]);
542 ROAR_DBG("req_on_get_vol(*): stream=%i", stream);
543
544 // TODO: change this code.
545 //       we should not directly change the stream object but use some stream_*()-func
546 //       for that job.
547
548 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
549  return -1;
550
551 s = g_streams[stream];
552
553 if ( s == NULL )
554  return -1;
555
556 ROAR_DBG("req_on_get_vol(*): s=%p", s);
557
558 // ok, we have everything
559
560 info[0] = 0;
561 info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels);
562
563 for (i = 0; i < chans; i++)
564  info[2+i] = ROAR_HOST2NET16(s->mixer.mixer[i]);
565
566 mes->datalen = (2 + chans)*2;
567 mes->cmd = ROAR_CMD_OK;
568
569 return 0;
570}
571
572int req_on_add_data (int client, struct roar_message * mes, char * data) {
573 struct roar_buffer * b;
574 char               * buf;
575
576 if ( roar_buffer_new(&b, mes->datalen) == -1 ) {
577  ROAR_ERR("req_on_add_data(*): Can not alloc buffer space!");
578  ROAR_DBG("req_on_add_data(*) = -1");
579  return -1;
580 }
581
582 roar_buffer_get_data(b, (void **)&buf);
583
584 if ( data == NULL ) {
585  memcpy(buf, mes->data, mes->datalen);
586 } else {
587  memcpy(buf, data, mes->datalen);
588 }
589
590 if ( stream_add_buffer(mes->stream, b) == -1 ) {
591  roar_buffer_free(b);
592  return -1;
593 }
594
595 mes->cmd     = ROAR_CMD_OK_STOP;
596 mes->datalen = 0;
597
598 return 0;
599}
600
601//ll
Note: See TracBrowser for help on using the repository browser.