Code Search for Developers
 
 
  

emview_config.c from EmStar at Krugle


Show emview_config.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.
 *
 */


#include <emview/emview.h>
#include "emview_i.h"
#include <libmisc/misc.h>
#include <emrun/emrun.h>


struct config_mod_state {
  emview_module_t *mod;
  emview_device_t *dev;
};

static struct config_mod_state state = {};

#define CONFIG_INIT   0
#define CONFIG_ASSIGN 1
#define CONFIG_ENABLE 2
#define CONFIG_DONE   3

/*
 *  config helper API 
 */

static 
int emview_config_parse_enable_string(char *val, int *enable_me)
{
  if (val == NULL) goto fail;

  if (strcmp(val, "none") == 0)
    *enable_me = 0;
  else if (strcmp(val, "data") == 0)
    *enable_me = EMVIEW_ENABLE;
  else if (strcmp(val, "links") == 0)
    *enable_me = EMVIEW_ENABLE | EMVIEW_ENABLE_LINK;	
  else if (strcmp(val, "all") == 0)
    *enable_me = EMVIEW_ENABLE_ALL;
  else 
    goto fail;
  return 0;

 fail:
  elog(LOG_WARNING, "Unexpected value for enable: %s", val);
  return -1;
}


emview_color_t emview_parse_color(char *color_str)
{
  if (color_str == NULL) goto fail;

  if (color_str[0] == 0) return EMVIEW_COLOR_NONE;
  if (strcmp(color_str, "none") == 0) return EMVIEW_COLOR_NONE;
  if (strcmp(color_str, "black") == 0) return EMVIEW_COLOR_BLACK;
  if (strcmp(color_str, "red") == 0) return EMVIEW_COLOR_RED;
  if (strcmp(color_str, "blue") == 0) return EMVIEW_COLOR_BLUE;
  if (strcmp(color_str, "green") == 0) return EMVIEW_COLOR_GREEN;
  if (strcmp(color_str, "yellow") == 0) return EMVIEW_COLOR_YELLOW;
  if (strcmp(color_str, "magenta") == 0) return EMVIEW_COLOR_MAGENTA;
  if (strcmp(color_str, "cyan") == 0) return EMVIEW_COLOR_CYAN;
  if (strcmp(color_str, "burgundy") == 0) return EMVIEW_COLOR_BURGANDY;
  if (strcmp(color_str, "white") == 0) return EMVIEW_COLOR_WHITE;
  
  if (isdigit(color_str[0]))
    return atoi(color_str);

 fail:
  elog(LOG_WARNING, "Unrecognized color string %s", color_str);
  return EMVIEW_COLOR_NONE;
}


char *emview_unparse_color(emview_color_t color)
{
  switch (color) {
  case EMVIEW_COLOR_NONE: return "none";
  case EMVIEW_COLOR_BLACK: return "black";
  case EMVIEW_COLOR_RED: return "red";
  case EMVIEW_COLOR_BLUE: return "blue";
  case EMVIEW_COLOR_GREEN: return "green";
  case EMVIEW_COLOR_YELLOW: return "yellow";
  case EMVIEW_COLOR_MAGENTA: return "magenta";
  case EMVIEW_COLOR_CYAN: return "cyan";
  case EMVIEW_COLOR_BURGANDY: return "burgandy";
  case EMVIEW_COLOR_WHITE: return "white";
  default:
    return "<unknown>";
 }
}


char *emview_unparse_component_field(int field)
{
  static char buf[50];

  switch (field) {
  case 0: return "all";
  case EMVIEW_BOX_ABOVE: return "above";
  case EMVIEW_BOX_INSIDE: return "inside";
  case EMVIEW_BOX_COLOR: return "color";
  case EMVIEW_BOX_BORDER: return "border";
  case EMVIEW_BOX_FLAG1: return "flag1";
  case EMVIEW_BOX_FLAG2: return "flag2";
  case EMVIEW_BOX_FLAG3: return "flag3";
  case EMVIEW_NODE_BELOW: return "below";
  default: {
    int i = field - EMVIEW_NODE_FIRST_COLOR_FLAG;
    if ((i < 0) || (i >= EMVIEW_MAX_COLORS-2)) {
      return "<unknown>";
    }
    sprintf(buf, "%s-flag", emview_unparse_color(i+2));
    return buf;
  }
  }
}


