source: roaraudio/libroar/simple.c @ 1762:0861ce6933cb

Last change on this file since 1762:0861ce6933cb 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
RevLine 
[0]1//simple.c:
2
[690]3/*
[1187]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008, 2009
[690]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
[0]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) {
[1158]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) {
[0]66 struct roar_connection con;
[1660]67 int ret;
[0]68
69 if ( roar_simple_connect(&con, server, name) == -1 ) {
70  ROAR_DBG("roar_simple_play(*): roar_simple_connect() faild!");
[1094]71  ROAR_ERR("roar_simple_stream(*): Can not connect to server");
[0]72  return -1;
73 }
74
[1158]75 if ( roar_stream_new(s, rate, channels, bits, codec) == -1 ) {
[0]76  roar_disconnect(&con);
77  return -1;
78 }
79
[1158]80 if ( roar_stream_connect(&con, s, dir) == -1 ) {
[0]81  roar_disconnect(&con);
82  return -1;
83 }
84
[1158]85 if ( roar_stream_exec(&con, s) == -1 ) {
[0]86  roar_disconnect(&con);
87  return -1;
88 }
89
[1660]90 if ( (ret = roar_get_connection_fh(&con)) == -1 ) {
91  roar_disconnect(&con);
92  return -1;
[54]93 }
94
[1660]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;
[0]102}
103
[1163]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
[1476]107 if ( (fh = roar_simple_stream_obj(s, rate, channels, bits, codec, NULL /* server, we hope this is ok here... */,
[1163]108                                   dir, "libroar temp stream")) == -1 )
109  return -1;
110
111 if ( roar_stream_attach_simple(con, s, roar_get_clientid(con)) == -1 ) {
[1476]112#ifdef ROAR_HAVE_IO_POSIX
[1163]113  close(fh);
[1476]114#endif /* no else as we return -1 anyway */
[1163]115  return -1;
116 }
117
[1166]118 s->fh = fh;
119
[1163]120 return fh;
121}
122
[82]123int roar_simple_new_stream (struct roar_connection * con, int rate, int channels, int bits, int codec, int dir) {
124 struct roar_stream     s;
[119]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) {
[1168]129 char file[80] = {0};
130 int fh = -1, listen = -1;
[82]131 static int count = 0;
[487]132 int    type = ROAR_SOCKET_TYPE_UNIX;
133 int    port = 0;
[1396]134#if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_LIBDNET)
[493]135 int    opt  = 1;
[1396]136#endif
[1466]137#ifdef ROAR_HAVE_IPV4
[487]138 struct sockaddr_in   socket_addr;
139 socklen_t            len            = sizeof(struct sockaddr_in);
[1466]140#else
141 struct sockaddr      socket_addr;
142 socklen_t            len            = sizeof(struct sockaddr);
143#endif
[1465]144#ifdef ROAR_HAVE_SELECT
[1161]145 fd_set fds;
146 struct timeval timeout = {10, 0};
[1465]147 struct roar_message    mes;
148#endif
[1396]149#ifdef ROAR_HAVE_UNIX
[1168]150 int socks[2]; // for socketpair()
[1396]151#endif
[82]152
[1476]153#ifdef ROAR_HAVE_BSDSOCKETS
[1660]154 if ( getsockname(roar_get_connection_fh(con), (struct sockaddr *)&socket_addr, &len) == -1 ) {
[82]155  return -1;
156 }
[1476]157#else
158 return -1;
159#endif
[82]160
[1178]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");
[1466]164  ((struct sockaddr*)&socket_addr)->sa_family = AF_UNIX;
[1178]165#else
[505]166  return -1;
[1178]167#endif
168 }
169
[1466]170 switch (((struct sockaddr*)&socket_addr)->sa_family) {
[1359]171#ifdef ROAR_HAVE_UNIX
[1178]172  case AF_UNIX:   type = ROAR_SOCKET_TYPE_UNIX; break;
[1359]173#endif
174#ifdef ROAR_HAVE_IPV4
[1178]175  case AF_INET:   type = ROAR_SOCKET_TYPE_INET; break;
[1359]176#endif
177#ifdef ROAR_HAVE_LIBDNET
[1178]178  case AF_DECnet: type = ROAR_SOCKET_TYPE_DECNET; break;
[1359]179#endif
[1178]180  default:
181    return -1;
182   break;
[487]183 }
184
[1187]185 if ( type == ROAR_SOCKET_TYPE_DECNET ) {
[526]186  if ( roar_socket_get_local_nodename() ) {
[1067]187   snprintf(file, 24,"%s::roar$TMP%04x%02x", roar_socket_get_local_nodename(), getpid(), count++);
[526]188  } else {
189   return -1;
190  }
[1380]191#ifdef ROAR_HAVE_IPV4
[487]192 } else {
[1068]193  strncpy(file, inet_ntoa(socket_addr.sin_addr), 79);
[1380]194#endif
[487]195 }
196
[1168]197 if ( type != ROAR_SOCKET_TYPE_UNIX ) {
198  if ( (listen = roar_socket_listen(type, file, port)) == -1 ) {
199   return -1;
200  }
[487]201 }
[451]202
[487]203 if ( type == ROAR_SOCKET_TYPE_INET ) {
[1380]204#ifdef ROAR_HAVE_IPV4
[487]205  len = sizeof(struct sockaddr_in);
[493]206  setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
207
[487]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);
[1380]213#else
214  return -1;
215#endif
[532]216 } else if ( type == ROAR_SOCKET_TYPE_DECNET ) {
[1395]217#ifdef ROAR_HAVE_LIBDNET
[532]218  len = sizeof(struct sockaddr_in);
219  setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
[1395]220#else
221  return -1;
222#endif
[487]223 }
[451]224
[119]225 if ( roar_stream_new(s, rate, channels, bits, codec) == -1 ) {
[82]226  return -1;
227 }
228
[119]229 if ( roar_stream_connect(con, s, dir) == -1 ) {
[82]230  return -1;
231 }
232
[1168]233 if ( type != ROAR_SOCKET_TYPE_UNIX ) {
[1465]234#ifdef ROAR_HAVE_SELECT
[1168]235  if ( roar_stream_connect_to_ask(con, s, type, file, port) != -1 ) {
[1161]236
[1168]237   FD_ZERO(&fds);
238   FD_SET(listen, &fds);
[1163]239
[1168]240   if ( select(listen + 1, &fds, &fds, &fds, &timeout) < 1 ) {
241    close(listen);
[1163]242
[1168]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;
[1161]246
[1168]247    if ( roar_kick(con, ROAR_OT_STREAM, s->id) == -1 )
248     return -1;
[1161]249
[1168]250    return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir);
[82]251   }
[1168]252
253   if ( (fh = accept(listen, NULL, NULL)) != -1 ) {
254    /* errr, do we need we any error handling here? */
255   }
[82]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   }
[1168]263  }
264
265  close(listen);
[1465]266#else
267  return -1;
268#endif
[1168]269 } else { // this is type == ROAR_SOCKET_TYPE_UNIX
[1395]270#ifdef ROAR_HAVE_UNIX
[1168]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];
[1395]285#else
286  roar_kick(con, ROAR_OT_STREAM, s->id);
287  return -1;
288#endif
[82]289 }
290
[1168]291/*
[487]292 if ( type == ROAR_SOCKET_TYPE_UNIX ) {
293  unlink(file);
294 }
[1168]295*/
296
297 if ( dir == ROAR_DIR_PLAY ) {
[1470]298  ROAR_SHUTDOWN(fh, SHUT_RD);
[1168]299 } else if ( dir == ROAR_DIR_MONITOR || dir == ROAR_DIR_RECORD ) {
[1470]300  ROAR_SHUTDOWN(fh, SHUT_WR);
[1168]301 }
[82]302
[505]303 s->fh = fh;
304
[82]305 return fh;
306}
307
[235]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
[0]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) {
[1476]337#ifdef ROAR_HAVE_IO_POSIX
[0]338 return close(fh);
[1476]339#else
340 return -1;
341#endif
[0]342}
343
344int roar_simple_get_standby (int fh) {
345 struct roar_connection con;
346
[1660]347 if ( roar_connect_fh(&con, fh) == -1 )
348  return -1;
[0]349
350 return roar_get_standby(&con);
351}
352
353//ll
Note: See TracBrowser for help on using the repository browser.