source: roaraudio/roard/req.c @ 465:82fd66e50dc3

Last change on this file since 465:82fd66e50dc3 was 465:82fd66e50dc3, checked in by phi, 16 years ago

added support to get the size of optimal read() and write()s

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