char *emview_unparse_source_type(emview_source_type_t type)
{
  switch (type) {
  case EMVIEW_SOURCE_SIMPLE: return "data";
  case EMVIEW_SOURCE_LINK : return "link";
  case EMVIEW_SOURCE_LAYOUT: return "layout";
  default:
    return "<unknown>";
  }
}


char *emview_config_unparse_enable(int enable)
{
  if (enable & EMVIEW_ENABLE_LINK_NOTE) return "all";
  if (enable & EMVIEW_ENABLE_LINK) return "links";
  if (enable) return "data";
  return "none";
}


static
void emview_config_parse_enable(parser_state_t *ps, int id, int mode)
{
  /* process custom enable specs */
  int enable_bit = 1;

  do {

    /* options? */
    if (strcmp(ps->key, "option") == 0) {
      if (mode == CONFIG_ENABLE) {
	if (ps->value)
	  emview_option_class_set_enable(id, ps->value, enable_bit);
	else
	  elog(LOG_WARNING, "enable_option, no name supplied");
      }
      continue;
    }
    
    /* enable? */
    if (strcmp(ps->key, "enable") == 0) {
      if (ps->value == NULL)
	enable_bit = 1;
      else {
	if (ps->value[0] == '1') enable_bit = 1;
	else if (ps->value[0] == '0') enable_bit = 0;
	else {
	  elog(LOG_WARNING, "Bad argument to enable key: %s", ps->value);
	}
      }
      continue;
    }

    elog(LOG_WARNING, "Unexpected key %s", ps->key);
    continue;    
        
  } while (misc_parse_next_kvp(ps) >= 0);
}



static
void emview_config_parse_options(parser_state_t *ps, int id, int mode)
{
  /* process custom options specs */
  
  /* this is the name of this custom option */
  char *option_name = strdup(ps->value);

  while (misc_parse_next_kvp(ps) >= 0) {
    int link=0;

    if (strcmp(ps->key, "assign") == 0) {}
    else if (strcmp(ps->key, "linkscheme") == 0) { link=1; }
    else {
      elog(LOG_WARNING, "Unexpected key %s", ps->key);
      continue;
    }
    
    /* assign statement */
    if (mode == CONFIG_ASSIGN) {
      parser_state_t *ps2 = misc_parse_init(ps->value, MISC_PARSE_COMMA_SCHEME);
      char *keys[4] = { "component", "field", "source", "enable_type" };
      char *args[4];
      int enable_me;
      
      if (misc_parse_n_args(ps2, keys, args, 4) < 0) {
	elog(LOG_WARNING, "Wrong number of arguments to assign(%s)", ps->value);
	goto cleanup;
      }

      if (emview_config_parse_enable_string(args[3], &enable_me) < 0) 	
	goto cleanup;
            
      if (link) {
	/* $$$ parse color field */
	if (emview_assign_link_source(id, args[0], atoi(args[1]), args[2], option_name, enable_me) < 0) {
	  elog(LOG_WARNING, "LinkAssign(%d,%s,%d,%s,%s) failed", id, args[0], atoi(args[1]), args[2],
	       args[3]);
	  elog(LOG_DEBUG(10), "'%s'", ps->value);
	}
	else
	  elog(LOG_DEBUG(0), "Assigned link (%s)", ps->value);
      }
      
      else {
	/* $$$ parse field field */
	if (emview_assign_source(id, args[0], atoi(args[1]), args[2], option_name, enable_me) < 0) {
	  elog(LOG_WARNING, "Assign(%d,%s,%d,%s,%s) failed", id, args[0], atoi(args[1]), args[2],
	       args[3]);
	  elog(LOG_DEBUG(10), "'%s'", ps->value);
	}
	else
	  elog(LOG_DEBUG(0), "Assigned (%s)", ps->value);
      }
      
    cleanup:
      misc_free_n_args(args, 4);
      misc_parse_cleanup(ps2);
    }
    continue;
  }
  
  free(option_name);  
}


