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
RevLine 
[0]1//basic.c:
2
[690]3/*
[3372]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2010
[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
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[690]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
[0]36#include "libroar.h"
37
38int roar_connect_raw (char * server) {
[4653]39 struct roar_libroar_config * config = roar_libroar_get_config();
[0]40 char user_sock[80];
41 char * roar_server;
[701]42 int i = 0;
[0]43 int port = 0;
44 int fh = -1;
[501]45 int is_decnet = 0;
[516]46 char * obj = NULL;
[1475]47#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
[1026]48 struct passwd * pwd;
[1393]49#endif
[828]50#ifdef ROAR_HAVE_LIBDNET
51 struct stat decnet_stat;
52#endif
[3372]53#ifdef ROAR_HAVE_LIBX11
54 struct roar_x11_connection * x11con;
55#endif
[0]56
[807]57 roar_errno = ROAR_ERROR_UNKNOWN;
58
[2897]59 // load config
60 roar_libroar_get_config();
61
[2567]62 if ( server == NULL )
63  server = roar_libroar_get_server();
64
[61]65 if ( server == NULL && (roar_server = getenv("ROAR_SERVER")) != NULL )
[0]66  server = roar_server;
67
[3372]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
[1436]77#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
[448]78 if ( server == NULL && (i = readlink("/etc/roarserver", user_sock, 79)) != -1 ) {
79   user_sock[i] = 0;
80   server = user_sock;
81 }
[1093]82#endif
[448]83
[3077]84 if ( server != NULL && !strcasecmp(server, "+slp") ) {
[3076]85  server = roar_slp_find_roard(0);
86  if ( server == NULL ) {
87   return -1;
88  }
89 }
90
[61]91 if ( server == NULL || *server == 0 ) {
[0]92  /* connect via defaults */
93
[1764]94#ifdef ROAR_HAVE_UNIX
[1436]95#ifndef ROAR_TARGET_MICROCONTROLLER
[1026]96  roar_server = getenv("HOME");
[1435]97#else
98  roar_server = NULL;
99#endif
[1026]100
101  if ( roar_server == NULL ) {
[1436]102#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
[1026]103   if ( (pwd = getpwuid(getuid())) == NULL ) {
104    roar_server = "/NX-HOME-DIR";
105   } else {
106    roar_server = pwd->pw_dir;
107   }
[1078]108#else
109   roar_server = "/WIN32-SUCKS";
110#endif
[1026]111  }
112
113  snprintf(user_sock, 79, "%s/%s", roar_server, ROAR_DEFAULT_SOCK_USER);
[0]114
115  if ( (fh = roar_socket_connect(user_sock, 0)) != -1 )
116   return fh;
117
[237]118  if ( (fh = roar_socket_connect(ROAR_DEFAULT_SOCK_GLOBAL, 0)) != -1 )
119   return fh;
[1764]120#endif
[237]121
[0]122  if ( (fh = roar_socket_connect(ROAR_DEFAULT_HOST, ROAR_DEFAULT_PORT)) != -1 )
123   return fh;
124
[828]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);
[2010]129    if ( (fh = roar_socket_connect(user_sock, ROAR_DEFAULT_NUM)) != -1 )
130     return fh;
[828]131   }
[522]132  }
[828]133#endif
[2007]134
[4109]135  if ( (fh = roar_socket_connect("+abstract", 0)) != -1 )
136   return fh;
137
[2007]138#ifdef ROAR_HAVE_LIBSLP
[4653]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;
[2014]143
[4653]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 }
[2007]151#endif
[522]152
[2014]153 return -1;
154
[0]155 } else {
156  /* connect via (char*)server */
[501]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;
[516]163      obj = &server[i+2];
[501]164      break;
165     }
166
167     port = atoi(server+i+1);
168     server[i] = 0;
169     break;
170    }
[0]171   }
172  }
173
[521]174  if ( is_decnet ) {
175    *user_sock = 0;
176   if ( *server == ':' ) {
177    if ( roar_socket_get_local_nodename() )
[1066]178     strncat(user_sock, roar_socket_get_local_nodename(), 6);
[521]179   }
180
[1066]181   strncat(user_sock, server, 79);
[516]182   server = user_sock;
[521]183   if ( *obj == 0 ) {
[1066]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
[521]189   }
[516]190  }
191
[501]192  if ( port || is_decnet ) {
[0]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
[807]201 if ( fh == -1 )
202  roar_errno = ROAR_ERROR_CONNREFUSED;
203
[0]204 ROAR_DBG("roar_connect_raw(*) = %i", fh);
205
206 return fh;
207}
208
209int roar_connect    (struct roar_connection * con, char * server) {
[1315]210 int fh;
211
212 if ( con == NULL ) {
213  roar_errno = ROAR_ERROR_INVAL;
214  return -1;
215 }
216
[807]217 roar_errno = ROAR_ERROR_UNKNOWN;
[1315]218 fh = roar_connect_raw(server);
[0]219
[1315]220 if ( fh == -1 )
[0]221  return -1;
222
[1315]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
[3869]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;
[1315]244
[807]245 roar_errno = ROAR_ERROR_NONE;
[0]246 return 0;
247}
248
[1660]249int roar_get_connection_fh (struct roar_connection * con) {
[3869]250 roar_debug_warn_sysio("roar_get_connection_fh", "roar_get_connection_vio2", NULL);
[2809]251
[2043]252 if ( con == NULL )
253  return -1;
254
[3869]255 if ( !(con->flags & ROAR_CON_FLAGS_FH) )
256  return -1;
257
[1660]258 return con->__fh;
259}
260
[2043]261int roar_get_connection_vio (struct roar_connection * con, struct roar_vio_calls * vio) {
[3869]262 roar_debug_warn_obsolete("roar_get_connection_vio", "roar_get_connection_vio2", NULL);
263
[2043]264 if ( con == NULL || vio == NULL )
265  return -1;
266
[3869]267 if ( !(con->flags & ROAR_CON_FLAGS_FH) )
268  return -1;
269
[2809]270 return roar_vio_open_fh_socket(vio, con->__fh);
[2043]271}
272
[3869]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
[0]285int roar_disconnect (struct roar_connection * con) {
[3869]286 struct roar_vio_calls * vio;
[0]287 struct roar_message m;
288
[3875]289 memset(&m, 0, sizeof(m));
290
[0]291 m.datalen = 0;
292 m.stream  = 0;
[133]293 m.pos     = 0;
[0]294 m.cmd     = ROAR_CMD_QUIT;
295
296 roar_req(con, &m, NULL);
297
[3869]298 if ( (vio = roar_get_connection_vio2(con)) != NULL ) {
299  roar_vio_close(vio);
[2809]300 }
[0]301
[1660]302 roar_connect_fh(con, -2);
[0]303
[807]304 roar_errno = ROAR_ERROR_NONE;
305
[0]306 return 0;
307}
308
[3913]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
[3914]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}
[3913]331
[3836]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
[0]346int roar_identify   (struct roar_connection * con, char * name) {
347 struct roar_message mes;
348 pid_t pid;
349 int max_len;
350
[807]351 roar_errno = ROAR_ERROR_UNKNOWN;
352
[0]353 ROAR_DBG("roar_identify(*): try to identify myself...");
354
[3875]355 memset(&mes, 0, sizeof(mes));
356
[0]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.