/*
* 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 ejip123.examples;
import com.jopdesign.sys.Const;
import ejip123.*;
import joprt.RtThread;
import ejip123.util.Dbg;
import ejip123.util.DbgUdp;
import ejip123.util.Serial;
import util.Timer;
/**
A small telnet server. This example shows how a TCP server can be implemented with the non-blocking socket orientated
TcpHandler interface.
*/
public class TelnetStreamd implements PingReplyHandler{
private TcpStreamConnection con;
private final int GREET = 0;
private final int ESTABLISHED = 1;
private final int PING = 2;
private final int PINGDONE = 3;
private int state = GREET;
private StringBuffer rcv = new StringBuffer(32);
private StringBuffer tmp = new StringBuffer(32);
public static void main(String[] args){
PacketPool.init(8, 1500);
// Dbg.initSerWait();
DbgUdp.init();
Router.init(3);
// Serial ser = new Serial(10, 1000, Const.IO_UART_BG_MODEM_BASE); // simulator
Serial ser = new Serial(10, 1000, Const.IO_UART1_BASE);
LinkLayer slip = Slip.init(9, 1000, ser, Ip.Ip(192, 168, 2, 2), 1500);
Ip.init(5, 5000);
Router.addRoute(new Route(Ip.Ip(192, 168, 2, 0), Ip.Ip(255, 255, 255, 0), slip));
Router.setDefaultInterface(slip);
Tcp.init(3, 4);
TelnetStreamd th = new TelnetStreamd();
th.con = new TcpStreamConnection(5, 1000);
Tcp.addHandler(23, th.con);
RtThread.startMission();
Router.print();
th.forever();
}
/**
@noinspection NonPrivateFieldAccessedInSynchronizedContext */
private void forever(){
for(; ;){
Timer.wd();
synchronized(this){
if(con.getStatus() == TcpStreamConnection.CLOSED)
state = GREET;
switch(state){
case ESTABLISHED:
processCmd();
break;
case GREET:
String welcome = "Welcome to JOP\r\n> ";
if(con.freeToWrite() >= welcome.length()){
con.write(welcome);
con.flush();
state = ESTABLISHED;
}
break;
case PINGDONE:
if(con.freeToWrite() >= tmp.length()){
con.write(tmp);
con.flush();
tmp.setLength(0);
state = ESTABLISHED;
}
break;
default:
break;
}
}
}
}
private void processCmd(){
int readCnt = con.freeToRead();
if(readCnt > 0){
for(int i = 0; i < readCnt; i++){
rcv.append((char)con.read());
}
Dbg.wr("cli=");
Dbg.wr(rcv);
Dbg.lf();
}
int cmdlen = rcv.length();
int tmpState = ESTABLISHED;
if(cmdlen > 0){
if(Util.CharSequenceStartsWith(rcv, "hello")){
rcv.setLength(0);
con.write("Hello from JOP\r\n> ");
con.flush();
} else if(Util.CharSequenceStartsWith(rcv, "ping")){
int ip = Ip.parseIp(rcv, 5);
rcv.setLength(0);
if(ip != 0){
con.write("PING ");
tmp.setLength(0);
Util.appendIp(tmp, ip);
con.write(tmp);
con.write("\r\n");
con.flush();
tmpState = PING;
Icmp.ping(ip, this);
} else{
con.write("parsing cmd failed\r\n> ");
con.flush();
}
} else{
rcv.setLength(0);
con.write("unknown command\r\n> ");
con.flush();
}
}
state = tmpState;
}
public void pingReply(int ms){
synchronized(this){
tmp.setLength(0);
tmp.append("got reply in ");
tmp.append(ms);
tmp.append("ms\r\n> ");
state = PINGDONE;
}
}
public void pingTimeout(){
synchronized(this){
tmp.setLength(0);
tmp.append("timed out\r\n> ");
state = PINGDONE;
}
}
}