Package com.xonami.javaBellsSample

Source Code of com.xonami.javaBellsSample.JavaBellsSample2

/**
*
*/
package com.xonami.javaBellsSample;

import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.logging.Level;

import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.JingleIQ;
import org.jitsi.service.libjitsi.LibJitsi;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Packet;

import org.jivesoftware.smackx.ServiceDiscoveryManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xonami.javaBells.JingleManager;
import org.jivesoftware.smackx.entitycaps.EntityCapsManager;

/**
*
* This is an alternate sample that shows a class that can both send and receive calls.
* This is similar in function to the main example, but structured differently -- there is more common code in the main class between
* the caller and the receiver. This may be a more useful example in real applications which need to both call out and in.
*
* @author bjorn
*
*/
public class JavaBellsSample2 {
  enum Action {
    CALL,
    ANSWER,
  }
  protected final static Logger logger = LoggerFactory.getLogger(Logger.class);
 
  private static final String CALLER = "Caller";
  private static final String RECEIVER = "Receiver";
 
  private final String username, password, host;
 
  private final String receiverJid;

  private XMPPConnection connection;
  private SampleJinglePacketHandler sampleJinglePacketHandler;
 
  private boolean running = true;
  private Thread mainThread;
 
  /** prints usage and exits. */
  public static void usage(String name) {
    System.out.println( "Usage: " + name + " action username password host" );
    System.out.println( "\t action: may be CALL or ANSWER" );
    System.exit(1);
  }

  public static void main(String[] args) {
    if( args.length != 5 )
      usage(args[0]);
   
    Thread.setDefaultUncaughtExceptionHandler( new UncaughtExceptionHandler() {
      @Override
      public void uncaughtException(Thread t, Throwable e) {
        logger.error("In thread: ", t);
        logger.error("Uncaught Exception: ", e);
      }
    }) ;
   
    // reduce the insane, unreadable amount of chattiness from libjitsi and ice4j:
    java.util.logging.Logger l = java.util.logging.Logger.getLogger("");
    l.setLevel(Level.WARNING);
   
    // -- libjitsi needs to be started
    LibJitsi.start();
   
    // -- we need to initialize jingle
    JingleManager.enableJingle();

    // parse commandline args:
    String cmd      = args[0];
    System.out.println( "cmd: " + cmd );
    Action action   = Action.valueOf(args[1]);
    System.out.println( "action: " + action );
    String username = args[2];
    String password = args[3];
    String host     = args[4];
   
    System.out.println( "u/p @ h: " + username + " / XXXXX @ " + host);
   
    // start threads to actually do the work of calling/answering:
    JavaBellsSample2 m = new JavaBellsSample2( username, password, host, action == Action.CALL ? CALLER : RECEIVER );

    if( !m.waitForLogin( 5000 ) ) {
      System.err.println( "Could not connect within 5 seconds." );
      System.exit(1);
    }
   
    if( action == Action.CALL ) {
      try {
        m.startCall(m.receiverJid);
      } catch (IOException e1) {
        e1.printStackTrace();
      }
    }
   
    // stop threads when the user hits enter, cleanup and exit.
    System.out.println( "Hit enter to stop: " );
    while( true )
      try {
        System.in.read();
        break;
      } catch (IOException e) {}
    m.joinMainThread();
    LibJitsi.stop();
    System.exit(0);
  }
 
  /** creates a new object with the given username and password on the given host. */
  public JavaBellsSample2( String username, String password, String host, String resource ) {
    this.username = username;
    this.password = password;
    this.host     = host;

    receiverJid = username + "@" + host + "/" + RECEIVER;
   
    startMainThread(resource);
  }
 
  /** waits for both calling and answering thread to return. */
  public void joinMainThread() {
    running = false;
    if( mainThread != null )
      while( true )
        try {
          synchronized(mainThread ) {
            mainThread.notify();
          }
          mainThread.join();
          break;
        } catch (InterruptedException e) {}
  }
 
