Package org.asteriskjava.iax.protocol

Source Code of org.asteriskjava.iax.protocol.BinderSE

package org.asteriskjava.iax.protocol;


import org.asteriskjava.iax.audio.javasound.AudioInterface;
import org.asteriskjava.iax.ui.GuiEventSender;
import org.asteriskjava.iax.util.ByteBuffer;

import java.io.IOException;
import java.net.*;
import java.util.Collection;
import java.util.HashMap;

/**
* Main program - binds the udp port.
* Each Friend object (representing an Asterisk host) is associated with
* one (or the) Binder object.
*/
public class BinderSE extends Binder implements Runnable {


    /**
     * The default IAX2 port (4569)
     */
    final static int IAX2SOC = 4569;

    /**
     * The default buffer size (4096)
     */
    final static int BUFFSZ = 4096;

    private DatagramSocket _lsoc;
    private boolean _done = false;
    private HashMap<InetAddress, Friend> _friends = new HashMap<InetAddress, Friend>(5);
    // private Hashtable _friends = new Hashtable(5);
    private Thread _listener;
    private String _host;
    private AudioInterface _a8;


    /**
     * Constructor for the Binder object
     *
     * @param host The asterisk host which will be our PBX
     * @throws SocketException Thrown if the datagram (udp) socket
     *                         cannot be created
     */
    @SuppressWarnings("empty-statement")
    public BinderSE(String host, AudioInterface a8) throws SocketException {
        try {
            String jversion = System.getProperty("java.version");
            Log.debug("Java version = " + jversion);
        } catch (Throwable t) {
            ;// don't care much
        }
        _host = host;
        _lsoc = new DatagramSocket(IAX2SOC);
        // _lsoc = new DatagramSocket();
        // _lsoc.setTrafficClass(0x10);
        _listener = new Thread(this, "Binder Listen");
        _listener.setPriority(Thread.MAX_PRIORITY - 1);
        _listener.start();
        _a8 = a8;
    }


    /**
     * Set up the infrastructure to make (and optionally receive)
     * calls. If we register for incoming calls gui.registered(Friend,
     * boolean) will be called when the asterisk registration
     * succeeds.
     *
     * @param username     A username to use
     * @param password     The password for the user
     * @param gui          A listener which needs to be told about the registration result
     * @param wantIncoming Whether we are waiting for incoming calls
     * @throws UnknownHostException
     */
    @Override
    public void register(String username, String password, ProtocolEventListener gui, boolean wantIncoming) throws Exception {

        InetAddress iad = InetAddress.getByName(_host);
        Log.debug("registering with " + _host);
        Friend f = findFriend(iad);
        if (f == null) {
            f = new Friend(this, _host, gui);
            _friends.put(iad, f);
        }

        if (wantIncoming) {
            f.register(username, password);
        } else {
            //We return true so that the gui knows that the Friend is setup
            //correctly. If there was a problem we'd have bailed before now!
            if (gui != null) {
                gui.registered(f, true);
            }
        }
    }


    /**
     * Unregisters from the asterisk pbx. This will only happen if we
     * are registered indeed.
     *
     * @param gui A listener which needs to be told about the unregistration result
     * @throws UnknownHostException
     */
    @Override
    public void unregister(ProtocolEventListener gui) throws Exception {

        InetAddress iad = InetAddress.getByName(_host);

        Log.debug("unregistering with " + _host);
        Friend f = findFriend(iad);
        if (f != null && f.isRegistered() == true) {
            f.unregister();
        } else {
            //We return false so that the gui knows that the Friend is
            //unregistered. If there was a problem we'd have bailed before now!
            if (gui != null) {
                gui.registered(f, false);
            }
        }
    }


    /**
     * Stop listening, if we were listening.
     */
    @Override
    public void stop() {
        _done = true;
        if (_listener != null) {
            _lsoc.close();
            Log.debug("Closed Socket");
            try {
                _listener.join();
                Log.debug("Joined binder thread");
            } catch (InterruptedException ex) {
                Log.warn(ex.getMessage());
            }
            _listener = null;
        }
        // Birgit: is this the best place for it??
        _a8.cleanUp();
    }


    /**
     * Keeps listening for incoming data.
     * It will pass the data to our friend.
     *
     * @see Friend#recv(byte[])
     */
    @Override
    public void run() {
        byte buff[] = new byte[BUFFSZ];
        while (!_done) {
            DatagramPacket dgp = new DatagramPacket(buff, BUFFSZ);
            try {
                _lsoc.receive(dgp);
                InetAddress iad = dgp.getAddress();
                int len = dgp.getLength();
                byte data[] = new byte[len];
                System.arraycopy(buff, 0, data, 0, len);
                //packetDump(data, len, iad, dgp.getPort(), true);
                Friend f = findFriend(iad);
                if (f != null) {
                    f.recv(data);
                } else {
                    //throw new IAX2ProtocolException("no friends ?");
                }
            } catch (IOException ex) {
                if (!_done) {
                    Log.warn(ex.getMessage());
                }
            }
        }
        // cleanup
        Collection fall = _friends.values();
        while (!fall.isEmpty()) {
            Friend f = (Friend) fall.iterator().next();
            f.stop();
        }
    }


    /**
     * Sends a frame (as bytes) to a specified address
     *
     * @param h The asterisk host address
     * @param b The frame (in bytes)
     * @see Friend#send(ByteBuffer)
     */
    @Override
    public void send(String h, ByteBuffer b) {
        InetAddress a = null;
        try {
            a = InetAddress.getByName(h);
            DatagramPacket p = new DatagramPacket(b.array(), b.position(), a, BinderSE.IAX2SOC);
            // packetDump(b.array(), b.position(), a, this.IAX2SOC, false);
            this._lsoc.send(p);

        } catch (Exception ex1) {
            ex1.printStackTrace();
        }
    }

    /**
     * Find the friend that belongs to the specified address.
     *
     * @param iad The asterisk host address
     * @return The found Friend
     */
    private Friend findFriend(InetAddress iad) {
        Friend ret = null;
        ret = (Friend) _friends.get(iad);
        return ret;
    }


    /**
     * Removes a friend. This will be called by friend when it has been
     * succesfully unregistered.
     *
     * @param host The asterisk host address
     * @return The found Friend
     */
    @Override
    public Friend removeFriend(String host) {
        InetAddress iad = null;
        Friend ret = null;
        try {
            iad = InetAddress.getByName(host);
            ret = (Friend) _friends.remove(iad);
        } catch (UnknownHostException ex) {
            Log.warn(ex.getMessage());
        }
        return ret;
    }

    @Override
    public AudioInterface getAudioFace() {
        return _a8;
    }

    /**
     * Dumps information of a frame (in bytes) to standard error.
     *
     * @param bs The in- or outgoing frame (in bytes)
     * @param i  The package size
     * @param a  The asterisk host address
     * @param i1 The port number
     * @param in Is it in (true) or outgoing (false)
     */
    protected void packetDump(byte[] bs, int i, InetAddress a, int i1,
                              boolean in) {
        StringBuffer os = new StringBuffer(500);
        if (in) {
            os.append("Packet got from ").append(a.getHostAddress()).append(":").
                    append(i1).append('\n');
        } else {
            os.append("Packet sent to ").append(a.getHostAddress()).append(":").
                    append(i1).append('\n');
        }
        os.append("Packet size = ").append(i).append('\n');
        byte[] bf = new byte[i];
        System.arraycopy(bs, 0, bf, 0, i);
        os.append(enHex(bf, Character.valueOf(' ')));
        os.append('\n');
        System.err.print(os);
    }

    /**
     * getGuiEventSender
     *
     * @param _gui ProtocolEventListener
     * @return ProtocolEventListener
     */
    @Override
    public ProtocolEventListener getGuiEventSender(ProtocolEventListener _gui) {
        return new GuiEventSender(_gui);
    }

}
TOP

Related Classes of org.asteriskjava.iax.protocol.BinderSE

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.