static
void emview_config_parse_module(parser_state_t *ps, int id, int mode)
{
  char *dev = "_";

  /* search for matching module */
  emview_module_t *mod = emvew_module_lookup(ps->value);
  
  /* not found ? */
  if (mod == NULL) {
    elog(LOG_WARNING, "Unrecognized module '%s'.. ignoring", ps->value);
    return;
  }
  
  /* this module ? */
  if (mod == state.mod) {
    elog(LOG_WARNING, "Not allowed to modify '%s'.. ignoring", ps->value);
    return;
  }
  
  /* next parse dev.. */
  while (misc_parse_next_kvp(ps) >= 0) {
    if (strcmp(ps->key, "dev") == 0) {
      dev = ps->value;
      break;
    }
    
    elog(LOG_WARNING, "Unexpected key: %s, second key MUST be 'dev='", ps->key);
    goto skip_rest;
  }
  
  {
    int created=0;
    emview_module_inst_t *inst = NULL;

    /* separate the nickname and the device */
    char *ptr;
    char *device_path = NULL;
    
    if ((ptr = strpbrk(dev, ","))) {
      *ptr = 0;
      device_path = ptr+1;
    }
    
    /* look up / create a new instance */
    inst = emview_mod_inst_lookup_or_create(mod, dev, &created);
    
    if (mode == CONFIG_INIT) {
      /* initially config the module.. */
      if (mod && mod->opts.config_new_instance) {
	if (created) {
	  mod->opts.config_new_instance(mod, inst, device_path, id);
	  elog(LOG_DEBUG(0), "config'd device %s,%s", dev, device_path);
	}
      }
      else 
	elog(LOG_WARNING, "Ignoring 'dev' specifier '%s'", dev);
      goto skip_rest;
    }
    
    if (mode == CONFIG_ASSIGN) {
      /* now do the option configuration */
      if (mod && mod->opts.config_assign) {
	elog(LOG_DEBUG(0), "config-ing assignments for device %s", dev);
	mod->opts.config_assign(mod, inst, id, ps);
      }
      goto skip_rest;
    }
    
    if (mode == CONFIG_ENABLE) {
      /* now do the option configuration */
      if (mod && mod->opts.config_opts) {
	elog(LOG_DEBUG(0), "configing options for device %s", dev);
	mod->opts.config_opts(mod, inst, id, ps);
      }
      goto skip_rest;
    }
    
    elog(LOG_ERR, "invalid mode ??? ");
    goto skip_rest;
  }
  
 skip_rest:
  return;
}


/*
 *  parse and process the visualizer config blocks
 */

void emview_config_parse(struct config_mod_state *state, node_t *n, parser_state_t *ps, int mode)
{
  /* parse the new config block */
  while (misc_parse_next_kvp(ps) >= 0) {
    parser_state_t *ps2 = misc_parse_init(ps->key, MISC_PARSE_COLON_SCHEME);

    elog(LOG_DEBUG(10), "got kvp='%s=%s'", ps->key, ps->value);
    
    /* re-parse for module initializer */
    if (misc_parse_next_kvp(ps2) >= 0) {    
      /* module? */
      if (strcmp(ps2->key, "module") == 0) {
	emview_config_parse_module(ps2, n->id, mode);
      }

      /* options? */
      else if (strcmp(ps2->key, "def_option") == 0) {
	emview_config_parse_options(ps2, n->id, mode);
      }

      /* enable? */
      else if (strcmp(ps2->key, "enable") == 0) {
	emview_config_parse_enable(ps2, n->id, mode);
      }

      else
	elog(LOG_WARNING, "Unexpected key: %s", ps2->key);
    }
    
    misc_parse_cleanup(ps2);
  }
  
  misc_parse_reset(ps);
}


