]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Previously, the serial forwarder would only release the COM port on exit. Now it...
authorrincon <rincon>
Fri, 18 May 2007 18:27:03 +0000 (18:27 +0000)
committerrincon <rincon>
Fri, 18 May 2007 18:27:03 +0000 (18:27 +0000)
support/sdk/java/net/tinyos/comm/NativeSerial.java
support/sdk/java/net/tinyos/comm/SerialPort.java
support/sdk/java/net/tinyos/comm/TOSSerial.java
support/sdk/java/net/tinyos/packet/Packetizer.java
support/sdk/java/net/tinyos/packet/SerialByteSource.java
support/sdk/java/tinyos.jar

index 6b370c2321eb1fb4a786f6d088510cacc073f344..d775820b7579e4fc20d5fcad45926a7b75c8f401 100644 (file)
@@ -1,3 +1,6 @@
+
+package net.tinyos.comm;
+
 /* ----------------------------------------------------------------------------
  * This file was automatically generated by SWIG (http://www.swig.org).
  * Version: 1.3.21
@@ -6,18 +9,65 @@
  * the SWIG interface file instead.
  * ----------------------------------------------------------------------------- */
 
-package net.tinyos.comm;
-
+/**
+ * Updated to include the open() method, which allows us to keep this
+ * object while being temporarily disconnected from the serial port
+ */
 
 public class NativeSerial {
+  
+  /** The handle to the serial port we're connected to */
   private long swigCPtr;
-  protected boolean swigCMemOwn;
-
-  protected NativeSerial(long cPtr, boolean cMemoryOwn) {
+  
+  /** True if we have an open serial port connection */
+  private boolean swigCMemOwn;
+  
+  /** Name of the port */
+  private String myPortname = "";
+  
+
+  /**
+   * Constructor
+   * @param portname
+   */
+  public NativeSerial(String portname) {
+    this(TOSCommJNI.new_NativeSerial(portname), true);
+  }
+  
+  /**
+   * Constructor
+   * @param cPtr
+   * @param cMemoryOwn
+   */
+  private NativeSerial(long cPtr, boolean cMemoryOwn) {
     swigCMemOwn = cMemoryOwn;
     swigCPtr = cPtr;
   }
 
+
+  /**
+   * Reconnect to this serial port 
+   * @return true if the connection is made
+   */
+  public boolean open() {
+    if(!swigCMemOwn && !myPortname.matches("")) {
+      swigCPtr = TOSCommJNI.new_NativeSerial(myPortname);
+      swigCMemOwn = true;
+      return true;
+    }
+    
+    return false;
+  }
+
+  public void close() {
+    // We can come here with swigCptr == 0 from finalize if the C++
+    // constructor throws an exception. Ideally, we should guard all
+    // methods in the C++ code, but this is simpler.
+    if (swigCPtr != 0) {
+      TOSCommJNI.NativeSerial_close(swigCPtr);
+    }
+  }
+  
   protected NativeSerial() {
     this(0, false);
   }
@@ -67,7 +117,11 @@ public class NativeSerial {
   }
 
   public boolean waitForEvent() {
-    return TOSCommJNI.NativeSerial_waitForEvent(swigCPtr);
+    try {
+      return TOSCommJNI.NativeSerial_waitForEvent(swigCPtr);
+    } catch (Exception e) {
+      return false;
+    }
   }
 
   public boolean cancelWait() {
@@ -114,20 +168,14 @@ public class NativeSerial {
     TOSCommJNI.NativeSerial_sendBreak(swigCPtr, millis);
   }
 
-  public NativeSerial(String portname) {
-    this(TOSCommJNI.new_NativeSerial(portname), true);
-  }
 
-  public void close() {
-    // We can come here with swigCptr == 0 from finalize if the C++
-    // constructor throws an exception. Ideally, we should guard all
-    // methods in the C++ code, but this is simpler.
-    if (swigCPtr != 0)
-      TOSCommJNI.NativeSerial_close(swigCPtr);
-  }
 
   public int available() {
-    return TOSCommJNI.NativeSerial_available(swigCPtr);
+    try {
+      return TOSCommJNI.NativeSerial_available(swigCPtr);
+    } catch (Exception e) {
+      return 0;
+    }
   }
 
   public int read() {
index 995959c6726aa6c6c27b5b0997f8b81231049aea..89e40502ad93d67bec9cb7f643c9f439a24452f2 100644 (file)
@@ -1,5 +1,7 @@
 //$Id$
 
+package net.tinyos.comm;
+
 /* "Copyright (c) 2000-2003 The Regents of the University of California.  
  * All rights reserved.
  *
@@ -22,7 +24,6 @@
 
 //@author Cory Sharp <cssharp@eecs.berkeley.edu>
 
-package net.tinyos.comm;
 
 import java.io.*;
 
@@ -43,8 +44,10 @@ public interface SerialPort
   public InputStream getInputStream() throws IOException;
   public OutputStream getOutputStream() throws IOException;
 
+  public boolean open();
   public void close();
-
+  public void finalize();
+  
   public void setSerialPortParams( 
     int baudrate, int dataBits, int stopBits, boolean parity )
     throws UnsupportedCommOperationException;
index ee292c526c518403e4b221241f010a15bdbb2bc7..5fbac78b7589cdb6398545f2dae8857e3f1fcf45 100644 (file)
  */
 
 //@author Cory Sharp <cssharp@eecs.berkeley.edu>
-
 package net.tinyos.comm;
 
 import java.io.*;
 import java.util.*;
 import java.util.regex.*;
 
-public class TOSSerial extends NativeSerial implements SerialPort
-{
-  class EventDispatcher extends Thread
-  {
+public class TOSSerial extends NativeSerial implements SerialPort {
+
+  class EventDispatcher extends Thread {
     boolean m_run;
 
-    public EventDispatcher()
-    {
+    public EventDispatcher() {
       m_run = true;
     }
 
-    void dispatch_event( int event )
-    {
-      if( didEventOccur(event) )
-      {
-       SerialPortEvent ev = new SerialPortEvent( TOSSerial.this, event );
-        synchronized(m_listeners) {
+    public void open() {
+      synchronized (this) {
+        this.notify();
+        m_run = true;
+      }
+    }
+
+    public void close() {
+      m_run = false;
+      cancelWait();
+    }
+
+    private void dispatch_event(int event) {
+      if (didEventOccur(event)) {
+        SerialPortEvent ev = new SerialPortEvent(TOSSerial.this, event);
+        synchronized (m_listeners) {
           Iterator i = m_listeners.iterator();
-          while( i.hasNext() )
-            ((SerialPortListener)i.next()).serialEvent( ev );
+          while (i.hasNext())
+            ((SerialPortListener) i.next()).serialEvent(ev);
         }
       }
     }
 
-    public void run()
-    {
-      while( m_run )
-      {
-       if( waitForEvent() )
-       {
-         if( m_run )
-         {
-           dispatch_event( SerialPortEvent.BREAK_INTERRUPT );
-           dispatch_event( SerialPortEvent.CARRIER_DETECT );
-           dispatch_event( SerialPortEvent.CTS );
-           dispatch_event( SerialPortEvent.DATA_AVAILABLE );
-           dispatch_event( SerialPortEvent.DSR );
-           dispatch_event( SerialPortEvent.FRAMING_ERROR );
-           dispatch_event( SerialPortEvent.OVERRUN_ERROR );
-           dispatch_event( SerialPortEvent.OUTPUT_EMPTY );
-           dispatch_event( SerialPortEvent.PARITY_ERROR );
-           dispatch_event( SerialPortEvent.RING_INDICATOR );
-         }
-       }
+    public void run() {
+      while (true) {
+
+        synchronized (this) {
+          if (!m_run) {
+            try {
+              this.wait();
+            } catch (InterruptedException e) {
+              e.printStackTrace();
+            }
+          }
+        }
+        
+        if (waitForEvent()) {
+          dispatch_event(SerialPortEvent.BREAK_INTERRUPT);
+          dispatch_event(SerialPortEvent.CARRIER_DETECT);
+          dispatch_event(SerialPortEvent.CTS);
+          dispatch_event(SerialPortEvent.DATA_AVAILABLE);
+          dispatch_event(SerialPortEvent.DSR);
+          dispatch_event(SerialPortEvent.FRAMING_ERROR);
+          dispatch_event(SerialPortEvent.OVERRUN_ERROR);
+          dispatch_event(SerialPortEvent.OUTPUT_EMPTY);
+          dispatch_event(SerialPortEvent.PARITY_ERROR);
+          dispatch_event(SerialPortEvent.RING_INDICATOR);
+        }
       }
     }
 
-    public void close()
-    {
-      m_run = false;
-      cancelWait();
-    }
   }
 
-
-  class SerialInputStream extends InputStream
-  {
+  class SerialInputStream extends InputStream {
     ByteQueue bq = new ByteQueue(128);
 
-    protected void gather()
-    {
+    protected void gather() {
       int navail = TOSSerial.this.available();
-      if( navail > 0 )
-      {
+      if (navail > 0) {
         byte buffer[] = new byte[navail];
-        bq.push_back( buffer, 0, TOSSerial.this.read( buffer, 0, navail ) );
+        bq.push_back(buffer, 0, TOSSerial.this.read(buffer, 0, navail));
       }
     }
 
-    public int read()
-    {
+    public int read() {
       gather();
       return bq.pop_front();
     }
 
-    public int read( byte[] b )
-    {
+    public int read(byte[] b) {
       gather();
       return bq.pop_front(b);
     }
 
-    public int read( byte[] b, int off, int len )
-    {
+    public int read(byte[] b, int off, int len) {
       gather();
-      return bq.pop_front(b,off,len);
+      return bq.pop_front(b, off, len);
     }
 
-    public int available()
-    {
+    public int available() {
       gather();
       return bq.available();
     }
   }
 
-
-  class SerialOutputStream extends OutputStream
-  {
-    public void write( int b )
-    {
+  class SerialOutputStream extends OutputStream {
+    public void write(int b) {
       TOSSerial.this.write(b);
     }
 
-    public void write( byte[] b )
-    {
-      TOSSerial.this.write(b,0,b.length);
+    public void write(byte[] b) {
+      TOSSerial.this.write(b, 0, b.length);
     }
 
-    public void write( byte[] b, int off, int len )
-    {
+    public void write(byte[] b, int off, int len) {
       int nwritten = 0;
-      while( nwritten < len )
-       nwritten += TOSSerial.this.write( b, nwritten, len-nwritten );
+      while (nwritten < len)
+        nwritten += TOSSerial.this.write(b, nwritten, len - nwritten);
     }
   }
 
+  private SerialInputStream m_in;
+
+  private SerialOutputStream m_out;
 
-  SerialInputStream m_in;
-  SerialOutputStream m_out;
-  Vector m_listeners = new Vector();
-  EventDispatcher m_dispatch;
+  private Vector m_listeners = new Vector();
 
-  static String map_portname( String mapstr, String portname )
-  {
+  private EventDispatcher m_dispatch;
+
+  static String map_portname(String mapstr, String portname) {
     // mapstr is of the form "from1=to1:from2=to2"
 
     // If "from", "to", and "portname" all end port numbers, then the ports in
     // "from" and "to" are used as a bias for the port in "portname", appended
-    // to the "to" string (without its original terminating digits).  If more
+    // to the "to" string (without its original terminating digits). If more
     // than one port mapping matches, the one with the smallest non-negative
     // port number wins.
 
     // For instance, if
-    //   mapstr="com1=COM1:com10=\\.\COM10"
+    // mapstr="com1=COM1:com10=\\.\COM10"
     // then
-    //   com1 => COM1
-    //   com3 => COM3
-    //   com10 => \\.\COM10
-    //   com12 => \\.\COM12
+    // com1 => COM1
+    // com3 => COM3
+    // com10 => \\.\COM10
+    // com12 => \\.\COM12
     // or if
-    //   mapstr="com1=/dev/ttyS0:usb1=/dev/ttyS100"
+    // mapstr="com1=/dev/ttyS0:usb1=/dev/ttyS100"
     // then
-    //   com1 => /dev/ttyS0
-    //   com3 => /dev/ttyS2
-    //   usb1 => /dev/ttyS100
-    //   usb3 => /dev/ttyS102
+    // com1 => /dev/ttyS0
+    // com3 => /dev/ttyS2
+    // usb1 => /dev/ttyS100
+    // usb3 => /dev/ttyS102
 
     String maps[] = mapstr.split(":");
     Pattern pkv = Pattern.compile("(.*?)=(.*?)");
@@ -182,111 +177,122 @@ public class TOSSerial extends NativeSerial implements SerialPort
     int match_distance = -1;
     String str_port_to = null;
 
-    for( int i=0; i<maps.length; i++ )
-    {
-      Matcher mkv = pkv.matcher( maps[i] );
-      if( mkv.matches() )
-      {
-       Matcher mfrom = pnum.matcher( mkv.group(1) );
-       Matcher mto = pnum.matcher( mkv.group(2) );
-       if( mfrom.matches() && mto.matches() && mport.matches()
-           && mfrom.group(1).equalsIgnoreCase( mport.group(1) )
-         )
-       {
-         int nfrom = Integer.parseInt( mfrom.group(2) );
-         int nto = Integer.parseInt( mto.group(2) );
-         int nport_from = Integer.parseInt( mport.group(2) );
-         int nport_to = nport_from - nfrom + nto;
-         int ndist = nport_from - nfrom;
-
-         if( (ndist >= 0) && ((ndist < match_distance) || (match_distance == -1)) )
-         {
-           match_distance = ndist;
-           str_port_to = mto.group(1) + nport_to;
-         }
-       }
-       else if( mkv.group(1).equalsIgnoreCase( portname ) )
-       {
-         match_distance = 0;
-         str_port_to = mkv.group(2);
-       }
+    for (int i = 0; i < maps.length; i++) {
+      Matcher mkv = pkv.matcher(maps[i]);
+      if (mkv.matches()) {
+        Matcher mfrom = pnum.matcher(mkv.group(1));
+        Matcher mto = pnum.matcher(mkv.group(2));
+        if (mfrom.matches() && mto.matches() && mport.matches()
+            && mfrom.group(1).equalsIgnoreCase(mport.group(1))) {
+          int nfrom = Integer.parseInt(mfrom.group(2));
+          int nto = Integer.parseInt(mto.group(2));
+          int nport_from = Integer.parseInt(mport.group(2));
+          int nport_to = nport_from - nfrom + nto;
+          int ndist = nport_from - nfrom;
+
+          if ((ndist >= 0)
+              && ((ndist < match_distance) || (match_distance == -1))) {
+            match_distance = ndist;
+            str_port_to = mto.group(1) + nport_to;
+          }
+        } else if (mkv.group(1).equalsIgnoreCase(portname)) {
+          match_distance = 0;
+          str_port_to = mkv.group(2);
+        }
       }
     }
 
     return (str_port_to == null) ? portname : str_port_to;
   }
 
-  public TOSSerial( String portname )
-  {
-    super( map_portname( NativeSerial.getTOSCommMap(), portname ) );
+  public TOSSerial(String portname) {
+    super(map_portname(NativeSerial.getTOSCommMap(), portname));
     m_in = new SerialInputStream();
     m_out = new SerialOutputStream();
     m_dispatch = new EventDispatcher();
     m_dispatch.start();
   }
+  
+  /**
+   * Open the serial port connection 
+   */
+  public boolean open() {
+    if (m_dispatch != null) {
+      m_dispatch.open();
+    }
+    return super.open();
+  }
+  
+  /**
+   * Close the serial port connection
+   */
+  public void close() {
+    if(m_dispatch != null) {
+      m_dispatch.close();
+    }
+    super.close();
+  }
 
-  public void addListener( SerialPortListener l )
-  {
-    synchronized(m_listeners) {
-      if( !m_listeners.contains(l) )
+  public void addListener(SerialPortListener l) {
+    synchronized (m_listeners) {
+      if (!m_listeners.contains(l))
         m_listeners.add(l);
     }
   }
 
-  public void removeListener( SerialPortListener l )
-  {
-    synchronized(m_listeners) {
+  public void removeListener(SerialPortListener l) {
+    synchronized (m_listeners) {
       m_listeners.remove(l);
     }
   }
 
-  public InputStream getInputStream()
-  {
+  public InputStream getInputStream() {
     return m_in;
   }
 
-  public OutputStream getOutputStream()
-  {
+  public OutputStream getOutputStream() {
     return m_out;
   }
 
-  public void close()
-  {
-    if( m_dispatch != null )
+  /**
+   * Finalize the serial port connection, do not expect to open it 
+   * again
+   */
+  public void finalize() {
+    // Be careful what you call here. The object may never have been
+    // created, so the underlying C++ object may not exist, and there's
+    // insufficient guarding to avoid a core dump. If you call other
+    // methods than super.close() or super.finalize(), be sure to
+    // add an if (swigCptr != 0) guard in NativeSerial.java.
+    if (m_dispatch != null) {
       m_dispatch.close();
+    }
 
-    try { if( m_dispatch != null ) m_dispatch.join(); }
-    catch( InterruptedException e ) { }
+    /*
+    try {
+      if (m_dispatch != null) {
+        m_dispatch.join();
+      }
+    } catch (InterruptedException e) {
+    }
+    */
 
     super.close();
 
-    try
-    {
-      if( m_in != null )
-       m_in.close();
+    try {
+      if (m_in != null) {
+        m_in.close();
+      }
 
-      if( m_out != null )
-       m_out.close();
-    }
-    catch( IOException e )
-    {
+      if (m_out != null) {
+        m_out.close();
+      }
+    } catch (IOException e) {
     }
 
     m_dispatch = null;
     m_in = null;
     m_out = null;
-  }
-
-  protected void finalize()
-  {
-    // Be careful what you call here. The object may never have been
-    // created, so the underlying C++ object may not exist, and there's
-    // insufficient guarding to avoid a core dump. If you call other
-    // methods than super.close() or super.finalize(), be sure to
-    // add an if (swigCptr != 0) guard in NativeSerial.java.
-    System.out.println("Java TOSSerial finalize");
-    close();
     super.finalize();
   }
 }
-
index d27ff284789cebb7fc4586189c4a6b69e8768768..eec1498abe586c3c194794a5f83cfef791cbba84 100644 (file)
@@ -36,334 +36,339 @@ import java.util.*;
 import java.nio.*;
 
 /**
- * The Packetizer class implements the new mote-PC protocol, using
- * a ByteSource for low-level I/O
+ * The Packetizer class implements the new mote-PC protocol, using a ByteSource
+ * for low-level I/O
  */
 public class Packetizer extends AbstractSource implements Runnable {
-    /* Protocol inspired by, but not identical to, RFC 1663.
-     * There is currently no protocol establishment phase, and a single
-     * byte ("packet type") to identify the kind/target/etc of each packet.
-     *
-     * The protocol is really, really not aiming for high performance.
-     * 
-     * There is however a hook for future extensions: implementations are
-     * required to answer all unknown packet types with a P_UNKNOWN packet.
-     *
-     * To summarise the protocol:
-     * - the two sides (A & B) are connected by a (potentially unreliable)
-     *   byte stream
-     * - the two sides exchange packets framed by 0x7e (SYNC_BYTE) bytes
-     * - each packet has the form
-     *     <packet type> <data bytes 1..n> <16-bit crc>
-     *   where the crc (see net.tinyos.util.Crc) covers the packet type
-     *   and bytes 1..n
-     * - bytes can be escaped by preceding them with 0x7d and their
-     *   value xored with 0x20; 0x7d and 0x7e bytes must be escaped, 
-     *   0x00 - 0x1f and 0x80-0x9f may be optionally escaped
-     * - There are currently 5 packet types:
-     *   P_PACKET_NO_ACK: A user-packet, with no ack required
-     *   P_PACKET_ACK: A user-packet with a prefix byte, ack required. 
-     *     The receiver must send a P_ACK packet with the prefix byte
-     *     as its contents.
-     *   P_ACK: ack for a previous P_PACKET_ACK packet
-     *   P_UNKNOWN: unknown packet type received. On reception of an
-     *     unknown packet type, the receicer must send a P_UNKNOWN packet,
-     *     the first byte must be the unknown packet type.
-     * - Packets that are greater than a (private) MTU are silently dropped.
-     */
-    final static boolean DEBUG = false;
-
-    final static int SYNC_BYTE = Serial.HDLC_FLAG_BYTE;
-    final static int ESCAPE_BYTE = Serial.HDLC_CTLESC_BYTE;
-    final static int MTU = 256;
-    final static int ACK_TIMEOUT = 1000; // in milliseconds
-
-    final static int P_ACK = Serial.SERIAL_PROTO_ACK;
-    final static int P_PACKET_ACK = Serial.SERIAL_PROTO_PACKET_ACK;
-    final static int P_PACKET_NO_ACK = Serial.SERIAL_PROTO_PACKET_NOACK;
-    final static int P_UNKNOWN = Serial.SERIAL_PROTO_PACKET_UNKNOWN;
-
-    private ByteSource io;
-    private boolean inSync;
-    private byte[] receiveBuffer = new byte[MTU];
-    private int seqNo;
-
-    // Packets are received by a separate thread and placed in a
-    // per-packet-type queue. If received[x] is null, then x is an
-    // unknown protocol (but P_UNKNOWN and P_PACKET_ACK are handled
-    // specially)
-    private Thread reader;
-    private LinkedList[] received;
-
-    /**
-     * Packetizers are built using the makeXXX methods in BuildSource
-     */
-    Packetizer(String name, ByteSource io) {
-       super(name);
-       this.io = io;
-       inSync = false;
-       seqNo = 13;
-       reader = new Thread(this);
-       received = new LinkedList[256];
-       received[P_ACK] = new LinkedList();
-       received[P_PACKET_NO_ACK] = new LinkedList();
-    }
+  /*
+   * Protocol inspired by, but not identical to, RFC 1663. There is currently no
+   * protocol establishment phase, and a single byte ("packet type") to identify
+   * the kind/target/etc of each packet.
+   * 
+   * The protocol is really, really not aiming for high performance.
+   * 
+   * There is however a hook for future extensions: implementations are required
+   * to answer all unknown packet types with a P_UNKNOWN packet.
+   * 
+   * To summarise the protocol: - the two sides (A & B) are connected by a
+   * (potentially unreliable) byte stream - the two sides exchange packets
+   * framed by 0x7e (SYNC_BYTE) bytes - each packet has the form <packet type>
+   * <data bytes 1..n> <16-bit crc> where the crc (see net.tinyos.util.Crc)
+   * covers the packet type and bytes 1..n - bytes can be escaped by preceding
+   * them with 0x7d and their value xored with 0x20; 0x7d and 0x7e bytes must be
+   * escaped, 0x00 - 0x1f and 0x80-0x9f may be optionally escaped - There are
+   * currently 5 packet types: P_PACKET_NO_ACK: A user-packet, with no ack
+   * required P_PACKET_ACK: A user-packet with a prefix byte, ack required. The
+   * receiver must send a P_ACK packet with the prefix byte as its contents.
+   * P_ACK: ack for a previous P_PACKET_ACK packet P_UNKNOWN: unknown packet
+   * type received. On reception of an unknown packet type, the receicer must
+   * send a P_UNKNOWN packet, the first byte must be the unknown packet type. -
+   * Packets that are greater than a (private) MTU are silently dropped.
+   */
+  final static boolean DEBUG = false;
+
+  final static int SYNC_BYTE = Serial.HDLC_FLAG_BYTE;
+
+  final static int ESCAPE_BYTE = Serial.HDLC_CTLESC_BYTE;
+
+  final static int MTU = 256;
+
+  final static int ACK_TIMEOUT = 1000; // in milliseconds
+
+  final static int P_ACK = Serial.SERIAL_PROTO_ACK;
+
+  final static int P_PACKET_ACK = Serial.SERIAL_PROTO_PACKET_ACK;
+
+  final static int P_PACKET_NO_ACK = Serial.SERIAL_PROTO_PACKET_NOACK;
+
+  final static int P_UNKNOWN = Serial.SERIAL_PROTO_PACKET_UNKNOWN;
+
+  private ByteSource io;
+
+  private boolean inSync;
+
+  private byte[] receiveBuffer = new byte[MTU];
+
+  private int seqNo;
+
+  // Packets are received by a separate thread and placed in a
+  // per-packet-type queue. If received[x] is null, then x is an
+  // unknown protocol (but P_UNKNOWN and P_PACKET_ACK are handled
+  // specially)
+  private Thread reader;
+
+  private LinkedList[] received;
+
+  /**
+   * Packetizers are built using the makeXXX methods in BuildSource
+   */
+  Packetizer(String name, ByteSource io) {
+    super(name);
+    this.io = io;
+    inSync = false;
+    seqNo = 13;
+    reader = new Thread(this);
+    received = new LinkedList[256];
+    received[P_ACK] = new LinkedList();
+    received[P_PACKET_NO_ACK] = new LinkedList();
+  }
 
-    synchronized public void open(Messenger messages) throws IOException {
-       super.open(messages);
-       reader.start();
+  synchronized public void open(Messenger messages) throws IOException {
+    super.open(messages);
+    if(!reader.isAlive()) {
+      reader.start();
     }
+  }
 
-    protected void openSource() throws IOException {
-       io.open();
-    }
+  protected void openSource() throws IOException {
+    io.open();
+  }
 
-    protected void closeSource() {
-        io.close();
-    }
+  protected void closeSource() {
+    io.close();
+  }
 
-    protected byte[] readProtocolPacket(int packetType, long deadline) throws IOException {
-       LinkedList inPackets = received[packetType];
-
-       // Wait for a packet on inPackets
-       synchronized (inPackets) {
-           while (inPackets.isEmpty()) {
-               long now = System.currentTimeMillis();
-               if (deadline != 0 && now >= deadline) {
-                   return null;
-               }
-               try {
-                   inPackets.wait(deadline != 0 ? deadline - now : 0);
-               }
-               catch (InterruptedException e) {
-                   throw new IOException("interrupted");
-               }
-           }
-           return (byte [])inPackets.removeFirst();
-       }
+  protected byte[] readProtocolPacket(int packetType, long deadline)
+      throws IOException {
+    LinkedList inPackets = received[packetType];
+
+    // Wait for a packet on inPackets
+    synchronized (inPackets) {
+      while (inPackets.isEmpty()) {
+        long now = System.currentTimeMillis();
+        if (deadline != 0 && now >= deadline) {
+          return null;
+        }
+        try {
+          inPackets.wait(deadline != 0 ? deadline - now : 0);
+        } catch (InterruptedException e) {
+          throw new IOException("interrupted");
+        }
+      }
+      return (byte[]) inPackets.removeFirst();
     }
+  }
 
-    // Place a packet in its packet queue, or reject unknown packet
-    // types (which don't have a queue)
-    protected void pushProtocolPacket(int packetType, byte[] packet) {
-       LinkedList inPackets = received[packetType];
-
-       if (inPackets != null) {
-           synchronized (inPackets) {
-               inPackets.add(packet);
-               inPackets.notify();
-           }
-       }
-       else if (packetType != P_UNKNOWN) {
-           try {
-               writeFramedPacket(P_UNKNOWN, packetType, ackPacket, 0);
-           }
-           catch (IOException e) { }
-           message(name + ": ignoring unknown packet type 0x" +
-                   Integer.toHexString(packetType));
-       }
+  // Place a packet in its packet queue, or reject unknown packet
+  // types (which don't have a queue)
+  protected void pushProtocolPacket(int packetType, byte[] packet) {
+    LinkedList inPackets = received[packetType];
+
+    if (inPackets != null) {
+      synchronized (inPackets) {
+        inPackets.add(packet);
+        inPackets.notify();
+      }
+    } else if (packetType != P_UNKNOWN) {
+      try {
+        writeFramedPacket(P_UNKNOWN, packetType, ackPacket, 0);
+      } catch (IOException e) {
+      }
+      message(name + ": ignoring unknown packet type 0x"
+          + Integer.toHexString(packetType));
     }
+  }
 
-    protected byte[] readSourcePacket() throws IOException {
-       // Packetizer packet format is identical to PacketSource's
-       for (;;) {
-           byte[] packet = readProtocolPacket(P_PACKET_NO_ACK,0);
-           if (packet.length >= 1) {
-               return packet;
-           }
-       }
+  protected byte[] readSourcePacket() throws IOException {
+    // Packetizer packet format is identical to PacketSource's
+    for (;;) {
+      byte[] packet = readProtocolPacket(P_PACKET_NO_ACK, 0);
+      if (packet.length >= 1) {
+        return packet;
+      }
     }
+  }
 
   // Write an ack-ed packet
   protected boolean writeSourcePacket(byte[] packet) throws IOException {
-      writeFramedPacket(P_PACKET_ACK, ++seqNo, packet, packet.length);
+    writeFramedPacket(P_PACKET_ACK, ++seqNo, packet, packet.length);
+
+    long deadline = System.currentTimeMillis() + ACK_TIMEOUT;
+    for (;;) {
+      byte[] ack = readProtocolPacket(P_ACK, deadline);
+      if (ack == null) {
+        if (DEBUG) {
+          message(name + ": ACK timed out");
+        }
+        return false;
+      }
+      if (ack[0] == (byte) seqNo) {
+        if (DEBUG) {
+          message(name + ": Rcvd ACK");
+        }
+        return true;
+      }
+    }
 
-      long deadline = System.currentTimeMillis() + ACK_TIMEOUT;
+  }
+
+  static private byte ackPacket[] = new byte[0];
+
+  public void run() {
+    try {
       for (;;) {
-         byte[] ack = readProtocolPacket(P_ACK, deadline);
-         if (ack == null) {
-             if (DEBUG) {
-                 message(name + ": ACK timed out");
-             }
-             return false;
-         }
-         if (ack[0] == (byte)seqNo) {
-             if (DEBUG) {
-                 message(name + ": Rcvd ACK");
-             }
-             return true;
-         }
+        byte[] packet = readFramedPacket();
+        int packetType = packet[0] & 0xff;
+        int pdataOffset = 1;
+
+        if (packetType == P_PACKET_ACK) {
+          // send ack
+          writeFramedPacket(P_ACK, packet[1], ackPacket, 0);
+          // And merge with un-acked packets
+          packetType = P_PACKET_NO_ACK;
+          pdataOffset = 2;
+        }
+        int dataLength = packet.length - pdataOffset;
+        byte[] dataPacket = new byte[dataLength];
+        System.arraycopy(packet, pdataOffset, dataPacket, 0, dataLength);
+        pushProtocolPacket(packetType, dataPacket);
       }
-    
+    } catch (IOException e) {
+    }
   }
 
-    static private byte ackPacket[] = new byte[0];
-
-    public void run() {
-       try {
-           for (;;) {
-               byte[] packet = readFramedPacket();
-               int packetType = packet[0] & 0xff;
-               int pdataOffset = 1;
-
-               if (packetType == P_PACKET_ACK) {
-                   // send ack
-                   writeFramedPacket(P_ACK, packet[1], ackPacket, 0);
-                   // And merge with un-acked packets
-                   packetType = P_PACKET_NO_ACK;
-                   pdataOffset = 2;
-               }
-               int dataLength = packet.length - pdataOffset;
-               byte[] dataPacket = new byte[dataLength];
-               System.arraycopy(packet, pdataOffset, dataPacket, 0, dataLength);
-               pushProtocolPacket(packetType, dataPacket);
-           }
-       }
-       catch (IOException e) { }
+  // Read system-level packet. If inSync is false, we currently don't
+  // have sync
+  private byte[] readFramedPacket() throws IOException {
+    int count = 0;
+    boolean escaped = false;
+
+    for (;;) {
+      if (!inSync) {
+        message(name + ": resynchronising");
+        // re-synchronise
+        while (io.readByte() != SYNC_BYTE)
+          ;
+        inSync = true;
+        count = 0;
+        escaped = false;
+      }
+
+      if (count >= MTU) {
+        // Packet too long, give up and try to resync
+        message(name + ": packet too long");
+        inSync = false;
+        continue;
+      }
+
+      byte b = io.readByte();
+      if (escaped) {
+        if (b == SYNC_BYTE) {
+          // sync byte following escape is an error, resync
+          message(name + ": unexpected sync byte");
+          inSync = false;
+          continue;
+        }
+        b ^= 0x20;
+        escaped = false;
+      } else if (b == ESCAPE_BYTE) {
+        escaped = true;
+        continue;
+      } else if (b == SYNC_BYTE) {
+        if (count < 4) {
+          // too-small frames are ignored
+          count = 0;
+          continue;
+        }
+        byte[] packet = new byte[count - 2];
+        System.arraycopy(receiveBuffer, 0, packet, 0, count - 2);
+
+        int readCrc = (receiveBuffer[count - 2] & 0xff)
+            | (receiveBuffer[count - 1] & 0xff) << 8;
+        int computedCrc = Crc.calc(packet, packet.length);
+
+        if (DEBUG) {
+          System.err.println("received: ");
+          Dump.printPacket(System.err, packet);
+          System.err.println(" rcrc: " + Integer.toHexString(readCrc)
+              + " ccrc: " + Integer.toHexString(computedCrc));
+        }
+
+        if (readCrc == computedCrc) {
+          return packet;
+        } else {
+          message(name + ": bad packet");
+          /*
+           * We don't lose sync here. If we did, garbage on the line at startup
+           * will cause loss of the first packet.
+           */
+          count = 0;
+          continue;
+        }
+      }
+
+      receiveBuffer[count++] = b;
+    }
+  }
+
+  // Class to build a framed, escaped and crced packet byte stream
+  static class Escaper {
+    byte[] escaped;
+
+    int escapePtr;
+
+    int crc;
+
+    // We're building a length-byte packet
+    Escaper(int length) {
+      escaped = new byte[2 * length];
+      escapePtr = 0;
+      crc = 0;
+      escaped[escapePtr++] = SYNC_BYTE;
     }
 
-    // Read system-level packet. If inSync is false, we currently don't
-    // have sync
-    private byte[] readFramedPacket() throws IOException {
-       int count = 0;
-       boolean escaped = false;
-
-       for (;;) {
-           if (!inSync) {
-               message(name + ": resynchronising");
-               // re-synchronise
-               while (io.readByte() != SYNC_BYTE)
-                   ;
-               inSync = true;
-               count = 0;
-               escaped = false;
-           }
-
-           if (count >= MTU) {
-               // Packet too long, give up and try to resync
-               message(name + ": packet too long");
-               inSync = false;
-               continue;
-           }
-
-           byte b = io.readByte();
-           if (escaped) {
-               if (b == SYNC_BYTE) {
-                   // sync byte following escape is an error, resync
-                   message(name + ": unexpected sync byte");
-                   inSync = false;
-                   continue;
-               }
-               b ^= 0x20;
-               escaped = false;
-           }
-           else if (b == ESCAPE_BYTE) {
-               escaped = true;
-               continue;
-           }
-           else if (b == SYNC_BYTE) {
-               if (count < 4) {
-                   // too-small frames are ignored
-                   count = 0;
-                   continue;
-               }
-               byte[] packet = new byte[count - 2];
-               System.arraycopy(receiveBuffer, 0, packet, 0, count - 2);
-
-               int readCrc = (receiveBuffer[count - 2]  & 0xff) |
-                 (receiveBuffer[count - 1] & 0xff) << 8;
-               int computedCrc = Crc.calc(packet, packet.length);
-
-               if (DEBUG) {
-                   System.err.println("received: ");
-                   Dump.printPacket(System.err, packet);
-                   System.err.println(" rcrc: " + Integer.toHexString(readCrc) +
-                                      " ccrc: " + Integer.toHexString(computedCrc));
-               }
-
-               if (readCrc == computedCrc) {
-                   return packet;
-               }
-               else {
-                   message(name + ": bad packet");
-                   /* We don't lose sync here. If we did, garbage on the line
-                      at startup will cause loss of the first packet. */
-                   count = 0;
-                   continue;
-               }
-           }
-
-           receiveBuffer[count++] = b;
-       }
+    static private boolean needsEscape(int b) {
+      return b == SYNC_BYTE || b == ESCAPE_BYTE;
     }
 
-    // Class to build a framed, escaped and crced packet byte stream
-    static class Escaper {
-       byte[] escaped;
-       int escapePtr;
-       int crc;
-
-       // We're building a length-byte packet
-       Escaper(int length) {
-           escaped = new byte[2 * length];
-           escapePtr = 0;
-           crc = 0;
-           escaped[escapePtr++] = SYNC_BYTE;
-       }
-
-       static private boolean needsEscape(int b) {
-           return b == SYNC_BYTE || b == ESCAPE_BYTE;
-       }
-
-       void nextByte(int b) {
-           b = b & 0xff;
-           crc = Crc.calcByte(crc, b);
-           if (needsEscape(b)) {
-               escaped[escapePtr++] = ESCAPE_BYTE;
-               escaped[escapePtr++] = (byte)(b ^ 0x20);
-           }
-           else {
-               escaped[escapePtr++] = (byte)b;
-           }
-       }
-
-       void terminate() {
-           escaped[escapePtr++] = SYNC_BYTE;
-       }
+    void nextByte(int b) {
+      b = b & 0xff;
+      crc = Crc.calcByte(crc, b);
+      if (needsEscape(b)) {
+        escaped[escapePtr++] = ESCAPE_BYTE;
+        escaped[escapePtr++] = (byte) (b ^ 0x20);
+      } else {
+        escaped[escapePtr++] = (byte) b;
+      }
     }
 
-    // Write a packet of type 'packetType', first byte 'firstByte'
-    // and bytes 2..'count'+1 in 'packet'
-    private synchronized void writeFramedPacket(int packetType, int firstByte,
-                                               byte[] packet, int count) throws IOException {
-       if (DEBUG) {
-           System.err.println("sending: ");
-           Dump.printByte(System.err, packetType);
-           Dump.printByte(System.err, firstByte);
-           Dump.printPacket(System.err, packet);
-           System.err.println();
-       }
-
-       Escaper buffer = new Escaper(count + 6);
-       
-       buffer.nextByte(packetType);
-       buffer.nextByte(firstByte);
-       for (int i = 0; i < count; i++) {
-           buffer.nextByte(packet[i]);
-       }
-
-       int crc = buffer.crc;
-       buffer.nextByte(crc & 0xff);
-       buffer.nextByte(crc >> 8);
-
-       buffer.terminate();
-
-       byte[] realPacket = new byte[buffer.escapePtr];
-       System.arraycopy(buffer.escaped, 0, realPacket, 0, buffer.escapePtr);
-
-       if (DEBUG) {
-           Dump.dump("encoded", realPacket);
-       }
-       io.writeBytes(realPacket);
+    void terminate() {
+      escaped[escapePtr++] = SYNC_BYTE;
     }
+  }
+
+  // Write a packet of type 'packetType', first byte 'firstByte'
+  // and bytes 2..'count'+1 in 'packet'
+  private synchronized void writeFramedPacket(int packetType, int firstByte,
+      byte[] packet, int count) throws IOException {
+    if (DEBUG) {
+      System.err.println("sending: ");
+      Dump.printByte(System.err, packetType);
+      Dump.printByte(System.err, firstByte);
+      Dump.printPacket(System.err, packet);
+      System.err.println();
+    }
+
+    Escaper buffer = new Escaper(count + 6);
+
+    buffer.nextByte(packetType);
+    buffer.nextByte(firstByte);
+    for (int i = 0; i < count; i++) {
+      buffer.nextByte(packet[i]);
+    }
+
+    int crc = buffer.crc;
+    buffer.nextByte(crc & 0xff);
+    buffer.nextByte(crc >> 8);
+
+    buffer.terminate();
+
+    byte[] realPacket = new byte[buffer.escapePtr];
+    System.arraycopy(buffer.escaped, 0, realPacket, 0, buffer.escapePtr);
+
+    if (DEBUG) {
+      Dump.dump("encoded", realPacket);
+    }
+    io.writeBytes(realPacket);
+  }
 }
index 32339f4f23383c81312e3eecec9e308b9f530eb8..73357f41ce15a8f3c345f8f31a444001aebe9ad0 100644 (file)
@@ -1,5 +1,7 @@
 // $Id$
 
+package net.tinyos.packet;
+
 /*                                                                     tab:4
  * "Copyright (c) 2000-2003 The Regents of the University  of California.  
  * All rights reserved.
  * 94704.  Attention:  Intel License Inquiry.
  */
 
-
-package net.tinyos.packet;
-
-import java.util.*;
 import java.io.*;
 import net.tinyos.comm.*;
 
 /**
  * A serial port byte source using net.tinyos.comm
  */
-public class SerialByteSource extends StreamByteSource implements SerialPortListener
-{
-    private SerialPort serialPort;
-    private String portName;
-    private int baudRate;
-
-    public SerialByteSource(String portName, int baudRate) {
-       this.portName = portName;
-       this.baudRate = baudRate;
+public class SerialByteSource extends StreamByteSource implements
+    SerialPortListener {
+  private SerialPort serialPort;
+
+  private String portName;
+
+  private int baudRate;
+
+  public SerialByteSource(String portName, int baudRate) {
+    this.portName = portName;
+    this.baudRate = baudRate;
+  }
+
+  public void openStreams() throws IOException {
+    //if (serialPort == null) {
+      try {
+        serialPort = new TOSSerial(portName);
+      } catch (Exception e) {
+        throw new IOException("Could not open " + portName + ": "
+            + e.getMessage());
+      }
+      /*
+    } else {
+      if (!serialPort.open()) {
+        throw new IOException("Could not re-open " + portName);
+      }
     }
+    */
 
-    public void openStreams() throws IOException {
-       try {
-            serialPort = new TOSSerial(portName);
-       }
-       catch (Exception e) {
-           throw new IOException("Could not open " + portName + ": " + e.getMessage());
-       }
-
-       try {
-           //serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
-           serialPort.setSerialPortParams(baudRate,
-                                          8,
-                                          SerialPort.STOPBITS_1,
-                                          false );
-
-           serialPort.addListener(this);
-           serialPort.notifyOn( SerialPortEvent.DATA_AVAILABLE, true );
-       }
-       catch (Exception e) {
-           serialPort.close();
-           throw new IOException("Could not configure " + portName + ": " + e.getMessage() );
-       }
-
-       is = serialPort.getInputStream();
-       os = serialPort.getOutputStream();
-    }
+    try {
+      // serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
+      serialPort.setSerialPortParams(baudRate, 8, SerialPort.STOPBITS_1, false);
 
-    public void closeStreams() throws IOException {
-       serialPort.close();
+      serialPort.addListener(this);
+      serialPort.notifyOn(SerialPortEvent.DATA_AVAILABLE, true);
+    } catch (Exception e) {
+      serialPort.close();
+      throw new IOException("Could not configure " + portName + ": "
+          + e.getMessage());
     }
 
-    public String allPorts() {
-      /*
-       Enumeration ports = CommPortIdentifier.getPortIdentifiers();
-       if (ports == null)
-           return "No comm ports found!";
-
-       boolean  noPorts = true;
-       String portList = "Known serial ports:\n";
-       while (ports.hasMoreElements()) {
-           CommPortIdentifier port = (CommPortIdentifier)ports.nextElement();
-
-           if (port.getPortType() == CommPortIdentifier.PORT_SERIAL) {
-               portList += "- " + port.getName() + "\n";
-               noPorts = false;
-           }
-       }
-       if (noPorts)
-           return "No comm ports found!";
-       else
-           return portList;
-      */
-      return "Listing available comm ports is no longer supported.";
+    is = serialPort.getInputStream();
+    os = serialPort.getOutputStream();
+  }
+
+  public void closeStreams() throws IOException {
+    serialPort.close();
+  }
+
+  public String allPorts() {
+    /*
+     * Enumeration ports = CommPortIdentifier.getPortIdentifiers(); if (ports ==
+     * null) return "No comm ports found!";
+     * 
+     * boolean noPorts = true; String portList = "Known serial ports:\n"; while
+     * (ports.hasMoreElements()) { CommPortIdentifier port =
+     * (CommPortIdentifier)ports.nextElement();
+     * 
+     * if (port.getPortType() == CommPortIdentifier.PORT_SERIAL) { portList += "- " +
+     * port.getName() + "\n"; noPorts = false; } } if (noPorts) return "No comm
+     * ports found!"; else return portList;
+     */
+    return "Listing available comm ports is no longer supported.";
+  }
+
+  Object sync = new Object();
+
+  public byte readByte() throws IOException {
+    // On Linux at least, javax.comm input streams are not interruptible.
+    // Make them so, relying on the DATA_AVAILABLE serial event.
+    synchronized (sync) {
+      while (is.available() == 0) {
+        try {
+          sync.wait();
+        } catch (InterruptedException e) {
+          close();
+          throw new IOException("interrupted");
+        }
+      }
     }
 
-    Object sync = new Object();
-
-    public byte readByte() throws IOException {
-       // On Linux at least, javax.comm input streams are not interruptible.
-       // Make them so, relying on the DATA_AVAILABLE serial event.
-       synchronized (sync) {
-           while (is.available() == 0) {
-               try {
-                   sync.wait();
-               }
-               catch (InterruptedException e) {
-                   close();
-                   throw new IOException("interrupted");
-               }
-           }
-       }
-
-       return super.readByte();
-    }
+    return super.readByte();
+  }
 
-    public void serialEvent(SerialPortEvent ev) {
-       synchronized (sync) {
-           sync.notify();
-       }
+  public void serialEvent(SerialPortEvent ev) {
+    synchronized (sync) {
+      sync.notify();
     }
+  }
 
-    protected void finalize() {
-      System.out.println("SerialByteSource finalize");
-      serialPort.close();
-    }
+  protected void finalize() {
+    serialPort.finalize();
+  }
 
 }
index 546ffe78deb1dd4c2e098d8b4f56391f9ffea799..cd6ec2e9bb944daf54fcb7d69f3fe0f8d2119772 100644 (file)
Binary files a/support/sdk/java/tinyos.jar and b/support/sdk/java/tinyos.jar differ