br.com.anteros.sms.modem.IPModemDriver.java Source code

Java tutorial

Introduction

Here is the source code for br.com.anteros.sms.modem.IPModemDriver.java

Source

/*******************************************************************************
 * Copyright 2016 Anteros Tecnologia
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/

package br.com.anteros.sms.modem;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.util.StringTokenizer;
import javax.net.ssl.SSLContext;
import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;
import org.apache.commons.net.telnet.SimpleOptionHandler;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
import br.com.anteros.sms.AGateway.GatewayStatuses;
import br.com.anteros.sms.GatewayException;
import br.com.anteros.sms.Service;
import br.com.anteros.sms.helper.Logger;
import br.com.anteros.sms.modem.ModemGateway.IPProtocols;

class IPModemDriver extends AModemDriver {
    private String ipAddress;

    private int ipPort;

    private TelnetClient tc;

    private InputStream in;

    private OutputStream out;

    private Peeker peeker;

    private TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);

    private SimpleOptionHandler binaryopt = new SimpleOptionHandler(0, true, false, true, false);

    private EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);

    private SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);

    protected IPModemDriver(ModemGateway myGateway, String deviceParms) {
        super(myGateway, deviceParms);
        StringTokenizer tokens = new StringTokenizer(deviceParms, ":");
        this.ipAddress = tokens.nextToken();
        this.ipPort = Integer.parseInt(tokens.nextToken());
        this.tc = null;
    }

    @Override
    protected void connectPort() throws GatewayException, IOException, InterruptedException {
        try {
            Logger.getInstance().logInfo("Opening: " + this.ipAddress + " @" + this.ipPort, null,
                    getGateway().getGatewayId());
            this.tc = new TelnetClient();
            this.tc.addOptionHandler(this.ttopt);
            this.tc.addOptionHandler(this.echoopt);
            this.tc.addOptionHandler(this.gaopt);
            if (getGateway().getIpProtocol() == IPProtocols.BINARY)
                this.tc.addOptionHandler(this.binaryopt); // Make telnet session binary, so ^Z in ATHander.Sendmessage is send raw!
            if (getGateway().getIpEncryption()) {
                try {
                    this.tc.setSocketFactory(SSLContext.getInstance("Default").getSocketFactory());
                } catch (NoSuchAlgorithmException e) {
                    Logger.getInstance().logError("Unable to find algorithm needed for using SSL", e,
                            getGateway().getGatewayId());
                    // TODO: although not supposed to happen, something should be done if it does
                }
            }
            this.tc.connect(this.ipAddress, this.ipPort);
            this.in = this.tc.getInputStream();
            this.out = this.tc.getOutputStream();
            this.peeker = new Peeker();
        } catch (InvalidTelnetOptionException e) {
            throw new GatewayException("Unsupported telnet option for the selected IP connection.");
        }
    }

    @Override
    protected void disconnectPort() throws IOException, InterruptedException {
        Logger.getInstance().logInfo("Closing: " + this.ipAddress + " @" + this.ipPort, null,
                getGateway().getGatewayId());
        synchronized (getSYNCReader()) {
            if (this.tc != null)
                this.tc.disconnect();
            this.tc = null;
            if (this.peeker != null) {
                this.peeker.interrupt();
                this.peeker.join();
            }
            this.peeker = null;
        }
    }

    @Override
    protected void clear() throws IOException {
        while (portHasData())
            read();
    }

    @Override
    protected boolean portHasData() throws IOException {
        return (this.in.available() > 0);
    }

    @Override
    public void write(char c) throws IOException {
        this.out.write((short) c);
        this.out.flush();
    }

    @Override
    public void write(byte[] s) throws IOException {
        this.out.write(s);
        this.out.flush();
    }

    @Override
    protected int read() throws IOException {
        return this.in.read();
    }

    TelnetClient getTc() {
        return this.tc;
    }

    private class Peeker extends Thread {
        public Peeker() {
            setPriority(MIN_PRIORITY);
            start();
        }

        @Override
        public void run() {
            Logger.getInstance().logDebug("Peeker started.", null, getGateway().getGatewayId());
            while (true) {
                try {
                    if (getTc() != null) {
                        if (portHasData()) {
                            synchronized (getSYNCReader()) {
                                setDataReceived(true);
                                getSYNCReader().notifyAll();
                            }
                        }
                    }
                    sleep(Service.getInstance().getSettings().SERIAL_POLLING_INTERVAL);
                } catch (InterruptedException e) {
                    if (getTc() == null)
                        break;
                } catch (IOException e) {
                    getGateway().setStatus(GatewayStatuses.RESTART);
                }
            }
            Logger.getInstance().logDebug("Peeker stopped.", null, getGateway().getGatewayId());
        }
    }
}