text:
/**
 * \addtogroup uip6
 * @{
 */
/*
 * Copyright (c) 2010, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
 *
 * This file is part of the Contiki operating system.
 *
 */
/**
 * \file
 *         Logic for Directed Acyclic Graphs in RPL.
 *
 * \author Joakim Eriksson <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se>
 */

#include "contiki.h"
#include "net/rpl/rpl-private.h"
#include "net/uip.h"
#include "net/uip-nd6.h"
#include "lib/list.h"
#include "lib/memb.h"
#include "sys/ctimer.h"

#include <limits.h>
#include <string.h>

#define DEBUG DEBUG_NONE
#include "net/uip-debug.h"

#include "net/neighbor-info.h"

/*---------------------------------------------------------------------------*/
extern rpl_of_t RPL_OF;
static rpl_of_t * const objective_functions[] = {&RPL_OF};

/*---------------------------------------------------------------------------*/
#ifndef RPL_CONF_MAX_PARENTS_PER_DAG
#define RPL_MAX_PARENTS_PER_DAG       8
#else
#define RPL_MAX_PARENTS_PER_DAG       RPL_CONF_MAX_PARENTS_PER_DAG
#endif /* !RPL_CONF_MAX_PARENTS_PER_DAG */

/*---------------------------------------------------------------------------*/
/* RPL definitions. */

#ifndef RPL_CONF_GROUNDED
#define RPL_GROUNDED                    0
#else
#define RPL_GROUNDED                    RPL_CONF_GROUNDED
#endif /* !RPL_CONF_GROUNDED */

/*---------------------------------------------------------------------------*/
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */
MEMB(parent_memb, struct rpl_parent,
     RPL_MAX_PARENTS_PER_DAG * RPL_MAX_INSTANCES * RPL_MAX_DAG_PER_INSTANCE);
/*---------------------------------------------------------------------------*/
/* Allocate instance table. */
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
rpl_instance_t *default_instance;
/*---------------------------------------------------------------------------*/
/* Greater-than function for the lollipop counter.                      */
/*---------------------------------------------------------------------------*/
static int
lollipop_greater_than(int a, int b)
{
  /* Check if we are comparing an initial value with an old value */
  if(a > RPL_LOLLIPOP_CIRCULAR_REGION && b <= RPL_LOLLIPOP_CIRCULAR_REGION) {
    return (RPL_LOLLIPOP_MAX_VALUE + 1 + b - a) > RPL_LOLLIPOP_SEQUENCE_WINDOWS;
  }
  /* Otherwise check if a > b and comparable => ok, or
     if they have wrapped and are still comparable */
  return (a > b && (a - b) < RPL_LOLLIPOP_SEQUENCE_WINDOWS) ||
    (a < b && (b - a) > (RPL_LOLLIPOP_CIRCULAR_REGION + 1-
			 RPL_LOLLIPOP_SEQUENCE_WINDOWS));
}
/*---------------------------------------------------------------------------*/
/* Remove DAG parents with a rank that is at least the same as minimum_rank. */
static void
remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
{
  rpl_parent_t *p, *p2;

  PRINTF("RPL: Removing parents (minimum rank %u)\n",
	minimum_rank);

  for(p = list_head(dag->parents); p != NULL; p = p2) {
    p2 = p->next;
    if(p->rank >= minimum_rank) {
      rpl_remove_parent(dag, p);
    }
  }
}
/*---------------------------------------------------------------------------*/
static void
nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
{
  rpl_parent_t *p, *p2;

  PRINTF("RPL: Removing parents (minimum rank %u)\n",
	minimum_rank);

  for(p = list_head(dag->parents); p != NULL; p = p2) {
    p2 = p->next;
    if(p->rank >= minimum_rank) {
      rpl_nullify_parent(dag, p);
    }
  }
}
/*---------------------------------------------------------------------------*/
static void
remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank)
{
  rpl_parent_t *p, *worst;

  PRINTF("RPL: Removing the worst parent\n");

  /* Find the parent with the highest rank. */
  worst = NULL;
  for(p = list_head(dag->parents); p != NULL; p = list_item_next(p)) {
    if(p != dag->preferred_parent &&
       (worst == NULL || p->rank > worst->rank)) {
      worst = p;
    }
  }
  /* Remove the neighbor if its rank is worse than the minimum worst rank. */
  if(worst != NULL && worst->rank > min_worst_rank) {
    rpl_remove_parent(dag, worst);
  }
}
/*---------------------------------------------------------------------------*/
static int
should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p)
{
  /* if MOP is set to no downward routes no DAO should be sent */
  if(instance->mop == RPL_MOP_NO_DOWNWARD_ROUTES) {
    return 0;
  }
  /* check if the new DTSN is more recent */
  return p == instance->current_dag->preferred_parent &&
    (lollipop_greater_than(dio->dtsn, p->dtsn));
}
/*---------------------------------------------------------------------------*/
static int
acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank)
{
  return rank != INFINITE_RANK &&
    ((dag->instance->max_rankinc == 0) ||
     DAG_RANK(rank, dag->instance) <= DAG_RANK(dag->min_rank + dag->instance->max_rankinc, dag->instance));
}
/*---------------------------------------------------------------------------*/
static rpl_dag_t *
get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
{
  rpl_instance_t *instance;
  rpl_dag_t *dag;
  int i;

  instance = rpl_get_instance(instance_id);
  if(instance == NULL) {
    return NULL;
  }

  for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; ++i) {
    dag = &instance->dag_table[i];
    if(dag->used && uip_ipaddr_cmp(&dag->dag_id, dag_id)) {
      return dag;
    }
  }

  return NULL;
}
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
{
  rpl_dag_t *dag;
  rpl_instance_t *instance;
  uint8_t version;

  version = RPL_LOLLIPOP_INIT;
  dag = get_dag(instance_id, dag_id);
  if(dag != NULL) {
    version = dag->version;
    RPL_LOLLIPOP_INCREMENT(version);
    PRINTF("RPL: Dropping a joined DAG when setting this node as root");
    if(dag == dag->instance->current_dag) {
      dag->instance->current_dag = NULL;
    }
    rpl_free_dag(dag);
  }

  dag = rpl_alloc_dag(instance_id, dag_id);
  if(dag == NULL) {
    PRINTF("RPL: Failed to allocate a DAG\n");
    return NULL;
  }

  instance = dag->instance;

  dag->version = version;
  dag->joined = 1;
  dag->grounded = RPL_GROUNDED;
  instance->mop = RPL_MOP_DEFAULT;
  instance->of = &RPL_OF;
  dag->preferred_parent = NULL;

  memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id));

  instance->dio_intdoubl = RPL_DIO_INTERVAL_DOUBLINGS;
  instance->dio_intmin = RPL_DIO_INTERVAL_MIN;
  /* The current interval must differ from the minimum interval in order to
     trigger a DIO timer reset. */
  instance->dio_intcurrent = RPL_DIO_INTERVAL_MIN +
    RPL_DIO_INTERVAL_DOUBLINGS;
  instance->dio_redundancy = RPL_DIO_REDUNDANCY;
  instance->max_rankinc = RPL_MAX_RANKINC;
  instance->min_hoprankinc = RPL_MIN_HOPRANKINC;
  instance->default_lifetime = RPL_DEFAULT_LIFETIME;
  instance->lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT;

  dag->rank = ROOT_RANK(instance);

  if(instance->current_dag != dag && instance->current_dag != NULL) {
    /* Remove routes installed by DAOs. */
    rpl_remove_routes(instance->current_dag);

    instance->current_dag->joined = 0;
  }

  instance->current_dag = dag;
  instance->dtsn_out = RPL_LOLLIPOP_INIT;
  instance->of->update_metric_container(instance);
  default_instance = instance;

  PRINTF("RPL: Node set to be a DAG root with DAG ID ");
  PRINT6ADDR(&dag->dag_id);
  PRINTF("\n");

  ANNOTATE("#A root=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);

  rpl_reset_dio_timer(instance);

  return dag;
}
/*---------------------------------------------------------------------------*/
int
rpl_repair_root(uint8_t instance_id)
{
  rpl_instance_t *instance;

  instance = rpl_get_instance(instance_id);
  if(instance == NULL ||
     instance->current_dag->rank != ROOT_RANK(instance)) {
    return 0;
  }

  RPL_LOLLIPOP_INCREMENT(instance->current_dag->version);
  RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
  rpl_reset_dio_timer(instance);
  return 1;
}
/*---------------------------------------------------------------------------*/
static void
set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix)
{
  memset(ipaddr, 0, sizeof(uip_ipaddr_t));
  memcpy(ipaddr, &prefix->prefix, (prefix->length + 7) / 8);
  uip_ds6_set_addr_iid(ipaddr, &uip_lladdr);
}
/*---------------------------------------------------------------------------*/
static void
check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix)
{
  uip_ipaddr_t ipaddr;
  uip_ds6_addr_t *rep;

  if(last_prefix != NULL && new_prefix != NULL &&
     last_prefix->length == new_prefix->length &&
     uip_ipaddr_prefixcmp(&last_prefix->prefix, &new_prefix->prefix, new_prefix->length) &&
     last_prefix->flags == new_prefix->flags) {
    /* Nothing has changed. */
    return;
  }

  if(last_prefix != NULL) {
    set_ip_from_prefix(&ipaddr, last_prefix);
    rep = uip_ds6_addr_lookup(&ipaddr);
    if(rep != NULL) {
      PRINTF("RPL: removing global IP address ");
      PRINT6ADDR(&ipaddr);
      PRINTF("\n");
      uip_ds6_addr_rm(rep);
    }
  }

  if(new_prefix != NULL) {
    set_ip_from_prefix(&ipaddr, new_prefix);
    if(uip_ds6_addr_lookup(&ipaddr) == NULL) {
      PRINTF("RPL: adding global IP address ");
      PRINT6ADDR(&ipaddr);
      PRINTF("\n");
      uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
    }
  }
}
/*---------------------------------------------------------------------------*/
int
rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len)
{
  if(len > 128) {
    return 0;
  }

  memset(&dag->prefix_info.prefix, 0, sizeof(dag->prefix_info.prefix));
  memcpy(&dag->prefix_info.prefix, prefix, (len + 7) / 8);
  dag->prefix_info.length = len;
  dag->prefix_info.flags = UIP_ND6_RA_FLAG_AUTONOMOUS;
  PRINTF("RPL: Prefix set - will announce this in DIOs\n");
  /* Autoconfigure an address if this node does not already have an address
     with this prefix. */
  check_prefix(NULL, &dag->prefix_info);
  return 1;
}
/*---------------------------------------------------------------------------*/
int
rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
{
  if(instance->def_route != NULL) {
    PRINTF("RPL: Removing default route through ");
    PRINT6ADDR(&instance->def_route->ipaddr);
    PRINTF("\n");
    uip_ds6_defrt_rm(instance->def_route);
    instance->def_route = NULL;
  }

  if(from != NULL) {
    PRINTF("RPL: Adding default route through ");
    PRINT6ADDR(from);
    PRINTF("\n");
    instance->def_route = uip_ds6_defrt_add(from,
                                            RPL_LIFETIME(instance,
                                                         instance->default_lifetime));
    if(instance->def_route == NULL) {
      return 0;
    }
  } else {
    PRINTF("RPL: Removing default route\n");
    if(instance->def_route != NULL) {
      uip_ds6_defrt_rm(instance->def_route);
    } else {
      PRINTF("RPL: Not actually removing default route, since instance had no default route\n");
    }
  }
  return 1;
}
/*---------------------------------------------------------------------------*/
rpl_instance_t *
rpl_alloc_instance(uint8_t instance_id)
{
  rpl_instance_t *instance, *end;

  for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
      instance < end; ++instance) {
    if(instance->used == 0) {
      memset(instance, 0, sizeof(*instance));
      instance->instance_id = instance_id;
      instance->def_route = NULL;
      instance->used = 1;
      return instance;
    }
  }
  return NULL;
}
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
{
  rpl_dag_t *dag, *end;
  rpl_instance_t *instance;

  instance = rpl_get_instance(instance_id);
  if(instance == NULL) {
    instance = rpl_alloc_instance(instance_id);
    if(instance == NULL) {
      RPL_STAT(rpl_stats.mem_overflows++);
      return NULL;
    }
  }

  for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
    if(!dag->used) {
      memset(dag, 0, sizeof(*dag));
      LIST_STRUCT_INIT(dag, parents);
      dag->used = 1;
      dag->rank = INFINITE_RANK;
      dag->min_rank = INFINITE_RANK;
      dag->instance = instance;
      return dag;
    }
  }

  RPL_STAT(rpl_stats.mem_overflows++);
  rpl_free_instance(instance);
  return NULL;
}
/*---------------------------------------------------------------------------*/
void
rpl_set_default_instance(rpl_instance_t *instance)
{
  default_instance = instance;
}
/*---------------------------------------------------------------------------*/
void
rpl_free_instance(rpl_instance_t *instance)
{
  rpl_dag_t *dag;
  rpl_dag_t *end;

  PRINTF("RPL: Leaving the instance %u\n", instance->instance_id);

  /* Remove any DAG inside this instance */
  for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
    if(dag->used) {
      rpl_free_dag(dag);
    }
  }

  rpl_set_default_route(instance, NULL);

  ctimer_stop(&instance->dio_timer);
  ctimer_stop(&instance->dao_timer);

  if(default_instance == instance) {
    default_instance = NULL;
  }

  instance->used = 0;
}
/*---------------------------------------------------------------------------*/
void
rpl_free_dag(rpl_dag_t *dag)
{
  if(dag->joined) {
    PRINTF("RPL: Leaving the DAG ");
    PRINT6ADDR(&dag->dag_id);
    PRINTF("\n");
    dag->joined = 0;

    /* Remove routes installed by DAOs. */
    rpl_remove_routes(dag);

   /* Remove autoconfigured address */
    if((dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS)) {
      check_prefix(&dag->prefix_info, NULL);
    }

    remove_parents(dag, 0);
  }
  dag->used = 0;
}
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
{
  rpl_parent_t *p;

  if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DAG) {
    return NULL;
  }

  p = memb_alloc(&parent_memb);
  if(p == NULL) {
    RPL_STAT(rpl_stats.mem_overflows++);
    return NULL;
  }
  memcpy(&p->addr, addr, sizeof(p->addr));
  p->dag = dag;
  p->rank = dio->rank;
  p->dtsn = dio->dtsn;
  p->link_metric = INITIAL_LINK_METRIC;
  memcpy(&p->mc, &dio->mc, sizeof(p->mc));
  list_add(dag->parents, p);
  return p;
}
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr)
{
  rpl_parent_t *p;

  for(p = list_head(dag->parents); p != NULL; p = p->next) {
    if(uip_ipaddr_cmp(&p->addr, addr)) {
      return p;
    }
  }
  return NULL;
}

