Package org.cipango.lab

Source Code of org.cipango.lab.UdpConnector$EventHandler

// ========================================================================
// Copyright 2008-2009 NEXCOM Systems
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================

package org.cipango.lab;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.LinkedList;

import javax.servlet.sip.URI;

import org.cipango.server.AbstractSipConnector;
import org.cipango.server.SipConnection;
import org.cipango.server.SipConnector;
import org.cipango.server.SipConnectors;
import org.cipango.server.SipMessage;
import org.cipango.server.SipRequest;
import org.cipango.server.SipResponse;
import org.cipango.sip.*;
import org.cipango.util.HexString;

import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.io.View;
import org.eclipse.jetty.util.log.Log;

public class UdpConnector extends AbstractSipConnector
{
  public static final int MAX_UDP_SIZE = 65536;
  public static final int DEFAULT_PORT = 5060;
  public static final boolean RELIABLE = false;
   
    private DatagramPacket[] _packets;
    private DatagramSocket _datagramSocket;
    private InetAddress _localAddr;
   
    private LinkedList<UdpBuffer> _bufferQueue;
     
  protected void doStart() throws Exception
  {   
    _packets = new DatagramPacket[getAcceptors()];
    for (int i = 0; i < getAcceptors(); i++)
    {
      _packets[i] = new DatagramPacket(new byte[MAX_UDP_SIZE], MAX_UDP_SIZE);
    }
    _bufferQueue = new LinkedList<UdpBuffer>();
   
    new Thread(new Processor()).start();
    new Thread(new Processor()).start();

    super.doStart();
  }
 
  protected void doStop() throws Exception
  {
    super.doStop();
  }
 
  public void open() throws IOException
  {
    _datagramSocket = newDatagramSocket();
    _localAddr = _datagramSocket.getLocalAddress();
  }

  public boolean isOpen()
  {
    return _datagramSocket != null && !_datagramSocket.isClosed();
  }
 
  public int getLocalPort()
  {
    if (_datagramSocket==null || _datagramSocket.isClosed())
            return -1;
        return _datagramSocket.getLocalPort();
  }
 
  public Object getConnection()
  {
    return _datagramSocket;
  }
 
  protected DatagramSocket newDatagramSocket() throws IOException
  {
    if (getHost() == null)
      _datagramSocket = new DatagramSocket(getPort());
    else
      _datagramSocket = new DatagramSocket(getPort(), InetAddress.getByName(getHost()));

    return _datagramSocket;
  }
 
  public void close()
  {
    _datagramSocket.close();
  }
 
  public void accept(int acceptorID) throws IOException, InterruptedException
  {
    DatagramPacket p = _packets[acceptorID];
   
    _datagramSocket.receive(p);

    int length = p.getLength();
    if (length == 2 || length == 4) return;
   
    byte[] b = new byte[length];
    System.arraycopy(p.getData(), 0, b, 0, length);
   
    Buffer buffer = new ByteArrayBuffer(b);
   
    UdpBuffer udpBuffer = new UdpBuffer();
    udpBuffer._buffer = buffer;
    udpBuffer._address = p.getAddress();
    udpBuffer._port = p.getPort();
   
    synchronized (_bufferQueue)
    {
      if (_bufferQueue.size() < 1024)
      {
        _bufferQueue.offer(udpBuffer);
        _bufferQueue.notifyAll();
      }
      else
        System.out.println("full");
    }
  }
 
  public SipConnection getConnection(InetAddress address, int port)
  {
    return new UdpConnection(address, port);
  }

  public int getDefaultPort()
  {
    return DEFAULT_PORT;
  }
 
  public InetAddress getAddr()
  {
    return _localAddr;
  }
 
  public int getTransportOrdinal()
  {
    return SipConnectors.UDP_ORDINAL;
  }

  public boolean isReliable()
  {
    return RELIABLE;
  }

  public boolean isSecure()
  {
    return false;
  }
 
  public Buffer newBuffer()
  {
    return new ByteArrayBuffer(MAX_UDP_SIZE);
  }

  public SipConnector getConnector()
  {
    return this;
  }
 
  class UdpConnection implements SipConnection
  {
    private InetAddress _remoteAddr;
    private int _remotePort;
   
    public UdpConnection(InetAddress remoteAddr, int remotePort)
    {
      _remoteAddr = remoteAddr;
      _remotePort = remotePort;
    }
   
    public SipConnector getConnector()
    {
      return UdpConnector.this;
    }
   
    public InetAddress getLocalAddress()
    {
      return _localAddr;
    }
   
    public int getLocalPort()
    {
      return UdpConnector.this.getPort();
    }
   
    public InetAddress getRemoteAddress()
    {
      return _remoteAddr;
    }
   
    public int getRemotePort()
    {
      return _remotePort;
    }
   
