source: roaraudio/roard/req.c @ 486:5f7954982f5a

Last change on this file since 486:5f7954982f5a was 486:5f7954982f5a, checked in by phi, 16 years ago

added some bugfixed because of roar_stream_m2s() change

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