/*---------------------------------------------------------------------------*/
static rpl_dag_t *
find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
{
  rpl_parent_t *p;
  rpl_dag_t *dag, *end;

  for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
    if(dag->used) {
      for(p = list_head(dag->parents); p != NULL; p = p->next) {
        if(uip_ipaddr_cmp(&p->addr, addr)) {
          return dag;
        }
      }
    }
  }
  return NULL;
}
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
{
  static rpl_parent_t *p;
  static rpl_dag_t *dag, *end;

  for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
    if(dag->used) {
      for(p = list_head(dag->parents); p != NULL; p = p->next) {
        if(uip_ipaddr_cmp(&p->addr, addr)) {
          return p;
        }
      }
    }
  }
  return NULL;
}
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
{
  static rpl_parent_t *last_parent;
  static rpl_dag_t *dag, *end, *best_dag;
  static rpl_rank_t old_rank;

  old_rank = instance->current_dag->rank;
  last_parent = instance->current_dag->preferred_parent;

  best_dag = instance->current_dag;
  if(best_dag->rank != ROOT_RANK(instance)) {
    if(rpl_select_parent(p->dag) != NULL) {
      if(p->dag != best_dag) {
        best_dag = instance->of->best_dag(best_dag, p->dag);
      }
    } else if(p->dag == best_dag) {
      best_dag = NULL;
      for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) {
        if(dag->used && dag->preferred_parent != NULL && dag->preferred_parent->rank != INFINITE_RANK) {
          if(best_dag == NULL) {
            best_dag = dag;
          } else {
            best_dag = instance->of->best_dag(best_dag, dag);
          }
        }
      }
    }
  }

  if(best_dag == NULL) {
    /* No parent found: the calling function handle this problem. */
    return NULL;
  }

  if(instance->current_dag != best_dag) {
    /* Remove routes installed by DAOs. */
    rpl_remove_routes(instance->current_dag);

    PRINTF("RPL: New preferred DAG: ");
    PRINT6ADDR(&best_dag->dag_id);
    PRINTF("\n");

    if(best_dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
      check_prefix(&instance->current_dag->prefix_info, &best_dag->prefix_info);
    } else if(instance->current_dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
      check_prefix(&instance->current_dag->prefix_info, NULL);
    }

    best_dag->joined = 1;
    instance->current_dag->joined = 0;
    instance->current_dag = best_dag;
  }

  instance->of->update_metric_container(instance);
  /* Update the DAG rank. */
  best_dag->rank = instance->of->calculate_rank(best_dag->preferred_parent, 0);
  if(best_dag->rank < best_dag->min_rank) {
    best_dag->min_rank = best_dag->rank;
  } else if(!acceptable_rank(best_dag, best_dag->rank)) {
    PRINTF("RPL: New rank unacceptable!\n");
    instance->current_dag->preferred_parent = NULL;
    if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) {
      /* Send a No-Path DAO to the removed preferred parent. */
      dao_output(last_parent, RPL_ZERO_LIFETIME);
    }
    return NULL;
  }

  if(best_dag->preferred_parent != last_parent) {
    rpl_set_default_route(instance, &best_dag->preferred_parent->addr);
    PRINTF("RPL: Changed preferred parent, rank changed from %u to %u\n",
  	(unsigned)old_rank, best_dag->rank);
    RPL_STAT(rpl_stats.parent_switch++);
    if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
      if(last_parent != NULL) {
        /* Send a No-Path DAO to the removed preferred parent. */
        dao_output(last_parent, RPL_ZERO_LIFETIME);
      }
      /* The DAO parent set changed - schedule a DAO transmission. */
      RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
      rpl_schedule_dao(instance);
    }
    rpl_reset_dio_timer(instance);
  } else if(best_dag->rank != old_rank) {
    PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n",
  	(unsigned)old_rank, best_dag->rank);
  }
  return best_dag;
}
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_select_parent(rpl_dag_t *dag)
{
  rpl_parent_t *p, *best;

  best = NULL;
  for(p = list_head(dag->parents); p != NULL; p = p->next) {
    if(p->rank == INFINITE_RANK) {
      /* ignore this neighbor */
    } else if(best == NULL) {
      best = p;
    } else {
      best = dag->instance->of->best_parent(best, p);
    }
  }

  if(best != NULL) {
    dag->preferred_parent = best;
  }

  return best;
}
/*---------------------------------------------------------------------------*/
void
rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent)
{
  rpl_nullify_parent(dag, parent);

  PRINTF("RPL: Removing parent ");
  PRINT6ADDR(&parent->addr);
  PRINTF("\n");

  list_remove(dag->parents, parent);
  memb_free(&parent_memb, parent);
}
/*---------------------------------------------------------------------------*/
void
rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
{
  if(parent == dag->preferred_parent) {
    dag->preferred_parent = NULL;
    dag->rank = INFINITE_RANK;
    if(dag->joined) {
      if(dag->instance->def_route != NULL) {
	PRINTF("RPL: Removing default route ");
	PRINT6ADDR(&parent->addr);
	PRINTF("\n");
	uip_ds6_defrt_rm(dag->instance->def_route);
        dag->instance->def_route = NULL;
      }
      dao_output(parent, RPL_ZERO_LIFETIME);
    }
  }

  PRINTF("RPL: Nullifying parent ");
  PRINT6ADDR(&parent->addr);
  PRINTF("\n");
}
/*---------------------------------------------------------------------------*/
void
rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
{
  if(parent == dag_src->preferred_parent) {
      dag_src->preferred_parent = NULL;
      dag_src->rank = INFINITE_RANK;
    if(dag_src->joined && dag_src->instance->def_route != NULL) {
      PRINTF("RPL: Removing default route ");
      PRINT6ADDR(&parent->addr);
      PRINTF("\n");
      PRINTF("rpl_move_parent\n");
      uip_ds6_defrt_rm(dag_src->instance->def_route);
      dag_src->instance->def_route = NULL;
    }
  } else if(dag_src->joined) {
    /* Remove uIPv6 routes that have this parent as the next hop. */
    rpl_remove_routes_by_nexthop(&parent->addr, dag_src);
  }

  PRINTF("RPL: Moving parent ");
  PRINT6ADDR(&parent->addr);
  PRINTF("\n");

  list_remove(dag_src->parents, parent);
  parent->dag = dag_dst;
  list_add(dag_dst->parents, parent);
}
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_get_any_dag(void)
{
  int i;

  for(i = 0; i < RPL_MAX_INSTANCES; ++i) {
    if(instance_table[i].used && instance_table[i].current_dag->joined) {
      return instance_table[i].current_dag;
    }
  }
  return NULL;
}
/*---------------------------------------------------------------------------*/
rpl_instance_t *
rpl_get_instance(uint8_t instance_id)
{
  int i;

  for(i = 0; i < RPL_MAX_INSTANCES; ++i) {
    if(instance_table[i].used && instance_table[i].instance_id == instance_id) {
      return &instance_table[i];
    }
  }
  return NULL;
}
/*---------------------------------------------------------------------------*/
rpl_of_t *
rpl_find_of(rpl_ocp_t ocp)
{
  unsigned int i;

  for(i = 0;
      i < sizeof(objective_functions) / sizeof(objective_functions[0]);
      i++) {
    if(objective_functions[i]->ocp == ocp) {
      return objective_functions[i];
    }
  }

  return NULL;
}
/*---------------------------------------------------------------------------*/
void
rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
{
  rpl_instance_t *instance;
  rpl_dag_t *dag;
  rpl_parent_t *p;
  rpl_of_t *of;

  dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id);
  if(dag == NULL) {
    PRINTF("RPL: Failed to allocate a DAG object!\n");
    return;
  }

  instance = dag->instance;

  p = rpl_add_parent(dag, dio, from);
  PRINTF("RPL: Adding ");
  PRINT6ADDR(from);
  PRINTF(" as a parent: ");
  if(p == NULL) {
    PRINTF("failed\n");
    instance->used = 0;
    return;
  }
  p->dtsn = dio->dtsn;
  PRINTF("succeeded\n");

  /* Determine the objective function by using the
     objective code point of the DIO. */
  of = rpl_find_of(dio->ocp);
  if(of == NULL) {
    PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n",
        dio->instance_id);
    rpl_remove_parent(dag, p);
    instance->used = 0;
    return;
  }

  /* Autoconfigure an address if this node does not already have an address
     with this prefix. */
  if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
    check_prefix(NULL, &dio->prefix_info);
  }

  dag->joined = 1;
  dag->preference = dio->preference;
  dag->grounded = dio->grounded;
  dag->version = dio->version;

  instance->of = of;
  instance->mop = dio->mop;
  instance->current_dag = dag;
  instance->dtsn_out = RPL_LOLLIPOP_INIT;

  instance->max_rankinc = dio->dag_max_rankinc;
  instance->min_hoprankinc = dio->dag_min_hoprankinc;
  instance->dio_intdoubl = dio->dag_intdoubl;
  instance->dio_intmin = dio->dag_intmin;
  instance->dio_intcurrent = instance->dio_intmin + instance->dio_intdoubl;
  instance->dio_redundancy = dio->dag_redund;
  instance->default_lifetime = dio->default_lifetime;
  instance->lifetime_unit = dio->lifetime_unit;

  memcpy(&dag->dag_id, &dio->dag_id, sizeof(dio->dag_id));

  /* Copy prefix information from the DIO into the DAG object. */
  memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t));

  dag->preferred_parent = p;
  instance->of->update_metric_container(instance);
  dag->rank = instance->of->calculate_rank(p, 0);
  /* So far this is the lowest rank we are aware of. */
  dag->min_rank = dag->rank;

  if(default_instance == NULL) {
    default_instance = instance;
  }

  PRINTF("RPL: Joined DAG with instance ID %u, rank %hu, DAG ID ",
         dio->instance_id, dag->rank);
  PRINT6ADDR(&dag->dag_id);
  PRINTF("\n");

  ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);

  rpl_reset_dio_timer(instance);
  rpl_set_default_route(instance, from);

  if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
    rpl_schedule_dao(instance);
  } else {
    PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n");
  }
}