    public void write(Buffer buffer) throws IOException
    {
      DatagramPacket packet = new DatagramPacket(
          buffer.array(),
          buffer.length(),
          _remoteAddr,
          _remotePort);
      _datagramSocket.send(packet);
    }
   
    public boolean isOpen()
    {
      return (_datagramSocket != null && !_datagramSocket.isClosed());
    }
   
    public String toString()
    {
      return "udp/" + _remoteAddr.getHostAddress() + ":" + _remotePort;
    }
  }
 
  class UdpBuffer
  {
    Buffer _buffer;
    InetAddress _address;
    int _port;
  }
 
  class Processor implements Runnable
  {
    public void run()
    {
      UdpBuffer udpBuffer;
      try
      {
        while (isRunning())
        {
          try
          {
            synchronized (_bufferQueue)
            {
              while (_bufferQueue.isEmpty())
                _bufferQueue.wait();
             
              udpBuffer = _bufferQueue.poll();
            }
           
            Buffer buffer = udpBuffer._buffer;
           
            EventHandler handler = new EventHandler();
            SipParser parser = new SipParser(buffer, handler);
           
            try
            {
              parser.parse();
             
              SipMessage message = handler.getMessage();
              message.setConnection(new UdpConnection(udpBuffer._address, udpBuffer._port));
             
              /*
              message.set5uple(getTransportOrdinal(), getAddr(), getPort(), p.getAddress(), p.getPort());
           
              if (message.isRequest())
                ((SipRequest) message).setEndpoint(this);
               
              */
             
              process(message);
            }
            catch (Throwable t)
            {
              Log.warn(t);
              //if (handler.hasException())
                //Log.warn(handler.getException());
               
              if (Log.isDebugEnabled())
                Log.debug("Buffer content: \r\n" + HexString.toDetailedHexString(buffer.array(), buffer.length()));
            }
          }
          catch (Exception e)
          {
            Log.warn(e);
          }
        }
      }
      finally
      {
       
      }
    }
  }
 
  class EventHandler extends SipParser.EventHandler
  {
    private SipMessage _message;
   
    @Override
    public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
    {
      try
      {
        URI ruri = URIFactory.parseURI(uri.toString());
        SipRequest request = new SipRequest();
        request.setMethod(method.toString());
        request.setRequestURI(ruri);
        _message = request;
      }
      catch (Exception e)
      {
        throw new IOException("Parsing error: " + e.getMessage());
      }
    }
   
    @Override
    public void startResponse(Buffer version, int status, Buffer reason) throws IOException
    {
      SipResponse response = new SipResponse();
      response.setStatus(status, reason.toString());
      _message = response;
    }
   
    public SipMessage getMessage()
    {
      return _message;
    }
   
    @Override
    public void header(Buffer name, Buffer value) throws IOException
    {
      if (_message == null)
        throw new IOException("no status line");
     
      if (SipHeaders.getType(name).isList())
          {
              boolean quote = false;
     
              int start = value.getIndex();
              int end = value.putIndex();
              byte[] b = value.array();
             
              //if (value == null) value = _value.asArray();
             
              int startValue = start;
              int endValue = end;
             
              while (end > start && b[end -1] <= ' ') end--;
                     
              for (int i = start; i < end; i++)
              {
                  int c = b[i];
                  if (c == '"') quote = !quote;
     
                  if (c == ',' && !quote)
                  {
                      endValue = i;
                      while (endValue > start && b[endValue -1] <= ' ') endValue--;
                     
                      while (startValue < endValue && b[startValue] <= ' ') startValue++;
                     
                      //byte[] bValue = asArray(b, startValue, endValue - startValue);
                     
                      Buffer buffer = new View(value, startValue, startValue, endValue, Buffer.READONLY);
                      _message.getFields().addBuffer(name, buffer);
                     
                      //value = new View(value, i + 1, i + 1, end, Buffer.READONLY);
                     
                      startValue = i + 1;
                  }
              }
              while (startValue < end && b[startValue] <= ' ') startValue++;
             
              value = new View(value, startValue, startValue, end, Buffer.READONLY);
             
              //byte[] bValue = asArray(b, startValue, end - startValue);
              _message.getFields().addBuffer(name, value);
             
              //value = new View(value, startValue, startValue, end, Buffer.READONLY);
          }
          else
          {
            _message.getFields().addBuffer(name, value);
            //msg.getFields().addBuffer(name, new ByteArrayBuffer(value.asArray()));
          }
    }
   
    @Override
    public void content(Buffer buffer) throws IOException
    {
      if (buffer.length() > 0)
        _message.setRawContent(buffer.asArray()); // TODO buffer
    }
  }

}
TOP

Related Classes of org.cipango.lab.UdpConnector$EventHandler

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.