⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modemio.java

📁 jtapi for telephone
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package net.sourceforge.gjtapi.raw.modem;
// NAME
//      $RCSfile: ModemIO.java,v $
// DESCRIPTION
//      [given below in javadoc format]
// DELTA
//      $Revision: 1.3 $
// CREATED
//      $Date: 2004/02/21 02:04:07 $
// COPYRIGHT
//      Westhawk Ltd
// TO DO
//

import java.io.*;
import java.util.TooManyListenersException;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.comm.*;

/**
 * A class which handles all of the IO for a Modem.
 *
 * This class works with modems connected to serial ports. Perhaps it should
 * be an interface and implementation.
 *
 * @author <a href="mailto:ray@westhawk.co.uk">Ray Tran</a>
 * @version $Revision: 1.3 $ $Date: 2004/02/21 02:04:07 $
 */
public class ModemIO implements SerialPortEventListener{
    private static final String     version_id =
        "@(#)$Id: ModemIO.java,v 1.3 2004/02/21 02:04:07 rdeadman Exp $ Copyright Westhawk Ltd";

    public static final int DLE = 0x10;
    public static final int ETX = 0x03;
    public static final int CR = 0x0c;
    public static final int LF = 0x0a;
    private static final int BUF_SIZE = 65536;
    private static final int MARK_INVALID = -1;
    public static final int TIMEOUT = -1;
    public static final int GOOD_MATCH = 0;
    public static final int BAD_MATCH = 1;

    private SerialPort port = null;
    private InputStream in;
    private PrintStream out;
    private byte[] buf;
    private int writePos, readPos;
    private int markPos = MARK_INVALID;
    private int limit = MARK_INVALID;
    private int limitCount;
    private String lastMatch ="";
    private ShieldHandler handler;
    private Modem modem;

    /**
     * Constructor.
     *
     * @param portname - Name of SerialPort used for talking to the modem.
     * @param modem - Reference back to the modem which we are the IO for
     */
    public ModemIO(String portname, Modem modem) {
        buf = new byte[BUF_SIZE];
        writePos = readPos = 0;
        this.modem = modem;
        handler = new ShieldHandler();
        Thread t = new Thread(handler);
        t.start();

        //First try to open a port to the modem
        try {
            CommPortIdentifier portID = CommPortIdentifier.getPortIdentifier(portname);
            port = (SerialPort) portID.open("ModemProvider", 5000);
            port.setSerialPortParams(
                115200,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE
            );

            //add ourself as a listener for certain events
            port.notifyOnRingIndicator(true);
            /*
            port.notifyOnDataAvailable(true);
            port.notifyOnBreakInterrupt(false);
            port.notifyOnCarrierDetect(false);
            port.notifyOnCTS(false);
            port.notifyOnDSR(false);
            port.notifyOnFramingError(false);
            port.notifyOnOutputEmpty(false);
            port.notifyOnOverrunError(false);
            port.notifyOnParityError(false);
            */
            port.addEventListener(this);
        }catch (TooManyListenersException ex) {
            System.err.println("Adding event listener to port (" +
                               portname + ") failed");
        }catch (Exception ex) {
            System.err.println("Can't open serial port (" + portname);
            ex.printStackTrace();
        }

        if (port != null){
            try{
                port.enableReceiveTimeout(1000);
            }catch (UnsupportedCommOperationException ex){
                System.err.println("Can't set timeout on port(" + portname + ")");
            }
            try{
                in = port.getInputStream();
                out = new PrintStream(port.getOutputStream());
            }catch (IOException ex){
                System.err.println("IOException in ModemIO(" + port.getName() + ")");
                ex.printStackTrace();
            }
        }
    }

    /**
     * Try to read bytes into the circular buffer until the buffer is full, or
     * no more bytes are available from the underlying device.
     * If there is space in the buffer then we always try to read
     * at least one byte, the read will timeout if nothing is available;
     *
     * @throws IOException
     */
    private void fill() throws IOException{
        //Don't bother if the buffer is nearly full
        if (this.free() > 32 && in.available() > 0){
            do{
                int read = in.read();
                if (read > -1){
                    //If we get a <DLE> we need to deal with it
                    if (read == DLE){
                        read = in.read();
                        //If the next char is <DLE> pass it thru otherwise
                        //handle it (quickly)
                        if (read != DLE){
                            if (read == -1){
                                //this really should NEVER happen!
                                break;
                            }
                            handleDLEShield((char)read);
                        }
                    }
                    buf[writePos++] = (byte)read;
                    if (writePos >= BUF_SIZE){
                        writePos = 0;
                    }
                }
            }while (in.available() > 0 && this.free() > 0);
        }
    }

    /**
     * Deals with &lt;DLE&gt; shielded characters.
     * As a character may require time consuming processing a seperate
     * thread does it to avoid slowing down the fill() loop.
     *
     * @param shielded -  character read after the &lt;DLE&gt; character
     */
     private void handleDLEShield(char shielded){
         //System.err.println("<DLE>0x" + Integer.toHexString(shielded));
         //Expect <DLE>s when the modem detects silence, <DLE>d when dialtone
         handler.setShield(shielded);
     }

    /**
     * Returns the number of bytes available to be read.
     * 
     * @return int - the number of bytes available to be read.
     * @see #free()
     */
    public int available(){
        int result;
        if (readPos <= writePos){
            result = writePos - readPos;
        }else{
            result = BUF_SIZE - readPos + writePos;
        }
        return result;
    }

    /**
     * Returns the number of spaces available to be written in.
     * 
     * @return int - the number of spaces available to be written in.
     * @see #available()
     */
    private int free(){
        int result;
        int comparePos = ((markPos == MARK_INVALID)?readPos:markPos);

        if (comparePos <= writePos){
            result = BUF_SIZE - writePos + comparePos - 1;
        }else{
            result = comparePos - writePos - 1;
        }
        return result;
    }

    /**
     * Read the next byte from the buffer, re-filling if required.
     * 
     * @return int - the next byte read from the buffer
     * @throws IOException
     */
    public int read() throws IOException{
        int result = -1;
        if (in != null && buf != null){
            //if the buffer is nearly empty try to fill it
            if (this.available() < 16){
                fill();
            }
            if (readPos != writePos){
                result = buf[readPos++] & 0xff;
                //If we have read more bytes than readlimit since marking then
                //clear the mark;
                if (markPos != MARK_INVALID){
                    if (--limitCount == -1){
                        markPos = MARK_INVALID;
                    }
                }
                if (readPos >= BUF_SIZE){
                    readPos = 0;
                }
            }
        }
        return result;
    }

    public int read(byte[] data) throws IOException{
        int result = 0;
        int read;
        for (int i=0, len = data.length; i<len; i++){
             if ((read = read()) > -1){
                data[i] = (byte)read;
             }else{
                result = i;
                break;
             }
        }
        return result;
    }

    public int read(byte[] data, int offs, int len) throws IOException{
        int result = 0;
        int read;
        int limit = offs + len;
        if (limit <= data.length){
            for (int i=offs; i<len; i++){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -