source: roaraudio/roard/req.c @ 96:95f59231f310

Last change on this file since 96:95f59231f310 was 92:2d61884489be, checked in by phi, 16 years ago

added support to set meta data

File size: 9.8 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[1024+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 if ( mode == ROAR_META_MODE_CLEAR ) {
153  stream_meta_clear(mes->stream);
154  mes->datalen = 0;
155  mes->cmd     = ROAR_CMD_OK;
156  return 0;
157 } else if ( mode == ROAR_META_MODE_DELETE ) { // unsuppoerted at the moment
158 } else if ( mode == ROAR_META_MODE_SET || mode == ROAR_META_MODE_ADD ) {
159  if ( mes->datalen < 5 )
160   return -1;
161
162  namelen = (unsigned) mes->data[3];
163  vallen  = (unsigned) mes->data[4];
164
165  if ( mes->datalen < (5 + namelen + vallen) )
166   return -1;
167
168  if ( namelen > ROAR_META_MAX_NAMELEN )
169   return -1;
170
171  strncpy(name, &(mes->data[5]), namelen);
172  name[namelen] = 0;
173
174  if ( vallen > 1024 )
175   return -1;
176
177  strncpy(val, &(mes->data[5+namelen]), vallen);
178  val[vallen] = 0;
179
180  if ( mode == ROAR_META_MODE_SET ) {
181   if ( stream_meta_set(mes->stream, type, name, val) == -1 )
182    return -1;
183  } else {
184   if ( stream_meta_add(mes->stream, type, name, val) == -1 )
185    return -1;
186  }
187
188  mes->datalen = 0;
189  mes->cmd     = ROAR_CMD_OK;
190  return 0;
191 } else { // unknown mode!
192  return -1;
193 }
194
195 return -1;
196}
197
198
199int req_on_server_oinfo    (int client, struct roar_message * mes, char * data) {
200 struct roar_stream s;
201//ROAR_DIR_OUTPUT
202
203 s.dir           = ROAR_DIR_OUTPUT;
204 s.pos_rel_id    = -1;
205 s.info.rate     = g_sa->rate;
206 s.info.bits     = g_sa->bits;
207 s.info.channels = g_sa->channels;
208 s.info.codec    = g_sa->codec;
209
210 if ( roar_stream_s2m(&s, mes) == -1 )
211  return -1;
212
213 mes->cmd = ROAR_CMD_OK;
214
215 return 0;
216}
217
218
219int req_on_get_standby (int client, struct roar_message * mes, char * data) {
220 mes->cmd = ROAR_CMD_OK;
221 mes->datalen = 2;
222
223 *((uint16_t*)mes->data) = ROAR_HOST2NET16((unsigned) g_standby);
224
225 return 0;
226}
227
228int req_on_set_standby (int client, struct roar_message * mes, char * data) {
229 if ( mes->datalen != 2 )
230  return -1;
231
232 g_standby = ROAR_NET2HOST16(*((uint16_t*)mes->data));
233
234 mes->cmd     = ROAR_CMD_OK;
235 mes->datalen = 0;
236
237 return 0;
238}
239
240int req_on_exit      (int client, struct roar_message * mes, char * data) {
241 mes->cmd     = ROAR_CMD_OK;
242 mes->datalen = 0;
243
244 alive = 0;
245
246 return 0;
247}
248
249int req_on_list_clients(int client, struct roar_message * mes, char * data) {
250 unsigned char filter, cmp;
251 uint32_t id;
252 int clients[ROAR_CLIENTS_MAX];
253 int i, c = 0;
254
255 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
256  return -1;
257
258 // TODO: add code to support filter
259 if ( filter != ROAR_CTL_FILTER_ANY )
260  return -1;
261
262 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
263  if ( g_clients[i] != NULL ) {
264   clients[c++] = i;
265  }
266 }
267
268 roar_ctl_ia2m(mes, clients, c);
269
270 mes->cmd = ROAR_CMD_OK;
271
272 return 0;
273}
274int req_on_list_streams(int client, struct roar_message * mes, char * data) {
275 unsigned char filter, cmp;
276 uint32_t id;
277 int streams[ROAR_STREAMS_MAX];
278 int i, c = 0;
279
280 if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 )
281  return -1;
282
283 // TODO: add code to support filter
284 if ( filter != ROAR_CTL_FILTER_ANY )
285  return -1;
286
287 for (i = 0; i < ROAR_STREAMS_MAX; i++) {
288  if ( g_streams[i] != NULL ) {
289   streams[c++] = i;
290  }
291 }
292
293 roar_ctl_ia2m(mes, streams, c);
294
295 mes->cmd = ROAR_CMD_OK;
296
297 return 0;
298}
299
300int req_on_get_client  (int client, struct roar_message * mes, char * data) {
301 struct roar_client * c;
302
303 if ( mes->datalen != 1 )
304  return -1;
305
306 if ( clients_get(mes->data[0], &c) == -1 )
307  return -1;
308
309 mes->cmd = ROAR_CMD_OK;
310
311 return roar_ctl_c2m(mes, c);
312}
313
314int req_on_get_stream  (int client, struct roar_message * mes, char * data) {
315 struct roar_stream_server * s;
316
317 if ( mes->datalen != 1 )
318  return -1;
319
320 if ( streams_get(mes->data[0], &s) == -1 )
321  return -1;
322
323 mes->cmd = ROAR_CMD_OK;
324
325 return roar_stream_s2m(ROAR_STREAM(s), mes);
326}
327
328int req_on_kick (int client, struct roar_message * mes, char * data) {
329 uint16_t * info = (uint16_t *) mes->data;
330
331 if ( mes->datalen != 4 )
332  return -1;
333
334 if ( info[0] == ROAR_OT_CLIENT ) {
335  clients_delete(info[1]);
336 } else if ( info[0] == ROAR_OT_STREAM ) {
337  streams_delete(info[1]);
338 } else {
339  return -1;
340 }
341
342 mes->cmd     = ROAR_CMD_OK;
343 mes->datalen = 0;
344
345 return 0;
346}
347
348int req_on_set_vol (int client, struct roar_message * mes, char * data) {
349 uint16_t * info = (uint16_t *) mes->data;
350 int stream;
351 struct roar_stream_server * s;
352 int i;
353 int chans;
354
355 ROAR_DBG("req_on_set_vol(*) = ?");
356 ROAR_DBG("req_on_set_vol(*): mes->datalen=%i", mes->datalen);
357
358 if ( mes->datalen < (4*2) )
359  return -1;
360
361 if ( info[0] != 0 ) // version
362  return -1;
363
364 stream = info[1];
365 ROAR_DBG("req_on_set_vol(*): stream=%i", stream);
366
367 // TODO: change this code.
368 //       we should not directly change the stream object but use some stream_*()-func
369 //       for that job.
370
371 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
372  return -1;
373
374 s = g_streams[stream];
375
376 if ( s == NULL )
377  return -1;
378
379 ROAR_DBG("req_on_set_vol(*): s=%p", s);
380
381 if ( info[2] == ROAR_SET_VOL_ALL ) {
382  chans = (mes->datalen/2) - 3;
383  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ALL, channes=%i", chans);
384
385  if ( chans >= ROAR_MAX_CHANNELS )
386   return -1;
387
388  ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer);
389
390  for (i = 0; i < chans; i++) {
391   s->mixer.mixer[i] = info[i+3];
392   ROAR_DBG("req_on_set_vol(*): channel %i: %i", i, info[i+3]);
393  }
394
395  ROAR_DBG("req_on_set_vol(*): mixer changed!");
396
397 } else if ( info[2] == ROAR_SET_VOL_ONE ) {
398  ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ONE");
399  if ( info[3] >= ROAR_MAX_CHANNELS )
400   return -1;
401
402  s->mixer.mixer[info[3]] = info[4];
403 } else {
404  return -1;
405 }
406
407 mes->cmd     = ROAR_CMD_OK;
408 mes->datalen = 0;
409
410 return 0;
411}
412
413int req_on_get_vol (int client, struct roar_message * mes, char * data) {
414 uint16_t * info = (uint16_t *) mes->data;
415 int stream;
416 struct roar_stream_server * s;
417 int i;
418 int chans;
419
420 ROAR_DBG("req_on_get_vol(*) = ?");
421 ROAR_DBG("req_on_get_vol(*): mes->datalen=%i", mes->datalen);
422
423 if ( mes->datalen < (2*2) )
424  return -1;
425
426 if ( info[0] != 0 ) // version
427  return -1;
428
429 stream = info[1];
430 ROAR_DBG("req_on_get_vol(*): stream=%i", stream);
431
432 // TODO: change this code.
433 //       we should not directly change the stream object but use some stream_*()-func
434 //       for that job.
435
436 if ( stream < 0 || stream >= ROAR_STREAMS_MAX )
437  return -1;
438
439 s = g_streams[stream];
440
441 if ( s == NULL )
442  return -1;
443
444 ROAR_DBG("req_on_get_vol(*): s=%p", s);
445
446 // ok, we have everything
447
448 info[0] = 0;
449 info[1] = chans = ROAR_STREAM(s)->info.channels;
450
451 for (i = 0; i < chans; i++)
452  info[2+i] = s->mixer.mixer[i];
453
454 mes->datalen = (2 + chans)*2;
455 mes->cmd = ROAR_CMD_OK;
456
457 return 0;
458}
459
460int req_on_add_data (int client, struct roar_message * mes, char * data) {
461 struct roar_buffer * b;
462 char               * buf;
463
464 if ( roar_buffer_new(&b, mes->datalen) == -1 ) {
465  ROAR_ERR("req_on_add_data(*): Can not alloc buffer space!");
466  ROAR_DBG("req_on_add_data(*) = -1");
467  return -1;
468 }
469
470 roar_buffer_get_data(b, (void **)&buf);
471
472 if ( data == NULL ) {
473  memcpy(buf, mes->data, mes->datalen);
474 } else {
475  memcpy(buf, data, mes->datalen);
476 }
477
478 if ( stream_add_buffer(mes->stream, b) == -1 ) {
479  roar_buffer_free(b);
480  return -1;
481 }
482
483 mes->cmd     = ROAR_CMD_OK;
484 mes->datalen = 0;
485
486 return 0;
487}
488
489//ll
Note: See TracBrowser for help on using the repository browser.