Logo Search packages:      
Sourcecode: ladcca version File versions

ladcca.c

/*
 *   LADCCA
 *    
 *   Copyright (C) 2002, 2003 Robert Ham <rah@bash.sh>
 *    
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netdb.h>
extern int h_errno;
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/param.h>                     

#include <ladcca/ladcca.h>
#include <ladcca/internal_headers.h>

cca_args_t *
cca_extract_args (int * argc, char *** argv)
{
  int i, j, valid_count;
  cca_args_t * args;
  
  args = cca_args_new ();
  
  for (i = 1; i < *argc; ++i)
    {
      if (strncasecmp ("--ladcca-server=", (*argv)[i], 16) == 0)
        {
          CCA_DEBUGARGS ("setting server from command line: '%s'", (*argv)[i] + 16);
          cca_args_set_server (args, (*argv)[i] + 16);
          (*argv)[i] = NULL;
          continue;
        }

      if (strncasecmp ("--ladcca-project=", (*argv)[i], 17) == 0)
        {
          CCA_DEBUGARGS ("setting project from command line: '%s'", (*argv)[i] + 17);
          cca_args_set_project (args, (*argv)[i] + 17);
          (*argv)[i] = NULL;
          continue;
        }
        
      if (strncmp ("--ladcca-id=", (*argv)[i], 12) == 0)
        {
          uuid_t id;
          
          CCA_DEBUGARGS ("setting id from command line: '%s'", (*argv)[i] + 12);
          
          j = uuid_parse ((*argv)[i] + 12, id);
          
          CCA_DEBUG ("id parsed");
          
          (*argv)[i] = NULL;
          
          if (j == -1)
            {
              fprintf(stderr, "%s: ERROR PARSING ID FROM COMMAND LINE!  THIS IS BAD!\n", __FUNCTION__);
            }
          else
            {
              cca_args_set_id (args, id);
            }
          continue;
        }

      if (strncmp ("--ladcca-no-autoresume", (*argv)[i], 22) == 0)
        {
          CCA_DEBUG ("setting CCA_No_Autoresume flag from command line");
          
          cca_args_set_flag (args, CCA_No_Autoresume);
          
          (*argv)[i] = NULL;
          
          continue;
        }
    }
    
  CCA_DEBUG ("args checked");
  
  /* sort out the argv pointers */
  valid_count = *argc;
  for (i = 1; i < valid_count; ++i)
    {
      CCA_DEBUGARGS ("checking argv[%d]", i);
      if ((*argv)[i] == NULL)
        {
          
          for (j = i; j < *argc - 1; ++j)
            (*argv)[j] = (*argv)[j + 1];
            
          valid_count--;
          i--;
        }
    }

  CCA_DEBUG ("done");
  
  *argc = valid_count;
  
  cca_args_set_args (args, *argc, (const char * const *) *argv);
  
  return args;
}

cca_client_t *
cca_init (cca_args_t *args,
          const char *class,
          int client_flags,
          cca_protocol_t protocol)
{
  cca_connect_params_t *connect_params;
  cca_client_t *client;
  int err;
  char *str;
  const char *cstr;
  char wd[MAXPATHLEN];
  
  client = cca_client_new ();
  connect_params = cca_connect_params_new ();

  client->args = args;
  client->args->flags |= client_flags;
  cca_client_set_class (client, class);
  
  str = getcwd (wd, MAXPATHLEN);
  if (!str)
    {
      fprintf (stderr, "%s: could not get current working directory: %s\n",
               __FUNCTION__, strerror (errno));
      str = getenv ("PWD");
      if (str)
        cca_connect_params_set_working_dir (connect_params, str);
      else
        cca_connect_params_set_working_dir (connect_params, getenv ("HOME"));
    }
  else
    {
      cca_connect_params_set_working_dir (connect_params, str);
    }

  CCA_DEBUGARGS ("protocol version for connect: %s", cca_protocol_string (protocol));
  connect_params->protocol_version = protocol;
  connect_params->flags = args->flags;
  cca_connect_params_set_project (connect_params, args->project);
  cca_connect_params_set_class   (connect_params, class);
  uuid_copy (connect_params->id, args->id);
  connect_params->argc = args->argc;
  connect_params->argv = args->argv;
  
  
  /* try and connect to the server */
  CCA_DEBUG ("connecting to server");
  cstr = cca_args_get_server (args);
  err = cca_comm_connect_to_server (client,
                                    cstr ? cstr : "localhost",
                            "ladcca",
                                    connect_params);
  if (err)
    err = cca_comm_connect_to_server (client,
                              cstr ? cstr : "localhost",
                              LADCCA_PORT,
                              connect_params);
  cca_connect_params_destroy (connect_params);
  if (err)
    {
      fprintf (stderr, "%s: could not connect to server '%s' - disabling ladcca\n",
               __FUNCTION__, cstr ? cstr : "localhost");
      cca_client_destroy (client);
      return NULL;
    }
  CCA_DEBUG ("connected to server");
  client->server_connected = 1;
  
  err = pthread_create (&client->recv_thread, NULL, cca_comm_recv_run, client);
  if (err)
    {
      fprintf (stderr, "%s: error creating recieve thread - disabling ladcca: %s\n",
               __FUNCTION__, strerror (err));
               
      cca_client_destroy (client);
      return NULL;
    }

  err = pthread_create (&client->send_thread, NULL, cca_comm_send_run, client);
  if (err)
    {
      fprintf (stderr, "%s: error creating send thread - disabling ladcca: %s\n",
               __FUNCTION__, strerror (err));
      
      client->recv_close = 1;
      pthread_join (client->recv_thread, NULL);
               
      cca_client_destroy (client);
      return NULL;
    }
  
  return client;
}