/*---------------------------------------------------------------------------*/
void
rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
{
  rpl_instance_t *instance;
  rpl_dag_t *dag, *previous_dag;
  rpl_parent_t *p;
  rpl_of_t *of;

  dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id);
  if(dag == NULL) {
    PRINTF("RPL: Failed to allocate a DAG object!\n");
    return;
  }

  instance = dag->instance;

  previous_dag = find_parent_dag(instance, from);
  if(previous_dag == NULL) {
    PRINTF("RPL: Adding ");
    PRINT6ADDR(from);
    PRINTF(" as a parent: ");
    p = rpl_add_parent(dag, dio, from);
    if(p == NULL) {
      PRINTF("failed\n");
      dag->used = 0;
      return;
    }
    PRINTF("succeeded\n");
  } else {
    p = rpl_find_parent(previous_dag, from);
    if(p != NULL) {
      rpl_move_parent(previous_dag, dag, p);
    }
  }

  /* Determine the objective function by using the
     objective code point of the DIO. */
  of = rpl_find_of(dio->ocp);
  if(of != instance->of ||
     instance->mop != dio->mop ||
     instance->max_rankinc != dio->dag_max_rankinc ||
     instance->min_hoprankinc != dio->dag_min_hoprankinc ||
     instance->dio_intdoubl != dio->dag_intdoubl ||
     instance->dio_intmin != dio->dag_intmin ||
     instance->dio_redundancy != dio->dag_redund ||
     instance->default_lifetime != dio->default_lifetime ||
     instance->lifetime_unit != dio->lifetime_unit) {
    PRINTF("RPL: DIO for DAG instance %u uncompatible with previos DIO\n",
	   dio->instance_id);
    rpl_remove_parent(dag, p);
    dag->used = 0;
    return;
  }

  dag->used = 1;
  dag->grounded = dio->grounded;
  dag->preference = dio->preference;
  dag->version = dio->version;

  memcpy(&dag->dag_id, &dio->dag_id, sizeof(dio->dag_id));

  /* copy prefix information into the dag */
  memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t));

  dag->preferred_parent = p;
  dag->rank = instance->of->calculate_rank(p, 0);
  dag->min_rank = dag->rank; /* So far this is the lowest rank we know of. */

  PRINTF("RPL: Joined DAG with instance ID %u, rank %hu, DAG ID ",
         dio->instance_id, dag->rank);
  PRINT6ADDR(&dag->dag_id);
  PRINTF("\n");

  ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);

  rpl_process_parent_event(instance, p);
  p->dtsn = dio->dtsn;
}

/*---------------------------------------------------------------------------*/
static void
global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
{
  rpl_parent_t *p;

  remove_parents(dag, 0);
  dag->version = dio->version;
  dag->instance->of->reset(dag);
  dag->min_rank = INFINITE_RANK;
  RPL_LOLLIPOP_INCREMENT(dag->instance->dtsn_out);

  p = rpl_add_parent(dag, dio, from);
  if(p == NULL) {
    PRINTF("RPL: Failed to add a parent during the global repair\n");
    dag->rank = INFINITE_RANK;
  } else {
    dag->rank = dag->instance->of->calculate_rank(p, 0);
    dag->min_rank = dag->rank;
    rpl_process_parent_event(dag->instance, p);
  }

  PRINTF("RPL: Participating in a global repair (version=%u, rank=%hu)\n",
         dag->version, dag->rank);

  RPL_STAT(rpl_stats.global_repairs++);
}
/*---------------------------------------------------------------------------*/
void
rpl_local_repair(rpl_instance_t *instance)
{
  int i;

  PRINTF("RPL: Starting a local instance repair\n");
  for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
    if(instance->dag_table[i].used) {
      instance->dag_table[i].rank = INFINITE_RANK;
      nullify_parents(&instance->dag_table[i], 0);
    }
  }

  rpl_reset_dio_timer(instance);

  RPL_STAT(rpl_stats.local_repairs++);
}
/*---------------------------------------------------------------------------*/
void
rpl_recalculate_ranks(void)
{
  rpl_instance_t *instance, *end;
  rpl_parent_t *p;
  int i;

  /*
   * We recalculate ranks when we receive feedback from the system rather
   * than RPL protocol messages. This periodical recalculation is called
   * from a timer in order to keep the stack depth reasonably low.
   */
  for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
    if(instance->used) {
      for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
        if(instance->dag_table[i].used) {
          for(p = list_head(instance->dag_table[i].parents); p != NULL; p = p->next) {
            if(p->updated) {
              p->updated = 0;
              if(!rpl_process_parent_event(instance, p)) {
                PRINTF("RPL: A parent was dropped\n");
              }
	      /*
	       * Stop calculating here because the parent list may have changed.
	       * If more ranks need to be recalculated, it will be taken care of
	       * in subsequent calls to this functions.
	       */
              break;
            }
          }
        }
      }
    }
  }
}
/*---------------------------------------------------------------------------*/
int
rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
{
  rpl_rank_t old_rank;
  int return_value;

  old_rank = instance->current_dag->rank;
  return_value = 1;

  if(!acceptable_rank(p->dag, p->rank)) {
    /* The candidate parent is no longer valid: the rank increase resulting
       from the choice of it as a parent would be too high. */
    PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank);
    if(p != instance->current_dag->preferred_parent) {
      rpl_nullify_parent(p->dag, p);
      return 0;
    } else {
      rpl_nullify_parent(p->dag, p);
      return_value = 0;
    }
  }

  if(rpl_select_dag(instance, p) == NULL) {
    /* No suitable parent; trigger a local repair. */
    PRINTF("RPL: No parents found in any DAG\n");
    rpl_local_repair(instance);
    return 0;
  }

#if DEBUG
  if(DAG_RANK(old_rank, instance) != DAG_RANK(instance->current_dag->rank, instance)) {
    PRINTF("RPL: Moving in the instance from rank %hu to %hu\n",
	   DAG_RANK(old_rank, instance), DAG_RANK(instance->current_dag->rank, instance));
    if(instance->current_dag->rank != INFINITE_RANK) {
      PRINTF("RPL: The preferred parent is ");
      PRINT6ADDR(&instance->current_dag->preferred_parent->addr);
      PRINTF(" (rank %u)\n",
           (unsigned)DAG_RANK(instance->current_dag->preferred_parent->rank, instance));
    } else {
      PRINTF("RPL: We don't have any parent");
    }
  }
#endif /* DEBUG */

  return return_value;
}
/*---------------------------------------------------------------------------*/
void
rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
{
  rpl_instance_t *instance;
  rpl_dag_t *dag, *previous_dag;
  rpl_parent_t *p;

  if(dio->mop != RPL_MOP_DEFAULT) {
    PRINTF("RPL: Ignoring a DIO with an unsupported MOP: %d\n", dio->mop);
    return;
  }

  dag = get_dag(dio->instance_id, &dio->dag_id);
  instance = rpl_get_instance(dio->instance_id);

  if(dag != NULL && instance != NULL) {
    if(lollipop_greater_than(dio->version, dag->version)) {
      if(dag->rank == ROOT_RANK(instance)) {
	PRINTF("RPL: Root received inconsistent DIO version number\n");
	dag->version = dio->version;
	RPL_LOLLIPOP_INCREMENT(dag->version);
	rpl_reset_dio_timer(instance);
      } else {
	global_repair(from, dag, dio);
      }
      return;
    }

    if(lollipop_greater_than(dag->version, dio->version)) {
      /* The DIO sender is on an older version of the DAG. */
      PRINTF("RPL: old version received => inconsistency detected\n");
      if(dag->joined) {
	rpl_reset_dio_timer(instance);
	return;
      }
    }
  }

  if(dio->rank == INFINITE_RANK) {
    PRINTF("RPL: Ignoring DIO from node with infinite rank: ");
    PRINT6ADDR(from);
    PRINTF("\n");
    return;
  }

  if(instance == NULL) {
    PRINTF("RPL: New instance detected: Joining...\n");
    rpl_join_instance(from, dio);
    return;
  }

  if(dag == NULL) {
    PRINTF("RPL: Adding new DAG to known instance.\n");
    rpl_add_dag(from, dio);
    return;
  }

  if(dio->rank < ROOT_RANK(instance)) {
    PRINTF("RPL: Ignoring DIO with too low rank: %u\n",
           (unsigned)dio->rank);
    return;
  } else if(dio->rank == INFINITE_RANK && dag->joined) {
    rpl_reset_dio_timer(instance);
  }

  if(dag->rank == ROOT_RANK(instance)) {
    if(dio->rank != INFINITE_RANK) {
      instance->dio_counter++;
    }
    return;
  }

  /*
   * At this point, we know that this DIO pertains to a DAG that
   * we are already part of. We consider the sender of the DIO to be
   * a candidate parent, and let rpl_process_parent_event decide
   * whether to keep it in the set.
   */

  p = rpl_find_parent(dag, from);
  if(p == NULL) {
    previous_dag = find_parent_dag(instance, from);
    if(previous_dag == NULL) {
      if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DAG) {
        /* Make room for a new parent. */
        remove_worst_parent(dag, dio->rank);
      }
      /* Add the DIO sender as a candidate parent. */
      p = rpl_add_parent(dag, dio, from);
      if(p == NULL) {
        PRINTF("RPL: Failed to add a new parent (");
        PRINT6ADDR(from);
        PRINTF(")\n");
        return;
      }
      PRINTF("RPL: New candidate parent with rank %u: ", (unsigned)p->rank);
      PRINT6ADDR(from);
      PRINTF("\n");
    } else {
      p = rpl_find_parent(previous_dag, from);
      if(p != NULL) {
        rpl_move_parent(previous_dag, dag, p);
      }
    }
  } else {
    if(p->rank == dio->rank) {
      PRINTF("RPL: Received consistent DIO\n");
      if(dag->joined) {
        instance->dio_counter++;
      }
    } else {
      p->rank=dio->rank;
    }
  }

  PRINTF("RPL: preferred DAG ");
  PRINT6ADDR(&instance->current_dag->dag_id);
  PRINTF(", rank %u, min_rank %u, ",
	 instance->current_dag->rank, instance->current_dag->min_rank);
  PRINTF("parent rank %u, parent etx %u, link metric %u, instance etx %u\n",
	 p->rank, p->mc.obj.etx, p->link_metric, instance->mc.obj.etx);

  /* We have allocated a candidate parent; process the DIO further. */

  memcpy(&p->mc, &dio->mc, sizeof(p->mc));
  if(rpl_process_parent_event(instance, p) == 0) {
    PRINTF("RPL: The candidate parent is rejected\n");
    return;
  }

  /* We don't use route control, so we can have only one official parent. */
  if(dag->joined && p == dag->preferred_parent) {
    if(should_send_dao(instance, dio, p)) {
      RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
      rpl_schedule_dao(instance);
    }
  }
  p->dtsn = dio->dtsn;
}
/*---------------------------------------------------------------------------*/


Star2Star Communications today announced a partnership with Bigleaf, the cloud-first SD-WAN service that optimizes internet and cloud performance by dynamically choosing the best connection and adapting application prioritization in real-time.
Star2Star's Full Spectrum Communications Solution has been making waves in the UC space with the recent release of StarSystem® Hosted which, according to the company, is the first truly end-to-end communications solution.
Star2Star and Bigleaf have established a partnership as part of this effort to provide end-to-end network optimization through the Full Spectrum product portfolio. Bigleaf's SD-WAN technology enhances communications by adapting to real-time network changes. Together Star2Star and Bigleaf deliver a prioritization of cloud, voice, and data services ensuring that the network performance for these critical business components is fully maximized.


If you have used eduroam in the past, first refer to this FAQ to remove any existing settings profiles.
The next step is to load a settings profile on to your iPhone / iPod Touch / iPad. When the profile loads, you should choose Install, enter your RBC username with @bruford.ac.uk added on to the end e.g. ab1234@bruford.ac.uk, and then enter your password.
If you are asked for a four digit number, this is your iPhone / iPod Touch / iPad's PIN number – it will be whatever you set it to.


Australian melodic death metal band Be'lakor have announced that their upcoming second release will be entilted "Stone's Reach." "Stone's Reach", the follow-up to the 2007 debut "The Frail Tide", is due to be released in June 2009. The album clocks in at around 55 minutes.
The online release of some of the new songs from this album is due in late April.
The cover art for Be'lakor's upcoming album "Stone's Reach" has been revealed here. Artwork was done by Sheri Tantawy at The Bodycage Media.
According to a press release, Be'lakor's highly anticipated second album, "Stone's Reach", is set for release on June 20, 2009. Be'lakor will be venturing across Australia for the first time, taking in performances in Melbourne, Adelaide, Brisbane & Sydney.
An additional Sydney date will be announced later.
Excellent, with hopefully a tour to follow!
Belakor is a great band!
Saw them live with NeObliviscaris, excellent mosh material.
Their first album was great!!! let's hope this will be too!! the cooer artwork is awesome!!!
"Artwork was done by Sheri Tantawy at The Bodycage Media." - She also did the artwork on Switchblade's new album and is also Sheri from Black Like Vengeance.
I can't wait for this album and can't wait to see them live. I just hope their Sydney gig doesn't end up being booked for the 18th July.


I wore a refashioned sweater with doilies and lace that I added on and in (one) day I had eight women approach me to ask where I got it.
Because each bride's unique personality is best reflected in her wedding gown, Ashford says brides want to add their own styles to refashioned heirlooms--or, in some cases, vice versa.
At the Falcon Theatre, he and composer/lyricist Paul Williams have refashioned ``Happy Days'' into a two-hour, movie-length single episode with a bunch of lesser plot threads lining up without jockeying each other for position.
And in his remarkable 1995 encyclical Ut Unum Sint John Paul offered an unprecedented invitation to other Christian leaders to enter into dialogue with him regarding how the papacy, within the limits of received doctrine, might be refashioned to become a ministry of unity for all Christian churches.
When in Rome ... once Pope Benedict XVI gets settled into his new apartment at St. Peter's, will he follow in John Paul II's footsteps or find his own way?
In 1989 I moved back to London, refashioned my portfolio, and wrangled an ad agency job reporting to a capriciously sadistic creative director.
The very next year a shining image of a towering Nichols graced NYCB's program cover, resplendent in the shimmering golds that defined the lacy wings and the almost-liquid train of the costume Karinska refashioned for Balanchine's Firebird.
Martin observes that Middleton's city comedies foreground the economic energies by which families are disrupted and refashioned in accordance with the values of commodity and exchange.
In Youngquist's refashioned story, the family Gruff--Little Billygoat, Williegoat, and Captain Bill E.
The company, originally an online pet sup ply retailer, refashioned itself as a traditional mail-order pet supply company after its August 1999 purchase of Humboldt Industries Inc.
Kaiser, for one, appears to be obeying the rules, although he has used the considerable political power his wealth brings to get some of those rules refashioned to his liking.
McNeill compares us to cyanobacteria, which refashioned the world's atmosphere two billion years ago by excreting oxygen and increasing its presence in the air from one part per trillion to the current one-fifth.
Enron has refashioned itself to be a one-stop energy shop for electricity, gas, and telecom bandwidth.


I'll be completely honest. I was skeptical of spending my summer working in a Microsoft stack, primarily because Microsoft receives a lot of flak in the undergraduate Computer Science community at Penn (and I'm sure elsewhere too). It seems as if students regard anything resembling open source as the best thing since sliced bread and condemn any proprietary tools as the plague of our industry. Classmates regaled me with horror stories about the awfulness of C# and the bloated software that results. I was left with a pretty bleak picture.
After having worked with C#/.NET for a few weeks now, I can say I've been oh so pleasantly surprised. From the automatic properties and lambda expressions of C# to the ubiquity and ease of WCF applications, I love working in it. Do I miss developing in Linux? Sure. Will I ditch Python and move everything to .NET? Absolutely not. But if I have to write a desktop application or a service to link a couple Windows machines together, you can bet I'll pick C# over Java every day of the week and twice on Sunday.


E. B. White circled his office, straightening the pictures on the wall until the work waiting on his desk demanded his attention. Toni Morrison, a mother of three, set her alarm & brewed a strong pot of coffee so she could work before the kids got up—& continues to do so even though those kids are grown. Victor Hugo had his valet hide his clothes, forcing him to stay in office until the day's work was done.
Whether much-published or new to the trade, every writer has a ritual for getting to the desk. I do a lot of desk-rearranging (much of it now on the MacBook, of course) before I sneak a look at what I'm working on. I tell myself I'll just read a few paragraphs. Then, before I know it, I'm once again immersed in the work itself.
". . .good writing. . .
is a daily exercise in psychic terror."
Why such elaborate ruses? Because good writing (and by good, I mean writing that connects with readers) is a daily exercise in psychic terror. In From Where You Dream, Robert Olen Butler asserts that our daily practice requires us to delve deep into the darkest recesses of our memories, to go to the dark places where the best writing resides. No wonder we need rituals to help us.
What gets you to the desk? Do you have a pre-writing ritual? Join the conversation on the Authorlink Facebook page. We'd love to hear from you, and we'll publish your comments as part of this column.
Lisa Lenard-Cook is a regular columnist for Authorlink. She is an award-winning published author and writing instructor. Read more about Lisa.


'Kill the Debbie Downers! Kill Them! Kill Them! Kill Them Off!" illustrates how vulnerable we all are. The energetic singing, dancing, leaping cast invites us to a Big Party! Set Designer Mikiko Uesugi has remodeled Shotgun Players' intimate stage to look like a meat locker. Three windows hang precariously, their silvery tint fogging any view. The grey and brown industrial set is cold—a century is ending.
The only warmth comes from an antique grand piano, reminding us, that this is indeed an old country house.
Shotgun Players' new 'theater piece' invokes Chekhov's tragi-comic 1900 "Three Sisters," employing the old, the new, and the fearful. Co-directors Mark Jackson and Beth Wilmurt explore past Czarist oppression and future liberation in timely, poignant waves. They reach out to us with visceral movement, powerful songs, and images of pain.
A suspended TV screen floats in darkness, showing the California wildfires. We see shocking videos of the Orlando nightclub and Las Vegas concert massacres. Jackson and Wilmurt warn that "particularly normal" days give rise to horrible events.
Interactive "Kill the Debbie Downers!" proves that all theatre is political and made for the present. Chekhov's three Russian sisters recount their memories, itching to leave the backwoods and return to their beloved Moscow. Eldest sister Olga (enigmatic Sam Jackson), sultry middle child Masha (serious Erin Mei-Ling Stuart), and troublemaker Irina (mischievous Gabby Battista) feel trapped in the 'burbs.
School Teacher Olga re-enacts one scene three times; her body language, tone of voice, and facial expressions make each one fresh. Masha, a seductive, dancing queen, crawls across the floor, reminiscing—she wants her man back.
Stuck in the past, the Three Sisters yearn for Moscow, for city life. Their socially awkward city-based sister in law Natasha (dorky Amanda Farbstein) adds to their envy. Watch for a single accordion, a butcher's knife, and tying a cherry stem with your tongue—like circus marvels. But the multi-talented crew sings, dances, and leaps into the air to express frustration—it's the end of old ways. A revolution is coming.
Soldier Solyony (intimidating Nathaniel Andalis) suffers unrequited love for Irina. His fears force him to remove any rival, including a fiance and father. Solyony spritzes his hands with antiseptic to remove the smell of death.
Out of frustration, Solyony brandishes a massive butcher knife to cut off the offending appendage. As the light illuminates him, he stops the action to point out the fire exits. He says, "In theaters over 1000 seats, it's not necessary to mention such things." He asks: Why do only poor people need to know these things, are the poor too stupid to realize basic safety measures? Solyony makes a remarkable villain.
"Kill the Debbie Downers!" expertly combines exciting song, dance, and live music. In the madness of the party, we comprehend that our present political/social system, too, occupies but a moment. How long will we go on in this fantasy?
Cast: Nathaniel Andalis, Gabbu Battista, Amanda Farbstein, Sam JAckson, Erin Mei-Ling Stuart, and Billy Raphael.


