Code Search for Developers
 
 
  

usfusd.c from EmStar at Krugle


Show usfusd.c syntax highlighted

/*
 *
 * Copyright (c) 2003 The Regents of the University of California.  All 
 * rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Neither the name of the University nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
 

/*
 *  usFUSD: the User-Space Framework for User-Space Devices
 *
 *  NOTE: Though it probably ought to be independent, this daemon depends
 *        on CENS utility libraries.  It was just a pain to reimplement
 *        everything.
 *  
 */

#include <fusd.h>
#include <fusd_msg.h>
#include <usfusd_msg.h>
#include "usfusd_i.h"

#include <libdev/glib_dev.h>
#include <libmisc/misc.h>

QUEUE_FUNCTION_INSTANTIATIONS(usfusd_clients,_,clients,struct client,usfusd_t);
QUEUE_FUNCTION_INSTANTIATIONS(usfusd_devices,_,devices,struct device,usfusd_t);

usfusd_t state = {};


/*
 *  destructors...
 */

static
void usfusd_device_destroy(device_t *d)
{
  if (d && !d->destroying) {
    client_t *c;

    /* set destroying bit */
    d->destroying = 1;

    /* free name */
    if (d->devname)
      free(d->devname);

    /* remove */
    usfusd_devices_remove(&state, d);

    /* kill server if any */
    if (d->server)
      usfusd_client_destroy(d->server);

    /* kill any clients of this device */
    for (c = usfusd_clients_top(&state); c; ) {
      client_t *tmp = c;
      c = usfusd_clients_next(c);
      
      if (tmp->usfusd_device == d) 
	usfusd_client_destroy(tmp);
    }
    
    /* free device */
    free(d);    
  }
}


static
void usfusd_client_destroy(client_t *c)
{
  if (c && !c->destroying) 
    usfusd_proto_destroy(c->proto);
}


/*
 *  protocol handlers
 */


static
void usfusd_handle_close(void *data)
{
  client_t *c = (client_t *)data;

  if (c && !c->destroying) {
    device_t *dev;
    
    /* set destroying bit */
    c->destroying = 1;

    /* if open, fake a close to device */
    if (c->usfusd_device && !c->defunct) {
      /* fake a close */
      /* $$$$ */
    }
    
#if 0
    /* close */
    if (c->local_fd >= 0)
      close(c->local_fd);
    for (i=0; i<BLOCK_MAX; i++)
      g_event_destroy(c->local_event[i]);
    g_event_destroy(c->poll_event);
#endif

    /* remove */
    usfusd_clients_remove(&state, c);
    
    /* kill device if any */
    for (dev = usfusd_devices_top(&state); dev; ) {
      device_t *tmp = dev;
      dev = usfusd_devices_next(dev);
      if (tmp->server == c)
	usfusd_device_destroy(tmp);
    }

    /* close the socket */
    __close(c->socket);

    /* free client struct */
    free(c);
  }
}


static
void usfusd_handle_input(usfusd_msg_t *msg, char *data_buf, void *data)
{
  client_t *c = (client_t *)data;

  /* ignore defunct conns */
  if (c->defunct) {
    elog(LOG_WARNING, "Recieved message on defunct connection?");
    return;
  }

  /* ignore blocked conns */
  if (c->blocked && (msg->subcmd != FUSD_CLOSE)) {    
    elog(LOG_WARNING, "Recieved message on blocked connection?");
    return;
  }
  
  switch (msg->cmd) {
  case USFUSD_CLIENT_OPEN:
    usfusd_open(c, msg, data_buf);
    break;

  case USFUSD_CLIENT_DUP:
    usfusd_dup(c, msg);
    break;

  case USFUSD_CLIENT_OP:

    switch (msg->subcmd) {
    case FUSD_READ: 
      usfusd_read(conn, msg); 
      break;
    
    case FUSD_WRITE:
      usfusd_write(conn, msg, data_buf); 
      break;
    
    case FUSD_IOCTL:
      usfusd_ioctl(conn, msg, data_buf); 
      break;
    
    case USFUSD_POLL:
      usfusd_poll(conn, msg, 0);
      break;

    case FUSD_POLL_DIFF:
      usfusd_poll(conn, msg, 1);
      break;

    case USFUSD_FCNTL:
      usfusd_fcntl(conn, msg);
      break;

    case FUSD_CLOSE: 
      /* set this conn to defunct */
      conn->defunct = 1;
      
      /* if this conn was blocking, unblock */
      usfusd_unblock_if(conn);
      
      /* drop this connection and close only if arg is set */
      if (msg->arg) usufsd_conn_close(conn);
      break;

    default:
      break;
    }
    break;

  default:
    break;
  }
}


/*
 *  accept handler
 */

int usfusd_handle_accept(void *data, int fd, int cond, g_event_t *event)
{
  usfusd_t *state = (usfusd_t *)data;
  struct sockaddr_in saddr;
  client_t *c;
  client_conn_t *conn;
  
  usfusd_proto_opts_t popts = {
    input: usfusd_handle_input,
    close: usfusd_handle_close    
  };

  /* accept new connection */
  int status = accept(fd, &saddr, sizeof(saddr));
  if (status < 0) {
    elog(LOG_CRIT, "Accept returned error: %m");
    exit(1);
  }

  /* create new client state */
  c = malloc(sizeof(client_t));
  conn = malloc(sizeof(client_conn_t));
  if ((c == NULL) || (conn == NULL)) {
    elog(LOG_CRIT, "Unable to alloc new client: %m\n");
    exit(1);
  }
  
  /* init */
  memset(c, 0, sizeof(client_t));
  memset(conn, 0, sizeof(client_conn_t));
  conn->socket = status;
  conn->parent = c;
  c->saddr = saddr;
  usfusd_conns_push(c, conn);
  usfusd_clients_push(&state, c);

  /* register an event.. */
  popts.private_data = conn;
  popts.socket = conn->socket;
  if (usfusd_proto_new(&popts, &(conn->proto)) < 0) {
    elog(LOG_CRIT, "Unable to create event for new connection: %m");
    exit(1);
  }

  return EVENT_RENEW;
}


/*
 *  init and bind
 */

void usfusd_init()
{
  struct sockaddr_in saddr = {
    sin_family: AF_INET,
    sin_port: htons(USFUSD_PORT),
    sin_addr: {
      s_addr: INADDR_ANY
    }
  };
  
  /* get a socket */
  state.usfusd_socket = socket(PF_INET, SOL_STREAM, IPPROTO_TCP);
  if (state.usfusd_socket < 0) {
    elog(LOG_CRIT, "Socket call failed: %m");
    exit(1);
  }
  
  /* try to bind */
  status = bind(state.usfusd_socket, &saddr, sizeof(struct sockaddr_in));
  if (status < 0) {
    elog(LOG_CRIT, "Unable to bind to usfusd server socket!  %m\n");
    exit(1);
  }

  /* register an event.. */
  if (g_event_add(state.usfusd_socket, FUSD_NOTIFY_INPUT, usfusd_handle_accept, &state, 
		  NULL, NULL) < 0) {
    elog(LOG_CRIT, "Failed to create event for accept socket: %m\n");
    exit(1);
  }
}


/*
 *  main
 */

int main(int argc, char **argv)
{
  /* process args? */

  /* initialize and bind */
  usfusd_init();

  /* run */
  g_main();

  return 0;
}




See more files for this project here

EmStar

EmStar is a software system for developing and deploying wireless sensor networks involving Linux-based platforms. As the wireless sensor network community has attempted to deploy more complex designs---large-scale, long-lived systems that need self-organization and adaptivity---a number of difficult software design issues have arisen. Advances in software design have not kept pace with the capabilities of hardware. This is because designing for an adaptive, efficient, and useful sensor network has turned out to be surprisingly complex and difficult. EmStar is a Linux-based software framework, whose goal is to dramatically reduce this complexity, enabling work to be shared and reused, and simplifying and speeding the design of new sensor network applications.

Project homepage: http://cvs.cens.ucla.edu/emstar/
Programming language(s): C,Shell Script
License: other

  usfusd.c
  usfusd_fusd.c
  usfusd_i.h
  usfusd_local.c