source: roaraudio/roard/req.c @ 84:cd538d13337e

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

fixed some bugs with multible streams per client

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