package oebb; /** * Flash.java: Flash handling for OEBB project. * * Author: Martin Schoeberl (martin.schoeberl@chello.at) * * Changelog: * */ import util.*; import com.jopdesign.sys.Native; public class Flash { public static final int DATA_START = 0xa0000; // user data, Streckendaten in oebb BG263 public static final int BGID_START = 0xb0000; // user data, bgid public static final int CONFIG_LEN = 256; // first 256 Bytes are confing data // than logbook public static final int BG_MASTER = 10*4; public static final int BG_MASTER_MAGIC = 1234; static final int OFF_VER = 4; static final int OFF_LEN = 8; static final int OFF_CNT = 12; static final int OFF_FIRST = 16; static final int STR_NR = 0; static final int STR_NET = 4; static final int STR_DIAL = 8; static final int STR_UID = 12; static final int STR_PWD = 16; static final int STR_IP = 20; static final int STR_CNT = 24; static final int STR_LEN = 28; // first point static final int PT_MELNR = 0; static final int PT_LAT = 4; static final int PT_LON = 8; static final int PT_PTR = 12; static final int PT_FLAGS = 16; static final int PT_LEN = 20; // Ankunft flag = station (used in ES)! static final int PT_FLG_STATION = 1; static final int PT_FLG_VERL = 2; static final int PT_FLG_ES = 4; static final int PT_FLG_NO_DIR = 8; static final int PT_FLG_NO_MOVE = 16; static final int PT_FLG_ANM = 32; static final int PT_HB_RIGHT = 64; static final int PT_HB_LEFT = 128; // static final int NO_COMM_ALARM_START = -1; // static final int NO_COMM_ALARM_END = -2; static class Point { int melnr; int lat; int lon; int ptr; int flags; boolean anmelden; boolean station; boolean verlassen; boolean checkMove; boolean checkDirection; boolean hbRight; boolean hbLeft; StringBuffer stationLine1; StringBuffer stationLine2; StringBuffer verschubVon; StringBuffer verschubBis; // start of Funkschatten hack // int fs1_lat, fs1_lon, fs2_lat, fs2_lon; Point() { stationLine1 = new StringBuffer(19); stationLine2 = new StringBuffer(19); verschubVon = new StringBuffer(19); verschubBis = new StringBuffer(19); } // TODO own class for Strecke and Points (immutable with Strings...) Point getPrev() { int i = Flash.getPrev(melnr); if (i==-1) return null; return Flash.getPoint(i); } Point getNext() { int i = Flash.getNext(melnr); if (i==-1) return null; return Flash.getPoint(i); } } static final int MAX_POINTS = 200; /** List of GPS points */ static Point[] str; /** start of Points in Flash */ static int addrPoints; /** Names valid */ static boolean textOk; /** Direction for names */ static boolean left2right; /** Streckennummer */ static int nrStr; /** len of Strecke (in points) */ static int lenStr; /** destination IP address */ static int dstIp; /** connection strings */ static StringBuffer[] connStr; static StringBuffer[] tmpStr; static int logPtr; public static void init() { nrStr = -1; if (str!=null) return; // allready called str = new Point[MAX_POINTS]; for (int i=0; i<MAX_POINTS; ++i) { str[i] = new Point(); } dstIp = 0; connStr = new StringBuffer[4]; connStr[0] = new StringBuffer(20); connStr[1] = new StringBuffer(40); connStr[2] = new StringBuffer(20); connStr[3] = new StringBuffer(20); tmpStr = new StringBuffer[6]; for (int i=0; i<6; ++i) { tmpStr[i] = new StringBuffer(19); } textOk = false; logPtr = 0; } public static int intVal(int addr) { int val = 0; synchronized (Main.tftpHandler) { for (int i=0; i<4; ++i) { val <<= 8; val += Native.rdMem(DATA_START+addr+i); } } return val; } public static void forceReload() { nrStr = -1; } /** * What's the IP address of the ZLB server? * @return */ public static int getIp() { return dstIp; } /** * How many points in the loaded Strecke? * @return */ /* public static int getStrLen() { return lenStr; } */ /** * Find first point to Strecke strnr. */ public static int getFirst(int strnr) { if (nrStr!=strnr) { System.out.println("getFirst: wrong strnr"); return -1; /* automatic load is disabled due to stack issues. if (!loadStr(strnr)) { return -1; } if (Status.esMode) { if (!esStr()) { return -1; } } */ } return str[0].melnr; } /* * Find last point to Strecke strnr. * * not used public static int getLast(int strnr) { if (nrStr!=strnr) { if (!loadStr(strnr)) { return -1; } if (Status.esMode) { if (!esStr()) { return -1; } } } return str[lenStr-1].melnr; } */ public static Point getPoint(int melnr) { for (int i=0; i<lenStr; ++i) { if (str[i].melnr == melnr) { return str[i]; } } Dbg.wr("\nPoint PROBLEM\n"); return null; } /** * Find next 'real' point after melnr. * -1 on last point. */ public static int getNext(int melnr) { for (int i=0; i<lenStr; ++i) { if (str[i].melnr == melnr) { for(; i<lenStr; ++i) { // Funkschatten hack // if (str[i].melnr==0) { // continue; // } if (str[i].melnr != melnr) { return str[i].melnr; } } } } return -1; } /** * Find previous point. * -1 on first point. */ public static int getPrev(int melnr) { for (int i=lenStr-1; i>=0; --i) { if (str[i].melnr == melnr) { for(; i>=0; --i) { // Funkschatten hack if (str[i].melnr==0) { continue; } if (str[i].melnr != melnr) { return str[i].melnr; } } } } return -1; } static boolean isCommAlarm(int melnr, int lat, int lon) { boolean ret = true; Point p = Flash.getPoint(melnr); if (p!=null) { // Funkschatten disabled // // Funkschatten hack // int len = Gps.dist(p.fs1_lat-p.fs2_lat, p.fs1_lon-p.fs2_lon); // int a = Gps.dist(p.fs1_lat-lat, p.fs1_lon-lon); // int b = Gps.dist(p.fs2_lat-lat, p.fs2_lon-lon); // if (a<len && b<len) { // ret = false; // } // was the original clean version // ret = !(p.ptr==NO_COMM_ALARM_START); } return ret; } static void loadString(StringBuffer str, int addr) { int i; str.setLength(0); addr = intVal(addr); // Dbg.wr("loadString\n"); // Dbg.intVal(addr); if (addr <= 0) { // Dbg.wr("no String\n"); return; } int val; for (i=0; i<80; ++i) { synchronized (Main.tftpHandler) { val = Native.rdMem(DATA_START+addr+i); } if (val==0) break; // Dbg.wr(val); str.append((char) val); } } /** * Load point data from flash to str array. */ static boolean loadStr(int strnr) { if (str==null) init(); textOk = false; nrStr = -1; // if not found int i, j, k; // number of Strecken int cnt = intVal(OFF_CNT); int addr = OFF_FIRST; Point p; Point last = null; for (i=0; i<cnt; ++i) { if (intVal(addr+STR_NR)==strnr) { int nrPt = intVal(addr+STR_CNT); if (nrPt>MAX_POINTS) { Dbg.wr("MAX_POINTS\n"); return false; } dstIp = intVal(addr+STR_IP); /* possible stack overfolw!!! loadString(connStr[0], addr+STR_DIAL); loadString(connStr[1], addr+STR_NET); loadString(connStr[2], addr+STR_UID); loadString(connStr[3], addr+STR_PWD); */ nrStr = strnr; lenStr = nrPt; addr += STR_LEN; addrPoints = addr; for (j=0; j<nrPt; ++j) { p = str[j]; p.melnr = intVal(addr+PT_MELNR); p.lat = intVal(addr+PT_LAT); p.lon = intVal(addr+PT_LON); p.ptr = intVal(addr+PT_PTR); // Funkschatten hack // Charly sets melrn to LAST one if not // set in the CSV!!!! // if (p.ptr<0) { // p.melnr = 0; // } p.flags = intVal(addr+PT_FLAGS); p.station = (p.flags & PT_FLG_STATION)!=0; p.anmelden = (p.flags & PT_FLG_ANM)!=0; p.verlassen = (p.flags & PT_FLG_VERL)!=0; p.checkDirection = (p.flags & PT_FLG_NO_DIR)==0; p.checkMove = (p.flags & PT_FLG_NO_MOVE)==0; p.hbRight = (p.flags & PT_HB_RIGHT)!=0; p.hbLeft = (p.flags & PT_HB_LEFT)!=0; last = p; // p.fs1_lat = 0; // p.fs1_lon = 0; // p.fs2_lat = 0; // p.fs2_lon = 0; // // Funkschatten hack // if (p.melnr!=0) { // // a real new point // last = p; // } else if (last!=null){ // k = intVal(addr+PT_PTR); // type // if (k==NO_COMM_ALARM_START) { // last.fs1_lat = intVal(addr+PT_LAT); // last.fs1_lon = intVal(addr+PT_LON); // } // if (k==NO_COMM_ALARM_END) { // last.fs2_lat = intVal(addr+PT_LAT); // last.fs2_lon = intVal(addr+PT_LON); // } // } addr += PT_LEN; } return true; } addr += STR_LEN+intVal(addr+STR_CNT)*PT_LEN; // find next Strecke } Dbg.wr("Strecke not found ", strnr); return false; // not found } /** * Load strings from flash to str array. * Points MUST be loaded with loadStr(). */ static void loadStrNames(int strnr, int von, int bis) { boolean l2r = bis-von>=0; if (l2r==left2right && textOk) return; Dbg.wr("loadStrNames "); Dbg.intVal(strnr); Dbg.lf(); // if we go from left to right, // ziel is right name int line = l2r ? 2 : 0; int addr = addrPoints; for (int i=0; i<lenStr; ++i) { Point p = str[i]; p.ptr = intVal(addr+PT_PTR); //Dbg.lf(); //Dbg.intVal(p.melnr); //Dbg.intVal(p.flags); // TODO: this earlier init is not // part of the current BG SW (1.05) p.stationLine1.setLength(0); p.stationLine2.setLength(0); p.verschubVon.setLength(0); p.verschubBis.setLength(0); int idx = p.ptr; if (idx<=0) { addr += PT_LEN; continue; } int val = ' '; int off = 0; for (int j=0; j<6 && val!=0; ++j) { tmpStr[j].setLength(0); for (int k=0; k<19; ++k) { synchronized (Main.tftpHandler) { val = Native.rdMem(DATA_START+idx+off); } ++off; if (val==0 || val=='^') break; tmpStr[j].append((char) val); } //Dbg.wr(tmpStr[j]); } // recycle first text if the second one is not set off = line; if (line==2 && tmpStr[line].length()==0) { off = 0; } p.stationLine1.append(tmpStr[off]); p.stationLine2.append(tmpStr[off+1]); p.verschubVon.append(tmpStr[4]); p.verschubBis.append(tmpStr[5]); addr += PT_LEN; } //Dbg.lf(); textOk = true; left2right = l2r; } /** * Change the data for ES mode. MUST be called after loadStr() * in ES mode! * */ static boolean esStrNotUsedAnymore() { int i, j, k; int txtPtr = -1; boolean left = true; Point p1, p2; // Suche die pointer zu den Stationstexten fuer die ES Strecke System.out.println("ES Strecke:"); for (i=0; i<lenStr; ++i) { p1 = str[i]; if ((p1.flags&PT_FLG_ES)!=0) { if (left) { // find next station name txtPtr = -1; for (j=i; j<lenStr; ++j) { p2 = str[j]; if ((p2.flags&PT_FLG_STATION)!=0) { txtPtr = p2.ptr; break; } } } left = !left; // use next (or same points) Name on left points // use previous name on right point p1.ptr = txtPtr; } } // shorten the list to ES length for (i=0; i<lenStr; ++i) { p1 = str[i]; if ((p1.flags&PT_FLG_ES)==0) { // we don't need this point in ES mode // remove it from the list --lenStr; for (k=i; k<lenStr; ++k) { p1 = str[k]; p2 = str[k+1]; p1.melnr = p2.melnr; p1.lat = p2.lat; p1.lon = p2.lon; p1.flags = p2.flags; p1.ptr = p2.ptr; } --i; // reevaluate moved point } } // in ES mode we load the text strings here for (i=0; i<lenStr; ++i) { p1 = str[i]; int idx = p1.ptr; if (idx<=0) continue; int val = ' '; int off = 0; tmpStr[0].setLength(0); for (k=0; k<19; ++k) { synchronized (Main.tftpHandler) { val = Native.rdMem(DATA_START+idx+k); } if (val==0 || val=='^') break; tmpStr[0].append((char) val); } p1.stationLine1.setLength(0); p1.stationLine2.setLength(0); p1.stationLine1.append(tmpStr[0]); } return lenStr>0; } /** * Start dial up and * set IP address in State. */ static boolean startComm(int strnr) { if (strnr<=0) return false; int cnt = intVal(OFF_CNT); int addr = OFF_FIRST; int i; for (i=0; i<cnt; ++i) { if (intVal(addr+STR_NR)==strnr) { dstIp = intVal(addr+STR_IP); loadString(connStr[0], addr+STR_DIAL); loadString(connStr[1], addr+STR_NET); loadString(connStr[2], addr+STR_UID); loadString(connStr[3], addr+STR_PWD); break; } addr += STR_LEN+intVal(addr+STR_CNT)*PT_LEN; // find next Strecke } if (i==cnt) return false; Main.state.destIp = dstIp; Main.ipLink.startConnection(connStr[0], connStr[1], connStr[2], connStr[3]); Dbg.wr("IP dest: "); Dbg.intVal((dstIp>>>24)&0xff); Dbg.intVal((dstIp>>>16)&0xff); Dbg.intVal((dstIp>>>8)&0xff); Dbg.intVal((dstIp>>>0)&0xff); Dbg.wr('\n'); for (i=0; i<4; ++i) { Dbg.wr('\"'); Dbg.wr(connStr[i]); Dbg.wr("\"\n"); } return true; } /** * Check if flash data is valid. */ public static boolean ok() { return (intVal(0)==0x0ebb0ebb); } public static void check(boolean log) { int i, j; if (!ok()) { System.out.println("Keine Streckendaten"); } // System.out.println("Streckendaten:"); // dump(); int cnt = intVal(OFF_CNT); Dbg.wr("Anzahl: "); Dbg.intVal(cnt); Dbg.wr('\n'); i = intVal(BGID_START-DATA_START); System.out.print("BG Id: "); System.out.println(i); if (log) System.out.println("Logbook:"); for (i=CONFIG_LEN; i<0x10000; ++i) { j = Native.rdMem(BGID_START+i); if (j=='\n') { if (log) System.out.println(); } else if (j==0xff) { if (log) System.out.println("Logbook end"); break; } else { if (log) System.out.print((char) j); } Timer.wd(); } // Move the log data // the threshold stand in relation to the copy length // in moveLog(). if (i>45000) { System.out.println("move logbook"); Main.tftpHandler.moveLog(); } for (logPtr=CONFIG_LEN; logPtr<0x10000; ++logPtr) { synchronized (Main.tftpHandler) { j = Native.rdMem(BGID_START+logPtr); } if (j==0xff) { break; } } /* for (int i=0; i<cnt; ++i) { info(i); Timer.wd(); } */ } public static int getVer() { return intVal(OFF_VER); } public static int getCnt() { return intVal(OFF_CNT); } public static int getStrNr(int idx) { int addr = OFF_FIRST; for (int i=0; i<idx; ++i) { addr += STR_LEN+intVal(addr+STR_CNT)*PT_LEN; // find next Strecke } return intVal(addr+STR_NR); } public static int getId() { return intVal(0+BGID_START-DATA_START); } public static boolean isMaster() { int val = intVal(BG_MASTER+BGID_START-DATA_START); return (val==BG_MASTER_MAGIC); } public static void dump() { int len = intVal(OFF_LEN); // for (int i=0; i<len; i+=4) { for (int i=0; i<len; ++i) { if ((i&0x03)==0) { Dbg.wr('\n'); Timer.wd(); } synchronized (Main.tftpHandler) { Dbg.hexVal(Native.rdMem(DATA_START+i)); } if ((i&0x03)==3) { Dbg.intVal(intVal(i&0xfffc)); } /* int val = intVal(i); Dbg.hexVal(val); Dbg.intVal(val); Dbg.wr('\n'); */ } Dbg.wr('\n'); } /** * Write logfile entry in the Flash * @param tmpStr2 */ public static void log(StringBuffer str) { int i, j; for (i=0; i<str.length(); ++i) { j = str.charAt(i); System.out.print((char) j); if (logPtr<0x10000) { synchronized (Main.tftpHandler) { Amd.program(BGID_START-0x80000+logPtr, j); } ++logPtr; } Timer.wd(); } } /* public static void info(int nr) { int i, j, addr; addr = OFF_FIRST; for (i=0; i<nr; ++i) { addr += STR_LEN+intVal(addr+STR_CNT)*PT_LEN; // find next Strecke } int str = intVal(addr+STR_NR); Dbg.wr("Nummer: ", str); Dbg.wr("IP: ", intVal(addr+STR_IP)); int cnt = intVal(addr+STR_CNT); Dbg.wr("Punkte: ", cnt); int melnr = getFirst(str); while (melnr!=-1) { Point p = getPoint(melnr); if (p!=null) { Dbg.wr("Melnr: ", p.melnr); Dbg.wr("lat: ", p.lat); Dbg.wr("long: ", p.lon); int idx = p.ptr; Dbg.wr("Text: "); if (idx<=0) { Dbg.intVal(idx); } else { for (j=0; j<20; ++j) { int val = Native.rdMem(DATA_START+idx+j); if (val==0) break; Dbg.wr(val); } } Dbg.wr('\n'); } melnr = getNext(melnr); } // read direct from Flash // addr += STR_LEN; // start of points // for (i=0; i<cnt; ++i) { // Dbg.wr("Melnr: ", intVal(addr+PT_MELNR)); // Dbg.wr("lat: ", intVal(addr+PT_LAT)); // Dbg.wr("long: ", intVal(addr+PT_LON)); // int idx = intVal(addr+PT_PTR); // addr += PT_LEN; // Dbg.wr("Text: "); // if (idx<=0) { // Dbg.intVal(idx); // } else { // for (j=0; j<20; ++j) { // int val = Native.rdMem(DATA_START+idx+j); // if (val==0) break; // Dbg.wr(val); // } // } // Dbg.wr('\n'); // } } */ }