📄 ppp.java
字号:
package tcpip;/*** Ppp.java** communicate with jopbb via serial line.*/import util.*;/*** Ppp driver.*/public class Ppp extends LinkLayer { private static final int MAX_BUF = 1500+4; // 1500 is PPP information field/*** period for thread in ms.*/ private static final int PERIOD = 10; private static final int IP = 0x0021; // Internet Protocol packet private static final int IPCP = 0x8021; // Internet Protocol Configuration Protocol packet private static final int CCP = 0x80fd; // Compression Configuration Protocol packet private static final int LCP = 0xc021; // Link Configuration Protocol packet private static final int PAP = 0xc023; // Password Authentication Protocol packet private static final int REQ = 1; // Request options list private static final int ACK = 2; // Acknowledge options list private static final int NAK = 3; // Not acknowledge options list private static final int REJ = 4; // Reject options list private static final int TERM = 5; // Termination private static final int NEG_SEND= 3000/PERIOD; // Period of send negotiation private static final int IP_SEND= 10000/PERIOD; // Send timout for ip for reconnect/*** 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;/*** a ppp 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;/*** flag (0x7e, ~) received*/ private static boolean flag;/*** number for lcp id*/ private static int lcpId;/*** state machine*/ private static int state;/*** reject counter*/ private static int rejCnt; private static final int MAX_REJ = 5;/*** remote ip address.*/ public static int ipRemote;/*** ip address.*/ public static int ip;/*** The one and only reference to this object.*/ // private static Ppp single;// for OEBB Testfahrtpublic static Ppp single;/*** private constructor. The singleton object is created in init().*/ private Ppp() { 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; flag = false; scnt = 0; sent = 0; lcpId = 0x11; ip = 0; ipRemote = 0; initStr(); Serial.init(); // start serial buffer thread single = new Ppp(); single.start(); // kick off the thread }/*** main loop.*/ public void run() { connect(); } /** * windoz PPP. */ private static int[] client; private static int[] ver; private static int[] ok; private static int[] connect; private static int[] ath; private static int[] pin; private static int[] con; private static int[] dial; private static int[] flow; private static void initStr() { int[] s1 = { 'C', 'L', 'I', 'E', 'N', 'T' }; client = s1; int[] s2 = { 'V', 'E', 'R' }; ver = s2; int [] s3 = { 'O', 'K' }; int [] s4 = { 'E', 'C', 'T' }; int [] s5 = { '|', '+', '+', '+', '|', 'A', 'T', 'H', '\r' }; // int [] s6 = { 'A', 'T', '+', 'C', 'P', 'I', 'N', '=', '9', '1', '7', '4','\r' }; int [] s6 = { 'A', 'T', '+', 'C', 'P', 'I', 'N', '=', '5', '6', '4', '4','\r' }; ok = s3; connect = s4; ath = s5; pin = s6; initStr2(); } private static void initStr2() { // int [] s7 = { 'A', 'T', '+', 'C', 'G', 'D', 'C', 'O', 'N', 'T', '=', '1', ',', '"', 'I', 'P', '"', ',', '"', 'w', 'e', 'b', '.', 'o', 'n', 'e', '.', 'a', 't', '"', '\r' }; // int [] s7 = { 'A', 'T', '+', 'C', 'G', 'D', 'C', 'O', 'N', 'T', '=', '1', ',', '"', 'I', 'P', '"', ',', '"', 'A', '1', '.', 'n', 'e', 't', '"', '\r' }; /* OEBB */ int [] s7 = { 'A', 'T', '+', 'C', 'G', 'D', 'C', 'O', 'N', 'T', '=', '1', ',', '"', 'I', 'P', '"', ',', '"', 'o', 'e', 'b', 'b', '.', 'A', '1', '.', 'n', 'e', 't', '"', '\r' }; int [] s8 = { 'A', 'T', 'D', '*', '9', '9', '*', '*', '*', '1', '#', '\r' }; int [] s9 = { 'A', 'T', '\\', 'Q', '3', '\r' }; con = s7; dial = s8; flow = s9; } /** * wait seconds */ void waitSec(int t) { // t *= 1000/PERIOD; for (int i=0; i<t; ++i) { for (int j=0; j<100; ++j) { waitForNextPeriod(); } dropIp(); } } /** * send a string to serial line buffer. * '|' has special meaning: wait one second. */ boolean wrString(int[] s) { int i, j, k, val; i = Serial.txFreeCnt(); j = s.length; if (j>i) return false;Dbg.wr('\''); for (i=0; i<j; ++i) { val = s[i]; if (val=='|') { waitSec(2); // for shure if send buffer is full } else { Serial.wr(val);Dbg.wr(val); } }Dbg.wr('\'');Dbg.wr('\n'); return true; } /** * send a string and loop until rcv string arrives or it times out * timeout in seconds for receive string, is also used for send (if handshake lines are not set) * return false means timeout. */ boolean sendWait(int[] snd, int[] rcv, int timeout) { timeout *= 1000/PERIOD; // // send string // int timer = timeout; // use same timeout for send while (!wrString(snd)) { waitForNextPeriod(); // wait till send buffer is free dropIp(); --timer; if (timer == 0) return false; // timeout on send means problem with handshake lines } if (rcv==null) return true; // no wait string, we're done int ptr = 0; int len = rcv.length; // // now wait on response string // for (timer = timeout; timer>0; --timer) { waitForNextPeriod(); dropIp(); for (int i = Serial.rxCnt(); i>0; --i) { int val = Serial.rd();Dbg.wr(val); if (val == rcv[ptr]) { ++ptr; if (ptr==len) {Dbg.wr('\n'); waitSec(1); return true; // we're done } } else { ptr = 0; // reset match pointer } } }Dbg.wr('?');Dbg.wr('\n'); return false; // timeout expired } /** * do the modem stuff till CONNECT */ void modemInit() { for (;;) { if (sendWait(ath, ok, 3)) { if (sendWait(flow, ok, 3)) { if (!sendWait(con, ok, 2)) { // when ERROR PIN is not set sendWait(pin, ok, 30); if (!sendWait(con, ok, 20)) { continue; // something really strange happend! } } if (sendWait(dial, connect, 10)) { break; } } } waitSec(1); } state = MODEM_OK; timer = 0; lcpAck = false; ipcpAck = false; } /** * cancel connection. */ void modemHangUp() { ip = 0; // stop sending ip data state = INIT; rejCnt = 0; // flush buffer for (int i = Serial.rxCnt(); i>0; --i) { Serial.rd(); } for (;;) { if (sendWait(ath, ok, 3)) { break; } waitSec(3); } } private static final int INIT = 0; private static final int MODEM_OK = 1; private static final int LCP_SENT = 2; private static final int LCP_OK = 3; private static final int PAP_SENT = 4; private static final int PAP_OK = 5; private static final int IPCP_SENT = 6; private static final int IPCP_SENT2 = 7; private static final int IPCP_OK = 8; private static final int CONNECTED = 9; private static int timer; // negotion send and ip-restart timer private static boolean lcpAck; private static boolean ipcpAck; /** * establish a connetcion. */ void connect() { timer = 0; state = INIT; rejCnt = 0; lcpAck = false; boolean ipcpAck = false; // // start the modem // modemInit(); // // now LCP negotiation // for (;;) { waitForNextPeriod(); loop(); if (state==MODEM_OK) { } if (rejCnt > MAX_REJ) { modemHangUp(); // start over modemInit(); } if (ready && scnt==0) { // one packet is read and send buffer is free yield(); // time for a thread switchdbgCon(); int prot = (rbuf[2]<<8)+rbuf[3]; int code = rbuf[4]; if (prot == LCP) { if (code == REQ) { if (checkOptions(LCP)) { lcpAck = true;; } else { ++rejCnt; } } else if (code==ACK && rbuf[5]==lcpId) { state = LCP_OK; } else if (code==TERM) { modemHangUp(); // start over modemInit(); } } else if (prot == PAP) { if (rbuf[4]==ACK && rbuf[5]==lcpId) { state = PAP_OK; } } else if (prot == IPCP) { if (code == REQ) { if (checkOptions(IPCP)) { ipcpAck = true;; } } else if (code == NAK) { // with this NAK we will get our IP address ip= (rbuf[10]<<24) + (rbuf[11]<<16) + (rbuf[12]<<8) + rbuf[13]; dbgIp(ip); makeIPCP(); state = IPCP_SENT2; } else if (code == ACK) { state = IPCP_OK; // nothing more to do ? state = CONNECTED;Dbg.wr('C');Dbg.wr('\n'); }//// des is net guat: kommt nur hierher, wenn der Sendbuffer frei ist!!!// } else if (prot == IP) { // we finally got an ip packet :-) readIp(); } cnt = 0; ready = false; } doSend(); } } void doSend() { if (state==CONNECTED) { // send waiting ip packets if (scnt==0) { // transmit buffer is free timer = 0; // // get a ready to send packet with source from this driver. // Packet p = Packet.getPacket(single, Packet.SND, Packet.ALLOC); if (p!=null) { sendIp(p); // send one packet } } else { // increment sendTimer; timer++; if (timer>IP_SEND) { modemHangUp(); // start over modemInit(); } } } else { // do the negotiation stuff dropIp(); ++timer; if (timer>NEG_SEND) {/*Dbg.intVal(state);if (lcpAck) Dbg.wr('t'); else Dbg.wr('f');*/ if (scnt==0) { // once every two seconds send a REQ if (state == MODEM_OK) { makeLCP(); state = LCP_SENT; } else if (state == LCP_OK && lcpAck) { makePAP(); state = PAP_SENT;// } else if (state == PAP_OK && ipcpAck) { // wait for remote ipcp and ACK first on Linux } else if (state>=PAP_OK && state<CONNECTED) { // ONE makeIPCP(); state = IPCP_SENT; ++rejCnt; // incremenet counter to start over when no respond } timer = 0; } } } } /** * drop waiting packet to prevent packet buffer overrun */ void dropIp() { Packet p = Packet.getPacket(single, Packet.SND, Packet.ALLOC); if (p!=null) { p.setStatus(Packet.FREE); // mark packet free } }void dbgCon() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -