All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dianduiot.bridge.BridgeServer Maven / Gradle / Ivy

package com.github.dianduiot.bridge;

import com.github.dianduiot.bridge.acceptor.BridgeAcceptor;
import com.github.dianduiot.bridge.handler.*;
import com.github.dianduiot.exception.DoException;
import com.github.dianduiot.exception.InstanceExistException;
import com.github.dianduiot.vttp.*;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.ExpiringSessionRecycler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.FilterEvent;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import java.net.InetSocketAddress;

public class BridgeServer implements IoHandler {
    private static final int MINA_UDP_FORCE_THROW_SESSION_SECONDS = 330;

    protected boolean startedFlag = false;
    protected String currentSocketType = null;
    protected NioSocketAcceptor socketAcceptor = null;
    protected NioDatagramAcceptor datagramAcceptor = null;

    private VttpServerConfig config;
    private int encryptType = VttpEncrypt.ENCRYPT_TYPE_AES256_CBC_PKCS5PADDING;

    private VttpHeartbeatManager heartbeatManager;
    private DoHardwareManager hardwareManager;
    private BridgeAcceptor bridgeAcceptor;

    private BridgeHandshakeHandler bridgeHandshakeHandler;
    private BridgeConfigHandler bridgeConfigHandler;
    private BridgeIotHandler bridgeIotHandler;
    private BridgeRootHandler bridgeRootHandler;
    private BridgeUpdateHandler bridgeUpdateHandler;
    private BridgeTransferHandler bridgeTransferHandler;

    private byte[] rootKey = null;

    public void startServer(String socketType) throws Exception {
        if (this.startedFlag) {
            throw new InstanceExistException();
        }

        // Fill missing items.
        // For server config.
        if (this.config == null) {
            this.config = VttpServerConfig.genDefault();
        }
        // For heartbeat manager.
        if (this.heartbeatManager == null) {
            this.heartbeatManager = new VttpHeartbeatManager();
            this.heartbeatManager.enableHeartbeatManager();
        }
        // For hardware manager.
        if (this.hardwareManager == null) {
            this.hardwareManager = new DoHardwareManager();
        }
        // For vttp acceptor.
        if (this.bridgeAcceptor == null) {
            this.bridgeAcceptor = new BridgeAcceptor();
        }
        // For handshake handler.
        if (this.bridgeHandshakeHandler == null) {
            this.bridgeHandshakeHandler = new BridgeHandshakeHandler();
        }
        // For config handler.
        if (this.bridgeConfigHandler == null) {
            this.bridgeConfigHandler = new BridgeConfigHandler();
        }
        // For iot handler.
        if (this.bridgeIotHandler == null) {
            this.bridgeIotHandler = new BridgeIotHandler();
        }
        // For root handler.
        if (this.bridgeRootHandler == null) {
            this.bridgeRootHandler = new BridgeRootHandler();
        }
        // For update handler.
        if (this.bridgeUpdateHandler == null) {
            this.bridgeUpdateHandler = new BridgeUpdateHandler();
        }
        // For transfer handler.
        if (this.bridgeTransferHandler == null) {
            this.bridgeTransferHandler = new BridgeTransferHandler();
        }
        // Ok.
        // Now try to bind the server.
        this.currentSocketType = socketType;
        if ("tcp".equalsIgnoreCase(socketType)) {
            this.startServerWithTcp(this.config);
        } else if ("udp".equalsIgnoreCase(socketType)) {
            this.startServerWithUdp(this.config);
        }
        this.startedFlag = true;
    }

    private void startServerWithTcp(VttpServerConfig config) throws Exception {
        this.socketAcceptor = new NioSocketAcceptor();
        DefaultIoFilterChainBuilder chainBuilder = this.socketAcceptor.getFilterChain();

        ProtocolCodecFactory codecFactory = new VttpCodecFactory();
        chainBuilder.addLast("codec", new ProtocolCodecFilter(codecFactory));
        chainBuilder.addLast("executor", new ExecutorFilter(config.getMinThread(), config.getMaxThread()));

        this.socketAcceptor.setHandler(this);
        this.socketAcceptor.getSessionConfig().setReadBufferSize(config.getBufferSize());
        this.socketAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, config.getIdleTime());

