source: roaraudio/roard/req.c @ 252:c5d4c35bbbe7

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

fixed byte-order bug in *_set/get_vol(), hey! one bug more :)

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