OpenCores
URL https://opencores.org/ocsvn/fpga-cf/fpga-cf/trunk

Subversion Repositories fpga-cf

[/] [fpga-cf/] [trunk/] [java/] [src/] [edu/] [byu/] [cc/] [plieber/] [fpgaenet/] [fcp/] [FCPProtocol.java] - Diff between revs 2 and 7

Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 7
/**
/**
 *
 *
 */
 */
package edu.byu.cc.plieber.fpgaenet.fcp;
package edu.byu.cc.plieber.fpgaenet.fcp;
 
 
import java.io.*;
import java.io.*;
import java.net.*;
import java.net.*;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
 
 
import javax.swing.text.html.MinimalHTMLWriter;
import javax.swing.text.html.MinimalHTMLWriter;
 
 
/**
/**
 * The main class to instantiate for communication of an FCP/UDP/IP connection.
 * The main class to instantiate for communication of an FCP/UDP/IP connection.
 * Provides methods to send data, request data, and received data. All data is
 * Provides methods to send data, request data, and received data. All data is
 * sent and received as byte arrays.
 * sent and received as byte arrays.
 *
 *
 * @author Peter Lieber
 * @author Peter Lieber
 *
 *
 */
 */
public class FCPProtocol {
public class FCPProtocol {
 
 
        /**
        /**
         * Creates new FCPProtocol object with default ports: 3001(remote), 3000(local)
         * Creates new FCPProtocol object with default ports: 3001(remote), 3000(local)
         *
         *
         * @throws IOException
         * @throws IOException
         */
         */
        public FCPProtocol() throws IOException {
        public FCPProtocol() throws IOException {
                this.init(0x3000, 0x3001);
                this.init(0x3000, 0x3001);
        }
        }
 
 
        /**
        /**
         * Creates new FCPProtocol object with default local port, 3000
         * Creates new FCPProtocol object with default local port, 3000
         * @param port Local UDP Port
         * @param port Local UDP Port
         * @throws IOException
         * @throws IOException
         */
         */
        public FCPProtocol(int port) throws IOException {
        public FCPProtocol(int port) throws IOException {
                this.init(port, 0x3001);
                this.init(port, 0x3001);
        }
        }
 
 
        /**
        /**
         * Creates new FCPProtocol object
         * Creates new FCPProtocol object
         * @param port Local UDP Port
         * @param port Local UDP Port
         * @param destport Remote UDP Port
         * @param destport Remote UDP Port
         * @throws IOException
         * @throws IOException
         */
         */
        public FCPProtocol(int port, int destport) throws IOException {
        public FCPProtocol(int port, int destport) throws IOException {
                this.init(port, destport);
                this.init(port, destport);
        }
        }
 
 
        /**
        /**
         * Initializes protocol parameters and threads
         * Initializes protocol parameters and threads
         * @param port
         * @param port
         * @param destport
         * @param destport
         * @throws IOException
         * @throws IOException
         */
         */
        private void init(int port, int destport) throws IOException {
        private void init(int port, int destport) throws IOException {
                rec_cur = 1;
                rec_cur = 1;
                rec_last_rcv = 0;
                rec_last_rcv = 0;
                snd_cur = 0;
                snd_cur = 0;
                snd_last_ack = 0;
                snd_last_ack = 0;
                timeout = 1000;
                timeout = 1000;
                socket = new DatagramSocket(port);
                socket = new DatagramSocket(port);
                socket.setSoTimeout(50);
                socket.setSoTimeout(50);
                connectedPort = destport;
                connectedPort = destport;
                connected = false;
                connected = false;
                this.receivedQueue = new LinkedBlockingQueue<FCPPacket>();
                this.receivedQueue = new LinkedBlockingQueue<FCPPacket>();
                this.packetOutbox = new ConcurrentHashMap<Integer, FCPPacket>();
                this.packetOutbox = new ConcurrentHashMap<Integer, FCPPacket>();
                recThread = new FCPReceiveThread(this);
                recThread = new FCPReceiveThread(this);
                recThread.start();
                recThread.start();
                sendThread = new FCPSendThread(this);
                sendThread = new FCPSendThread(this);
                sendThread.start();
                sendThread.start();
        }
        }
 
 
        protected int recWindow = 1;
        protected int recWindow = 1;
        protected int sendWindow = 20;
        protected int sendWindow = 20;
 
 
        protected volatile int rec_cur;
        protected volatile int rec_cur;
        protected volatile int rec_last_rcv;
        protected volatile int rec_last_rcv;
        protected volatile int snd_cur;
        protected volatile int snd_cur;
        protected volatile int snd_last_ack;
        protected volatile int snd_last_ack;
 
 
        protected DatagramSocket socket;
        protected DatagramSocket socket;
        private FCPReceiveThread recThread;
        private FCPReceiveThread recThread;
        private FCPSendThread sendThread;
        private FCPSendThread sendThread;
        protected boolean connected;
        protected boolean connected;
        protected InetAddress connectedAddress;
        protected InetAddress connectedAddress;
        protected int connectedPort;
        protected int connectedPort;
 
 
        LinkedBlockingQueue<FCPPacket> receivedQueue;
        LinkedBlockingQueue<FCPPacket> receivedQueue;
        ConcurrentHashMap<Integer, FCPPacket> packetOutbox;
        ConcurrentHashMap<Integer, FCPPacket> packetOutbox;
        protected long timeout = 500;
        protected long timeout = 500;
 
 
        public boolean packetsPending() {
        public boolean packetsPending() {
                return !packetOutbox.isEmpty() || !sendThread.sendQueue.isEmpty();
                return !packetOutbox.isEmpty() || !sendThread.sendQueue.isEmpty();
        }
        }
 
 
        /**
        /**
         * Sends acknowledgement packet (internal)
         * Sends acknowledgement packet (internal)
         * @param address
         * @param address
         * @param seq
         * @param seq
         */
         */
        protected void sendAck(InetAddress address, int seq) {
        protected void sendAck(InetAddress address, int seq) {
                // TODO Auto-generated method stub
                // TODO Auto-generated method stub
                FCPPacket fp = new FCPPacket();
                FCPPacket fp = new FCPPacket();
                fp.version = 0;
                fp.version = 0;
                fp.command = 1;
                fp.command = 1;
                fp.port = 0;
                fp.port = 0;
                fp.seq = seq;
                fp.seq = seq;
                fp.len = 0;
                fp.len = 0;
                fp.dest = connectedAddress;
                fp.dest = connectedAddress;
                fp.dstPort = connectedPort;
                fp.dstPort = connectedPort;
                try {
                try {
                        sendThread.sendQueue.put(fp);
                        sendThread.sendQueue.put(fp);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
        }
        }
 
 
        /**
        /**
         * Sends connection acknowledgement packet (internal)
         * Sends connection acknowledgement packet (internal)
         */
         */
        public void sendConAck() {
        public void sendConAck() {
                FCPPacket fp = new FCPPacket();
                FCPPacket fp = new FCPPacket();
                fp.version = 0;
                fp.version = 0;
                fp.command = 3;
                fp.command = 3;
                fp.port = 0;
                fp.port = 0;
                fp.seq = 0;
                fp.seq = 0;
                fp.len = 0;
                fp.len = 0;
                fp.dest = connectedAddress;
                fp.dest = connectedAddress;
                fp.dstPort = connectedPort;
                fp.dstPort = connectedPort;
                try {
                try {
                        sendThread.sendQueue.put(fp);
                        sendThread.sendQueue.put(fp);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
        }
        }
 
 
        /**
        /**
         * Sends a request for some number of bytes.
         * Sends a request for some number of bytes.
         * @param port FCP port number
         * @param port FCP port number
         * @param numBytes Number of bytes expected
         * @param numBytes Number of bytes expected
         * @return
         * @return
         * @throws FCPException
         * @throws FCPException
         */
         */
        public boolean sendDataRequest(int port, int numBytes) throws FCPException {
        public boolean sendDataRequest(int port, int numBytes) throws FCPException {
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
                FCPPacket fp = new FCPPacket();
                FCPPacket fp = new FCPPacket();
                fp.version = 0;
                fp.version = 0;
                fp.command = 4;
                fp.command = 4;
                fp.port = port;
                fp.port = port;
                fp.len = numBytes;
                fp.len = numBytes;
                fp.dest = connectedAddress;
                fp.dest = connectedAddress;
                fp.dstPort = connectedPort;
                fp.dstPort = connectedPort;
                try {
                try {
                        sendThread.sendQueue.put(fp);
                        sendThread.sendQueue.put(fp);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
                return true;
                return true;
        }
        }
 
 
        /**
        /**
         * Sends data through the specified FCP port. The data must be less than 1024 bytes long.
         * Sends data through the specified FCP port. The data must be less than 1024 bytes long.
         * @param port FCP port number
         * @param port FCP port number
         * @param data data to be sent
         * @param data data to be sent
         * @param count number of bytes to send
         * @param count number of bytes to send
         * @return
         * @return
         * @throws IOException
         * @throws IOException
         * @throws FCPException
         * @throws FCPException
         */
         */
        public boolean send(int port, byte[] data, int count) throws FCPException {
        public boolean send(int port, byte[] data, int count) throws FCPException {
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
                FCPPacket fp = new FCPPacket();
                FCPPacket fp = new FCPPacket();
                fp.version = 0;
                fp.version = 0;
                fp.command = 0;
                fp.command = 0;
                fp.port = port;
                fp.port = port;
                fp.len = count;
                fp.len = count;
                fp.dest = connectedAddress;
                fp.dest = connectedAddress;
                fp.dstPort = connectedPort;
                fp.dstPort = connectedPort;
                fp.data = data.clone();
                fp.data = data.clone();
                try {
                try {
                        sendThread.sendQueue.put(fp);
                        sendThread.sendQueue.put(fp);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        throw new FCPException("Interrupted Send Operation");
                        throw new FCPException("Interrupted Send Operation");
                }
                }
                checkHealth();
                checkHealth();
                return true;
                return true;
        }
        }
 
 
        /**
        /**
         * Sends data through the specified FCP port.  The data can be any length (within reason).
         * Sends data through the specified FCP port.  The data can be any length (within reason).
         * @param port
         * @param port
         * @param bytes
         * @param bytes
         * @param numBytes
         * @param numBytes
         * @return
         * @return
         * @throws FCPException
         * @throws FCPException
         */
         */
        public boolean sendData(int port, List<Byte> bytes, int numBytes) throws FCPException {
        public boolean sendData(int port, List<Byte> bytes, int numBytes) throws FCPException {
                int offset = 0;
                int offset = 0;
                int numRead = 0;
                int numRead = 0;
                while (offset < numBytes) {
                while (offset < numBytes) {
                        numRead = Math.min(offset+1024, numBytes) - offset;
                        numRead = Math.min(offset+1024, numBytes) - offset;
                        this.send(port, bytes.subList(offset, offset+numRead), numRead);
                        this.send(port, bytes.subList(offset, offset+numRead), numRead);
                        offset += 1024;
                        offset += 1024;
                }
                }
                return true;
                return true;
        }
        }
 
 
        public void sendData(int port, ArrayList<Byte> bytes) throws FCPException {
        public void sendData(int port, ArrayList<Byte> bytes) throws FCPException {
                this.sendData(port, bytes, bytes.size());
                this.sendData(port, bytes, bytes.size());
        }
        }
 
 
        public void sendData(int port, byte value) throws FCPException {
        public void sendData(int port, byte value) throws FCPException {
                this.send(port, value);
                this.send(port, value);
        }
        }
 
 
        /**
        /**
         * Sends data through the specified FCP port. The data must be less than 1024 bytes long.
         * Sends data through the specified FCP port. The data must be less than 1024 bytes long.
         * @param port FCP port number
         * @param port FCP port number
         * @param bytes data to be sent
         * @param bytes data to be sent
         * @param count number of bytes to send
         * @param count number of bytes to send
         * @return
         * @return
         * @throws FCPException
         * @throws FCPException
         */
         */
        public boolean send(int port, List<Byte> bytes, int count) throws FCPException {
        public boolean send(int port, List<Byte> bytes, int count) throws FCPException {
 
 
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
                FCPPacket fp = new FCPPacket();
                FCPPacket fp = new FCPPacket();
                fp.version = 0;
                fp.version = 0;
                fp.command = 0;
                fp.command = 0;
                fp.port = port;
                fp.port = port;
                fp.len = count;
                fp.len = count;
                fp.dest = connectedAddress;
                fp.dest = connectedAddress;
                fp.dstPort = connectedPort;
                fp.dstPort = connectedPort;
                fp.data = new byte[bytes.size()];
                fp.data = new byte[bytes.size()];
                for (int i=0; i<fp.data.length; i++) {
                for (int i=0; i<fp.data.length; i++) {
                        fp.data[i] = bytes.get(i);
                        fp.data[i] = bytes.get(i);
                }
                }
                try {
                try {
                        sendThread.sendQueue.put(fp);
                        sendThread.sendQueue.put(fp);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
                return true;
                return true;
        }
        }
 
 
        private boolean send(int port, byte value) throws FCPException {
        private boolean send(int port, byte value) throws FCPException {
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
                FCPPacket fp = new FCPPacket();
                FCPPacket fp = new FCPPacket();
                fp.version = 0;
                fp.version = 0;
                fp.command = 0;
                fp.command = 0;
                fp.port = port;
                fp.port = port;
                fp.len = 1;
                fp.len = 1;
                fp.dest = connectedAddress;
                fp.dest = connectedAddress;
                fp.dstPort = connectedPort;
                fp.dstPort = connectedPort;
                fp.data = new byte[1];
                fp.data = new byte[1];
                fp.data[0] = value;
                fp.data[0] = value;
                try {
                try {
                        sendThread.sendQueue.put(fp);
                        sendThread.sendQueue.put(fp);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
                return true;
                return true;
        }
        }
 
 
        private void checkHealth() throws FCPException {
        private void checkHealth() throws FCPException {
                if (!this.sendThread.isAlive()) {
                if (!this.sendThread.isAlive()) {
                        if (this.sendThread.sendTimeout) throw new FCPException("Send Error: timeout");
                        if (this.sendThread.sendTimeout) throw new FCPException("Send Error: timeout");
                        else if (this.sendThread.ioException) throw new FCPException("I/O Error");
                        else if (this.sendThread.ioException) throw new FCPException("I/O Error");
                }
                }
        }
        }
 
 
        void processPacket(FCPPacket fcppacket) {
        void processPacket(FCPPacket fcppacket) {
                if (fcppacket.command == 5) {
                if (fcppacket.command == 5) {
                        try {
                        try {
                                this.receivedQueue.put(fcppacket);
                                this.receivedQueue.put(fcppacket);
                        } catch (InterruptedException e) {
                        } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                e.printStackTrace();
                        }
                        }
                }
                }
        }
        }
 
 
        /**
        /**
         * Connects to an FPGA at the given address
         * Connects to an FPGA at the given address
         * @param address Address (usually derived from IP address)
         * @param address Address (usually derived from IP address)
         * @param port Remote UDP port (0x3001)
         * @param port Remote UDP port (0x3001)
         */
         */
        public void connect(InetAddress address, int port) {
        public void connect(InetAddress address, int port) {
                FCPPacket fp = new FCPPacket();
                FCPPacket fp = new FCPPacket();
                fp.version = 0;
                fp.version = 0;
                fp.command = 2;
                fp.command = 2;
                fp.port = 0;
                fp.port = 0;
                fp.seq = 0;
                fp.seq = 0;
                fp.len = 0;
                fp.len = 0;
                fp.dest = address;
                fp.dest = address;
                fp.dstPort = port;
                fp.dstPort = port;
 
                this.connected = false;
                try {
                try {
                        sendThread.sendQueue.put(fp);
                        sendThread.sendQueue.put(fp);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
        }
        }
        public void connect(InetAddress address) {
        public void connect(InetAddress address) {
                FCPPacket fp = new FCPPacket();
                FCPPacket fp = new FCPPacket();
                fp.version = 0;
                fp.version = 0;
                fp.command = 2;
                fp.command = 2;
                fp.port = 0;
                fp.port = 0;
                fp.seq = 0;
                fp.seq = 0;
                fp.len = 0;
                fp.len = 0;
                fp.dest = address;
                fp.dest = address;
                fp.dstPort = 0x3001;
                fp.dstPort = 0x3001;
                try {
                try {
                        sendThread.sendQueue.put(fp);
                        sendThread.sendQueue.put(fp);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
        }
        }
 
 
        /**
        /**
         * Disconnect from FPGA.  This method does not send anything to the FPGA,
         * Disconnect from FPGA.  This method does not send anything to the FPGA,
         * but only ends the send and receiving threads of execution and closes
         * but only ends the send and receiving threads of execution and closes
         * the UDP socket.
         * the UDP socket.
         */
         */
        public void disconnect() {
        public void disconnect() {
                recThread.done = true;
                recThread.done = true;
                sendThread.done = true;
                sendThread.done = true;
                try {
                try {
                        synchronized (recThread) {
                        synchronized (recThread) {
                                recThread.join();
                                recThread.join();
                        }
                        }
                        synchronized (sendThread) {
                        synchronized (sendThread) {
                                sendThread.join();
                                sendThread.join();
                        }
                        }
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
                socket.close();
                socket.close();
        }
        }
 
 
        void resetSW() {
        void resetSW() {
                rec_cur = 1;
                rec_cur = 1;
                rec_last_rcv = 0;
                rec_last_rcv = 0;
                snd_cur = 0;
                snd_cur = 0;
                snd_last_ack = 0;
                snd_last_ack = 0;
        }
        }
 
 
        /**
        /**
         * Gets the response data that has been received due to a data request.
         * Gets the response data that has been received due to a data request.
         * Blocks until data is available.
         * Blocks until data is available.
         *
         *
         * @return
         * @return
         * @throws InterruptedException
         * @throws InterruptedException
         */
         */
        public byte[] getDataResponse() {
        public byte[] getDataResponse() {
                FCPPacket packet;
                FCPPacket packet;
                try {
                try {
                        packet = this.receivedQueue.take();
                        packet = this.receivedQueue.take();
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        packet = null;
                        packet = null;
                }
                }
                if (packet != null)
                if (packet != null)
                        return packet.data;
                        return packet.data;
                else return null;
                else return null;
        }
        }
 
 
        @Override
        @Override
        public String toString() {
        public String toString() {
                return "FCP Protocol< FPGA: " + this.connectedAddress.toString() + " >";
                return "FCP Protocol< FPGA: " + this.connectedAddress.toString() + " >";
        }
        }
 
 
        void send(FCPPacket fcpPacket) {
        void send(FCPPacket fcpPacket) {
                try {
                try {
                        this.socket.send(fcpPacket.wrapInDatagram());
                        this.socket.send(fcpPacket.wrapInDatagram());
                } catch (IOException e) {
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        e.printStackTrace();
                }
                }
        }
        }
 
 
        public boolean isConnected() {
        public boolean isConnected() {
                return this.connected;
                return this.connected;
        }
        }
 
 
        public void setSendWindow(int i) {
        public void setSendWindow(int i) {
                this.sendWindow = i;
                this.sendWindow = i;
        }
        }
 
 
        public int getSourceUDPPort() {
        public int getSourceUDPPort() {
                return this.socket.getLocalPort();
                return this.socket.getLocalPort();
        }
        }
 
 
        public int getDestUDPPort() {
        public int getDestUDPPort() {
                return this.connectedPort;
                return this.connectedPort;
        }
        }
 
 
        public InetAddress getDestIPAddress() {
        public InetAddress getDestIPAddress() {
                return this.connectedAddress;
                return this.connectedAddress;
        }
        }
 
 
        public long getWhileCount() {
        public long getWhileCount() {
                return this.sendThread.whileCount;
                return this.sendThread.whileCount;
        }
        }
 
 
        public void resetWhileCount() {
        public void resetWhileCount() {
                this.sendThread.whileCount = 0;
                this.sendThread.whileCount = 0;
        }
        }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.