[Tinyos-commits] CVS: tinyos-1.x/tools/java/net/tinyos/drip Drip.java, NONE, 1.1 DripDaemon.java, NONE, 1.1 DripSniff.java, NONE, 1.1 Makefile, NONE, 1.1

Gilman Tolle gtolle at users.sourceforge.net
Mon Oct 31 08:58:25 PST 2005


Update of /cvsroot/tinyos/tinyos-1.x/tools/java/net/tinyos/drip
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31750

Added Files:
	Drip.java DripDaemon.java DripSniff.java Makefile 
Log Message:
Import of Drip Java tools

--- NEW FILE: Drip.java ---
/** 
 *
 * Reliable Message Injector for the Drip protocol.
 * 
 * @author Gilman Tolle <get at cs.berkeley.edu>
 * @since  0.1
 */

package net.tinyos.drip;

import net.tinyos.message.*;
import net.tinyos.util.*;

import org.apache.log4j.*;

import java.io.*; 
import java.text.*;
import java.util.*;

public class Drip implements MessageListener {

  public static int SEND_COUNT = 12;
  public static int SEND_RATE = DripConsts.DRIP_TIMER_PERIOD;

  public static int WAKEUP_SEND_COUNT = 25;
  public static int WAKEUP_SEND_RATE = 40;

  private Logger log = Logger.getLogger(Drip.class.getName());

  private static final int IDLE = 0;
  private static final int PROBING = 1;
  private static final int SENDING_SEQNO = 2;
  private static final int SENT_SEQNO = 3;
  private static final int SENDING_NEW = 4;

  private int state = IDLE;

  int id;
  int seqno;
  int sendCount = 0;
  int maxSendCount;

  Timer trickle;
  TimerTask trickleTask;

  MoteIF moteIF;
  DripMsg dripMsg;
  boolean hasMessage = false;
  boolean sentOK = true;

  boolean wakeupMsg = false;

  public Drip(int id) {

    log.info("Started id=" + id);
    try {
      moteIF = new MoteIF();
      moteIF.registerListener(new DripMsg(), this);
    } catch (Exception e) {
      System.out.println("ERROR: Couldn't contact serial forwarder.");
      System.exit(1);
    }

    this.id = id;
  }

  public Drip(int id, MoteIF p_moteIF) {

    log.info("Started with own moteIF id=" + id);

    try {
      moteIF = p_moteIF;
      moteIF.registerListener(new DripMsg(), this);
    } catch (Exception e) {
      System.out.println("ERROR: Couldn't contact serial forwarder.");
      System.exit(1);
    }

    this.id = id;
  }

  void setupDrip(Message msg, int msgSize) {
    trickle = new Timer();
    trickleTask = new DripSender();
    dripMsg = new DripMsg(DripMsg.DEFAULT_MESSAGE_SIZE + msgSize);
    dripMsg.dataSet(msg.dataGet(), 0, dripMsg.offset_data(0),
		    msgSize);
    sendCount = 0;
  }

  Message buildAddrMsg(int dest, Message msg, int msgSize) {
    AddressMsg addrMsg = new AddressMsg(AddressMsg.DEFAULT_MESSAGE_SIZE + msgSize);
    String moteid = Env.getenv("MOTEID");
    int source = 0xFFFF;
    
    if (moteid != null) {
      source = Integer.parseInt(moteid);
    }

    addrMsg.dataSet(msg.dataGet(), 0, addrMsg.offset_data(0), msgSize);
    
    addrMsg.set_dest(dest);
    addrMsg.set_source(source);

    return addrMsg;
  }

  public synchronized void send(Message msg, int msgSize) {
    setupDrip(msg, msgSize);

    state = PROBING;
    wakeupMsg = false;
    sendCount = 0;
    maxSendCount = SEND_COUNT;
    trickle.schedule(trickleTask, 0, 500);
    try {
      wait();
    } catch (InterruptedException e) {
      // return
    }
  }

  public synchronized void sendAddressed(int dest, Message msg, int msgSize) {

    AddressMsg addrMsg = (AddressMsg) buildAddrMsg(dest, msg, msgSize);
    send(addrMsg, msgSize + AddressMsg.DEFAULT_MESSAGE_SIZE);
  }

  public synchronized void sendUnreliable(Message msg, int msgSize) {
    setupDrip(msg, msgSize);

    state = SENDING_NEW;
    wakeupMsg = false;
    sendCount = 0;
    maxSendCount = 1;
    trickle.schedule(trickleTask, 0, SEND_RATE);
    try {
      wait();
    } catch (InterruptedException e) {
      // return
    }
  }

  public synchronized void sendAddressedUnreliable(int dest, Message msg, 
						   int msgSize) {
    AddressMsg addrMsg = (AddressMsg) buildAddrMsg(dest, msg, msgSize);
    sendUnreliable(addrMsg, msgSize + AddressMsg.DEFAULT_MESSAGE_SIZE);
  }

