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

📄 station.java

📁 著名的dialogic电话语音卡的java驱动程序,已经验证可用。
💻 JAVA
字号:
// Station: Manage MSI stations
// $Id: Station.java,v 1.7 2003/11/13 11:55:18 cgm8 Exp $
/* 
 * Copyright (c) 1999 Carlos G Mendioroz.
 *
 *  This file is part of D4J.
 *
 *  D4J is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *  
 *  D4J is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *  
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the
 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *  Boston, MA  02111-1307, USA.
 *
 * Report problems and direct all questions to:
 *
 *	tron@acm.org
 */
package local.dialogic;

import java.util.*;
/**
 * Station:
 * First API was clearly targetted at a resource for a channel, with:
 * assign (to channel and route audio) and connect/disconnect with channel
 * audio.
 * Now the API is extended to cope with autonomous (kind of) behaviour,
 * implementing assign(channel, boolean route) to do light attaching
 */

public class Station extends Device implements Resource, ResourceServer
{
    // Class variables
    private static Hashtable extensions;
    private static Vector stationAtDev;
    private static StationServerThread stationServerThread;
    private static LinkedList events;
    
    static {
        extensions = new Hashtable();
        stationAtDev = new Vector(5,4);
        stationServerThread = new StationServerThread();
        stationServerThread.setName("Stations service thread");
        events = new LinkedList();
        stationServerThread.start();
    }
    
    // Instance variables
    private String extension;	// my address
    private boolean hookState; 	// I know my hookstate
    private boolean onHook; 	// my hook state
    private boolean ringing;	// am I ringing ?
    
    private int ts;             // my TX ts
    private Channel channel;    // talking to channel
    private boolean routedRx;   // Have we done routing of audio rx at attach time
    private boolean routedTx;   // Have we done routing of audio tx via connect
    private StationServer server; // what takes care of my dialing
    private ResourceServer xserver; // who activelly looks after me (i.e. gets all events)
    private Thread serviceThread; // the thread for this station server
    private ThreadGroup serviceGroup; // a group for this station server
    private Channel serviceChannel;  // a channel bound to this station server

    /** Open an MSI station device */
    public Station(String name, String extension)
    {
        super(null, name);
        // msiBnCm
        if (! name.substring(0, 4).equals("msiB"))
            throw new RuntimeException("Station: bad name");
        device = Dialogic.ms_open(name, 0);
        // Extensions table
        this.extension = extension;
        extensions.put(extension, this);
        // Device lookup 
        if (stationAtDev.size() <= device) {
            stationAtDev.setSize(device + 1);
        }
        stationAtDev.setElementAt(this, device);
	// etc...        
        ts = Dialogic.ms_getxmitslot(device);
        onHook = (Dialogic.ATMS_TSSGBIT(device) == 0);
        hookState = true;
        channel = null;
        routedRx = false;
        routedTx = false;
        server = null;
        xserver = null;
        serviceThread = null;
        serviceGroup = new ThreadGroup(name + " group");
        serviceChannel = null;
        Channel.register(this, device);
        // Let us know onhook/offhook/flash events
        Dialogic.ms_setevtmsk(device, Dialogic.DTG_SIGEVT, 
            Dialogic.MSMM_ONHOOK|Dialogic.MSMM_OFFHOOK|Dialogic.MSMM_HOOKFLASH, Dialogic.DTA_SETMSK);
        register();
    }
    
    // Get a reference to an extension by name. Kind of protect busy (offHook) extensions
    public static Station getStation(String anExtension) {
    	Station stat = (Station)extensions.get(anExtension);
    	if (stat == null)
    		throw new RuntimeException("Unknown extension");
    	if (!stat.onHook)
    		throw new BusyException("Busy extension");
    	return stat;
    }
    