int emview_config_global_now(void *data, int interval, g_event_t *ev)
{
  node_t *n;
  emview_dev_node_t *dn;
  int stage;

  /* set marks on each node */
  for (n = emview_node_top(&(_core.node_list)); n; n = emview_node_next(n)) {
    /* mark existing components */
    emview_component_list_mark(&(n->display.components));
    
    /* unmark the node component */
    emview_component_register(g_quark_from_string(EMVIEW_NODE_COMPONENT), n->id, EMVIEW_COMP_TYPE_NODE);
  }

  /* staged parse for each node */
  for (stage = CONFIG_INIT; stage < CONFIG_DONE; stage++) {
    for (dn = emview_dn_top(state.dev); dn; dn = emview_dn_next(dn)) {
      n = emview_node_lookup_nocreate(emview_dn_get_node_id(dn));

      if (n && dn->data) {
	/* set up the parse */
	parser_state_t *ps = misc_parse_init(dn->data, MISC_PARSE_LF_SCHEME);
	
	/* parse all the component declarations etc */
	emview_config_parse(&state, n, ps, stage);

	/* free it */
	misc_parse_cleanup(ps);
      }
    }
  }
  
  /* prune marked components */
  for (n = emview_node_top(&(_core.node_list)); n; n = emview_node_next(n)) {
    emview_component_list_prune_marked(&(n->display.components));
  }

  /* relink */
  emview_node_global_relink_display();
  
  /* rebuild menu if needed */
  emview_build_options_menu();

  /* OK, done! */
  return TIMER_DONE;
}


void emview_config_schedule_reconfig()
{
  static g_event_t *timer = NULL;
  if (timer == NULL)
    g_timer_add(1000, emview_config_global_now, NULL, NULL, &timer);
}


int config_handle_data(emview_device_t *dev, emproxy_reply_hdr_t *reply, 
		       emview_dev_node_t *node)
{
  node_t *n = emview_node_lookup_nocreate(emview_dn_get_node_id(node));
  
  elog(LOG_DEBUG(1), "Got emview config data for node %d", emview_dn_get_node_id(node));
  elog(LOG_DEBUG(1), "got '%s'", reply->data);
  
  /* check for node present */
  if (n == NULL) {
    elog(LOG_ERR, "Null node in config handler");
    goto out;
  }

  /* is this new config different? */
  if (node->data && 
      (strncmp(reply->data, node->data, reply->data_length) == 0)) {
    /* no change.. */
    goto out;
  }

  /* save.. */
  if (node->data) free(node->data);
  node->data = malloc(reply->data_length+1);
  memmove(node->data, reply->data, reply->data_length);
  ((char*)node->data)[reply->data_length]=0;

  /* OK, now do a global reconfiguration */
  emview_config_schedule_reconfig();

 out:
  return 0;
}


int config_node_timeout(emview_device_t *dev, emview_dev_node_t *node)
{
  elog(LOG_DEBUG(10), "Node %d timed out!", emview_dn_get_node_id(node));
  return 0;
}


void emview_config_test(node_t *n, buf_t *buf)
{
  emproxy_reply_hdr_t *reply = malloc(sizeof(emproxy_reply_hdr_t) + buf->len);
  memset(reply, 0, sizeof(emproxy_reply_hdr_t));
  memmove(reply->data, buf->buf, buf->len);
  reply->data_length = buf->len;
  
  config_handle_data(state.dev, reply, emview_dev_node_lookup(state.dev, n->id));
}


/*
 *  "main" function for the config module
 */

int config_main(int *argc, char **argv)
{
  emview_module_opts_t mod_opts = {
    name: "__Config",
    private_data: &state,
  };

  /* register with emview and get context structure */
  state.mod = emview_register(&mod_opts);

  /* add new device */
  {
    char buf[128];

    /* register the device */
    emview_device_opts_t opts = {
      name: "__config",
      private_data: &state,
      proxy_string: buf,
      data_handler: config_handle_data,
      node_timeout: config_node_timeout,
      parent: state.mod,
      always_active: 1
    };
    sprintf(buf, "dev=%s:ascii", EMRUN_EMVIEW_CONFIG_DEVNAME);
    
    /* register device */
    state.dev = emview_register_device(&opts);
  }
  
  return 0;
}

