*/
//@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("(.*?)=(.*?)");
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();
}
}
-
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);
+ }
}
// $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();
+ }
}