        // Run it.
        this.socketAcceptor.bind(new InetSocketAddress(config.getPort()));
        // Add server to heartbeat manager.
        this.heartbeatManager.addAcceptor(this.socketAcceptor);
    }

    private void startServerWithUdp(VttpServerConfig config) throws Exception {
        this.datagramAcceptor = new NioDatagramAcceptor();
        DefaultIoFilterChainBuilder chainBuilder = this.datagramAcceptor.getFilterChain();

        ProtocolCodecFactory codecFactory = new VttpCodecFactory();
        chainBuilder.addLast("codec", new ProtocolCodecFilter(codecFactory));
        chainBuilder.addLast("executor", new ExecutorFilter(config.getMinThread(), config.getMaxThread()));

        this.datagramAcceptor.setHandler(this);
        this.datagramAcceptor.setSessionRecycler(new ExpiringSessionRecycler(MINA_UDP_FORCE_THROW_SESSION_SECONDS));
        this.datagramAcceptor.getSessionConfig().setReadBufferSize(config.getBufferSize());
        this.datagramAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, config.getIdleTime());

        // Run it.
        this.datagramAcceptor.bind(new InetSocketAddress(config.getPort()));
        // Add server to heartbeat manager.
        this.heartbeatManager.addAcceptor(this.datagramAcceptor);
    }

    @Override
    public void sessionCreated(IoSession ioSession) throws Exception {
        // Init hardware obj.
        DoHardware hw = new DoHardware(ioSession, this);
        ioSession.setAttribute(DoHardware.SESSION_ATTR_KEY, hw);
        // Init heartbeat obj.
        VttpHeartbeat heartbeat = new VttpHeartbeat();
        heartbeat.setLastReceivedTs(System.currentTimeMillis());
        heartbeat.setCycle(60);
        heartbeat.setSendCd(60);
        ioSession.setAttribute(VttpHeartbeat.HEARTBEAT_ATTR_KEY, heartbeat);
    }

    @Override
    public void sessionOpened(IoSession ioSession) throws Exception {
    }

    @Override
    public void sessionClosed(IoSession ioSession) throws Exception {
        DoHardware hardware = (DoHardware) ioSession.getAttribute(DoHardware.SESSION_ATTR_KEY);
        if (this.hardwareManager.ifManagedHardware(hardware)) {
            String hardwareType = hardware.getHardwareType();
            if (hardwareType == null || hardwareType.equals(DoHardware.TYPE_HARDWARE)) {
                // Remove from manager.
                boolean unManageSuccessFlag = this.hardwareManager.removeHardware(hardware.getGatewayId(), hardware);
                if (unManageSuccessFlag) {
                    this.bridgeIotHandler.onDisconnected(hardware);
                }
            }
        }
        hardware.release();
    }

    @Override
    public void sessionIdle(IoSession ioSession, IdleStatus idleStatus) throws Exception {
    }

    @Override
    public void exceptionCaught(IoSession ioSession, Throwable throwable) throws Exception {
    }

    @Override
    public void messageReceived(IoSession ioSession, Object message) throws Exception {
        try {
            VttpFrame frame = (VttpFrame) message;
            if (frame.isHeartbeat()) {
                this.heartbeatReceived(ioSession);
            } else {
                this.speedUpProcessFrame(ioSession, frame);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new DoException(e);
        }
    }

    @Override
    public void messageSent(IoSession ioSession, Object o) throws Exception {
    }

    @Override
    public void inputClosed(IoSession ioSession) throws Exception {
        ioSession.closeNow();
    }

    @Override
    public void event(IoSession ioSession, FilterEvent filterEvent) throws Exception {
    }

    private void heartbeatReceived(IoSession session) {
        // Update heartbeat.
        VttpHeartbeat heartbeat = (VttpHeartbeat) session.getAttribute(VttpHeartbeat.HEARTBEAT_ATTR_KEY);
        heartbeat.setLastReceivedTs(System.currentTimeMillis());
    }

    private void speedUpProcessFrame(IoSession ioSession, VttpFrame frame) {
        byte[] uri = frame.getUri();
        if (uri.length < 3) {
            return;
        }
        if (uri[0] == '/' && uri[2] == '/') {
            byte speedUpHandlerSign = uri[1];
            switch (speedUpHandlerSign) {
                case 't':
                    this.bridgeTransferHandler.handleSpeedUpFrame((DoHardware) ioSession.getAttribute(DoHardware.SESSION_ATTR_KEY), frame);
                    break;
                case 'i':
                    this.bridgeIotHandler.handleSpeedUpFrame((DoHardware) ioSession.getAttribute(DoHardware.SESSION_ATTR_KEY), frame);
                    break;
                case 'h':
                    this.bridgeHandshakeHandler.handleSpeedUpFrame((DoHardware) ioSession.getAttribute(DoHardware.SESSION_ATTR_KEY), frame);
                    break;
                case 'c':
                    this.bridgeConfigHandler.handleSpeedUpFrame((DoHardware) ioSession.getAttribute(DoHardware.SESSION_ATTR_KEY), frame);
                    break;
                case 'r':
                    this.bridgeRootHandler.handleSpeedUpFrame((DoHardware) ioSession.getAttribute(DoHardware.SESSION_ATTR_KEY), frame);
                    break;
                case 'u':
                    this.bridgeUpdateHandler.handleSpeedUpFrame((DoHardware) ioSession.getAttribute(DoHardware.SESSION_ATTR_KEY), frame);
                    break;
            }
        }
    }

    public VttpServerConfig getConfig() {
        return config;
    }

    public void setConfig(VttpServerConfig config) {
        this.config = config;
    }

    public int getEncryptType() {
        return encryptType;
    }

    public void setEncryptType(int encryptType) {
        this.encryptType = encryptType;
    }

    public VttpHeartbeatManager getHeartbeatManager() {
        return heartbeatManager;
    }

    public void setHeartbeatManager(VttpHeartbeatManager heartbeatManager) {
        this.heartbeatManager = heartbeatManager;
    }

    public DoHardwareManager getHardwareManager() {
        return hardwareManager;
    }

    public void setHardwareManager(DoHardwareManager hardwareManager) {
        this.hardwareManager = hardwareManager;
    }

    public BridgeAcceptor getBridgeAcceptor() {
        return bridgeAcceptor;
    }

    public void setBridgeAcceptor(BridgeAcceptor bridgeAcceptor) {
        this.bridgeAcceptor = bridgeAcceptor;
    }

    public BridgeHandshakeHandler getBridgeHandshakeHandler() {
        return bridgeHandshakeHandler;
    }

    public void setBridgeHandshakeHandler(BridgeHandshakeHandler bridgeHandshakeHandler) {
        this.bridgeHandshakeHandler = bridgeHandshakeHandler;
    }

    public BridgeConfigHandler getBridgeConfigHandler() {
        return bridgeConfigHandler;
    }

    public void setBridgeConfigHandler(BridgeConfigHandler bridgeConfigHandler) {
        this.bridgeConfigHandler = bridgeConfigHandler;
    }

    public BridgeIotHandler getBridgeIotHandler() {
        return bridgeIotHandler;
    }

    public void setBridgeIotHandler(BridgeIotHandler bridgeIotHandler) {
        this.bridgeIotHandler = bridgeIotHandler;
    }

    public BridgeRootHandler getBridgeRootHandler() {
        return bridgeRootHandler;
    }

    public void setBridgeRootHandler(BridgeRootHandler bridgeRootHandler) {
        this.bridgeRootHandler = bridgeRootHandler;
    }

    public BridgeUpdateHandler getBridgeUpdateHandler() {
        return bridgeUpdateHandler;
    }

    public void setBridgeUpdateHandler(BridgeUpdateHandler bridgeUpdateHandler) {
        this.bridgeUpdateHandler = bridgeUpdateHandler;
    }

    public BridgeTransferHandler getBridgeTransferHandler() {
        return bridgeTransferHandler;
    }

    public void setBridgeTransferHandler(BridgeTransferHandler bridgeTransferHandler) {
        this.bridgeTransferHandler = bridgeTransferHandler;
    }

    public byte[] getRootKey() {
        return rootKey;
    }

    public void setRootKey(byte[] rootKey) {
        this.rootKey = rootKey;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy