Package gov.nist.javax.sip.stack.sctp

Source Code of gov.nist.javax.sip.stack.sctp.SCTPMessageProcessor

package gov.nist.javax.sip.stack.sctp;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpServerChannel;

import gov.nist.core.HostPort;
import gov.nist.javax.sip.stack.MessageChannel;
import gov.nist.javax.sip.stack.MessageProcessor;
import gov.nist.javax.sip.stack.SIPTransactionStack;

/**
* SCTP Message Processor
*
* @author Jeroen van Bemmel
*/
public final class SCTPMessageProcessor extends MessageProcessor implements Runnable {

  private SctpServerChannel sctpServerChannel;
  private Selector selector;
  private SelectionKey key;
  private boolean isRunning, doClose;
 
  private final Set<SCTPMessageChannel> channels
    = new ConcurrentSkipListSet<SCTPMessageChannel>();
 
  /**
   * Constructor, called via Class.newInstance() by SIPTransactionStack
   */
  public SCTPMessageProcessor() {
    super( "sctp" );
  }

  Selector getSelector() { return selector; }
 
  SelectionKey registerChannel( SCTPMessageChannel c, SctpChannel channel )
    throws ClosedChannelException {
    synchronized (this) {
      selector.wakeup();
      return channel.register( selector, SelectionKey.OP_READ, c );
    }
  }
 
  @Override
  public MessageChannel createMessageChannel(HostPort targetHostPort)
      throws IOException {   
    return this.createMessageChannel( targetHostPort.getInetAddress(), targetHostPort.getPort() );
  }

  @Override
  public MessageChannel createMessageChannel(InetAddress targetHost, int port)
      throws IOException {
   
    SCTPMessageChannel c = new SCTPMessageChannel( this,
        new InetSocketAddress(targetHost,port) );
    channels.add( c );
    return c;
  }

  @Override
  public int getDefaultTargetPort() {   
    return 5060// same as UDP and TCP
  }

  @Override
  public int getMaximumMessageSize() {
    return Integer.MAX_VALUE;
  }

  @Override
  public SIPTransactionStack getSIPStack() {
    return sipStack;
  }

  @Override
  public boolean inUse() {
    return isRunning;
  }

  @Override
  public boolean isSecure() {
    return false;
  }

  public void run() {
    try {
      do {
        int n = selector.select();
        if (n>0) {
          Iterator<SelectionKey> i = selector.selectedKeys().iterator();
          while ( i.hasNext() ) {
            SelectionKey key = i.next();
            i.remove();
            if ( key.isReadable() ) {
              SCTPMessageChannel channel = (SCTPMessageChannel) key.attachment();
              channel.readMessages();
            } else if (key.isAcceptable()) {
              SctpChannel ch = sctpServerChannel.accept();
              SCTPMessageChannel c = new SCTPMessageChannel( this, ch );
              channels.add( c );
            }
          }
        }
       
        synchronized (this) {
          if (doClose) {
            selector.close();
            return;
          }
        }       
      } while ( selector.isOpen() );
    } catch (IOException ioe) {
      ioe.printStackTrace();
      try {
        selector.close();
      } catch (IOException e) {
        e.printStackTrace();
      } finally {
        this.stop();
      }
    }
  }

  @Override
  public void start() throws IOException {

    this.sctpServerChannel = SctpServerChannel.open();   
    sctpServerChannel.bind( new InetSocketAddress(this.getIpAddress(),this.getPort()) );
    sctpServerChannel.configureBlocking( false );
   
    this.selector = Selector.open();
    this.key = sctpServerChannel.register( selector, SelectionKey.OP_ACCEPT );
       
    // Start a daemon thread to handle reception
    this.isRunning = true;
        Thread thread = new Thread(this);
        thread.setDaemon(true);
        thread.setName("SCTPMessageProcessorThread");
        thread.setPriority(Thread.MAX_PRIORITY);
        thread.start();
  }

  @Override
  public void stop() {
    this.isRunning = false;
    this.doClose = true;
   
    for ( SCTPMessageChannel c : channels ) {
      c.closeNoRemove()// avoids call to removeChannel -> ConcurrentModification
    }
    channels.clear();
    try {
      key.cancel();
      sctpServerChannel.close();     
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      synchronized (this) {
        selector.wakeup();
      }
    }
  }

  void removeChannel(SCTPMessageChannel messageChannel) {
    channels.remove( messageChannel );
  }

}
TOP

Related Classes of gov.nist.javax.sip.stack.sctp.SCTPMessageProcessor

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.