  public synchronized void sendWakeup(Message msg, int msgSize) {
    setupDrip(msg, msgSize);

    state = SENDING_NEW;
    wakeupMsg = true;
    sendCount = 0;
    maxSendCount = WAKEUP_SEND_COUNT;
    trickle.schedule(trickleTask, 0, WAKEUP_SEND_RATE);
    try {
      wait();
    } catch (InterruptedException e) {
      // return
    }
  }
    
  private synchronized void sendDone() {
    notifyAll();
    state = IDLE;
  }
    
  class DripSender extends TimerTask {
    
    public void run() {

      boolean stopSending = false;

      log.debug("DripSender.run(state=" + state + " sendCount= " + sendCount + ")");

      dripMsg.set_metadata_id((short)id);
      
      switch (state) {
      case PROBING:
	if (sendCount < maxSendCount) {
	  log.debug("probing");
	  dripMsg.set_metadata_seqno((byte)DripConsts.DRIP_SEQNO_OLDEST);
	} else {
	  log.debug("probing finished");
	  stopSending = true;
	}
	break;
      case SENDING_SEQNO:
	if (sendCount < maxSendCount) {
	  log.debug("sending new seqno "+seqno);
	  dripMsg.set_metadata_seqno((byte)seqno);
	} else {
	  log.debug("sending finished");
	  stopSending = true;
	}
	break;
      case SENDING_NEW:
	if (sendCount < maxSendCount) {
	  log.debug("sending unreliably");
	  dripMsg.set_metadata_seqno((byte)DripConsts.DRIP_SEQNO_NEWEST);
	} else {
	  log.debug("sending unreliably finished");
	  stopSending = true;
	}
	break;
      case SENT_SEQNO:
	log.debug("done sending");
	stopSending = true;
	return;
      default:
      }
      
      if (wakeupMsg == true) {
	dripMsg.set_metadata_seqno((short)((dripMsg.get_metadata_seqno()+1) % 256));
      }

      if (stopSending) {
	trickle.cancel();
	trickleTask.cancel();
	sendDone();
      } else {
	log.info("Sending Msg " + sendCount + ": id=" + id + ",seqno=" + dripMsg.get_metadata_seqno());
	send(dripMsg);
	sendCount++;
      }
    }
  }

