source: roaraudio/libroar/basic.c @ 5248:0133acb5ae31

Last change on this file since 5248:0133acb5ae31 was 5240:db409850667a, checked in by phi, 12 years ago

Removed roar_debug_audio_info_print().

File size: 10.8 KB
RevLine 
[0]1//basic.c:
2
[690]3/*
[4708]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2011
[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
[5237]38int roar_connect_raw (const char * server, int flags, uint_least32_t timeout) {
[4780]39#ifdef ROAR_HAVE_LIBSLP
[4653]40 struct roar_libroar_config * config = roar_libroar_get_config();
[4780]41#endif
[5114]42 char user_sock[128];
[0]43 char * roar_server;
[701]44 int i = 0;
[0]45 int port = 0;
46 int fh = -1;
[501]47 int is_decnet = 0;
[5114]48 const char * obj = NULL;
[1475]49#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
[1026]50 struct passwd * pwd;
[1393]51#endif
[828]52#ifdef ROAR_HAVE_LIBDNET
53 struct stat decnet_stat;
54#endif
[3372]55#ifdef ROAR_HAVE_LIBX11
56 struct roar_x11_connection * x11con;
57#endif
[4945]58#ifdef ROAR_HAVE_LIBSLP
[4806]59 struct roar_server * list;
60 int workarounds_store;
[4945]61#endif
[0]62
[4873]63 roar_err_set(ROAR_ERROR_UNKNOWN);
[807]64
[4806]65 if ( timeout != 0 ) {
[4873]66  roar_err_set(ROAR_ERROR_INVAL);
[4806]67  return -1;
68 }
69
70 if ( flags & ROAR_ENUM_FLAG_HARDNONBLOCK )
71  flags |= ROAR_ENUM_FLAG_NONBLOCK;
72
73
[2567]74 if ( server == NULL )
75  server = roar_libroar_get_server();
76
[61]77 if ( server == NULL && (roar_server = getenv("ROAR_SERVER")) != NULL )
[0]78  server = roar_server;
79
[3372]80#ifdef ROAR_HAVE_LIBX11
81 if ( server == NULL ) {
82  if ( (x11con = roar_x11_connect(NULL)) != NULL ) {
83   server = roar_x11_get_prop(x11con, "ROAR_SERVER");
84   roar_x11_disconnect(x11con);
85  }
86 }
87#endif
88
[1436]89#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
[5114]90 if ( server == NULL && (i = readlink("/etc/roarserver", user_sock, sizeof(user_sock)-1)) != -1 ) {
[448]91   user_sock[i] = 0;
92   server = user_sock;
93 }
[1093]94#endif
[448]95
[3077]96 if ( server != NULL && !strcasecmp(server, "+slp") ) {
[3076]97  server = roar_slp_find_roard(0);
98  if ( server == NULL ) {
99   return -1;
100  }
101 }
102
[61]103 if ( server == NULL || *server == 0 ) {
[0]104  /* connect via defaults */
105
[1764]106#ifdef ROAR_HAVE_UNIX
[1436]107#ifndef ROAR_TARGET_MICROCONTROLLER
[1026]108  roar_server = getenv("HOME");
[1435]109#else
110  roar_server = NULL;
111#endif
[1026]112
113  if ( roar_server == NULL ) {
[1436]114#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
[1026]115   if ( (pwd = getpwuid(getuid())) == NULL ) {
116    roar_server = "/NX-HOME-DIR";
117   } else {
118    roar_server = pwd->pw_dir;
119   }
[1078]120#else
121   roar_server = "/WIN32-SUCKS";
122#endif
[1026]123  }
124
[5114]125  snprintf(user_sock, sizeof(user_sock)-1, "%s/%s", roar_server, ROAR_DEFAULT_SOCK_USER);
126  user_sock[sizeof(user_sock)-1] = 0;
[0]127
128  if ( (fh = roar_socket_connect(user_sock, 0)) != -1 )
129   return fh;
130
[237]131  if ( (fh = roar_socket_connect(ROAR_DEFAULT_SOCK_GLOBAL, 0)) != -1 )
132   return fh;
[1764]133#endif
[237]134
[0]135  if ( (fh = roar_socket_connect(ROAR_DEFAULT_HOST, ROAR_DEFAULT_PORT)) != -1 )
136   return fh;
137
[828]138#ifdef ROAR_HAVE_LIBDNET
139  if ( stat(ROAR_PROC_NET_DECNET, &decnet_stat) == 0 ) {
140   if ( roar_socket_get_local_nodename() ) {
141    snprintf(user_sock, 79, "%s::%s", roar_socket_get_local_nodename(), ROAR_DEFAULT_OBJECT);
[2010]142    if ( (fh = roar_socket_connect(user_sock, ROAR_DEFAULT_NUM)) != -1 )
143     return fh;
[828]144   }
[522]145  }
[828]146#endif
[2007]147
[4109]148  if ( (fh = roar_socket_connect("+abstract", 0)) != -1 )
149   return fh;
150
[2007]151#ifdef ROAR_HAVE_LIBSLP
[4806]152 if ( !(config->workaround.workarounds & ROAR_LIBROAR_CONFIG_WAS_NO_SLP) &&
153      !(flags & ROAR_ENUM_FLAG_NONBLOCK)
154    ) {
155  if ( (server = roar_slp_find_roard(0)) != NULL ) {
[5237]156   if ( (fh = roar_connect_raw(server, 0, 0)) != -1 )
[4653]157    return fh;
[2014]158
[4806]159   /* in case we can not connect to the server given this may be a cache problem,
160      we do a new lookup with the cache disabled in this case                     */
[5237]161   ROAR_WARN("roar_connect_raw(*): Can not connect to SLP located server, disabling cache");
[4806]162   if ( (server = roar_slp_find_roard(1)) != NULL )
[5237]163    if ( (fh = roar_connect_raw(server, 0, 0)) != -1 )
[4806]164     return fh;
165  }
166 }
167
168 workarounds_store = config->workaround.workarounds;
169 config->workaround.workarounds |= ROAR_LIBROAR_CONFIG_WAS_NO_SLP;
170 list = roar_enum_servers(flags, -1, -1);
171 config->workaround.workarounds = workarounds_store;
172 if ( list != NULL ) {
173  for (i = 0; list[i].server != NULL; i++) {
[5237]174   if ( (fh = roar_connect_raw((char*)list[i].server, 0, 0)) != -1 ) {
[4806]175    roar_enum_servers_free(list);
[4653]176    return fh;
[4806]177   }
178  }
179  roar_enum_servers_free(list);
[4653]180 }
[2007]181#endif
[522]182
[2014]183 return -1;
184
[0]185 } else {
186  /* connect via (char*)server */
[501]187  // find a port:
[5114]188
[5185]189  if ( !strcmp(server, "+invalid") ) {
190   roar_err_set(ROAR_ERROR_CANCELED);
191   return -1;
192  }
193
[5120]194  strncpy(user_sock, server, sizeof(user_sock)-1);
[5114]195  user_sock[sizeof(user_sock)-1] = 0;
196
197  if ( *user_sock != '/' ) { // don't test AF_UNIX sockets for ports
198   for (i = 0; user_sock[i] != 0; i++) {
199    if ( user_sock[i] == ':' ) {
200     if ( user_sock[i+1] == ':' ) { // DECnet, leave unchanged
[501]201      is_decnet = 1;
[5114]202      obj = &user_sock[i+2];
[501]203      break;
204     }
205
[5114]206     port = atoi(&(user_sock[i+1]));
207     user_sock[i] = 0;
[501]208     break;
209    }
[0]210   }
211  }
212
[521]213  if ( is_decnet ) {
[5114]214   if ( *user_sock == ':' ) {
[5120]215    if ( roar_socket_get_local_nodename() != NULL ) {
216     strncpy(user_sock, roar_socket_get_local_nodename(), sizeof(user_sock)-1);
[5114]217     user_sock[sizeof(user_sock)-1] = 0;
[5120]218     roar_mm_strlcat(user_sock, server, sizeof(user_sock)-1);
219     user_sock[sizeof(user_sock)-1] = 0;
220     obj  = strstr(user_sock, "::");
221     obj += 2;
222    }
[521]223   }
224
225   if ( *obj == 0 ) {
[1066]226#ifdef DN_MAXOBJL
[5114]227    roar_mm_strlcat(user_sock, ROAR_DEFAULT_OBJECT, sizeof(user_sock)-1);
228    user_sock[sizeof(user_sock)-1] = 0;
[1066]229#else
[5237]230    ROAR_ERR("roar_connect_raw(*): size of DECnet object unknown.");
[1066]231#endif
[521]232   }
[5237]233    ROAR_DBG("roar_connect_raw(*): user_sock='%s'", user_sock);
[516]234  }
235
[501]236  if ( port || is_decnet ) {
[5114]237   fh = roar_socket_connect(user_sock, port);
[0]238   // restore the original string
[5114]239   user_sock[i] = ':';
[0]240  } else {
[5114]241   fh = roar_socket_connect(user_sock, ROAR_DEFAULT_PORT);
[0]242  }
243 }
244
[5237]245 ROAR_DBG("roar_connect_raw(*) = %i", fh);
[0]246
247 return fh;
248}
249
[5237]250int roar_connect     (struct roar_connection * con, const char * server, int flags, uint_least32_t timeout) {
[1315]251 int fh;
252
253 if ( con == NULL ) {
[4873]254  roar_err_set(ROAR_ERROR_FAULT);
[1315]255  return -1;
256 }
257
[4873]258 roar_err_set(ROAR_ERROR_UNKNOWN);
[5237]259 fh = roar_connect_raw(server, flags, timeout);
[0]260
[1315]261 if ( fh == -1 )
[0]262  return -1;
263
[1315]264 return roar_connect_fh(con, fh);
265}
266
267int roar_connect_fh (struct roar_connection * con, int fh) {
268
269 if ( con == NULL || fh == -1 ) {
[4873]270  roar_err_set(ROAR_ERROR_INVAL);
[1315]271  return -1;
272 }
273
274 // specal hack to set an ilegal value used internaly in libroar:
275 if ( fh == -2 )
276  fh = -1;
277
278 memset(con, 0, sizeof(struct roar_connection));
[5232]279 con->refc        = 0;
280 con->flags       = ROAR_CON_FLAGS_NONE;
281 con->version     = 0;
282 con->cb_userdata = NULL;
283 con->cb          = NULL;
284
285 roar_err_init(&(con->errorframe));
[1315]286
[5231]287 if ( roar_vio_open_fh_socket(&(con->viocon), fh) != -1 ) {
[3869]288  con->flags |= ROAR_CON_FLAGS_VIO;
[5231]289 }
[1315]290
[4873]291 roar_err_set(ROAR_ERROR_NONE);
[0]292 return 0;
293}
294
[1660]295int roar_get_connection_fh (struct roar_connection * con) {
[5231]296 int fh;
297
298 ROAR_DBG("roar_get_connection_fh(con=%p) = ?", con);
299
[3869]300 roar_debug_warn_sysio("roar_get_connection_fh", "roar_get_connection_vio2", NULL);
[2809]301
[2043]302 if ( con == NULL )
303  return -1;
304
[5231]305 ROAR_DBG("roar_get_connection_fh(con=%p) = ?", con);
306
307 if ( roar_vio_ctl(&(con->viocon), ROAR_VIO_CTL_GET_FH, &fh) == -1 )
[3869]308  return -1;
309
[5231]310 ROAR_DBG("roar_get_connection_fh(con=%p) = %i", con, fh);
[3869]311
[5231]312 return fh;
[2043]313}
314
[3869]315struct roar_vio_calls * roar_get_connection_vio2 (struct roar_connection * con) {
316 if ( con == NULL )
317  return NULL;
318
319 if ( con->flags & ROAR_CON_FLAGS_VIO )
320  return &(con->viocon);
321
322// TODO: try to open the VIO.
323
324 return NULL;
325}
326
[0]327int roar_disconnect (struct roar_connection * con) {
[3869]328 struct roar_vio_calls * vio;
[0]329 struct roar_message m;
330
[3875]331 memset(&m, 0, sizeof(m));
332
[5144]333 m.datalen =  0;
334 m.stream  = -1;
335 m.pos     =  0;
[0]336 m.cmd     = ROAR_CMD_QUIT;
337
338 roar_req(con, &m, NULL);
339
[3869]340 if ( (vio = roar_get_connection_vio2(con)) != NULL ) {
341  roar_vio_close(vio);
[2809]342 }
[0]343
[1660]344 roar_connect_fh(con, -2);
[0]345
[4873]346 roar_err_set(ROAR_ERROR_NONE);
[807]347
[0]348 return 0;
349}
350
[3913]351int roar_set_connection_callback(struct roar_connection * con,
352                                 void (*cb)(struct roar_connection * con,
353                                            struct roar_message    * mes,
[5231]354                                            void                   * data,
[3913]355                                            void                   * userdata),
356                                 void * userdata) {
357 if ( con == NULL )
358  return -1;
359
360 con->cb       = cb;
[5231]361 con->cb_userdata = userdata;
[3913]362
363 return 0;
364}
365
[3914]366int roar_sync         (struct roar_connection * con) {
367 // wait for any non-client reqs
368 return roar_wait_msg(con, 0x0000, 0x8000);
369}
370
371int roar_wait_msg     (struct roar_connection * con, int16_t seq, int16_t seqmask) {
[5148]372 roar_err_set(ROAR_ERROR_NOSYS);
[3914]373 return -1;
374}
[3913]375
[3836]376int roar_noop         (struct roar_connection * con) {
377 struct roar_message mes;
378
379 if ( con == NULL ) {
[5148]380  roar_err_set(ROAR_ERROR_FAULT);
[3836]381  return -1;
382 }
383
384 memset(&mes, 0, sizeof(mes));
385
386 mes.cmd = ROAR_CMD_NOOP;
[5144]387 mes.stream = -1;
[3836]388
[5146]389 return roar_req3(con, &mes, NULL);
[3836]390}
391
[5114]392int roar_identify   (struct roar_connection * con, const char * name) {
[0]393 struct roar_message mes;
[5132]394 uint32_t pid;
[0]395 int max_len;
396
[4873]397 roar_err_set(ROAR_ERROR_UNKNOWN);
[807]398
[0]399 ROAR_DBG("roar_identify(*): try to identify myself...");
400
[3875]401 memset(&mes, 0, sizeof(mes));
402
[0]403 mes.cmd    = ROAR_CMD_IDENTIFY;
[5144]404 mes.stream = -1;
405 mes.pos    =  0;
[0]406
407 ROAR_DBG("roar_identify(*): name=%p", name);
408
409 if ( name == NULL )
410  name = "libroar client";
411
412 ROAR_DBG("roar_identify(*): name=%p", name);
413
[5114]414 max_len = roar_mm_strlen(name);
[0]415 ROAR_DBG("roar_identify(*): strlen(name) = %i", max_len);
416
417 if ( max_len > (LIBROAR_BUFFER_MSGDATA - 5) )
418  max_len = LIBROAR_BUFFER_MSGDATA - 5;
419
420 mes.datalen = 5 + max_len;
421 mes.data[0] = 1;
422
423 pid = getpid();
[5132]424 mes.data[1] = (pid & 0xFF000000UL) >> 24;
425 mes.data[2] = (pid & 0x00FF0000UL) >> 16;
426 mes.data[3] = (pid & 0x0000FF00UL) >>  8;
427 mes.data[4] = (pid & 0x000000FFUL) >>  0;
428 ROAR_DBG("roar_identify(*): pid = %i", (int)pid);
[0]429
430 strncpy(mes.data+5, name, max_len);
431
[5146]432 return roar_req3(con, &mes, NULL);
[0]433}
434
435//ll
Note: See TracBrowser for help on using the repository browser.