unsigned int
cca_get_pending_event_count (cca_client_t * client)
{
  unsigned int count;
  
  if (!client)
    return 0;
  
  pthread_mutex_lock (&client->events_in_lock);
  
  if (client->events_in)
    count = cca_list_length (client->events_in);
    
  pthread_mutex_unlock (&client->events_in_lock);
  
  return count;
}

unsigned int
cca_get_pending_config_count (cca_client_t * client)
{
  unsigned int count;
  
  if (!cca_enabled (client))
    return 0;
  
  pthread_mutex_lock (&client->configs_in_lock);
  
  if (client->events_in)
    count = cca_list_length (client->configs_in);
    
  pthread_mutex_unlock (&client->configs_in_lock);
  
  return count;
}

cca_event_t *
cca_get_event (cca_client_t * client)
{
  cca_event_t * event = NULL;
  
  if (!client)
    return NULL;
  
  pthread_mutex_lock (&client->events_in_lock);
  
  if (client->events_in)
    {
      event = (cca_event_t *) client->events_in->data;
      client->events_in =
        cca_list_remove (client->events_in, event);
    }
    
  pthread_mutex_unlock (&client->events_in_lock);
  
  return event;
}

cca_config_t *
cca_get_config (cca_client_t * client)
{
  cca_config_t * config = NULL;
  
  if (!client)
    return NULL;
  
  pthread_mutex_lock (&client->configs_in_lock);
  
  if (client->configs_in)
    {
      config = (cca_config_t *) client->configs_in->data;
      client->configs_in =
        cca_list_remove (client->configs_in, config);
    }
    
  pthread_mutex_unlock (&client->configs_in_lock);
  
  return config;
}

void
cca_send_comm_event (cca_client_t * client, cca_comm_event_t * event)
{
  pthread_mutex_lock (&client->comm_events_out_lock);
  client->comm_events_out = cca_list_append (client->comm_events_out, event);
  pthread_mutex_unlock (&client->comm_events_out_lock);
  pthread_cond_signal (&client->send_conditional);
}

void
cca_send_event (cca_client_t * client, cca_event_t * event)
{
  cca_comm_event_t * comm_event;
  
  if (!cca_enabled (client))
    {
      cca_event_destroy (event);
      return;
    }
  
  comm_event = cca_malloc (sizeof (cca_comm_event_t));
  comm_event->type = CCA_Comm_Event_Event;
  comm_event->event_data.event = event;
  
  cca_send_comm_event (client, comm_event);
}

void
cca_send_config (cca_client_t * client, cca_config_t * config)
{
  cca_comm_event_t * comm_event;
  
  if (!cca_enabled (client))
    {
      cca_config_destroy (config);
      return;
    }
  
  comm_event = cca_malloc (sizeof (cca_comm_event_t));
  comm_event->type = CCA_Comm_Event_Config;
  comm_event->event_data.config = config;
  
  cca_send_comm_event (client, comm_event);
}

const char *
cca_get_server_name (cca_client_t * client)
{
  if (!cca_enabled (client))
    return NULL;
  
  return cca_lookup_peer_name (client->socket);
}

int
cca_server_connected (cca_client_t * client)
{
  if (!client)
    return 0;
  
  return client->server_connected;
}

void
cca_jack_client_name (cca_client_t * client, const char * name)
{
  cca_event_t * event;
  
  if (!cca_enabled (client))
    return;

  if (!name)
    return;

  event = cca_event_new_with_all (CCA_Jack_Client_Name, name);
  
  cca_send_event (client, event);
}

void
cca_alsa_client_id (cca_client_t * client, unsigned char id)
{
  cca_event_t * event;
  
  if (!cca_enabled (client))
    return;

  if (!id)
    return;

  event = cca_event_new ();
  cca_event_set_alsa_client_id (event, id);
  
  cca_send_event (client, event);
}

/* EOF */

Generated by  Doxygen 1.6.0   Back to index