/*
 *  Options tree
 */

typedef struct {
  char *option_name;
  char *usage;
  char *description;
  int select_state;
  char **mutex_options;
  GtkWidget *menu;
  emview_module_t *parent;
} option_state_t;

/*
 *  Options menu support
 */

static int b0rken_gtk = 0;

static
int emview_option_config(void *data)
{
  option_state_t *option = (option_state_t *)data;
  if (!b0rken_gtk) {
    /* this will set the state and call the function to set the check */
    emview_option_class_set_enable(0, option->option_name, !option->select_state);
    emview_reconfig();
  }
  return TRUE;
}

static
void emview_option_set_check(option_state_t *opt)
{
  if (opt->menu) {
    b0rken_gtk = 1;
    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(opt->menu), opt->select_state);
    b0rken_gtk = 0;
  }
}


/*
 *  globals to compute flat tree...  grr..
 */

static int flat_count = 0;
static option_state_t **flat = NULL;

static
int emview_flatten(void *key, void *value, void *data)
{
  flat[flat_count] = (option_state_t *)value;
  flat_count++;
  return 0;
}


void emview_recurse_rebuild(int *index, char *prefix, GtkWidget *parent_menu)
{
  int prefix_len = strlen(prefix);
  
  while (*index < flat_count) {
    char *next_slash;
    
    elog(LOG_DEBUG(1), "processing item '%s', prefix '%s'", flat[*index]->option_name, prefix);

    /* is prefix NOT a prefix of the current string? */
    if (strncmp(prefix, flat[*index]->option_name, prefix_len)) {
      /* pop! */
      return;
    }

    /* OK, prefix is a prefix. */
    
    /* is there a '/' after prefix? */
    next_slash = strpbrk(flat[*index]->option_name + prefix_len, "/");
    if (next_slash) {
      char *new_prefix = strdup(flat[*index]->option_name);
      GtkWidget *submenu;
      new_prefix[next_slash - flat[*index]->option_name + 1] = 0;

      /* OK, create a submenu */
      submenu = emview_sub_menu(parent_menu, new_prefix + prefix_len);
      
      /* now start filling it. */
      emview_recurse_rebuild(index, new_prefix, submenu);

      /* free the prefix */
      free(new_prefix);

      /* retry this one */
      continue;
    }

    /* no slash.. just add a check item */
    else {
      elog(LOG_DEBUG(1), "appending new menu item '%s'", flat[*index]->option_name + prefix_len);
      flat[*index]->menu = 
	emview_menu_item
	(parent_menu, gtk_check_menu_item_new_with_label(flat[*index]->option_name + prefix_len),
	 emview_option_config, flat[*index]);
      emview_option_set_check(flat[*index]);
    }

    /* next.. */
    (*index)++;
  }
}


void emview_build_options_menu()
{ 
  if (_core.config.rebuild_menu) {
    int index;

    if (!_core.nogui) {
      /* destroy old */
      if (_core.config.menu) {
	gtk_container_remove(GTK_CONTAINER(_core.gui.menu_bar), _core.config.menu_item);
	gtk_widget_destroy(_core.config.menu_item);
      }
      
      /* create new */
      _core.config.menu = emview_toplevel_menu("Options", &(_core.config.menu_item));
    }

    /* flatten the tree -- glib types totally suck :( */
    flat_count = 0;
    flat = malloc(sizeof(option_state_t *)*(g_tree_nnodes(_core.config.option_tree)));
    g_tree_foreach(_core.config.option_tree, emview_flatten, NULL);
      
    /* 
     * OK, now we've got a flat tree, that can be iterated
     * more conveniently!
     */
    
    /* add each menu in turn */
    if (!_core.nogui) {
      index = 0;
      emview_recurse_rebuild(&index, "", _core.config.menu);
    }

    /* free! */
    free(flat);
    flat = NULL;
    flat_count = 0;
  }
  
  _core.config.rebuild_menu = 0;
}