  private void send(Message m) {
    try {
      moteIF.send(MoteIF.TOS_BCAST_ADDR, m);
    } catch (IOException e) {
      e.printStackTrace();
      System.out.println("ERROR: Can't send message");
      System.exit(1);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void messageReceived(int to, Message m) {
	
    DripMsg msg = (DripMsg)m;
	
    int newId = msg.get_metadata_id();
    int newSeqno = msg.get_metadata_seqno();

    log.debug("Received Msg: id=" + newId + ",seqno=" + newSeqno);
	
    if (newId != id) {
      log.debug("dropped, not ID " + id);
      return;
    }

    if ((newSeqno & ~DripConsts.DRIP_WAKEUP_BIT) == DripConsts.DRIP_SEQNO_NEWEST) {
      log.debug("dropped, a special seqno " + newSeqno);
      return;
    }

    switch (state) {
    case PROBING:
      seqno = newSeqno;
      log.info("Receive: id=" + id + ",seqno=" + dripMsg.get_metadata_seqno() + " Heard Old Seqno");
      incrementSeqno();
      state = SENDING_SEQNO;
    case SENDING_SEQNO:
      if (seqno == newSeqno) {
	log.info("Receive: id=" + id + ",seqno=" + dripMsg.get_metadata_seqno() + " Heard New Seqno");
	trickle.cancel();
	trickleTask.cancel();
	sendDone();
      }
    default:
    }
  }
    
  private void incrementSeqno() {
    if (wakeupMsg && ((seqno & DripConsts.DRIP_WAKEUP_BIT) == 0)) {
      seqno = (seqno + 1) % 256;      
    }

    if (!wakeupMsg && ((seqno & DripConsts.DRIP_WAKEUP_BIT) == 1)) {
      seqno = (seqno + 1) % 256;
    }

    seqno = (seqno + 1) % 256;
    seqno = (seqno + 1) % 256;

    while ((seqno & ~DripConsts.DRIP_WAKEUP_BIT) == DripConsts.DRIP_SEQNO_OLDEST ||
	   (seqno & ~DripConsts.DRIP_WAKEUP_BIT) == DripConsts.DRIP_SEQNO_NEWEST ||
	   (seqno & ~DripConsts.DRIP_WAKEUP_BIT) == DripConsts.DRIP_SEQNO_UNKNOWN) {

      seqno = (seqno + 1) % 256;
      seqno = (seqno + 1) % 256;
    }
  }

  private static int data = 1000;
  private static int channel = 254;
  private static boolean wakeup = false;

  public static void main(String[] args) {

    parseArgs(args);

    Drip drip = new Drip(channel);
    TestDripMsg msg = new TestDripMsg();
    msg.set_data((short)data);
    
    if (wakeup) {
      drip.sendWakeup(msg, TestDripMsg.DEFAULT_MESSAGE_SIZE);
    } else {
      drip.send(msg, TestDripMsg.DEFAULT_MESSAGE_SIZE);
    }
    System.exit(0);
  }

  private static void parseArgs(String args[]) {

    ArrayList cleanedArgs = new ArrayList();

    for(int i = 0; i < args.length; i++) {
      if (args[i].startsWith("--")) {

        // Parse Long Options
        String longopt = args[i].substring(2);
	
	if (longopt.equals("help")) {
	  usage();
	}

      } else if (args[i].startsWith("-")) {

        // Parse Short Options
	String opt = args[i].substring(1);

	if (opt.equals("d")) {
	  data = Integer.parseInt(args[++i]);
	} else if (opt.equals("w")) {
	  wakeup = true;
	} else if (opt.equals("c")) {
	  channel = Integer.parseInt(args[++i]);
	} else if (opt.equals("h")) {
	  usage();
	}
	
      } else {

        // Place into args string
        cleanedArgs.add(args[i]);
      }
    }
  }

  private static void usage() {
    System.err.println("usage: java net.tinyos.drain.Drip <opts>");
    System.err.println("  -d <data value>");
    System.err.println("  -c <channel id>");
    System.err.println("  -w : send message with wakeup bit set");
    System.err.println("  -h, --help : this information");
    System.exit(1);
  }

}

--- NEW FILE: DripDaemon.java ---
package net.tinyos.drip;

import net.tinyos.message.*;
import net.tinyos.util.*;

import org.apache.log4j.*;

import java.io.*; 
import java.text.*;
import java.util.*;

public class DripDaemon implements MessageListener {

  private Logger log = Logger.getLogger(DripDaemon.class.getName());

  MoteIF moteIF;

  int id;
  int seqno;
  Message store;
  int storeSize;
  boolean storeForever;
  boolean newStore;
  boolean doneInjecting;

  Timer trickle = new Timer();
  TimerTask trickleTimer = new DripSender();

  int period;
  int round;


  public DripDaemon(int id) {
    
    log.info("Started id=" + id);

    try {
      moteIF = new MoteIF();
      moteIF.registerListener(new DripMsg(), this);
    } catch (Exception e) {
      System.out.println("ERROR: Couldn't contact serial forwarder.");
      System.exit(1);
    }

    this.id = id;
  }

  public void storeOnce(Message m, int size) {
    store(m, size, false);
  }

  public void storeForever(Message m, int size) {
    store(m, size, true);
  }

  private void store(Message m, int size, boolean forever) {
    log.info("id=" + id + ": storing new message");

    doneInjecting = false;

    store = m;
    storeSize = size;
    storeForever = forever;

    newStore = true;
    seqno = DripConsts.DRIP_SEQNO_OLDEST;


    round = 0;
    period = DripConsts.DRIP_TIMER_PERIOD * (1 << round);
    
    trickleTimer.cancel();
    trickleTimer = new DripSender();
    trickle.schedule(trickleTimer, period);
  }

  public void messageReceived(int to, Message m) {
    
    DripMsg msg = (DripMsg)m;
    
    int newId = msg.get_metadata_id();
    int newSeqno = msg.get_metadata_seqno();
    
    log.info("id=" + id + ": received msg id=" + newId + ",seqno=" + newSeqno);
	
    if (newId != id) {
      return;
    }

    if (doneInjecting) {
      return;
    }

    if (newStore) {
      seqno = newSeqno;
      log.info("id=" + id + ": heard packet with old seqno = " + seqno);
      incrementSeqno();
      log.info("id=" + id + ": injecting packet with new seqno = " + seqno);
      newStore = false;
    } else {
      if (storeForever) {
	if (newSeqno > seqno) {
	  seqno = newSeqno;
	  log.info("id=" + id + ": (subsequent) heard packet with old seqno = " + seqno);
	  incrementSeqno();
	  log.info("id=" + id + ": (subsequent) injecting packet with new seqno = " + seqno);
	}
      } else {
	if (seqno == newSeqno) {
	  log.info("id=" + id + ": done injecting");
	  doneInjecting = true;
	  trickleTimer.cancel();
	}
      }
    }

    if (seqno != newSeqno) {
      round = 0;
      period = DripConsts.DRIP_TIMER_PERIOD * (1 << round);
      
      trickleTimer.cancel();
      trickleTimer = new DripSender();
      trickle.schedule(trickleTimer, period);
    }
  }

  class DripSender extends TimerTask {
    public void run() {

      log.info("id=" + id + ": sending msg seqno=" + seqno);

      DripMsg dripMsg = new DripMsg(DripMsg.DEFAULT_MESSAGE_SIZE + storeSize);

      dripMsg.set_metadata_id((short)id);
      dripMsg.set_metadata_seqno((short)seqno);
      dripMsg.dataSet(store.dataGet(), 0, dripMsg.offset_data(0),
		      storeSize);
      send(dripMsg);

      if (round < DripConsts.DRIP_MAX_SEND_INTERVAL) {
	round++;
      }
      period = DripConsts.DRIP_TIMER_PERIOD * (1 << round);
      trickleTimer = new DripSender();
      trickle.schedule(trickleTimer, period);
    }
  }

  private void send(Message m) {
    try {
      moteIF.send(MoteIF.TOS_BCAST_ADDR, m);
    } catch (IOException e) {
      e.printStackTrace();
      System.out.println("ERROR: Can't send message");
      System.exit(1);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private void incrementSeqno() {
    seqno = (seqno + 1) % 256;
    seqno = (seqno + 1) % 256;

    while ((seqno & ~DripConsts.DRIP_WAKEUP_BIT) == DripConsts.DRIP_SEQNO_OLDEST ||
	   (seqno & ~DripConsts.DRIP_WAKEUP_BIT) == DripConsts.DRIP_SEQNO_NEWEST ||
	   (seqno & ~DripConsts.DRIP_WAKEUP_BIT) == DripConsts.DRIP_SEQNO_UNKNOWN) {


      seqno = (seqno + 1) % 256;
      seqno = (seqno + 1) % 256;
    }

    seqno &= ~DripConsts.DRIP_WAKEUP_BIT;
  }
}

--- NEW FILE: DripSniff.java ---
package net.tinyos.drip;

import net.tinyos.message.*;
import net.tinyos.util.*;

import org.apache.log4j.*;

import java.io.*; 
import java.text.*;
import java.util.*;
import java.net.*;

public class DripSniff {
  private MoteIF moteIF;

  public DripSniff() {
    moteIF = new MoteIF();
    moteIF.registerListener(new DripMsg(), new DripMsgReceiver());
  }

  private class DripMsgReceiver implements MessageListener {
    synchronized public void messageReceived(int to, Message m) {
      
      DripMsg mhMsg = (DripMsg)m;
      
      System.out.print("incoming: " +
		       " id: " + mhMsg.get_metadata_id() + 
		       " seqno: " + mhMsg.get_metadata_seqno());
      if (mhMsg.get_metadata_seqno() == 2) {
	System.out.print(" -- new node -- ");
      }

      System.out.println("");
    }
  }

  public static void main(String args[]) {
    DripSniff ds = new DripSniff();
  }
}

--- NEW FILE: Makefile ---
TOS = $(shell ncc -print-tosdir)
PACKAGE = net.tinyos.drip
MIG = mig java
NCG = ncg java
LIB = $(TOSDIR)/lib/Drip

# List of message classes to build
MSGS = DripMsg.java AddressMsg.java TestDripMsg.java
CONSTS = DripConsts.java
INITIAL_TARGETS = $(CONSTS) $(MSGS)
OTHER_CLEAN = cleanmig
PLATFORM = telosb
PLATFORM_LIBS = -I$(TOS)/lib/CC2420Radio

ROOT = $(TOSDIR)/../tools/java
include $(ROOT)/Makefile.include

DripMsg.java: $(LIB)/Drip.h
	$(MIG) -target=$(PLATFORM) $(PLATFORM_LIBS) -java-classname=$(PACKAGE).DripMsg $(LIB)/Drip.h DripMsg -o $@

AddressMsg.java: $(LIB)/DripSend.h
	$(MIG) -target=$(PLATFORM) $(PLATFORM_LIBS) -java-classname=$(PACKAGE).AddressMsg $(LIB)/DripSend.h AddressMsg -o $@

DripConsts.java: $(LIB)/Drip.h
	$(NCG) -target=$(PLATFORM) $(PLATFORM_LIBS) -java-classname=$(PACKAGE).DripConsts -I$(LIB) $(LIB)/Drip.h Drip.h -o $@

TestDripMsg.java: $(TOSDIR)/../apps/TestDrip/TestDrip.h
	$(MIG) -target=$(PLATFORM) $(PLATFORM_LIBS) -java-classname=$(PACKAGE).TestDripMsg $(TOSDIR)/../apps/TestDrip/TestDrip.h TestDripMsg -o $@

cleanmig:
	rm -f $(MSGS) $(CONSTS) platforms.properties




More information about the Tinyos-commits mailing list