source: roaraudio/libroar/simple.c @ 1660:99bfd21f00ef

Last change on this file since 1660:99bfd21f00ef was 1660:99bfd21f00ef, checked in by phi, 15 years ago

changed name of fh in con struct to fh, this should all apps requiring the private member to fail to build, added function to get fh, change code to use them both everythere

File size: 9.4 KB
Line 
1//simple.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008, 2009
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "libroar.h"
36
37int roar_simple_connect (struct roar_connection * con, char * server, char * name) {
38
39 ROAR_DBG("roar_simple_connect(*): trying to connect...");
40
41 if ( roar_connect(con, server) == -1 ) {
42  ROAR_DBG("roar_simple_connect(*): roar_connect() faild!");
43  return -1;
44 }
45
46 if ( roar_identify(con, name) == -1 ) {
47  ROAR_DBG("roar_simple_connect(*): roar_identify() faild!");
48  return -1;
49 }
50
51 if ( roar_auth(con) == -1 ) {
52  ROAR_DBG("roar_simple_connect(*): roar_auth() faild!");
53  return -1;
54 }
55
56 return 0;
57}
58
59int roar_simple_stream(int rate, int channels, int bits, int codec, char * server, int dir, char * name) {
60 struct roar_stream     s;
61
62 return roar_simple_stream_obj(&s, rate, channels, bits, codec, server, dir, name);
63}
64
65int roar_simple_stream_obj  (struct roar_stream * s, int rate, int channels, int bits, int codec, char * server, int dir, char * name) {
66 struct roar_connection con;
67 int ret;
68
69 if ( roar_simple_connect(&con, server, name) == -1 ) {
70  ROAR_DBG("roar_simple_play(*): roar_simple_connect() faild!");
71  ROAR_ERR("roar_simple_stream(*): Can not connect to server");
72  return -1;
73 }
74
75 if ( roar_stream_new(s, rate, channels, bits, codec) == -1 ) {
76  roar_disconnect(&con);
77  return -1;
78 }
79
80 if ( roar_stream_connect(&con, s, dir) == -1 ) {
81  roar_disconnect(&con);
82  return -1;
83 }
84
85 if ( roar_stream_exec(&con, s) == -1 ) {
86  roar_disconnect(&con);
87  return -1;
88 }
89
90 if ( (ret = roar_get_connection_fh(&con)) == -1 ) {
91  roar_disconnect(&con);
92  return -1;
93 }
94
95 if ( dir == ROAR_DIR_PLAY ) {
96  ROAR_SHUTDOWN(ret, SHUT_RD);
97 } else if ( dir == ROAR_DIR_MONITOR || dir == ROAR_DIR_RECORD ) {
98  ROAR_SHUTDOWN(ret, SHUT_WR);
99 }
100
101 return ret;
102}
103
104int roar_simple_new_stream_attachexeced_obj (struct roar_connection * con, struct roar_stream * s, int rate, int channels, int bits, int codec, int dir) {
105 int fh;
106
107 if ( (fh = roar_simple_stream_obj(s, rate, channels, bits, codec, NULL /* server, we hope this is ok here... */,
108                                   dir, "libroar temp stream")) == -1 )
109  return -1;
110
111 if ( roar_stream_attach_simple(con, s, roar_get_clientid(con)) == -1 ) {
112#ifdef ROAR_HAVE_IO_POSIX
113  close(fh);
114#endif /* no else as we return -1 anyway */
115  return -1;
116 }
117
118 s->fh = fh;
119
120 return fh;
121}
122
123int roar_simple_new_stream (struct roar_connection * con, int rate, int channels, int bits, int codec, int dir) {
124 struct roar_stream     s;
125 return roar_simple_new_stream_obj(con, &s, rate, channels, bits, codec, dir);
126}
127
128int roar_simple_new_stream_obj (struct roar_connection * con, struct roar_stream * s, int rate, int channels, int bits, int codec, int dir) {
129 char file[80] = {0};
130 int fh = -1, listen = -1;
131 static int count = 0;
132 int    type = ROAR_SOCKET_TYPE_UNIX;
133 int    port = 0;
134#if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_LIBDNET)
135 int    opt  = 1;
136#endif
137#ifdef ROAR_HAVE_IPV4
138 struct sockaddr_in   socket_addr;
139 socklen_t            len            = sizeof(struct sockaddr_in);
140#else
141 struct sockaddr      socket_addr;
142 socklen_t            len            = sizeof(struct sockaddr);
143#endif
144#ifdef ROAR_HAVE_SELECT
145 fd_set fds;
146 struct timeval timeout = {10, 0};
147 struct roar_message    mes;
148#endif
149#ifdef ROAR_HAVE_UNIX
150 int socks[2]; // for socketpair()
151#endif
152
153#ifdef ROAR_HAVE_BSDSOCKETS
154 if ( getsockname(roar_get_connection_fh(con), (struct sockaddr *)&socket_addr, &len) == -1 ) {
155  return -1;
156 }
157#else
158 return -1;
159#endif
160
161 if ( len == 0 ) {
162#ifdef ROAR_OS_OPENBSD
163  ROAR_WARN("roar_simple_new_stream_obj(*): Unknown address family: guess AF_UNIX because OS is OpenBSD");
164  ((struct sockaddr*)&socket_addr)->sa_family = AF_UNIX;
165#else
166  return -1;
167#endif
168 }
169
170 switch (((struct sockaddr*)&socket_addr)->sa_family) {
171#ifdef ROAR_HAVE_UNIX
172  case AF_UNIX:   type = ROAR_SOCKET_TYPE_UNIX; break;
173#endif
174#ifdef ROAR_HAVE_IPV4
175  case AF_INET:   type = ROAR_SOCKET_TYPE_INET; break;
176#endif
177#ifdef ROAR_HAVE_LIBDNET
178  case AF_DECnet: type = ROAR_SOCKET_TYPE_DECNET; break;
179#endif
180  default:
181    return -1;
182   break;
183 }
184
185 if ( type == ROAR_SOCKET_TYPE_DECNET ) {
186  if ( roar_socket_get_local_nodename() ) {
187   snprintf(file, 24,"%s::roar$TMP%04x%02x", roar_socket_get_local_nodename(), getpid(), count++);
188  } else {
189   return -1;
190  }
191#ifdef ROAR_HAVE_IPV4
192 } else {
193  strncpy(file, inet_ntoa(socket_addr.sin_addr), 79);
194#endif
195 }
196
197 if ( type != ROAR_SOCKET_TYPE_UNIX ) {
198  if ( (listen = roar_socket_listen(type, file, port)) == -1 ) {
199   return -1;
200  }
201 }
202
203 if ( type == ROAR_SOCKET_TYPE_INET ) {
204#ifdef ROAR_HAVE_IPV4
205  len = sizeof(struct sockaddr_in);
206  setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
207
208  if ( getsockname(listen, (struct sockaddr *)&socket_addr, &len) == -1 ) {
209   return -1;
210  }
211  port = ROAR_NET2HOST16(socket_addr.sin_port);
212  ROAR_DBG("roar_simple_new_stream_obj(*): port=%i", port);
213#else
214  return -1;
215#endif
216 } else if ( type == ROAR_SOCKET_TYPE_DECNET ) {
217#ifdef ROAR_HAVE_LIBDNET
218  len = sizeof(struct sockaddr_in);
219  setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
220#else
221  return -1;
222#endif
223 }
224
225 if ( roar_stream_new(s, rate, channels, bits, codec) == -1 ) {
226  return -1;
227 }
228
229 if ( roar_stream_connect(con, s, dir) == -1 ) {
230  return -1;
231 }
232
233 if ( type != ROAR_SOCKET_TYPE_UNIX ) {
234#ifdef ROAR_HAVE_SELECT
235  if ( roar_stream_connect_to_ask(con, s, type, file, port) != -1 ) {
236
237   FD_ZERO(&fds);
238   FD_SET(listen, &fds);
239
240   if ( select(listen + 1, &fds, &fds, &fds, &timeout) < 1 ) {
241    close(listen);
242
243    // we don't need to check the content as we know it failed...
244    if ( roar_recv_message(con, &mes, NULL) == -1 )
245     return -1;
246
247    if ( roar_kick(con, ROAR_OT_STREAM, s->id) == -1 )
248     return -1;
249
250    return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir);
251   }
252
253   if ( (fh = accept(listen, NULL, NULL)) != -1 ) {
254    /* errr, do we need we any error handling here? */
255   }
256   if ( roar_recv_message(con, &mes, NULL) == -1 ) {
257    close(fh);
258    fh = -1;
259   } else if ( mes.cmd != ROAR_CMD_OK ) {
260    close(fh);
261    fh = -1;
262   }
263  }
264
265  close(listen);
266#else
267  return -1;
268#endif
269 } else { // this is type == ROAR_SOCKET_TYPE_UNIX
270#ifdef ROAR_HAVE_UNIX
271  if ( socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1 ) {
272   roar_kick(con, ROAR_OT_STREAM, s->id); // we do not need to check for errors
273                                          // as we return -1 in both whys
274   return -1;
275  }
276
277  if ( roar_stream_passfh(con, s, socks[0]) == -1 ) {
278   roar_kick(con, ROAR_OT_STREAM, s->id); // we do not need to check for errors
279                                          // as we return -1 in both whys
280   return -1;
281  }
282
283  close(socks[0]);
284  fh = socks[1];
285#else
286  roar_kick(con, ROAR_OT_STREAM, s->id);
287  return -1;
288#endif
289 }
290
291/*
292 if ( type == ROAR_SOCKET_TYPE_UNIX ) {
293  unlink(file);
294 }
295*/
296
297 if ( dir == ROAR_DIR_PLAY ) {
298  ROAR_SHUTDOWN(fh, SHUT_RD);
299 } else if ( dir == ROAR_DIR_MONITOR || dir == ROAR_DIR_RECORD ) {
300  ROAR_SHUTDOWN(fh, SHUT_WR);
301 }
302
303 s->fh = fh;
304
305 return fh;
306}
307
308
309int roar_simple_play_file(char * file, char * server, char * name) {
310 struct roar_connection con;
311
312 if ( roar_simple_connect(&con, server, name) == -1 ) {
313  return -1;
314 }
315
316 return roar_file_play(&con, file, 1); // con is closed by this as this stream will be an execed one.
317}
318
319int roar_simple_play(int rate, int channels, int bits, int codec, char * server, char * name) {
320 return roar_simple_stream(rate, channels, bits, codec, server, ROAR_DIR_PLAY, name);
321}
322
323int roar_simple_monitor(int rate, int channels, int bits, int codec, char * server, char * name) {
324 return roar_simple_stream(rate, channels, bits, codec, server, ROAR_DIR_MONITOR, name);
325}
326
327int roar_simple_record(int rate, int channels, int bits, int codec, char * server, char * name) {
328 return roar_simple_stream(rate, channels, bits, codec, server, ROAR_DIR_RECORD, name);
329}
330
331int roar_simple_filter(int rate, int channels, int bits, int codec, char * server, char * name) {
332 return roar_simple_stream(rate, channels, bits, codec, server, ROAR_DIR_FILTER, name);
333}
334
335
336int roar_simple_close(int fh) {
337#ifdef ROAR_HAVE_IO_POSIX
338 return close(fh);
339#else
340 return -1;
341#endif
342}
343
344int roar_simple_get_standby (int fh) {
345 struct roar_connection con;
346
347 if ( roar_connect_fh(&con, fh) == -1 )
348  return -1;
349
350 return roar_get_standby(&con);
351}
352
353//ll
Note: See TracBrowser for help on using the repository browser.