www.pudn.com > ejip.zip > Slip.java
/*
* Copyright (c) Martin Schoeberl, martin@jopdesign.com
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Martin Schoeberl
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
package ejip;
/**
* Slip.java
*
* communicate with jopbb via serial line.
*/
import util.*;
/**
* Slip driver.
*/
public class Slip extends LinkLayer {
private static final int MAX_BUF = 1500; // or should we use 1006
/**
* period for thread in ms.
*/
private static final int PERIOD = 10;
private static final int END = 0xc0;
private static final int ESC = 0xdb;
private static final int ESC_END = 0xdc;
private static final int ESC_ESC = 0xdd;
/**
* receive buffer
*/
private static int[] rbuf;
/**
* send buffer
*/
private static int[] sbuf;
/**
* bytes received.
*/
private static int cnt;
/**
* mark escape sequence.
*/
private static boolean esc;
/**
* an ip packet is in the receive buffer.
*/
private static boolean ready;
/**
* bytes to be sent. 0 means txFree
*/
private static int scnt;
/**
* allready sent bytes.
*/
private static int sent;
/**
* The one and only reference to this object.
*/
private static Slip single;
/**
* private constructor. The singleton object is created in init().
*/
private Slip() {
super(PERIOD); // thats the period.
}
/**
* allocate buffer, start serial buffer and slip Thread.
*/
public static void init() {
if (single != null) return; // allready called init()
rbuf = new int[MAX_BUF];
sbuf = new int[MAX_BUF];
cnt = 0;
esc = false;
ready = false;
scnt = 0;
sent = 0;
Serial.init(); // start serial buffer thread
single = new Slip();
single.start(); // kick off the thread
}
/**
* main loop.
*/
public void run() {
int timer = 0;;
Packet p;
for (;;) {
waitForNextPeriod();
//
// read, write loop
//
if (loop()) {
timer = 0;
} else {
++timer;
if (timer>1000/PERIOD && cnt>0) { // flush buffer on timeout
Dbg.wr('t');
for (int i=0; i0) {
Serial.wr('C');
Serial.wr('L');
Serial.wr('I');
Serial.wr('E');
Serial.wr('N');
Serial.wr('T');
Serial.wr('S');
Serial.wr('E');
Serial.wr('R');
Serial.wr('V');
Serial.wr('E');
Serial.wr('R');
Serial.wr('\r');
}
}
}
//
// copy packet to packet buffer.
//
if (ready) { // we got a packet
read();
}
if (scnt==0) { // transmit buffer is free
//
// get a ready to send packet with source from this driver.
//
p = Packet.getPacket(single, Packet.SND, Packet.ALLOC);
if (p!=null) {
send(p); // send one packet
}
}
}
}
/**
* get a Packet buffer and copy from receive buffer.
*/
private static void read() {
int i, j, k;
Packet p = Packet.getPacket(Packet.FREE, Packet.ALLOC, single);
if (p==null) {
Dbg.wr('!');
return; // try again later
} // buf blocks receive buffer :-<
int[] pb = p.buf;
rbuf[cnt] = 0;
rbuf[cnt+1] = 0;
rbuf[cnt+2] = 0;
// copy buffer
k = 0;
for (i=0; i>>2] = k;
}
p.len = cnt;
Dbg.wr('s');
Dbg.intVal(cnt);
cnt = 0;
ready = false;
p.setStatus(Packet.RCV); // inform upper layer
}
/**
* copy packet to send buffer.
*/
private static void send(Packet p) {
int i, k;
int[] pb = p.buf;
Dbg.wr('S');
Dbg.intVal(p.len);
scnt = p.len;
sent = 0;
for (i=0; i>>2];
sbuf[i] = k>>>24;
sbuf[i+1] = (k>>>16)&0xff;
sbuf[i+2] = (k>>>8)&0xff;
sbuf[i+3] = k&0xff;
}
p.setStatus(Packet.FREE); // mark packet free
}
/* warum geht das nicht !!!!!
private void loop() {
*/
/**
* read from serial buffer and build an ip packet.
* send a packet if one is in our send buffer.
*/
private static boolean loop() {
int i;
boolean ret = false;
i = Serial.rxCnt();
if (i!=0) {
ret = true;
rcv(i);
}
if (scnt!=0) {
i = Serial.txFreeCnt();
if (i>2) {
snd(i);
}
}
return ret;
}
/**
* copy from send buffer to serial buffer.
*/
private static void snd(int free) {
int i;
if (sent==0) {
Serial.wr(END);
--free;
}
for (i=sent; free>1 && i=20) {
ready = true; // we got one packet
break;
} else { // ignore too short packages
cnt = 0;
continue;
}
} else {
rbuf[cnt++] = val;
}
}
}
}
}