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] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 peteralieb
/**
2
 *
3
 */
4
package edu.byu.cc.plieber.fpgaenet.fcp;
5
 
6
import java.io.*;
7
import java.net.*;
8
import java.util.ArrayList;
9
import java.util.List;
10
import java.util.concurrent.ConcurrentHashMap;
11
import java.util.concurrent.LinkedBlockingQueue;
12
 
13
import javax.swing.text.html.MinimalHTMLWriter;
14
 
15
/**
16
 * The main class to instantiate for communication of an FCP/UDP/IP connection.
17
 * Provides methods to send data, request data, and received data. All data is
18
 * sent and received as byte arrays.
19
 *
20
 * @author Peter Lieber
21
 *
22
 */
23
public class FCPProtocol {
24
 
25
        /**
26
         * Creates new FCPProtocol object with default ports: 3001(remote), 3000(local)
27
         *
28
         * @throws IOException
29
         */
30
        public FCPProtocol() throws IOException {
31
                this.init(0x3000, 0x3001);
32
        }
33
 
34
        /**
35
         * Creates new FCPProtocol object with default local port, 3000
36
         * @param port Local UDP Port
37
         * @throws IOException
38
         */
39
        public FCPProtocol(int port) throws IOException {
40
                this.init(port, 0x3001);
41
        }
42
 
43
        /**
44
         * Creates new FCPProtocol object
45
         * @param port Local UDP Port
46
         * @param destport Remote UDP Port
47
         * @throws IOException
48
         */
49
        public FCPProtocol(int port, int destport) throws IOException {
50
                this.init(port, destport);
51
        }
52
 
53
        /**
54
         * Initializes protocol parameters and threads
55
         * @param port
56
         * @param destport
57
         * @throws IOException
58
         */
59
        private void init(int port, int destport) throws IOException {
60
                rec_cur = 1;
61
                rec_last_rcv = 0;
62
                snd_cur = 0;
63
                snd_last_ack = 0;
64
                timeout = 1000;
65
                socket = new DatagramSocket(port);
66
                socket.setSoTimeout(50);
67
                connectedPort = destport;
68
                connected = false;
69
                this.receivedQueue = new LinkedBlockingQueue<FCPPacket>();
70
                this.packetOutbox = new ConcurrentHashMap<Integer, FCPPacket>();
71
                recThread = new FCPReceiveThread(this);
72
                recThread.start();
73
                sendThread = new FCPSendThread(this);
74
                sendThread.start();
75
        }
76
 
77
        protected int recWindow = 1;
78
        protected int sendWindow = 20;
79
 
80
        protected volatile int rec_cur;
81
        protected volatile int rec_last_rcv;
82
        protected volatile int snd_cur;
83
        protected volatile int snd_last_ack;
84
 
85
        protected DatagramSocket socket;
86
        private FCPReceiveThread recThread;
87
        private FCPSendThread sendThread;
88
        protected boolean connected;
89
        protected InetAddress connectedAddress;
90
        protected int connectedPort;
91
 
92
        LinkedBlockingQueue<FCPPacket> receivedQueue;
93
        ConcurrentHashMap<Integer, FCPPacket> packetOutbox;
94
        protected long timeout = 500;
95
 
96
        public boolean packetsPending() {
97
                return !packetOutbox.isEmpty() || !sendThread.sendQueue.isEmpty();
98
        }
99
 
100
        /**
101
         * Sends acknowledgement packet (internal)
102
         * @param address
103
         * @param seq
104
         */
105
        protected void sendAck(InetAddress address, int seq) {
106
                // TODO Auto-generated method stub
107
                FCPPacket fp = new FCPPacket();
108
                fp.version = 0;
109
                fp.command = 1;
110
                fp.port = 0;
111
                fp.seq = seq;
112
                fp.len = 0;
113
                fp.dest = connectedAddress;
114
                fp.dstPort = connectedPort;
115
                try {
116
                        sendThread.sendQueue.put(fp);
117
                } catch (InterruptedException e) {
118
                        // TODO Auto-generated catch block
119
                        e.printStackTrace();
120
                }
121
        }
122
 
123
        /**
124
         * Sends connection acknowledgement packet (internal)
125
         */
126
        public void sendConAck() {
127
                FCPPacket fp = new FCPPacket();
128
                fp.version = 0;
129
                fp.command = 3;
130
                fp.port = 0;
131
                fp.seq = 0;
132
                fp.len = 0;
133
                fp.dest = connectedAddress;
134
                fp.dstPort = connectedPort;
135
                try {
136
                        sendThread.sendQueue.put(fp);
137
                } catch (InterruptedException e) {
138
                        // TODO Auto-generated catch block
139
                        e.printStackTrace();
140
                }
141
        }
142
 
143
        /**
144
         * Sends a request for some number of bytes.
145
         * @param port FCP port number
146
         * @param numBytes Number of bytes expected
147
         * @return
148
         * @throws FCPException
149
         */
150
        public boolean sendDataRequest(int port, int numBytes) throws FCPException {
151
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
152
                FCPPacket fp = new FCPPacket();
153
                fp.version = 0;
154
                fp.command = 4;
155
                fp.port = port;
156
                fp.len = numBytes;
157
                fp.dest = connectedAddress;
158
                fp.dstPort = connectedPort;
159
                try {
160
                        sendThread.sendQueue.put(fp);
161
                } catch (InterruptedException e) {
162
                        // TODO Auto-generated catch block
163
                        e.printStackTrace();
164
                }
165
                return true;
166
        }
167
 
168
        /**
169
         * Sends data through the specified FCP port. The data must be less than 1024 bytes long.
170
         * @param port FCP port number
171
         * @param data data to be sent
172
         * @param count number of bytes to send
173
         * @return
174
         * @throws IOException
175
         * @throws FCPException
176
         */
177
        public boolean send(int port, byte[] data, int count) throws FCPException {
178
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
179
                FCPPacket fp = new FCPPacket();
180
                fp.version = 0;
181
                fp.command = 0;
182
                fp.port = port;
183
                fp.len = count;
184
                fp.dest = connectedAddress;
185
                fp.dstPort = connectedPort;
186
                fp.data = data.clone();
187
                try {
188
                        sendThread.sendQueue.put(fp);
189
                } catch (InterruptedException e) {
190
                        throw new FCPException("Interrupted Send Operation");
191
                }
192
                checkHealth();
193
                return true;
194
        }
195
 
196
        /**
197
         * Sends data through the specified FCP port.  The data can be any length (within reason).
198
         * @param port
199
         * @param bytes
200
         * @param numBytes
201
         * @return
202
         * @throws FCPException
203
         */
204
        public boolean sendData(int port, List<Byte> bytes, int numBytes) throws FCPException {
205
                int offset = 0;
206
                int numRead = 0;
207
                while (offset < numBytes) {
208
                        numRead = Math.min(offset+1024, numBytes) - offset;
209
                        this.send(port, bytes.subList(offset, offset+numRead), numRead);
210
                        offset += 1024;
211
                }
212
                return true;
213
        }
214
 
215
        public void sendData(int port, ArrayList<Byte> bytes) throws FCPException {
216
                this.sendData(port, bytes, bytes.size());
217
        }
218
 
219
        public void sendData(int port, byte value) throws FCPException {
220
                this.send(port, value);
221
        }
222
 
223
        /**
224
         * Sends data through the specified FCP port. The data must be less than 1024 bytes long.
225
         * @param port FCP port number
226
         * @param bytes data to be sent
227
         * @param count number of bytes to send
228
         * @return
229
         * @throws FCPException
230
         */
231
        public boolean send(int port, List<Byte> bytes, int count) throws FCPException {
232
 
233
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
234
                FCPPacket fp = new FCPPacket();
235
                fp.version = 0;
236
                fp.command = 0;
237
                fp.port = port;
238
                fp.len = count;
239
                fp.dest = connectedAddress;
240
                fp.dstPort = connectedPort;
241
                fp.data = new byte[bytes.size()];
242
                for (int i=0; i<fp.data.length; i++) {
243
                        fp.data[i] = bytes.get(i);
244
                }
245
                try {
246
                        sendThread.sendQueue.put(fp);
247
                } catch (InterruptedException e) {
248
                        // TODO Auto-generated catch block
249
                        e.printStackTrace();
250
                }
251
                return true;
252
        }
253
 
254
        private boolean send(int port, byte value) throws FCPException {
255
                if (!this.connected) throw new FCPException("Not connected to FPGA!");
256
                FCPPacket fp = new FCPPacket();
257
                fp.version = 0;
258
                fp.command = 0;
259
                fp.port = port;
260
                fp.len = 1;
261
                fp.dest = connectedAddress;
262
                fp.dstPort = connectedPort;
263
                fp.data = new byte[1];
264
                fp.data[0] = value;
265
                try {
266
                        sendThread.sendQueue.put(fp);
267
                } catch (InterruptedException e) {
268
                        // TODO Auto-generated catch block
269
                        e.printStackTrace();
270
                }
271
                return true;
272
        }
273
 
274
        private void checkHealth() throws FCPException {
275
                if (!this.sendThread.isAlive()) {
276
                        if (this.sendThread.sendTimeout) throw new FCPException("Send Error: timeout");
277
                        else if (this.sendThread.ioException) throw new FCPException("I/O Error");
278
                }
279
        }
280
 
281
        void processPacket(FCPPacket fcppacket) {
282
                if (fcppacket.command == 5) {
283
                        try {
284
                                this.receivedQueue.put(fcppacket);
285
                        } catch (InterruptedException e) {
286
                                // TODO Auto-generated catch block
287
                                e.printStackTrace();
288
                        }
289
                }
290
        }
291
 
292
        /**
293
         * Connects to an FPGA at the given address
294
         * @param address Address (usually derived from IP address)
295
         * @param port Remote UDP port (0x3001)
296
         */
297
        public void connect(InetAddress address, int port) {
298
                FCPPacket fp = new FCPPacket();
299
                fp.version = 0;
300
                fp.command = 2;
301
                fp.port = 0;
302
                fp.seq = 0;
303
                fp.len = 0;
304
                fp.dest = address;
305
                fp.dstPort = port;
306
                try {
307
                        sendThread.sendQueue.put(fp);
308
                } catch (InterruptedException e) {
309
                        // TODO Auto-generated catch block
310
                        e.printStackTrace();
311
                }
312
        }
313
        public void connect(InetAddress address) {
314
                FCPPacket fp = new FCPPacket();
315
                fp.version = 0;
316
                fp.command = 2;
317
                fp.port = 0;
318
                fp.seq = 0;
319
                fp.len = 0;
320
                fp.dest = address;
321
                fp.dstPort = 0x3001;
322
                try {
323
                        sendThread.sendQueue.put(fp);
324
                } catch (InterruptedException e) {
325
                        // TODO Auto-generated catch block
326
                        e.printStackTrace();
327
                }
328
        }
329
 
330
        /**
331
         * Disconnect from FPGA.  This method does not send anything to the FPGA,
332
         * but only ends the send and receiving threads of execution and closes
333
         * the UDP socket.
334
         */
335
        public void disconnect() {
336
                recThread.done = true;
337
                sendThread.done = true;
338
                try {
339
                        synchronized (recThread) {
340
                                recThread.join();
341
                        }
342
                        synchronized (sendThread) {
343
                                sendThread.join();
344
                        }
345
                } catch (InterruptedException e) {
346
                        // TODO Auto-generated catch block
347
                        e.printStackTrace();
348
                }
349
                socket.close();
350
        }
351
 
352
        void resetSW() {
353
                rec_cur = 1;
354
                rec_last_rcv = 0;
355
                snd_cur = 0;
356
                snd_last_ack = 0;
357
        }
358
 
359
        /**
360
         * Gets the response data that has been received due to a data request.
361
         * Blocks until data is available.
362
         *
363
         * @return
364
         * @throws InterruptedException
365
         */
366
        public byte[] getDataResponse() {
367
                FCPPacket packet;
368
                try {
369
                        packet = this.receivedQueue.take();
370
                } catch (InterruptedException e) {
371
                        // TODO Auto-generated catch block
372
                        packet = null;
373
                }
374
                if (packet != null)
375
                        return packet.data;
376
                else return null;
377
        }
378
 
379
        @Override
380
        public String toString() {
381
                return "FCP Protocol< FPGA: " + this.connectedAddress.toString() + " >";
382
        }
383
 
384
        void send(FCPPacket fcpPacket) {
385
                try {
386
                        this.socket.send(fcpPacket.wrapInDatagram());
387
                } catch (IOException e) {
388
                        // TODO Auto-generated catch block
389
                        e.printStackTrace();
390
                }
391
        }
392
 
393
        public boolean isConnected() {
394
                return this.connected;
395
        }
396
 
397
        public void setSendWindow(int i) {
398
                this.sendWindow = i;
399
        }
400
 
401
        public int getSourceUDPPort() {
402
                return this.socket.getLocalPort();
403
        }
404
 
405
        public int getDestUDPPort() {
406
                return this.connectedPort;
407
        }
408
 
409
        public InetAddress getDestIPAddress() {
410
                return this.connectedAddress;
411
        }
412
 
413
        public long getWhileCount() {
414
                return this.sendThread.whileCount;
415
        }
416
 
417
        public void resetWhileCount() {
418
                this.sendThread.whileCount = 0;
419
        }
420
}

powered by: WebSVN 2.1.0

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