    // Start ringing
    public void ring() 
    {
        if (onHook() && !ringing) {
            Dialogic.ms_genring(device, 100, Dialogic.EV_ASYNC);
            ringing = true;
            if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
                System.out.println(this.toString() + " ringing!");
            }
        }
    }
    
    // Stop ringing
    public void ringOff()
    {
        if (onHook() && ringing) {
            Dialogic.ms_stopfn(device, Dialogic.MTF_RING);
            ringing = false;
            if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
                System.out.println(this.toString() + " stop ringing!");
            }
        }
    }
    
    // Answer my hook state
    public boolean onHook() 
    {
    	if (!hookState) 
    		onHook = (Dialogic.ATMS_TSSGBIT(device) == 0);
        return onHook;
    }
    
    // Answer my tx TS
    public int getTs() {
        return ts;
    }

    // Answer my tx TS, resource interface version (ours does not depend on Channel)
    public int getTs(Channel aChannel) {
        return ts;
    }

    // Listen to a device
    public void listen(Device source) {
        if (source != null)
            Dialogic.ms_listen(device, source.getTs());
        else
            Dialogic.ms_unlisten(device);
    }

    // Listen to a resource ??? 
     public void listen(Channel ch, Resource res) {
        int ts = res.getTs(ch);
        if (ts < 0)
            Dialogic.ms_unlisten(device);
        else 
            Dialogic.ms_listen(device, ts);
    }
    
    public void finalize() throws Throwable 
    {
        close();
        super.finalize();
    }
    
    public void close()
    {
        if (channel != null && routedTx)
            disconnect(channel);
        listen(null);
        Dialogic.ms_setevtmsk(device, Dialogic.DTG_SIGEVT, 
            0, Dialogic.DTA_SETMSK);
        super.close();
        extensions.remove(extension);
        stationAtDev.setElementAt(null, device);
    }
    
    /**
     * assign: Assign to channel
     * This can optionally route (default) audio from channel to station
     */
    public void assign(Channel ch) {
        assign(ch, true);
    }
    
    public void assign(Channel ch, boolean route) {
        if (channel != null)
            free(channel);

        if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
            System.out.println(this.toString() + " assigned to " + ch + (route ? "(routed)":""));
        }
        channel = ch;
        routedRx = route;
        if (routedRx)
            Dialogic.ms_listen(device, ch.getNetwork().getTs());
        ch.attach(this);
    }
    
    // Channel getting cleared
    public void free(Channel ch) {
        if (channel != ch)
            return;
        if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
            System.out.println(this.toString() + " deassigned from " + ch);
        }
        if (routedTx)
            disconnect(ch);
        routedTx = false;
        channel = null;
        ch.dettach(this);
        listen(null);
        routedRx = false;
    }
    
    // Talk to channel
    public void connect(Channel ch) {
        if (channel != ch)
            return;
        if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
            System.out.println(this.toString() + " connected to " + ch);
        }
        ch.listen(this);
        routedTx = true;
    }
    
    // Stop talking to channel
    public void disconnect(Channel ch) {
        if (channel != ch)
            return;
        if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
            System.out.println(this.toString() + " disconnected from " + ch);
        }
        ch.getNetwork().listen(ch.getVoice());
        routedTx = false;
    }
    
    public String toString() {
        StringBuffer desc = new StringBuffer();
        desc.append("MSI Station " + extension);
        return desc.toString();
    }

    public boolean service(EVT evt) {
        if (evt.type == EVT.DTEV_SIG) {
            if ((evt.data & Dialogic.DTC_ABIT) != 0) {
                if ((evt.data & Dialogic.DTB_ABIT) == 0) 
                    onHook = true;
                else
                    onHook = false;
                hookState = true;
                if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) 
                    System.out.println(this.toString() + (onHook?" OnHook":" OffHook"));
            }
            // chain to xserver, deal if none or not serviced by it
            if (xserver == null || !xserver.service(evt)) {
                if (channel != null)
                    channel.newEvent(evt);
                else 
                	newEvent(evt);
            }
            return true;
        } else if (evt.type == EVT.MSEV_RING || evt.type == EVT.MSEV_NORING) {
            ringing = false;
            // Carefull, usually hook state changed
            // but we are at interrupt time now... so wait for next user action
            // onHook = (Dialogic.ATMS_TSSGBIT(device) == 0);
            hookState = false;
            // chain to xserver, deal if none or not serviced by it
            if (xserver == null || !xserver.service(evt)) {
                if (channel != null)
                    channel.newEvent(evt);
                else 
                	newEvent(evt);
            }
            return true;
        }
        return false;
    }

    public void setServer(StationServer aServer) {
    	server = aServer;
    }

    public void register(ResourceServer aServer) {
    	xserver = aServer;
    }

    public void setServiceChannel(Channel ch) {
        serviceChannel = ch;
    }
    
    private void newEvent(EVT evt) {
        synchronized(events) {
            events.add(evt);
            events.notifyAll();
        }
    }
    
    private static class StationServerThread extends Thread {
        // Run: Keep looking for station unclaimed events, dispatch new servers
        public void run()
        {
            EVT evt;
            if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
              System.out.println("Station thread started");
            }
            while (true) {
                synchronized(events) {
                    while (events.size() == 0) {
                        try { 
                           events.wait();
                        } catch (InterruptedException ie) {}
                    }
                    evt = (EVT)events.removeFirst();
                }
	            if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
		            System.out.println("Station thread: " + evt);
          	    }
          	    if (evt.type == EVT.DTEV_SIG && (evt.data & Dialogic.DTB_ABIT) != 0) {
          		    // Offhook
          		    Station stat = (Station)stationAtDev.elementAt(evt.dev);
          		    if (stat == null) continue; // ??
          		    if (stat.server == null) continue; // No server code
          		    if (stat.serviceChannel != null) {
          		        stat.serviceChannel.newEvent(evt);
          		        continue;
          		    }
          		    if (stat.serviceThread != null) continue; // Already being served ???
          		    stat.serviceThread = new StationThread(stat);
	                if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
		                System.out.println("Station thread: firing server for station "+stat.extension);
          	        }
          		    stat.serviceThread.start();
                } else if (evt.type == EVT.DTEV_SIG && (evt.data & Dialogic.DTB_ABIT) == 0) {
                    // OnHook
                    Station stat = (Station)stationAtDev.elementAt(evt.dev);
          	        if (stat == null) continue; // ??
          	        if (stat.serviceChannel != null) {
          	            stat.serviceChannel.newEvent(evt);
          	            continue;
          	        }
          	        if (stat.serviceThread != null) {
          	            // Has a server...
        	            if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
    		                System.out.println("Station thread: killing server for station "+stat.extension);
              	        }
              		    stat.serviceThread.interrupt();
                    }
                }
            }
        }
    }
    

    // Give service (e.g. dialtone) to an offhook station
    private static class StationThread extends Thread {
        Station myStation;
        
        StationThread(Station aStation) {
            super(aStation.serviceGroup, "Station " + aStation.extension + " thread");
            myStation = aStation;
        }
        
        public void run()
        {
            try {
                myStation.server.service(myStation);
            } finally {
                myStation.serviceThread = null;
          	    myStation.serviceChannel = null;
                myStation.listen(null);
        	    if ((Dialogic.debug & Dialogic.DEBUG_STATION) != 0) {
		            System.out.println("Station thread: finished!");
          	    }
          	}
        }
    }
}

⌨️ 快捷键说明

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