text:
Governance & Historic Documents
Miscellaneous Regulations
Section 1: Nomination & Election of Alumni Fellows
Section 2: Protection of the Yale Name
Section 3: Patent Policy
Section 4: Research Use of the University Archives
Section 5: Residential College Fellowships
Section 6: Replacement Diplomas & Certificates of Graduation
Section 7: Academic Costume
Section 8: Degrees
Section 1. Nomination & Election of Alumni Fellows
I. Nomination by the Standing Committee of the Yale Alumni Association (YAA) for the Nomination of Alumni Fellows (the Committee).
A. The Committee shall be constituted no later than July 1 of each year.
The Committee shall consist of the following members:
the entire Board of Governors (including officers, collectively the "Board") of the YAA or not fewer than six members of the Board as appointed by the Chair of the YAA Board of Governors;
one Fellow of the Yale Corporation appointed by the Yale Corporation's Trusteeship Committee;
ex officiis members as follows:
a. the Chair of the YAA Board of Governors
b. the University officer(s) with responsibility for Alumni Affairs and Development or such officer's designee(s)
c. the Secretary of the University or the Secretary's designee
d. the President of the University Council; and
the Executive Director of the YAA, who shall serve as the Committee's nonvoting Secretary.
ii. Terms
YAA Board members serve at the discretion of the Chair of the YAA Board of Governors. If fewer than all Board members serve, those who do shall be appointed to serve one-year terms. No Board member may serve more than three consecutive one-year terms. If a Board member of the Committee resigns prior to the completion of such Board member's term, a new appointee shall fill the unexpired portion of the term.
The Fellow of the Yale Corporation shall serve for one year but may be reappointed by the Corporation's Trusteeship Committee.
Ex officiis members shall serve as long as they remain in their respective offices as indicated in subparagraph I.A.i.
The Executive Director of the YAA shall serve as long as s/he remains in office as indicated in subparagraph I.A.i.
iii. Eligibility
Committee membership requires that
no YAA Board member shall be eligible for reappointment to the Committee until one year after the expiration of the member's previous term of service; and
no Fellow of the Yale Corporation shall be appointed during the Fellow's first year of service on the Corporation.
iv. Leadership
The Committee's Chair shall be appointed by the Chair of the YAA Board of Governors from among the YAA Board members on the Committee.
B. The Committee shall meet promptly and frequently so as to complete candidate selection by February 1.
i. Method of selection
Candidates shall be selected as follows:
The Committee shall solicit candidate recommendations from members of the YAA Assembly, duly-elected leaders of constituencies entitled to representation on the YAA Assemblies (classes, clubs, the Graduate School and professional schools' alumni associations, and the senior class of Yale College), and other such groups as the Committee deems appropriate.
All candidate recommendations shall be sent to the Secretary of the Committee or the Secretary of the Committee's designee to determine eligibility and then for Committee consideration.
ii. Candidate eligibility
When reviewing candidates, the Committee shall note that:
All candidates must be Yale graduates of the first degree who graduated at least five years ago or graduates who have received any degree higher than the first in the University, whether honorary or in course.
Alumni Fellows who have served full terms may be candidates again after they have been off the Yale Corporation for one year.
Candidates must be at least age thirty, in keeping with the University Charter's provisions regarding Alumni Fellows.
iii. Number of candidates
The Committee shall name for each Alumni Fellow vacancy due to occur in that year a sufficient number of nominees so that the total number of nominees for such vacancy shall be no fewer than two nor more than five.
C. The Committee's report of nominees shall be completed by February 1.
i. Nominee consent
The Chair of the Committee shall secure the consent of each nominee to stand for election.
ii. Nominee withdrawal
Nominees who wish to withdraw shall notify the Chair of the Committee in writing before February l5.
iii. Statement of qualifications
The Secretary of the Committee or the Secretary of the Committee's designee shall prepare a factual statement of qualifications for each nominee. It shall include degree and year, department or school, residence, occupation, and other information that may be of value in assisting voters to make a choice. The Secretary of the Committee or the Secretary of the Committee's designee shall deliver the statements to the Secretary of the University or the Secretary of the University's designee no later than March 1.
II. Election
A. Report
The Secretary of the Committee or the Secretary of the Committee's designee shall report the Committee's nominations to the Secretary of the University or the Secretary of the University's designee no later than February 1.
B. Qualified Electors
All graduates of the first degree of five or more years standing and all persons that have been admitted to any degree higher than the first in the University, whether honorary or in course, may vote.
C. Election materials
The Secretary of the University or the Secretary's designee shall prepare and send election materials to all Qualified Electors no later than May 1. The election materials shall contain:
i. Biographical sketch. The Secretary of the University or the Secretary's designee shall prepare a short biographical sketch of each candidate incorporating the official statement of qualifications of the candidates, as defined in 1.I.C.iii. above. The Secretary or the Secretary's designee may forward to each candidate such candidate's own sketch for review but shall make all final judgments about the sketches.
ii. Additional background information. The Secretary or the Secretary's designee may collect additional background information from and about the candidates for internal purposes or for the purpose of providing additional information to the electorate.
iii. Ballot. The official ballot shall contain the names of nominees listed in alphabetical order with their residences, years of graduation, and a space for indicating the elector's vote. No votes shall be counted that are not received on this ballot or by other certified voting means.
iv. Ballot return envelope. The return envelope shall be clearly marked "Alumni Fellow Ballot" and addressed to the Secretary of the University or the Secretary's designee.
v. Other information. The Secretary of the University or the Secretary's designee may include other information pertinent to the election.
D. Replacement ballot
A replacement ballot may be issued to a Qualified Elector only upon written application to the email address or address established for that purpose and published on the university's website, stating that the original ballot was lost, mutilated, or destroyed.
E. Voting
i. Electors may vote for as many candidates as there are vacancies to be filled. The manner by which electors may cast their votes shall be determined by the Yale Corporation, provided that:
adequate safeguards are in place to ensure that each elector may cast only one vote;
the confidentiality of each elector is guaranteed; and
the accuracy of the tally is ensured.
ii. All votes, regardless of the method of voting, must be cast before the polls close; as provided in the Charter, the polls close on the day next preceding the commencement day of Yale University. The candidate(s) who receive(s) the greatest number of votes shall be elected Alumni Fellow(s) of the Yale Corporation. The candidate who receives the greatest number of votes shall serve for the longest term when there is more than one vacancy.
F. Certification and results
i. The Secretary of the University or the Secretary's designee shall appoint a third party to certify the election and to report the results to the President of the University.
ii. The President of the University shall ensure that the Chair of the Committee, the Yale Corporation, and the candidates are notified and shall announce the results publicly. The term of the elected Alumni Fellow(s) shall commence on July 1 following the election.
G. Ballot preservation
The Secretary of the University or the Secretary's designee shall preserve all ballots and other records of voting for a period of two months after the results are announced.
H. Reopening of slate
In the event of a candidate's death, incapacity, or late withdrawal from an election for any reason, the Yale Corporation shall have the right to reopen the slate to fill the vacancy left by the former candidate. In such event, the Corporation may direct the Secretary of the University or the Secretary's designee to consult with the Alumni Fellow Nominating Committee to provide a substitute candidate for election. The Secretary of the University or the Secretary's designee shall then, as soon as practicable, prepare and send revised election materials to all qualified electors.
I. Enforcement
The Secretary of the University enforces the proper use of the name, seal, coat of arms, and other insignia of the University, Yale College, the Graduate School, and the professional schools.
II. General Use
A. The use of the name "Yale University," "Yale College," or "Yale" as titles or captions of publications, organizations, etc., implying or tending to imply some official connection with the University is prohibited, except with the written permission of the Secretary of the University or his or her duly authorized agents, and under such restrictions and explanations as he, she or they may impose.
B. The schools, departments, and other offices of the University may use the Yale name, the coat of arms, and other insignia of the University, Yale College, the Graduate School, and the professional schools on stationery, reprints, etc., in accordance with policy established by the Secretary of the University.
C. When an official or other employee of the University uses his or her name in connection with the authorship of a book or article or for a lecture or other appearance where it is stated or implied that he or she is associated with the University, his or her exact University title or position shall be specified.
III. Licensing
Use of the name, the coat of arms, and other insignia of the University, Yale College, the Graduate School, and the professional schools may be licensed by the Secretary of the University under such terms as he or she shall determine.
IV. Yale Seal
The Yale seal is to be used only to authenticate documents bearing the signature of Officers of Yale University and for such other official purposes of the University as the Yale Corporation prescribes.
I. Encouragement of Patents
In the course of teaching, research, and other intellectual and administrative activity by faculty, staff, fellows, students, and other individuals in the University community, discoveries or inventions both patentable and practical occur. Encouragement of such inventions in appropriate ways is both supportive of the public interest and consistent with the advancement of knowledge for its own sake, the primary purpose of teaching and research in a university. The University Patent Policy states the procedure to be followed in the administration of inventions which result from teaching, research, and other intellectual activity performed under University auspices except as further defined in paragraph VI.
II. Purpose of Patent Policy
The purposes of this University Patent Policy are:
A. to help assure, in the public interest, that the patentability (or other means of exploitation) and practicality of inventions will be evaluated by qualified persons and that the income from inventions will be used to support further research or other desirable University activities; and
B. to define remunerations to the inventor or inventors (hereinafter the "Inventor") and the University as long as the invention is productive of royalties.
III. Procedure as to Inventions
The University has established a Committee on Cooperative Research, Patents, and Licensing appointed from among members of the faculty and administration. One function of the Committee is to advise the University on matters of patents policy and administration. The University has also established an Office of Cooperative Research to facilitate transfer of its inventions/discoveries in the public interest.
A. Patent Applications. All inventions of the kind referred to in paragraph I shall be reported promptly in writing to the Provost through the Director of the Office of Cooperative Research. The Director, with the advice of the Committee on Cooperative Research, Patents, and Licensing, shall conduct an initial screening followed, when indicated, by a detailed evaluation of the invention. This may be done through an internal review, or by referral to an external organization that manages the evaluation. After evaluation, the University may, alone or with the assistance of an external organization, make application for letters patent. At the request of the Office of Cooperative Research, the Inventors shall execute assignments or other documents assigning to the University all their rights in the invention and any patent applications or resulting patents on the invention. Yale will retain title to all such patent applications and resulting patents. If the University decides that it does not wish, and has no legal obligation, to participate in the patenting or licensing of an invention, the University may release to the Inventor the University's interest in the invention, and the Inventor shall then be free to dispose of the invention as he or she wishes.
B. License Agreement.
i. If the University decides to participate in the patenting or licensing of an invention, the Office of Cooperative Research will seek to enter into appropriate licensing arrangements to commercialize the invention. The objective of the University is to assure the development of its technology in furtherance of its own educational mission and for the benefit of society in general. Therefore, as a general policy, the University will set the terms of its licenses so as to further the achievement of this objective. Exclusive licenses will be granted if it appears to the Office of Cooperative Research that this is the most effective way of ensuring development to the point that the public will benefit. Any exclusive license agreement will be so drawn as to protect against failure of the licensee to carry out effective development and marketing within a specified time period.
ii. In research grants or contracts sponsored by industrial companies there will typically be a section covering patents on future inventions, if any, as in all government grants. When deemed appropriate, the sponsor may be granted a license to any inventions developed during the term of the grant or contract in accordance with the policies outlined in i) above.
IV. Royalties
A. Definition. For purposes of this policy, "royalties" shall include running royalties, advances against running royalties, up-front license fees, milestone payments, shares of stock or other securities issued by the licensee or another corporation ("equity"), and any other payments received by the University under a license agreement in consideration for licensing and invention, but shall not include amounts received from a licensee or others in sponsorship of research or under other agreements for other goods, services or rights.
B. Recovery of Expenses. Royalties shall be used first to offset out-of-pocket expenses incurred by the University in applying for, obtaining, and defending a patent and in developing and negotiating license agreements during the life of the patent. Expenses for this purpose will include fees paid to outside legal, consulting, and licensing organizations and any other out-of-pocket costs incurred by the University. The fees paid to the external individuals or organizations for such services may be of fixed dollar amount or may be in the form of an agreed-upon fraction of the gross royalty income, if any, or in any other form directly associated with commercialization/licensing of the invention. In addition, 10% of Royalties, after reduction as provided above for out-of-pocket expenses, received in any year from an invention made on or after April 11, 1992, shall be retained by the University and applied toward the general support of the Office of Cooperative Research; provided, that if the total of such recoveries in any year exceeds the Office's approved budget, the excess shall be allocated on a pro rata basis among those inventions from which it was recovered and shall be distributed as part of Net Royalties in accordance with subparagraph D).
C. Net Royalties. After recovery of expenses by the University as provided in subparagraph B), the remaining royalties will be designated Net Royalties.
D. Distribution of Net Royalties. The Net Royalties as defined above shall be divided between the Inventor(s) (as defined under the patent law) and the University as follows:
i. The first $100,000 of Net Royalties
50% to the Inventor(s)
50% allocated to the general support of University research as described in paragraph V.
ii. Net Royalties between $100,000 and $200,000
iii. Net Royalties exceeding $200,000
For purposes of applying the above Net Royalty distribution formula (i.e., whether aggregate Net Royalties are $100,000 or less, between $100,000 and $200,000, or more than $200,000), equity shall be deemed to have the per-share value agreed upon in a good-faith negotiation between the University and the licensee at the time the license agreement is executed, and the equity shall be deemed received after all cash Net Royalties received at or before the time the equity is issued. In the absence of such negotiated value, the Inventors shall receive 32% of the equity Net Royalties.
In its discretion, the University may either distribute equity to the Inventor(s) when it is received or arrange for the licensee to issue the Inventor's share of equity directly to the Inventor(s).
As used in this document, the term "Inventor" may represent two or more individuals. These individuals will be expected to agree among themselves on the fractional distribution of the "Inventor" share of any royalties. A written agreement must be signed by all the individuals involved, and deposited for the record in the Office of Cooperative Research. (Appropriate forms are available from the Office of Cooperative Research.) If no written agreement has been deposited at the time of a distribution of Net Royalties, the Inventors' share of such distribution shall be divided equally among the Inventors.
E. Overriding Agreements with Third Parties. The foregoing provisions of this paragraph and the rest of this University Patent Policy are subject to the terms of applicable grants and contracts with third parties. See paragraph VII.
V. General Research Support from Net Royalties
The University's share of Net Royalties will be used in support of research, or if not specifically prohibited by the funding agency contract, will accrue to the Science Development Fund or other appropriate research fund, and will be allocated by the Provost. Before allocating funds, the Provost shall, consult with the relevant subdivision of the University concerning the research to be supported.
VI. Inventions Not Under University Auspices
Inventions by University employees usually result from teaching, research, or other intellectual activity involving University facilities or personnel. Accordingly, all inventions by University employees must be reported to the Office of Cooperative Research. When the University determines that an invention by a University employee is unrelated to the activities for which the individual is employed and has not involved the use of University facilities, then the University will make no claim to such an invention. All inventions made or conceived under circumstances involving University facilities or personnel are the property of the University.
An invention made by a faculty member in the course of a paid consulting engagement for a company may be assigned to the company only if it is unrelated to the activities for which the faculty member is employed by Yale and it was not made or conceived under circumstances involving University facilities or personnel. Such an invention will be considered unrelated to the activities for which the faculty member is employed by Yale if the invention arises directly out of consulting activity paid for by the company, and, for example, it is made in response to a problem posed by the company or is based on nonpublic information provided by the company to the faculty member for use in the consulting engagement. It will be considered not to have involved the use of University facilities if no University facilities or resources (including but not limited to space, computers, laboratory equipment and supplies), no University-administered funds, and no University personnel other than the faculty member himself or herself, are involved in the conception or reduction to practice of the invention. All inventions made by Yale faculty members in the course of consulting, and any assignments of rights to such inventions, must be reported promptly to the Office of Cooperative Research. That Office will agree to abide by reasonable confidentiality restrictions for disclosures of inventions and assignments made in the course of consulting.
VII. When Arrangements with Outside Organizations Override this Policy
Arrangements with outside organizations that propose terms that are exceptions to this Policy must be submitted to the President or Provost for review by the University with the advice of the Committee on Cooperative Research, Patents, and Licensing. If approved by the University the terms shall be binding upon all members of the faculty, staff, and employees of the University conducting such research or utilizing such facilities, and will supersede the provisions of the patent policy to the extent that the terms are inconsistent therewith.
VIII. Inventions by Staff Resulting from Performance of the Responsibilities of Their Employment
Not infrequently, in the course of carrying out assigned responsibilities of their employment, staff employees may make commercially useful inventions or develop licensable property (i.e., the employee received salary or wages for the specific function of developing the work which ultimately has commercial value). In such cases, there is no presumption that the University will share royalty (or other) revenues with the employee. Normally, the University does not share revenues with staff except in cases where it appears that the invention or commercially valuable property has not resulted from the performance of assigned duties. In these instances, the invention (or other commercially valuable work) will be reviewed by the Committee on Cooperative Research, Patents, and Licensing and a recommendation will be made to the Provost. In these cases, the division of royalties as specified in paragraph IV.D) of this policy may not apply and the Provost may substitute different provisions after review of the recommendations of the Committee on Cooperative Research, Patents, and Licensing.
IX. Governmental Rights in Certain Inventions
Current governmental regulations permit educational institutions to retain rights and title to patentable inventions which result from federally funded experimental, developmental and research work. Retention of rights by the University is contingent upon the fulfilling of a number of obligations on the part of the University and of the Inventor(s) and these obligations must be discharged in order to protect the interests of all parties. Though the University may retain rights and title to such patentable inventions, the federal government retains a royalty free license and places certain other restrictions upon the ultimate disposition of the patents(s). Details of the implementing regulations may be obtained from the Office of Cooperative Research. Incumbent upon members of the University community who apply for and receive federal funding to support research or who use federal monies in the conduct of their research is the requirement for written agreement that they will promptly disclose patentable inventions to the University and will execute all instruments necessary to protect the rights of the government and/or the University. Forms for this agreement will be provided to all faculty and will be available for other participants (i.e., collaborators, post-doctoral students, graduate students) from the appropriate departmental chair or, at the Chair's option, from the Departmental Business Office.
X. Revocation or Amendment
This patent policy is subject to revocation or amendment by the Corporation. In case of doubt as to the interpretation of this patent policy, a definitive interpretation will be provided by the President or Provost after receiving the advice of the Committee on Cooperative Research, Patents, and Licensing. This patent policy is effective as to all inventions/discoveries made on or after February 23, 1998.
Section 4: Research Use of the Yale University Archives
I. General Policy
A. All memoranda, letters, or reports issued from any administrator or committee to a school-wide or University-wide audience will be immediately available for public review. All such documents will be maintained by the Yale University Archives as part of the permanent records of the University.
B. With the exception of materials noted below, all other records in the Archives that are more than 35 years old are open to qualified researchers. Archival records are made available in accordance with the rules of the University Library governing the use of manuscript materials.
C. Records of major University officers and administrators, such as the President, Provost, and deans, are closed to research use for 35 years beginning on the date on which the person leaves office; the restriction applies to the entire body of records created during the administrator's tenure. Accessions of records documenting the activities and functions of other University units and offices are opened for research 35 years after the latest inclusive date of each accession.
II. Categories of Records Closed Longer than 35 Years
Exceptions to the 35-year restriction policy:
A. Minutes of the Yale Corporation and its committees are closed for 50 years.
B. Student records (defined as credentials, grade sheets, correspondence, reports, notes, applications, and all other records pertaining to past and present students) are closed for the life of the student plus five years or 75 years from the date the student graduates or withdraws from the University, whichever is longer. Records of the Yale College Executive Committee and records of student disciplinary matters in the graduate and professional schools are subject to the same restriction that applies to other student records.
C. Personnel records of the University's faculty and staff, including search committee and tenure review files, are closed for the life of the person plus five years or 75 years after an individual's retirement or departure, whichever is longer. Records related to personnel recruitment, searches, promotions, or reappointments, as well as disciplinary/grievance procedures for staff and faculty, are considered part of personnel records.
D. Legal and audit records and records relating to donors will be closed permanently. Exceptions to the policy may be authorized on a case-by-case basis by the Secretary.
E. Records of the above types, even where located in runs of otherwise unrestricted material, are still considered closed and not available for use by researchers. Police and medical records are not part of the Archives, and they are subject to restrictions by law.
F. Exceptions that would allow earlier access to documents for scholarly purposes may be authorized by the Secretary after consultation with the Archivist.
III. Access to Oral History Interviews
Access to oral history interviews is governed by the 35 year restriction policy as set forth above, except that oral history interviews granted by private persons in their private capacity (as distinguished from Yale University officers speaking in their official capacity) are governed by the restrictions and stipulations, if any, set forth in the deeds of gift which effect the donation of such interviews to the Yale University Library.
I. Appointment
A. Fellows shall be appointed to the residential colleges by the Corporation upon recommendation of the Council of the Heads of College for limited terms.
B. There shall be five basic categories of Fellows: Honorary Fellow, Fellow Emeritus, Fellow, Associate Fellow, and Guest Fellow.
C. A Fellow who resides in a residential college shall be known as a Resident Fellow. A Guest Fellow who resides in a college shall be known as a Resident Guest Fellow.
II. Privileges of Members
The privileges of all members of a residential college fellowship shall be the same except for the meal privilege, which is granted to all but Associate Fellows. Privileges are described in detail in a document entitled "The College Fellowships," which is available in the Office of the Council of the Heads of College.
Persons eligible for appointment must fall into one of the following categories:
A. Honorary Fellow. Only the current and former Presidents of Yale shall be eligible for appointment as Honorary Fellows.
B. Fellow Emeritus. Only Fellows who hold academic Emeritus status shall be eligible for appointment as Fellows Emeriti.
C. Fellow. In general, members of the University faculty, either teaching or non-teaching, holding one of the ranks listed in Section IX of "The College Fellowships;" managerial and professional employees of the University; and certain chaplains and other persons with pastoral responsibilities at Yale shall be eligible for appointment as Fellows. No person shall be eligible, however, until after service to the University for at least one academic term. These rules are modified by the following exceptions:
i. Full professors appointed to the faculty from outside the University shall be eligible for appointment as Fellows upon appointment, once they have assumed their duties in New Haven as members of the faculty.
ii. The term-of-service requirements for former Fellows that have returned to the University after a period of employment at some other institution and for visiting faculty members that have been Guest Fellows and are then appointed to the Yale faculty or to administrative positions at Yale are defined in Section VI of "The College Fellowships."
iii. Resident or Resident Guest Fellows shall be members of the Faculty of Arts and Sciences, senior administrative officers (e.g. an Officer of the University, a Dean of a school, the Director of Athletics, the University Chaplain) or other individuals whose work consistently brings them into regular and close contact with undergraduates.
iv. Persons holding unpaid clinical appointments are not eligible for appointment as Fellows.
D. Associate Fellow. Any person except Yale employees, Yale College alumni who have graduated within the past five years, current Yale students, and postdoctoral appointees at the University, shall be eligible for appointment as an Associate Fellow. Persons holding unpaid clinical appointments shall be eligible for appointment in this category.
E. Guest Fellow. A person holding an academic teaching appointment at some other educational institution, who qualifies under the basic rules of eligibility for Fellow, and whose appointment at Yale is for two years or less is eligible to be made Guest Fellow without regard to term of service.
I. Lost diplomas
The holder of any Yale degree may secure a replacement diploma upon application to the Secretary of the University, under the following conditions:
A. The applicant shall submit a statement regarding the loss of the original diploma to the Secretary.
B. One year shall have elapsed since the loss of the original diploma unless fire, flood, shipwreck, or other disaster destroyed the diploma.
C. The applicant shall agree to return the replacement diploma to the Secretary in the event the original diploma is found and restored to him or her.
D. The replacement diploma shall bear the word "Iteratum."
E. The applicant shall pay to Yale University the cost of producing the replacement.
II. Name changes
Diplomas may be issued with a changed name under the following conditions:
A. The applicant shall submit the diploma with the former name to the Secretary.
B. The applicant shall submit a photocopy of the court record authorizing the use of the new name to the Secretary.
C. The new diploma shall contain, in the lower margin (in Latin): "This diploma replaces one previously issued. See statement on reverse."
D. The applicant shall pay to Yale University the cost of producing the replacement.
III. Certificates of graduation
A. A certificate of graduation, in a design approved by the Secretary and bearing the University's seal, may be issued to any degree holder upon application to the Secretary.
B. An applicant who requests that the certificate be issued in a legally changed name shall submit a photocopy of the court order by which the legal change of name was authorized to the Secretary.
C. The applicant shall pay to Yale University the cost of producing the replacement.
I. General Guidelines
A. Holders of and candidates for degrees from Yale University may wear approved academic costume on appropriate occasions.
B. Academic costume is to be worn over subdued apparel.
II. Gowns
A. Blue gowns shall be of the shade known as "Yale blue" as designated by the Secretary of the University. Yale blue gowns may not be made without having the color and style approved by the Secretary.
B. Holders of and candidates for Bachelor's degrees shall wear untrimmed black gowns with open pointed sleeves.
C. Holders of and candidates for Master's degrees may wear untrimmed black or blue gowns with oblong sleeves, open at the wrist.
D. Holders of and candidates for Doctor's degrees may wear black or blue gowns with velvet facing, bell sleeves, and three velvet bars on each sleeve. If the gown is black, the facing and bars may be black or a color distinctive of the degree. If the gown is blue, the facing and bars shall be black.
III. Hoods
A. Yale blue hoods may not be made without having the color and style approved by the Secretary.
B. The material shall be the same as that of the gown.
C. The color shall be black and lined with Yale blue material.
D. The length shall be three feet for Bachelor's degrees, three and one-half feet for Master's degrees, and four feet with panels at the sides for Doctor's degrees.
E. The anterior edge of the hood shall be bound with velvet or velveteen two, three, and five inches wide for Bachelor's, Master's, and Doctor's degrees, respectively. The color is distinctive of the degree conferred: Liberal Arts, white; Architecture, blue-violet; Art and Drama, brown; Divinity, scarlet; Engineering, orange; Forestry, russet; Law, purple; Medicine, green; Music, pink; Nursing, apricot; Management, sapphire blue; Philosophy, dark blue; Public Health, salmon pink; Science, gold-yellow.
IV. Caps
A. The cap for all degrees is a mortarboard of black fabric. The Doctor's cap may be of velvet.
B. The tassel may be black or the color distinctive of the degree. The Doctor's tassel may be gold or the color distinctive of the degree.
V. Protocol
A. Candidates for degrees may wear, on the day of their graduation, the cap and gown of the degree then to be received, but only candidates for Doctor's degrees and Master's degrees may wear hoods. Candidates for the J.S.D., L.L.M. and S.T.M. degrees, who took their prior professional degree at an institution other than Yale, may wear a black Doctor's gown or a gown suitable to that institution.
B. All three-year graduate and professional degree recipients may wear the Doctor's gown on the day of their graduation and thereafter.
C. Recipients of honorary degrees wear a Yale blue Doctor's gown at Commencement when their degrees are conferred.
D. Members of the Yale Corporation, during their term of office and thereafter, may wear the Doctor's gown and the hood appropriate to the degrees that they may severally have received. Their cap may be of distinctive design.
E. The President may wear a gown of distinctive design; the Deans of Schools and Heads of Colleges may adopt distinctive badges subject to the approval of the Corporation.
F. Deans and other senior officials and faculty who have been granted the M.A. Privatim may wear a Yale blue gown commensurate with their earned academic rank when they attend an inauguration or similar ceremony outside Yale as official representatives of Yale.
Honorary Degrees Conferred
Bachelor of Arts (B.A.Hon.) 1705–1879 This degree, referred to as ad eundem grandum, was most frequently conferred upon the holder of a degree earned in the same year at another institution.
Bachelor of Laws (LL.B. Hon.) 1893– Records indicate degree has only been awarded once.
Bachelor of Philosophy (Ph.B. Hon.) 1858–1885
Master of Arts (M.A. Hon.) 1702– This degree was the principal honorary degree awarded between 1702 and 1773. Since 1902 it has been awarded privatim to certain persons not already holding M.A. or Ph.D. degrees from Yale: members of the Corporation, members of the faculty appointed to the rank of Professor, and other officers.
Master of Science (M.S. Hon.) 1928–1954
Doctor of Divinity (D.D.) 1773–
Doctor of Engineering and Technology (D.Eng. & Tech.) 2011–
Doctor of Fine Arts (D.F.A. Hon.) 1941–
Doctor of Humane Letters (L.H.D.) 1934–
Doctor of Humanities (D.Hum.) 2004–
Doctor of Laws (LL.D.) 1773–
Doctor of Letters (Litt.D.) 1892–
Doctor of Medical Sciences (D.M.S.) 1990–
Doctor of Medicine (M.D. Hon.) 1723–1871
Doctor of Music (Mus.D.)
Doctor of Philosophy (Ph.D.) 1866–1871
Doctor of Science (Sc.D.) 1905–
Doctor of Social Science (S.Sc.D.) 1968–
Degrees In Course Conferred
Bachelor of Architecture (B.Arch.) 1942–1997
Bachelor of Arts (B.A.) 1702–
Bachelor of Civil Law (B.C.L.) 1887–1917
Bachelor of Divinity (B.D.) 1867–1971 In 1971 the B.D. was changed to the M.Div
Bachelor of Engineering (B.E.) 1936–1966
Bachelor of Fine Arts (B.F.A.) 1891–1975 B.F.A. designated Architecture, Painting and Sculpture 1926–1941 when B.Arch. was established.
Bachelor of Laws (LL.B.) 1843–1971 With honors, approved 1882. In 1971 the LL.B. was changed to the J.D.
Bachelor of Liberal Studies 1984–2013 Approved in 1981.
Bachelor of Music (B.M.) 1894–1961 Abbreviation changed from Mus.B. 1968–
Bachelor of Nursing (B.N.) 1926–1936
Bachelor of Philosophy (Ph.B.) 1852–1931 Ph.B. on recommendation of S.S.S. 1852–1921, Yale College 1922-1931.
Bachelor of Science (B.S.) 1922– B.S. on recommendation of S.S.S. 1922–1945, School of Engineering, 1933–1966, Yale College, October 24, 1945.
Master of Advanced Management (M.A.M.) 2012–
Master of Architecture (M.Arch.) 1944–
Master of Arts (M.A.) without examination 1702–1871
Master of Arts (M.A.) upon examination 1876–
Master of Arts in Religion (M.A.R.) 1961–
Master of Arts in Teaching (M.A.T.) 1960–1971
Master of Business Administration (M.B.A.) 1999– Authorized in 1998.
Master of City Planning (M.C.P.) 1951–1972
Master of Divinity (M.Div.) 1971– In 1971 the B.D. was changed to the M.Div.
Master of Engineering (M.Eng.) 1936–1966; 1996– B.S./M.Eng. degree is offered by the Graduate School of Arts and Sciences.
Master of Environmental Design (M.E.D.) 1968–
Master of Environmental Management M.E.M. 2000– Replaced Master of Environmental Studies in 2000.
Master of Environmental Science M.E.Sc. 2000–
Master of Environmental Studies (M.E.S.) 1982–1999 Replaced by Master of Environmental Management in 2000.
Master of Fine Arts (M.F.A.-Architecture) 1927–1940 Conferred on recommendation of the Graduate School.
Master of Fine Arts (M.F.A.-Drama) 1931– The Master of Fine Arts is awarded by both the School of Drama and the School of Art.
Master of Fine Arts (M.F.A.-Art) 1936– The Master of Fine Arts is awarded by both the School of Drama and the School of Art.
Master of Forestry (M.F.) 1902–
Master of Forest Science (M.F.S.) 1968–
Master of Health Science (M.H.S.) 2006–
Master of Industrial Administration (M.I.A.) 1958–1967
Master of Laws (LL.M.) 1877–
Master of Medical Science (M.M.Sc.) 1999– M.M.Sc. supersedes Physician Associate Certificate.
Master of Management Studies (M.M.S.) 2017– Authorized in 2016 to be awarded by the School of Management
Master of Music (M.M.) 1932– Abbreviation changed from Mus.M. 1968–
Master of Musical Arts (M.M.A.) 1969–
Artist Diploma (Music) A.D. 1992– Authorized in 1991.
Master of Nursing (M.N.) 1937–1959
Master of Public and Private Management (M.P.P.M.) 1978–2001 Authorized in 1974 and closed as of 2001 by vote of the Corporation in August 1998.
Master of Philosophy (M.Phil.) 1967–
Master of Public Health (M.P.H.) 1936– In 1946 holders of the Certificate in Public Health were transferred to the M.P.H.; therefore the M.P.H. list of graduates starts with 1918.
Master of Public Policy (M.P.P.) 2021– First degrees to be awarded in 2023, the first year of The Yale Jackson School of Global Affairs.
Master of Religious Education (M.R.E.) 1954–1960
Master of Sacred Theology (S.T.M.) 1939–
Master of Science (M.S.) 1899–
Master of Science in Nursing (M.S.N.) 1957–
Master of Studies in Law (M.S.L.) 1974–
Master of Urban Studies (M.U.S.) 1965–1973
Juris Doctor (J.D.) 1972– In 1971 LL.B. was changed to J.D.
Chemical Engineer (Chem.E.) 1934–1937
Civil Engineer (C.E.) 1860–1941
Electrical Engineer (E.E.) 1914–1940
Mechanical Engineer (M.E.) 1873–1938
Metallurgical Engineer (Met.E.) 1916–1917
Engineer of Mines (E.M) 1908–1934
Master of Science in Civil Engineering (M.S. in C.E.) 1927–1934
Master of Science in Electrical Engineering (M.S. in E.E.) 1923–1933
Master of Science in Mechanical Engineering (M.S. in M.E.) 1923–1933
Master of Science in Mining Engineering (M.S. in E.M.) 1924–1927
Master of Science in Mining and Metallurgy (M.S. in Min. and Met.) 1925–2006 The degree was awarded only once.
Master of Science in Transportation Engineering (M.S. in Trans. Eng.) 1927–1929
Master of Science in Transportation (M.S.T.) 1930–1934
Doctor of Civil Law (D.C.L.) 1878–1990
Doctor of Engineering (D.Eng.) 1936–1971
Doctor of Fine Arts (Drama) (D.F.A.) 1958–
Doctor of Forestry (D.For.) 1948–1992 The degree was changed to Doctor of Forestry and Environmental Studies (D.F.E.S.).
Doctor of Forestry and Environmental Studies (D.F.E.S.) 1992–2006 In the 2003/04 academic year the D.F.E.S. program merged with the Ph.D. program. No students have been admitted to the D.F.E.S. since 2003/04.
Doctor of Medicine (M.D.) 1814–
Doctor of Musical Arts (D.M.A.) 1973–
Doctor of Nursing Science (D.N.Sc.) 1998-2011 Authorized in 1992
Doctor of Nursing Practice (D.N.P.) 2011–
Doctor of Philosophy (Ph.D.) 1861– The first in the U.S.
Doctor of Public Health (Dr.P.H.) 1920–
Doctor of the Science of Law (J.S.D.) 1925–
Certificates Conferred
Program in Global Medicine 2012–
Certificate in Drama 1927–
Certificate in Nurse-Midwifery 1961–1974
Certificate in Nursing 1976–
Post Master's Certificate in Nursing 1997–
Certificate in Performance 1974– Music
Physician Associate Certificate 1976–1999 This degree was superseded by the M.M.Sc.
Certificate in Public Health 1918–1935 In 1946 holders of the C.P.H. were automatically transferred to the M.P.H.
Certificate in Transportation 1935–1968
Certificates have also been issued in Art, Music, Nursing (1926–1928), Highway Traffic, and the Institute of Far Eastern Languages.
About the Board of Trustees
Current Board Contact the Trustees Committees Board Roles & Selection Process What Happens at Board Meetings Governance Documents Former Trustees

redpajama_set_name: RedPajamaCommonCrawl


BBC Three has ordered another 18 episodes of Sweat The Small Stuff.
The panel show focuses on celebrity culture and "fickle obsessions", and is hosted by Radio 1 DJ Nick Grimshaw with team captains Rochelle Humes and Melvin Odoom.
The format, which launched in April 2013, has so far run for two series. Trade magazine Broadcast reports that the newly ordered episodes for 2014 will be split across two further series, running to 9 episodes each.
BBC Three controller Zai Bennett said: "Sweat The Small Stuff with Grimmy is a potent combination for BBC Three, so I'm delighted it's back for two more series. It's hilarious, quick witted and smart and is one of the only panel shows that riffs off of the great British public's niggles."
This panel show is the first to be recommissioned since BBC boss Danny Cohen publicly announced it was no longer acceptable for BBC comedy shows to have all-male line-ups. Sweat The Small Stuff is currently the only BBC panel show to feature a female team captain.
This new series news follows last week's announcement from the BBC that it intends to turn BBC Three into an online only channel in 2015. However, both series will be shown on television before the channel is shut.
On Thursday, Director of Television and former BBC Three boss Danny Cohen provided further details of the broadcaster's plans for the station. The corporation is stressing that the channel is not closed, and when it does go online-only they will still be looking to commission shows, which will later be broadcast on BBC One or BBC Two at 10:35pm. He said: "We are running BBC Three as a television channel for the next 18 months. We've got slots available and we're hungry for new ideas in all the genres, so there's a lot of work to be done."
BBC Three currently spends £14m on comedy, but it has not yet been decided how much of the channel's proposed reduced budget of £30m in 2015 will go to comedy production.


text:
Start News Cyber/Coms Rafael Seeking to Sell BNET More Widely
Rafael Seeking to Sell BNET More Widely
ARIE EGOZI
European armies and air forces are evaluating the use of the Rafael BNET, with the Israeli company now in negotiations with some European companies to adapt the system to clients in the region. The BNET system replaces existing radio systems installed in aircraft and while half in size and weight, reportedly offers a very wide communications channel for data, operating on all frequencies simultaneously, creating a free flow of communications, speech and data of an unlimited number of users.
A contract for the BNET to be used by the German Army has been signed, with international company ATOS as the main contractor. According to Yoav Wermuth of Rafael's C3I directorate, the BNET will be the basis for a system that will allow German infantry soldiers, aerial platforms and other systems to operate in parallel, all using the same communication systems. One demo has already been performed and another will be held this year. According Wermuth, by simultaneously receiving and processing hundreds of MHz's and merging them into a single IP network, BNET provides unprecedented network capacity in terms of data rates, number of users and minimal delay. The Rafael official told ESD that similar programmes are being developed in Spain and the UK, with BNET on offer.
Aerial applications
According to Rafael, the BNET communications systems have been selected by the air forces of Brazil and Colombia while recently, the Indian Air Force begun to integrate the Rafael BNET software defined radio onto all its combat aircraft, with the Israeli company supplying 1000 systems. RAFAEL has transferred considerable elements of the system development and production to India, enabling local partners to share a major part of the programme in the current phase and also benefit from its future spinoffs.
The senior Rafael official, added that the BNET allows the aircraft to achieve a fully networked communication system between airborne platforms and ground a naval forces. The system is seamless and it allows the transfer of data including video images in unprecedented rates. RAFAEL began the development of BNET as a ground based network, and later adapted the system for airborne and air-ground applications with it now being the main communication system of the Israeli Air Force existing and future platforms.


text:
Sudiyah Istichomah, Indonesia
December 14, 201500WFI AlumniTags: 2014, Indonesia
Sudiyah Istichomah completed a six month Fellowship in November 2014. During her WFI Fellowship, Sudiyah looked at models of public involvement and stakeholder engagement in river management, especially focused on the Willamette River. Sudiyah currently works for RECOFTC (Regional Community Forestry Training Center for Asia and the Pacific) Indonesia Country Program at the office in Bogor, West Java, Indonesia.
Krystina Kny, Australia
December 14, 201500WFI AlumniTags: 2014, Australia
Krystina Kny completed a six-month Fellowship in December 2014. She is from Melbourne, Australia and works for VicForests as their Manager of Operational Performance. Krystina is responsible for the management of VicForests' Sustainable Forest Management System and maintaining compliance against relevant certification schemes and regulatory requirements. She has worked in both tree farming and native forestry in Australia and during her six month Fellowship Krystina completed a project on Social Acceptance of Working Native Forests, contrasting Victoria, Australia and the Pacific Northwest
Wai Wai Than, Myanmar
December 14, 201500WFI AlumniTags: 2014, Burma, Myanmar
Wai Wai Than completed a 6-month Fellowship in March 2015. During her six-month Fellowship Ms. Than studied the pathways of invasive species-invasion, how to detect them at the ports, quarantine laws and documentation systems, risk assessment, and awareness and public participation in those activities. Wai Wai was funded in part by a fellowship award she received from the International Tropical Timber Association. In 2017 she retired from the Forest Research Institute in Yezin, Maynmar. Currently she is writing articles about the environment and learning about Buddhism.
Vincent Upton, Ireland
December 14, 201500WFI AlumniTags: 2014, Ireland
Dr. Vincent Upton completed a six month Fellowship in November 2014. Vincent is a researcher from Ireland who works in the rural economy and development program in Teagasc, the Irish agriculture and food development authority. Vincent trained as a forester in University College Dublin before working with a number of private and public forest management and research organizations. His research focuses on the economics and valuation of forests and forest ecosystem services and he examined public preferences and values for afforestation while completing his PhD from University College Dublin. During his 6 month WFI fellowship, Vincent focused his research on how forest policy and management in the Pacific Northwest account for ecosystem services.
Ruo-Yun "Zoe" Yeh, Taiwan
December 14, 201500WFI AlumniTags: 2014, Taiwan
Zoe completed a six month Fellowship in November 2014. Zoe is from Taipei, Taiwan and works for the Taiwan Forestry Research Institute. She is an assistant research fellow in the Division of Wood Cellulose, responsible for managing the Forest Products Chemistry Laboratory. Her research interest is in wood and paper chemistry, chemical utilization of non-wood forest products, fungal secondary metabolites, and prevention of paper microbial degradation. During her six month Fellowship, Zoe studied the production of essential oils from forest products and how that related to sustainable forest management.