  public boolean waitForLogin( long wait ) {
    //FIXME: this function doesn't check for error conditions
    long start = System.currentTimeMillis();
    while( connection == null || !connection.isAuthenticated() )
      try {
        if( start - System.currentTimeMillis() > wait )
          return false;
        Thread.sleep(100);
      } catch (InterruptedException e) {}
    return true;
  }
  public void startCall(String targetJid) throws IOException {
    sampleJinglePacketHandler.initiateOutgoingCall(targetJid);
  }
 
  /** starts a "receiver" in another thread. The receiver connects to the XMPP server,
   * and waits for a jingle session initiation request from the caller.
   */
  public void startMainThread(final String resource) {
    mainThread = new Thread() {
      @Override
      public void run() {
        try {
          log( resource, "connecting to " + host );
         
          // connect to host (don't log in yet)
          ConnectionConfiguration config = new ConnectionConfiguration(host);
          connection = new XMPPConnection( config );
          connection.connect();
          // setup service discovery and entity capabilities.
          // this ensures that other software, such as Jitsi, knows that we support
          // ice and so on
          //ServiceDiscoveryManager.setIdentityName("Java Bells");
          ServiceDiscoveryManager disco = ServiceDiscoveryManager.getInstanceFor(connection);
          EntityCapsManager ecm = EntityCapsManager.getInstanceFor(connection);
         
          ecm.enableEntityCaps();

          disco.addFeature("http://jabber.org/protocol/disco#info");
          disco.addFeature("urn:xmpp:jingle:1");
          disco.addFeature("urn:xmpp:jingle:transports:ice-udp:1");
          disco.addFeature("urn:xmpp:jingle:apps:rtp:1");
          disco.addFeature("urn:xmpp:jingle:apps:rtp:audio");
          disco.addFeature("urn:xmpp:jingle:apps:rtp:video");
         
          // Handle all incoming Jingle packets with a Jingle Packet Handler.
          sampleJinglePacketHandler = new SampleJinglePacketHandler(connection) ;
         
          // display out all packets that get sent:
          connection.addPacketSendingListener(
            new PacketListener() {
              @Override
              public void processPacket(Packet packet) {
                System.out.println( RECEIVER + " -----> : " + packet.toXML() );
              }
            },
            new PacketFilter() {
              @Override
              public boolean accept(Packet packet) {
                return true;
              }
            } ) ;

          //display all incoming packets
          connection.addPacketListener( new PacketListener() {
            @Override
            public void processPacket(Packet packet) {
              if( packet.getClass() == JingleIQ.class ) {
                JingleIQ jiq = (JingleIQ) packet ;
                System.out.println( resource + " <----- [jingle packet]: " + jiq.getSID() + " : " + jiq.getAction() );
              } else {
                System.out.println( resource + " <----- : " + packet.toXML() );
              }
            }},
            new PacketFilter() {
            @Override
            public boolean accept(Packet packet) {
              return true;
            }} );

          // -- log in
          log( RECEIVER, "logging on as " + username + "/" + resource );
          connection.login(username, password, resource);
         
          // -- just hang out until we are asked to exit.
          // the work will be done by the SampleJingleSession created by the SampleJinglePacketHandler
          // we created and applied earlier.
          log( RECEIVER, "Waiting..." );
          while( running ) {
            synchronized ( this ) {
              try {
                wait(1000);
              } catch (InterruptedException e) {}
            }
          }
          connection.disconnect();
          log( resource, "Done. Exiting thread." );
        } catch ( Exception e ) {
          System.out.println( resource + ": " + e );
          e.printStackTrace();
          System.exit(1);
        }
      }
    };
    mainThread.start();
  }
 
  private void log( String tag, String message ) {
    logger.info( "[{}]: {}", tag, message );
  }
}
TOP

Related Classes of com.xonami.javaBellsSample.JavaBellsSample2

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.