Package org.knopflerfish.bundle.consoletelnet

Source Code of org.knopflerfish.bundle.consoletelnet.TelnetServer

/*
* Copyright (c) 2003-2009, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - 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.
*
* - Neither the name of the KNOPFLERFISH project nor the names of its
*   contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
* COPYRIGHT OWNER 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 org.knopflerfish.bundle.consoletelnet;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;

import org.knopflerfish.service.console.ConsoleService;
import org.knopflerfish.service.log.LogRef;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;

/**
* The telnet console server listens to a port for connections and
* upon accept, creates a telnet session to handle that connection.
*/
public class TelnetServer implements org.osgi.framework.BundleActivator,
        Runnable, ManagedService {
    private static BundleContext bc;

    private static LogRef log = null;

    private static TelnetConfig telnetConfig = null;

    private static ServiceRegistration configServReg = null;

    private static Thread telnetServerThread;

    private static Hashtable telnetSessions = null;

    private TelnetSession telnetSession = null;

    private boolean accept = true; // control of main loop running

    private boolean updated = true; // control of main loop server update

    private boolean first = true; // first time server start

    public TelnetServer() {

    }

    // BundleActivator methods implementation

    public void start(BundleContext bc) {
        TelnetServer.bc = bc;

        log = new LogRef(bc, true);

        telnetSessions = new Hashtable();

        Hashtable conf = new Hashtable();
        try {
            telnetConfig = new TelnetConfig(bc);
            conf.put(Constants.SERVICE_PID, getClass().getName());

            configServReg = bc.registerService(ManagedService.class.getName(),
                    this, conf);
        } catch (ConfigurationException cexp) {
            log.error("Consoletelnet configuration error " + cexp.toString());
        }

        telnetServerThread = new Thread(this, "ConsoleTelnetServer");
        telnetServerThread.setDaemon(true);
        telnetServerThread.start();
    }

    public void stop(BundleContext bc) {
        // Stop accepting new connections
        accept = false;
        telnetServerThread.interrupt();

        // Close all pending sessions

        Enumeration e = telnetSessions.keys();
        while (e.hasMoreElements()) {
            telnetSession = (TelnetSession) e.nextElement();
            telnetSession.close();
        }

        configServReg.unregister();
        configServReg = null;

        log.close();
        log = null;
        bc = null;
    }

    // Telnet server main loop, listen for connections and
    // also look for configuration updates.

    public void run() {
        ServerSocket serverSocket = null;
        // int socketTimeout = 10000;
        // int backlog = 100;

        boolean bFailed = false;

        while (accept && !bFailed) {
            if (updated) {
                log.info("updating in server main loop");
                if (serverSocket != null) {
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        log.error("Server socket exception ", e);
                        log.error("Port: " + telnetConfig.getPort());
                        bFailed = true;
                    }
                }
                try {
                    // serverSocket = new ServerSocket(telnetConfig.getPort());
                    serverSocket = new ServerSocket(telnetConfig.getPort(),
                                                    telnetConfig.getBacklog(),
                                                    telnetConfig.getAddress());

                    log.info("listening on port " + telnetConfig.getPort());

                    updated = false;
                } catch (IOException iox) {
                    log.error("Server socket exception", iox);
                    updated = true;
                    bFailed = true;
                }
            } else {
                // System.out.print(":");
                try {
                    serverSocket.setSoTimeout(telnetConfig.getSocketTimeout());
                    Socket socket = serverSocket.accept();

                    // System.out.println("accepting on " + socket);
                    TelnetSession telnetSession = new TelnetSession(socket,
                            telnetConfig, log, bc, this);
                    Thread telnetSessionThread = new Thread(telnetSession,
                            "TelnetConsoleSession");
                    telnetSessions.put(telnetSession, telnetSessionThread);
                    telnetSessionThread.setDaemon(false);
                    telnetSessionThread.start();
                } catch (InterruptedIOException iox) { // Timeout
                    // iox.printStackTrace();
                } catch (IOException iox) {
                    // iox.printStackTrace();
                    log.error("Server exception", iox);
                }
            }
        } // end while (accept)

        // Accept no connections, shut down server socket

        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                log.error("Server socket exception " + e);
                log.error("Port: " + telnetConfig.getPort());
            }
        }
    } // end run

    public void removeSession(TelnetSession tels) {
        telnetSessions.remove(tels);
    }

    public TelnetConfig getTelnetConfig() {
        return telnetConfig;
    }

    public void updated(Dictionary dict) {
        // Get port and host of present config
        // If they differ from the new configuration,
        // set semaphore updated = true
        // so that the main loop may detect the change and
        // close and reopen the server socket

        try {
            boolean portupdated;
            boolean hostupdated = false;

            int oldport = telnetConfig.getPort();
            InetAddress oldinet = telnetConfig.getAddress();

            telnetConfig.updated(dict);

            int port = telnetConfig.getPort();
            InetAddress inet = telnetConfig.getAddress();

            // port change check
            if (oldport != port) {
                portupdated = true;
            } else {
                portupdated = false;
            }

            // inet address change check
            if (oldinet == null && inet == null) {
                hostupdated = false;
            } else if (oldinet == null && inet != null) {
                hostupdated = true;
            } else if (oldinet != null && inet == null) {
                hostupdated = true;
            } else if (oldinet != null && inet != null) {
                if (oldinet.equals(inet)) {
                    hostupdated = false;
                } else {
                    hostupdated = true;
                }
            }
            updated = portupdated || hostupdated || first;
            first = false;

            log.info("p " + portupdated);
            log.info("h " + hostupdated);
            log.info("upda " + updated);
        } catch (Exception ex) {
            log.error("Consoltelnet config exception " + ex);
            ex.printStackTrace();
        }
    }
} // TelnetServer
TOP

Related Classes of org.knopflerfish.bundle.consoletelnet.TelnetServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.