📄 comm.java
字号:
package oebb;/*** Comm.java: Communication for OEBB project.** Author: Martin Schoeberl (martin.schoeberl@chello.at)** Changelog:**/import util.*;import ejip.*;import joprt.*;public class Comm extends RtThread { // UDP destination ports public static final int BG_REQUEST = 2000; public static final int FDL_REPLY = 2001; public static final int FDL_REQUEST = 2002; public static final int BG_REPLY = 2003; // header public static final int UDP_DATA = Udp.DATA; public static final int OFF_CMD = UDP_DATA; public static final int OFF_ID = UDP_DATA+1; public static final int OFF_BGID = UDP_DATA+2; public static final int OFF_DATA = UDP_DATA+3; // local linux pc // public static final int DST_IP = (192<<24) + (168<<16) + (0<<8) + 1; // local slip pc // public static final int DST_IP = (192<<24) + (168<<16) + (1<<8) + 1; // local Windoz pc // public static final int DST_IP = (192<<24) + (168<<16) + (0<<8) + 5; // linux pc (chello) // public static final int DST_IP = (80<<24) + (110<<16) + (200<<8) + 231; // walter (dial up) // public static final int DST_IP = (212<<24) + (152<<16) + (141<<8) + 241; // Sagner PC // public static final int DST_IP = (10<<24) + (19<<16) + (36<<8) + 71; // Wieselburg // public static final int DST_IP = (10<<24) + (49<<16) + (70<<8) + 243; public static int dst_ip;/*** ping periode in n x 100 ms*/ private static final int PING_PERIOD = 200; // two times msg. timeout (2*5 s) private static int ptim; private static boolean pingOut;/*** some statistics*/ private static int[] stat;private static int rtim;private static boolean scheduleReset;/*** The one and only reference to this object.*/ private static Comm single; private static int bgid; private static LinkLayer ipLink;/*** helper class for outstanding commands.*/ private static class MsgOut { final static int MAX_OUTSTANDING = 4; final static int MAX_DATA = 5; // maximum length of data// final static int TIMEOUT = 5000000; // 5 seconds final static int TIMEOUT = 10000000; // 10 seconds final static int RETRY = 3; // maximum send count int cmd; // waiting for repley on this command int id; // timestamp of sending int[] data; int len; // length of data int cnt; // send count (for retrys) private static boolean init; private static MsgOut[] list; private static Object monitor; private MsgOut() { cmd = 0; id = 0; data = new int[MAX_DATA]; len = 0; int cnt = 0; // 0 means it is a free packet } static void init() { if (init) return; init = true; monitor = new Object(); list = new MsgOut[MAX_OUTSTANDING]; for (int i=0; i<MAX_OUTSTANDING; ++i) { list[i] = new MsgOut(); } } static MsgOut getFree(int cmd) { if (!init) init(); for (int i=0; i<MAX_OUTSTANDING; ++i) { synchronized (monitor) { if (list[i].cmd == 0) { list[i].cmd = cmd; // mark it allocated return list[i]; } } }Dbg.wr("no free MsgOut\n"); return null; } void setFree() { synchronized (monitor) { cnt = 0; cmd = 0; } } static void setAllFree() { synchronized (monitor) { for (int i=0; i<MAX_OUTSTANDING; ++i) { MsgOut m = list[i]; m.cnt = 0; m.cmd = 0; } } } static void setAllFreeErr() { synchronized (monitor) { for (int i=0; i<MAX_OUTSTANDING; ++i) { MsgOut m = list[i]; m.cnt = 0; m.cmd = 0; } } // force a reconnect in Ppp-Modem ipLink.reconnect(); Status.connOk = false; Status.commErr = 1; } /** * get a Packet and send or resend the message. */ boolean send() { if (cnt>=RETRY) {Dbg.wr("give up ");Dbg.intVal(cmd);Dbg.lf(); setAllFreeErr(); // give up! return false; } // get an IP packet Packet p = Packet.getPacket(Packet.FREE, Packet.ALLOC, ipLink); if (p == null) { // got no free buffer! Dbg.wr('!'); Dbg.wr('b'); return false; } ++cnt; p.buf[OFF_CMD] = cmd; id = Timer.us(); // id is timer value p.buf[OFF_ID] = id; p.buf[OFF_BGID] = bgid; // bg263 serial numberif (len>MAX_DATA) {Dbg.wr("big problem\n");synchronized (monitor) { for(;;); }} for (int i=0; i<len; ++i) { p.buf[OFF_DATA+i] = data[i]; } p.len = (OFF_DATA+len)<<2; // in bytesDbg.wr("send cmd ");Dbg.intVal(p.buf[Udp.DATA]);/*for (int i=Udp.DATA; i<(p.len>>2); ++i) { Dbg.intVal(p.buf[i]);}*/Dbg.lf(); // and send itstat[0]++;stat[1] += p.len; Udp.build(p, dst_ip, BG_REQUEST); return true; } /** * resend a packet. */ static void checkList() { if (!init) init(); for (int i=0; i<MAX_OUTSTANDING; ++i) { MsgOut m = list[i]; synchronized (monitor) { // find a waiting message if (m.cmd!=0 && m.cnt!=0) { int tim = Timer.us()-m.id; if (tim > TIMEOUT) { m.send(); return; // only one resend to not // fill up the ip buffer too // much } } } } } /** * find the message to the reply and * remove it from the list. * Is there a race condition with checkList? * checkList get's called from Comm-Thread * inList from Udp/Net-Thread */ static boolean inList(Packet p) { if (!init) init(); int cmd = p.buf[OFF_CMD]-1; int id = p.buf[OFF_ID]; for (int i=0; i<MAX_OUTSTANDING; ++i) { MsgOut m = list[i]; synchronized (monitor) { // find the waiting message if (m.cmd==cmd && m.cnt!=0) { if (id==m.id) { m.setFree(); return true; } } } }Dbg.wr("not found inList ");Dbg.intVal(cmd);Dbg.lf(); p.setStatus(Packet.FREE); return false; } } // end MsgOut/*** private because it's a singleton Thread.*/ private Comm(int prio, int us) { super(prio, us); } public static void init(int id, int prio, int period, LinkLayer ipl) { if (single != null) return; // allready called init() bgid = id; Status.connOk = false; Status.download = false; Status.anmOk = false; Status.commErr = 0; ptim = 0; pingOut = false; rtim = 0; scheduleReset = false; ipLink = ipl; dst_ip = 0; // as default MsgOut.init(); // // some statistics in HTML server // stat = new int[5]; for (int i=0; i<stat.length; ++i) stat[i]=0; Html.setValArray(stat); // // start my own thread // single = new Comm(prio, period); // // generate UDP handlers as inner classes and add to as UDP server. // UdpHandler uh; uh = new UdpHandler() { public void request(Packet p) { rpl(p); } }; Udp.addHandler(FDL_REPLY, uh); uh = new UdpHandler() { public void request(Packet p) { rqt(p); } }; Udp.addHandler(FDL_REQUEST, uh); }/*** Do the ping!*/ public void run() { int i, j; int val; for (;;) { waitForNextPeriod(); // resend outstanding packets MsgOut.checkList(); if (ipLink.getIpAddress()==0) { continue; } if (scheduleReset) { Dbg.wr('$'); ++rtim; if (rtim==20) { Main.reset = true; } } if (Status.connOk) { ++ptim; if (ptim==PING_PERIOD) { if (pingOut) { // last ping not replayed timeout(); } ptim = 0; ping(); } } } } public static void startConnection(int dstIp, StringBuffer[] connStr) {System.out.println("start Connection"); dst_ip = dstIp; ipLink.startConnection(connStr[0], connStr[1], connStr[2], connStr[3]); } public static void connect() { MsgOut m = MsgOut.getFree(Cmd.CONN); if (m!=null) { m.data[0] = (Main.VER_MAJ<<16)+Main.VER_MIN; // SW Ver. m.data[1] = Flash.getVer(); m.len = 2; Status.connOk = false; Status.download = false; m.send(); }Dbg.wr('#'); } public static void anmelden(int art, int zugnr, int strnr, int melnr) { MsgOut m = MsgOut.getFree(Cmd.ANM); if (m!=null) { m.data[0] = art; // art 1 m.data[1] = zugnr; m.data[2] = strnr; m.data[3] = melnr; m.len = 4; m.send(); } } public static void verschub(int strnr, int melnr) { MsgOut m = MsgOut.getFree(Cmd.VERSCHUB); if (m!=null) { m.data[0] = strnr; m.data[1] = melnr; m.len = 2; m.send(); } } public static void lern(int strnr, int melnr, int lat, int lon) { MsgOut m = MsgOut.getFree(Cmd.LERN); if (m!=null) { m.data[0] = strnr; m.data[1] = melnr; m.data[2] = lat; m.data[3] = lon; m.len = 4; m.send(); } } public static void alarm(int strnr, int melnr, int alarmType) { MsgOut m = MsgOut.getFree(Cmd.ALARM); if (m!=null) { m.data[0] = strnr; m.data[1] = melnr; m.data[2] = alarmType; m.len = 3; m.send(); } } public static void gpsStatus(int gpsInfo, int lat, int lon) { MsgOut m = MsgOut.getFree(Cmd.GPS_INFO); if (m!=null) { m.data[0] = Status.strNr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -