source: roaraudio/libroar/basic.c @ 4653:fb6662ea5f57

Last change on this file since 4653:fb6662ea5f57 was 4653:fb6662ea5f57, checked in by phi, 13 years ago

Support option to disable OpenSLP

File size: 10.1 KB
Line 
1//basic.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2010
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, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38int roar_connect_raw (char * server) {
39 struct roar_libroar_config * config = roar_libroar_get_config();
40 char user_sock[80];
41 char * roar_server;
42 int i = 0;
43 int port = 0;
44 int fh = -1;
45 int is_decnet = 0;
46 char * obj = NULL;
47#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
48 struct passwd * pwd;
49#endif
50#ifdef ROAR_HAVE_LIBDNET
51 struct stat decnet_stat;
52#endif
53#ifdef ROAR_HAVE_LIBX11
54 struct roar_x11_connection * x11con;
55#endif
56
57 roar_errno = ROAR_ERROR_UNKNOWN;
58
59 // load config
60 roar_libroar_get_config();
61
62 if ( server == NULL )
63  server = roar_libroar_get_server();
64
65 if ( server == NULL && (roar_server = getenv("ROAR_SERVER")) != NULL )
66  server = roar_server;
67
68#ifdef ROAR_HAVE_LIBX11
69 if ( server == NULL ) {
70  if ( (x11con = roar_x11_connect(NULL)) != NULL ) {
71   server = roar_x11_get_prop(x11con, "ROAR_SERVER");
72   roar_x11_disconnect(x11con);
73  }
74 }
75#endif
76
77#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
78 if ( server == NULL && (i = readlink("/etc/roarserver", user_sock, 79)) != -1 ) {
79   user_sock[i] = 0;
80   server = user_sock;
81 }
82#endif
83
84 if ( server != NULL && !strcasecmp(server, "+slp") ) {
85  server = roar_slp_find_roard(0);
86  if ( server == NULL ) {
87   return -1;
88  }
89 }
90
91 if ( server == NULL || *server == 0 ) {
92  /* connect via defaults */
93
94#ifdef ROAR_HAVE_UNIX
95#ifndef ROAR_TARGET_MICROCONTROLLER
96  roar_server = getenv("HOME");
97#else
98  roar_server = NULL;
99#endif
100
101  if ( roar_server == NULL ) {
102#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
103   if ( (pwd = getpwuid(getuid())) == NULL ) {
104    roar_server = "/NX-HOME-DIR";
105   } else {
106    roar_server = pwd->pw_dir;
107   }
108#else
109   roar_server = "/WIN32-SUCKS";
110#endif
111  }
112
113  snprintf(user_sock, 79, "%s/%s", roar_server, ROAR_DEFAULT_SOCK_USER);
114
115  if ( (fh = roar_socket_connect(user_sock, 0)) != -1 )
116   return fh;
117
118  if ( (fh = roar_socket_connect(ROAR_DEFAULT_SOCK_GLOBAL, 0)) != -1 )
119   return fh;
120#endif
121
122  if ( (fh = roar_socket_connect(ROAR_DEFAULT_HOST, ROAR_DEFAULT_PORT)) != -1 )
123   return fh;
124
125#ifdef ROAR_HAVE_LIBDNET
126  if ( stat(ROAR_PROC_NET_DECNET, &decnet_stat) == 0 ) {
127   if ( roar_socket_get_local_nodename() ) {
128    snprintf(user_sock, 79, "%s::%s", roar_socket_get_local_nodename(), ROAR_DEFAULT_OBJECT);
129    if ( (fh = roar_socket_connect(user_sock, ROAR_DEFAULT_NUM)) != -1 )
130     return fh;
131   }
132  }
133#endif
134
135  if ( (fh = roar_socket_connect("+abstract", 0)) != -1 )
136   return fh;
137
138#ifdef ROAR_HAVE_LIBSLP
139 if ( !(config->workaround.workarounds & ROAR_LIBROAR_CONFIG_WAS_NO_SLP) ) {
140  if ( (server = roar_slp_find_roard(0)) != NULL )
141   if ( (fh = roar_connect_raw(server)) != -1 )
142    return fh;
143
144  /* in case we can not connect to the server given this may be a cache problem,
145     we do a new lookup with the cache disabled in this case                     */
146  ROAR_WARN("roar_connect_raw(*): Can not connect to SLP located server, disabling cache");
147  if ( (server = roar_slp_find_roard(1)) != NULL )
148   if ( (fh = roar_connect_raw(server)) != -1 )
149    return fh;
150 }
151#endif
152
153 return -1;
154
155 } else {
156  /* connect via (char*)server */
157  // find a port:
158  if ( *server != '/' ) { // don't test AF_UNIX sockets for ports
159   for (i = 0; server[i] != 0; i++) {
160    if ( server[i] == ':' ) {
161     if ( server[i+1] == ':' ) { // DECnet, leave unchanged
162      is_decnet = 1;
163      obj = &server[i+2];
164      break;
165     }
166
167     port = atoi(server+i+1);
168     server[i] = 0;
169     break;
170    }
171   }
172  }
173
174  if ( is_decnet ) {
175    *user_sock = 0;
176   if ( *server == ':' ) {
177    if ( roar_socket_get_local_nodename() )
178     strncat(user_sock, roar_socket_get_local_nodename(), 6);
179   }
180
181   strncat(user_sock, server, 79);
182   server = user_sock;
183   if ( *obj == 0 ) {
184#ifdef DN_MAXOBJL
185    strncat(user_sock, ROAR_DEFAULT_OBJECT, DN_MAXOBJL+2);
186#else
187    ROAR_ERR("roar_connect_raw(*): size of DECnet object unknown.");
188#endif
189   }
190  }
191
192  if ( port || is_decnet ) {
193   fh = roar_socket_connect(server, port);
194   // restore the original string
195   server[i] = ':';
196  } else {
197   fh = roar_socket_connect(server, ROAR_DEFAULT_PORT);
198  }
199 }
200
201 if ( fh == -1 )
202  roar_errno = ROAR_ERROR_CONNREFUSED;
203
204 ROAR_DBG("roar_connect_raw(*) = %i", fh);
205
206 return fh;
207}
208
209int roar_connect    (struct roar_connection * con, char * server) {
210 int fh;
211
212 if ( con == NULL ) {
213  roar_errno = ROAR_ERROR_INVAL;
214  return -1;
215 }
216
217 roar_errno = ROAR_ERROR_UNKNOWN;
218 fh = roar_connect_raw(server);
219
220 if ( fh == -1 )
221  return -1;
222
223 return roar_connect_fh(con, fh);
224}
225
226int roar_connect_fh (struct roar_connection * con, int fh) {
227
228 if ( con == NULL || fh == -1 ) {
229  roar_errno = ROAR_ERROR_INVAL;
230  return -1;
231 }
232
233 // specal hack to set an ilegal value used internaly in libroar:
234 if ( fh == -2 )
235  fh = -1;
236
237 memset(con, 0, sizeof(struct roar_connection));
238
239 con->flags = ROAR_CON_FLAGS_FH;
240 con->__fh  = fh;
241
242 if ( roar_vio_open_fh_socket(&(con->viocon), fh) != -1 )
243  con->flags |= ROAR_CON_FLAGS_VIO;
244
245 roar_errno = ROAR_ERROR_NONE;
246 return 0;
247}
248
249int roar_get_connection_fh (struct roar_connection * con) {
250 roar_debug_warn_sysio("roar_get_connection_fh", "roar_get_connection_vio2", NULL);
251
252 if ( con == NULL )
253  return -1;
254
255 if ( !(con->flags & ROAR_CON_FLAGS_FH) )
256  return -1;
257
258 return con->__fh;
259}
260
261int roar_get_connection_vio (struct roar_connection * con, struct roar_vio_calls * vio) {
262 roar_debug_warn_obsolete("roar_get_connection_vio", "roar_get_connection_vio2", NULL);
263
264 if ( con == NULL || vio == NULL )
265  return -1;
266
267 if ( !(con->flags & ROAR_CON_FLAGS_FH) )
268  return -1;
269
270 return roar_vio_open_fh_socket(vio, con->__fh);
271}
272
273struct roar_vio_calls * roar_get_connection_vio2 (struct roar_connection * con) {
274 if ( con == NULL )
275  return NULL;
276
277 if ( con->flags & ROAR_CON_FLAGS_VIO )
278  return &(con->viocon);
279
280// TODO: try to open the VIO.
281
282 return NULL;
283}
284
285int roar_disconnect (struct roar_connection * con) {
286 struct roar_vio_calls * vio;
287 struct roar_message m;
288
289 memset(&m, 0, sizeof(m));
290
291 m.datalen = 0;
292 m.stream  = 0;
293 m.pos     = 0;
294 m.cmd     = ROAR_CMD_QUIT;
295
296 roar_req(con, &m, NULL);
297
298 if ( (vio = roar_get_connection_vio2(con)) != NULL ) {
299  roar_vio_close(vio);
300 }
301
302 roar_connect_fh(con, -2);
303
304 roar_errno = ROAR_ERROR_NONE;
305
306 return 0;
307}
308
309int roar_set_connection_callback(struct roar_connection * con,
310                                 void (*cb)(struct roar_connection * con,
311                                            struct roar_message    * mes,
312                                            void                   * userdata),
313                                 void * userdata) {
314 if ( con == NULL )
315  return -1;
316
317 con->cb       = cb;
318 con->userdata = userdata;
319
320 return 0;
321}
322
323int roar_sync         (struct roar_connection * con) {
324 // wait for any non-client reqs
325 return roar_wait_msg(con, 0x0000, 0x8000);
326}
327
328int roar_wait_msg     (struct roar_connection * con, int16_t seq, int16_t seqmask) {
329 return -1;
330}
331
332int roar_noop         (struct roar_connection * con) {
333 struct roar_message mes;
334
335 if ( con == NULL ) {
336  return -1;
337 }
338
339 memset(&mes, 0, sizeof(mes));
340
341 mes.cmd = ROAR_CMD_NOOP;
342
343 return roar_req(con, &mes, NULL);
344}
345
346int roar_identify   (struct roar_connection * con, char * name) {
347 struct roar_message mes;
348 pid_t pid;
349 int max_len;
350
351 roar_errno = ROAR_ERROR_UNKNOWN;
352
353 ROAR_DBG("roar_identify(*): try to identify myself...");
354
355 memset(&mes, 0, sizeof(mes));
356
357 mes.cmd    = ROAR_CMD_IDENTIFY;
358 mes.stream = 0;
359 mes.pos    = 0;
360
361 ROAR_DBG("roar_identify(*): name=%p", name);
362
363 if ( name == NULL )
364  name = "libroar client";
365
366 ROAR_DBG("roar_identify(*): name=%p", name);
367
368 max_len = strlen(name);
369 ROAR_DBG("roar_identify(*): strlen(name) = %i", max_len);
370
371 if ( max_len > (LIBROAR_BUFFER_MSGDATA - 5) )
372  max_len = LIBROAR_BUFFER_MSGDATA - 5;
373
374 mes.datalen = 5 + max_len;
375 mes.data[0] = 1;
376
377 pid = getpid();
378 *(uint32_t*)(mes.data+1) = ROAR_HOST2NET32(pid);
379 ROAR_DBG("roar_identify(*): pid = %i", pid);
380
381 strncpy(mes.data+5, name, max_len);
382
383 return roar_req(con, &mes, NULL);
384}
385
386int roar_debug_message_print (struct roar_message * mes) {
387 if ( mes == NULL )
388  return -1;
389
390 ROAR_DBG("roar_debug_message_print(*): Command: %i", mes->cmd);
391 ROAR_DBG("roar_debug_message_print(*): Stream : %u", mes->stream);
392 ROAR_DBG("roar_debug_message_print(*): Pos    : %u", mes->pos);
393 ROAR_DBG("roar_debug_message_print(*): Datalen: %i", mes->datalen);
394
395 ROAR_DBG("roar_debug_message_print(*) = 0");
396 return 0;
397}
398
399int roar_debug_audio_info_print (struct roar_audio_info * info) {
400 if ( info == NULL )
401  return -1;
402
403 ROAR_DBG("roar_debug_audio_info_print(*): Rate    : %i", info->rate);
404 ROAR_DBG("roar_debug_audio_info_print(*): Channels: %i", info->channels);
405 ROAR_DBG("roar_debug_audio_info_print(*): Bits    : %i", info->bits);
406 ROAR_DBG("roar_debug_audio_info_print(*): Codec   : %i", info->codec);
407
408 ROAR_DBG("roar_debug_audio_info_print(*) = 0");
409 return 0;
410}
411
412//ll
Note: See TracBrowser for help on using the repository browser.