Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Conditions Of Use 
   * 
   * This software was developed by employees of the National Institute of
   * Standards and Technology (NIST), an agency of the Federal Government.
   * Pursuant to title 15 Untied States Code Section 105, works of NIST
   * employees are not subject to copyright protection in the United States
   * and are considered to be in the public domain.  As a result, a formal
   * license is not needed to use the software.
  * 
  * This software is provided by NIST as a service and is expressly
  * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
  * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
  * AND DATA ACCURACY.  NIST does not warrant or make any representations
  * regarding the use of the software or the results thereof, including but
  * not limited to the correctness, accuracy, reliability or usefulness of
  * the software.
  * 
  * Permission to use this software is contingent upon your acceptance
  * of the terms of this agreement
  *  
  * .
  * 
  */
Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * /
 
 
 package gov.nist.javax.sip.stack;
 
 
 
Message channel abstraction for the SIP stack.

Author(s):
M. Ranganathan
Contains additions for support of symmetric NAT contributed by Hagai.
Version:
1.2 $Revision: 1.36 $ $Date: 2010/10/28 03:20:33 $
 
 public abstract class MessageChannel {
 
     // Incremented whenever a transaction gets assigned
     // to the message channel and decremented when
     // a transaction gets freed from the message channel.
 	protected int useCount;

Hook method, overridden by subclasses
 
 	protected void uncache() {}

    
Message processor to whom I belong (if set).
 
     protected transient MessageProcessor messageProcessor;
    
    
The client transaction that this message channel points to.
 
Close the message channel.
 
     public abstract void close();

    
Get the SIPStack object from this message channel.

Returns:
SIPStack object of this message channel
    public abstract SIPTransactionStack getSIPStack();

    
Get transport string of this message channel.

Returns:
Transport string of this message channel.
    public abstract String getTransport();

    
Get whether this channel is reliable or not.

Returns:
True if reliable, false if not.
    public abstract boolean isReliable();

    
Return true if this is a secure channel.
    public abstract boolean isSecure();

    
Send the message (after it has been formatted)

Parameters:
sipMessage Message to send.
    public abstract void sendMessage(SIPMessage sipMessagethrows IOException;

    
Get the peer address of the machine that sent us this message.

Returns:
a string contianing the ip address or host name of the sender of the message.
    public abstract String getPeerAddress();
    protected abstract InetAddress getPeerInetAddress();
    protected abstract String getPeerProtocol();

    
Get the sender port ( the port of the other end that sent me the message).
    public abstract int getPeerPort();
    public abstract int getPeerPacketSourcePort();
    public abstract InetAddress getPeerPacketSourceAddress();

    
Generate a key which identifies the message channel. This allows us to cache the message channel.
    public abstract String getKey();

    
Get the host for a viaHeader.
    public abstract String getViaHost();

    
Get the port to assign for the via header of an outgoing message.
    public abstract int getViaPort();
        

    
Send the message (after it has been formatted), to a specified address and a specified port

Parameters:
message Message to send.
receiverAddress Address of the receiver.
receiverPort Port of the receiver.
    protected abstract void sendMessage(byte[] messageInetAddress receiverAddress,
            int receiverPortboolean reconnectFlagthrows IOException;

    
Get the host of this message channel.

Returns:
host of this messsage channel.
    public String getHost() {
        return this.getMessageProcessor().getIpAddress().getHostAddress();
    }

    
Get port of this message channel.

Returns:
Port of this message channel.
    public int getPort() {
        if (this. != null)
            return .getPort();
        else
            return -1;
    }

    
Send a formatted message to the specified target.

Parameters:
sipMessage Message to send.
hop hop to send it to.
Throws:
java.io.IOException If there is an error sending the message
    public void sendMessage(final SIPMessage sipMessageHop hopthrows IOException {
        long time = System.currentTimeMillis();
        InetAddress hopAddr = InetAddress.getByName(hop.getHost());
        try {
            for (MessageProcessor messageProcessor : getSIPStack().getMessageProcessors()) {
                if (messageProcessor.getIpAddress().equals(hopAddr)
                        && messageProcessor.getPort() == hop.getPort()
                        && messageProcessor.getTransport().equalsIgnoreCase(hop.getTransport())) {
                    MessageChannel messageChannel = messageProcessor.createMessageChannel(
                            hopAddrhop.getPort());
                    if (messageChannel instanceof RawMessageChannel) {
                    	final RawMessageChannel channel = (RawMessageChannelmessageChannel;
                    	Runnable processMessageTask = new Runnable() {
							public void run() {
								try {
									((RawMessageChannelchannel).processMessage(sipMessage);
catch (Exception ex) {
						        		getSIPStack().getStackLogger().logError("Error self routing message cause by: "ex);
						        	}
								}
							}
						};
                        
                        if (getSIPStack().isLoggingEnabled(.))
                        	getSIPStack().getStackLogger().logDebug("Self routing message");
                        return;
                    }
                }
            }
            byte[] msg = sipMessage.encodeAsBytes(this.getTransport());
            this.sendMessage(msghopAddrhop.getPort(), sipMessage instanceof SIPRequest);
        } catch (IOException ioe) {
            throw ioe;
        } catch (Exception ex) {
        		this.getSIPStack().getStackLogger().logError("Error self routing message cause by: "ex);
        	}
        	// TODO: When moving to Java 6, use the IOExcpetion(message, exception) constructor
            throw new IOException("Error self routing message");
        } finally {
                logMessage(sipMessagehopAddrhop.getPort(), time);
        }
    }

    
Send a message given SIP message.

Parameters:
sipMessage is the messge to send.
receiverAddress is the address to which we want to send
receiverPort is the port to which we want to send
    public void sendMessage(SIPMessage sipMessageInetAddress receiverAddressint receiverPort)
            throws IOException {
        long time = System.currentTimeMillis();
        byte[] bytes = sipMessage.encodeAsBytes(this.getTransport());
        sendMessage(bytesreceiverAddressreceiverPortsipMessage instanceof SIPRequest);
        logMessage(sipMessagereceiverAddressreceiverPorttime);
    }

    
Convenience function to get the raw IP source address of a SIP message as a String.
    public String getRawIpSourceAddress() {
        String sourceAddress = getPeerAddress();
        String rawIpSourceAddress = null;
        try {
            InetAddress sourceInetAddress = InetAddress.getByName(sourceAddress);
            rawIpSourceAddress = sourceInetAddress.getHostAddress();
        } catch (Exception ex) {
            InternalErrorHandler.handleException(ex);
        }
        return rawIpSourceAddress;
    }

    
generate a key given the inet address port and transport.
    public static String getKey(InetAddress inetAddrint portString transport) {
        return (transport + ":" + inetAddr.getHostAddress() + ":" + port).toLowerCase();
    }

    
Generate a key given host and port.
    public static String getKey(HostPort hostPortString transport) {
        return (transport + ":" + hostPort.getHost().getHostname() + ":" + hostPort.getPort())
                .toLowerCase();
    }

    
Get the hostport structure of this message channel.
    public HostPort getHostPort() {
        HostPort retval = new HostPort();
        retval.setHost(new Host(this.getHost()));
        retval.setPort(this.getPort());
        return retval;
    }

    
Get the peer host and port.

Returns:
a HostPort structure for the peer.
    public HostPort getPeerHostPort() {
        HostPort retval = new HostPort();
        retval.setHost(new Host(this.getPeerAddress()));
        retval.setPort(this.getPeerPort());
        return retval;
    }

    
Get the Via header for this transport. Note that this does not set a branch identifier.

Returns:
a via header for outgoing messages sent from this channel.
    public Via getViaHeader() {
        Via channelViaHeader;
        channelViaHeader = new Via();
        try {
            channelViaHeader.setTransport(getTransport());
        } catch (ParseException ex) {
        }
        channelViaHeader.setSentBy(getHostPort());
        return channelViaHeader;
    }

    
Get the via header host:port structure. This is extracted from the topmost via header of the request.

Returns:
a host:port structure
    public HostPort getViaHostPort() {
        HostPort retval = new HostPort();
        retval.setHost(new Host(this.getViaHost()));
        retval.setPort(this.getViaPort());
        return retval;
    }

    
Log a message sent to an address and port via the default interface.

Parameters:
sipMessage is the message to log.
address is the inet address to which the message is sent.
port is the port to which the message is directed.
    public void logMessage(SIPMessage sipMessageInetAddress addressint portlong time) {
            return;
        // Default port.
        if (port == -1)
            port = 5060;
        getSIPStack()..logMessage(sipMessagethis.getHost() + ":" + this.getPort(),
                address.getHostAddress().toString() + ":" + porttruetime);
    }

    
Log a response received at this message channel. This is used for processing incoming responses to a client transaction.

Parameters:
receptionTime is the time at which the response was received.
status is the processing status of the message.
    public void logResponse(SIPResponse sipResponselong receptionTimeString status) {
        int peerport = getPeerPort();
        if (peerport == 0 && sipResponse.getContactHeaders() != null) {
            ContactHeader contact = (ContactHeadersipResponse.getContactHeaders().getFirst();
            peerport = ((AddressImplcontact.getAddress()).getPort();
        }
        String from = getPeerAddress().toString() + ":" + peerport;
        String to = this.getHost() + ":" + getPort();
        this.getSIPStack()..logMessage(sipResponsefromtostatusfalse,
                receptionTime);
    }

    
Creates a response to a bad request (ie one that causes a ParseException)

Parameters:
badReq
Returns:
message bytes, null if unable to formulate response
    protected final String createBadReqRes(String badReqParseException pe) {
        StringBuilder buf = new StringBuilder(512);
        buf.append("SIP/2.0 400 Bad Request (" + pe.getLocalizedMessage() + ')');
        // We need the following headers: all Vias, CSeq, Call-ID, From, To
        if (!copyViaHeaders(badReqbuf))
            return null;
        if (!copyHeader(.badReqbuf))
            return null;
        if (!copyHeader(.badReqbuf))
            return null;
        if (!copyHeader(.badReqbuf))
            return null;
        if (!copyHeader(.badReqbuf))
            return null;
        // Should add a to-tag if not already present...
        int toStart = buf.indexOf(.);
        if (toStart != -1 && buf.indexOf("tag"toStart) == -1) {
            buf.append(";tag=badreq");
        }
        // Let's add a Server header too..
        ServerHeader s = MessageFactoryImpl.getDefaultServerHeader();
        if ( s != null ) {
            buf.append("\r\n" + s.toString());
        }
        int clength = badReq.length();
        if (! (this instanceof UDPMessageChannel) ||
                clength + buf.length() + ..length()
                + ": message/sipfrag\r\n".length() +
                ..length()  < 1300) { 
            
            /*
             * Check to see we are within one UDP packet.
             */
            ContentTypeHeader cth = new ContentType("message""sipfrag");
            buf.append("\r\n" + cth.toString());
            ContentLength clengthHeader = new ContentLength(clength);
            buf.append("\r\n" + clengthHeader.toString());
            buf.append("\r\n\r\n" + badReq);
        } else {
            ContentLength clengthHeader = new ContentLength(0);
            buf.append("\r\n" + clengthHeader.toString());
        }
        
        return buf.toString();
    }

    
Copies a header from a request

Parameters:
name
fromReq
buf
Returns:
Note: some limitations here: does not work for short forms of headers, or continuations; problems when header names appear in other parts of the request
    private static final boolean copyHeader(String nameString fromReqStringBuilder buf) {
        int start = fromReq.indexOf(name);
        if (start != -1) {
            int end = fromReq.indexOf("\r\n"start);
            if (end != -1) {
                // XX Assumes no continuation here...
                buf.append(fromReq.subSequence(start - 2, end)); // incl CRLF
                // in front
                return true;
            }
        }
        return false;
    }

    
Copies all via headers from a request

Parameters:
fromReq
buf
Returns:
Note: some limitations here: does not work for short forms of headers, or continuations
    private static final boolean copyViaHeaders(String fromReqStringBuilder buf) {
        int start = fromReq.indexOf(.);
        boolean found = false;
        while (start != -1) {
            int end = fromReq.indexOf("\r\n"start);
            if (end != -1) {
                // XX Assumes no continuation here...
                buf.append(fromReq.subSequence(start - 2, end)); // incl CRLF
                // in front
                found = true;
                start = fromReq.indexOf(.end);
            } else {
                return false;
            }
        }
        return found;
    }

    
Get the message processor.
        return this.;
    }
    
    	return this.;
    }
		this. = transaction;
	}
New to GrepCode? Check out our FAQ X