/*
 *  Options tree functions
 */

static
int option_key_compare(const void *x, const void *y)
{
  return strcmp((const char*)x, (const char*)y);
}


static
option_state_t *emview_option_tree_lookup(char *option_name)
{
  return (option_state_t *) g_tree_lookup(_core.config.option_tree, option_name);
}


int emview_option_tree_update(char *option_name, int enable_bit)
{
  option_state_t *opt = emview_option_tree_lookup(option_name);
  if (opt == NULL) {
    elog(LOG_WARNING, "Trying to update option tree for %s, not in tree!", option_name);
    return -1;
  }

  opt->select_state = enable_bit;
  emview_option_set_check(opt);

  if (enable_bit) {
    /* $$$$ add support for mutex options.. unset all mutex entries */
  }
  
  return 0;
}


void emview_document_option_class(emview_module_t *module,
				  char *option, char *usage, char *description, 
				  char **mutex_options)
{
  option_state_t *found;
  
  /* stupid defaults */
  if (usage == NULL)
    usage = "<no usage info>";
  if (description == NULL)
    description = "<no description>";

  /* create tree if needed */
  if (_core.config.option_tree == NULL) {
    _core.config.option_tree = g_tree_new(option_key_compare);
  }
  
  /* lookup this option in the tree */
  if ((found = emview_option_tree_lookup(option))) {
    /* already present */
    if ((found->usage && strcmp(found->usage, usage)) || 
	(found->description && strcmp(found->description, description))) {
      elog(LOG_WARNING, "Option document call differs from existing option %s [%p]",
	   option, found);
      elog(LOG_WARNING, "%s,%s/%s,%s", usage, found->usage, description, found->description);
    }
    /* $$$$ add same check for mutex list. */
    return;
  }
  
  /* otherwise, add us to the options tree */
  {
    /* $$$$ add support for mutex options.. copy null-term array of strings */
    option_state_t *opt = g_new0(option_state_t, 1);
    opt->option_name = strdup(option);
    opt->usage = strdup(usage);
    opt->description = strdup(description);
    opt->parent = module;

    _core.config.rebuild_menu = 1;
    g_tree_insert(_core.config.option_tree, opt->option_name, opt);
  }
}


static buf_t *__buf = NULL;
static node_t *__node = NULL;

static
int emview_cd_aux(void *key, void *value, void *data)
{
  option_state_t *opt = (option_state_t *)value;
  emview_module_t *mod = (emview_module_t *)data;

  if (opt->parent == mod) {
    GQuark option_q = g_quark_from_string(opt->option_name);

    bufprintf(__buf, "\n  Option '%s': Usage: %s\n", opt->option_name, 
	      opt->usage ? opt->usage : "");
    bufprintf(__buf, "    %s\n", opt->description);
    /* $$$ dump mutex */

    /* search through for component slots */
    emview_slots_list_status_printable(&(__node->display.slots), __buf, option_q);
  }

  return 0;
} 


void emview_config_dump(emview_module_t *module, node_t *n, buf_t *buf)
{
  __buf = buf;
  __node = n;
  bufprintf(buf, "Module %s:  %s\n", module->opts.name,
	    module->opts.description);
  g_tree_foreach(_core.config.option_tree, emview_cd_aux, module);

  bufprintf(buf, "\n\n");
}






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

  emview_analysis.c
  emview_analysis.h
  emview_box_component.c
  emview_component.c
  emview_component.h
  emview_config.c
  emview_config.h
  emview_device.c
  emview_device.h
  emview_gui.c
  emview_gui.h
  emview_gui_menu.c
  emview_i.h
  emview_main.c
  emview_node.c
  emview_node.h
  emview_node_component.c
  emview_slots.c
  emview_source.c
  emview_source.h