1/*
2* Conditions Of Use
3*
4* This software was developed by employees of the National Institute of
5* Standards and Technology (NIST), an agency of the Federal Government.
6* Pursuant to title 15 Untied States Code Section 105, works of NIST
7* employees are not subject to copyright protection in the United States
8* and are considered to be in the public domain.  As a result, a formal
9* license is not needed to use the software.
10*
11* This software is provided by NIST as a service and is expressly
12* provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
13* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
15* AND DATA ACCURACY.  NIST does not warrant or make any representations
16* regarding the use of the software or the results thereof, including but
17* not limited to the correctness, accuracy, reliability or usefulness of
18* the software.
19*
20* Permission to use this software is contingent upon your acceptance
21* of the terms of this agreement
22*
23* .
24*
25*/
26package gov.nist.javax.sip;
27
28import java.io.IOException;
29import java.net.InetAddress;
30import java.text.ParseException;
31
32import javax.sip.*;
33import javax.sip.address.SipURI;
34import javax.sip.header.ContactHeader;
35import javax.sip.header.ViaHeader;
36
37import gov.nist.core.Host;
38import gov.nist.core.HostPort;
39import gov.nist.core.InternalErrorHandler;
40import gov.nist.javax.sip.address.AddressImpl;
41import gov.nist.javax.sip.address.SipUri;
42import gov.nist.javax.sip.header.Contact;
43import gov.nist.javax.sip.header.Via;
44import gov.nist.javax.sip.message.SIPRequest;
45import gov.nist.javax.sip.stack.*;
46
47/**
48 * Implementation of the ListeningPoint interface
49 *
50 * @version 1.2 $Revision: 1.15 $ $Date: 2009/11/19 05:26:58 $
51 *
52 * @author M. Ranganathan   <br/>
53 *
54 *
55 *
56 */
57public class ListeningPointImpl implements javax.sip.ListeningPoint, gov.nist.javax.sip.ListeningPointExt {
58
59
60    protected String transport;
61
62    /** My port. (same thing as in the message processor) */
63
64    int port;
65
66    /**
67     * Pointer to the imbedded mesage processor.
68     */
69    protected MessageProcessor messageProcessor;
70
71    /**
72     * Provider back pointer
73     */
74    protected SipProviderImpl sipProvider;
75
76    /**
77     * Our stack
78     */
79    protected SipStackImpl sipStack;
80
81
82
83
84    /**
85     * Construct a key to refer to this structure from the SIP stack
86     * @param host host string
87     * @param port port
88     * @param transport transport
89     * @return a string that is used as a key
90     */
91    public static String makeKey(String host, int port, String transport) {
92        return new StringBuffer(host)
93            .append(":")
94            .append(port)
95            .append("/")
96            .append(transport)
97            .toString()
98            .toLowerCase();
99    }
100
101    /**
102     * Get the key for this strucut
103     * @return  get the host
104     */
105    protected String getKey() {
106        return makeKey(this.getIPAddress(), port, transport);
107    }
108
109    /**
110     * Set the sip provider for this structure.
111     * @param sipProvider provider to set
112     */
113    protected void setSipProvider(SipProviderImpl sipProviderImpl) {
114        this.sipProvider = sipProviderImpl;
115    }
116
117    /**
118     * Remove the sip provider from this listening point.
119     */
120    protected void removeSipProvider() {
121        this.sipProvider = null;
122    }
123
124    /**
125     * Constructor
126     * @param sipStack Our sip stack
127     */
128    protected ListeningPointImpl(
129        SipStack sipStack,
130        int port,
131        String transport) {
132        this.sipStack = (SipStackImpl) sipStack;
133
134        this.port = port;
135        this.transport = transport;
136
137    }
138
139    /**
140     * Clone this listening point. Note that a message Processor is not
141     * started. The transport is set to null.
142     * @return cloned listening point.
143     */
144    public Object clone() {
145        ListeningPointImpl lip =
146            new ListeningPointImpl(this.sipStack, this.port, null);
147        lip.sipStack = this.sipStack;
148        return lip;
149    }
150
151
152
153    /**
154     * Gets the port of the ListeningPoint. The default port of a ListeningPoint
155     * is dependent on the scheme and transport.  For example:
156     * <ul>
157     * <li>The default port is 5060 if the transport UDP the scheme is <i>sip:</i>.
158     * <li>The default port is 5060 if the transport is TCP the scheme is <i>sip:</i>.
159     * <li>The default port is 5060 if the transport is SCTP the scheme is <i>sip:</i>.
160     * <li>The default port is 5061 if the transport is TLS over TCP the scheme is <i>sip:</i>.
161     * <li>The default port is 5061 if the transport is TCP the scheme is <i>sips:</i>.
162     * </ul>
163     *
164     * @return port of ListeningPoint
165     */
166    public int getPort() {
167        return messageProcessor.getPort();
168    }
169
170    /**
171     * Gets transport of the ListeningPoint.
172     *
173     * @return transport of ListeningPoint
174     */
175    public String getTransport() {
176        return messageProcessor.getTransport();
177    }
178
179    /**
180     * Get the provider.
181     *
182     * @return the provider.
183     */
184    public SipProviderImpl getProvider() {
185        return this.sipProvider;
186    }
187
188    /* (non-Javadoc)
189     * @see javax.sip.ListeningPoint#getIPAddress()
190     */
191    public String getIPAddress() {
192
193        return this.messageProcessor.getIpAddress().getHostAddress();
194    }
195
196
197
198    /* (non-Javadoc)
199     * @see javax.sip.ListeningPoint#setSentBy(java.lang.String)
200     */
201    public void setSentBy(String sentBy) throws ParseException {
202        this.messageProcessor.setSentBy(sentBy);
203
204    }
205
206    /* (non-Javadoc)
207     * @see javax.sip.ListeningPoint#getSentBy()
208     */
209    public String getSentBy() {
210
211        return this.messageProcessor.getSentBy();
212    }
213
214    public boolean isSentBySet() {
215        return this.messageProcessor.isSentBySet();
216    }
217    public Via getViaHeader() {
218        return this.messageProcessor.getViaHeader();
219     }
220
221    public MessageProcessor getMessageProcessor() {
222        return this.messageProcessor;
223    }
224
225    public ContactHeader createContactHeader() {
226        try {
227            String ipAddress = this.getIPAddress();
228            int port = this.getPort();
229            SipURI sipURI = new SipUri();
230            sipURI.setHost(ipAddress);
231            sipURI.setPort(port);
232            sipURI.setTransportParam(this.transport);
233            Contact contact = new Contact();
234            AddressImpl address = new AddressImpl();
235            address.setURI(sipURI);
236            contact.setAddress(address);
237
238            return contact;
239        } catch (Exception ex) {
240            InternalErrorHandler.handleException("Unexpected exception",sipStack.getStackLogger());
241            return null;
242        }
243    }
244
245
246    public void sendHeartbeat(String ipAddress, int port) throws IOException {
247
248        HostPort targetHostPort  = new HostPort();
249        targetHostPort.setHost(new Host( ipAddress));
250        targetHostPort.setPort(port);
251        MessageChannel messageChannel = this.messageProcessor.createMessageChannel(targetHostPort);
252        SIPRequest siprequest = new SIPRequest();
253        siprequest.setNullRequest();
254        messageChannel.sendMessage(siprequest);
255
256    }
257
258
259    public ViaHeader createViaHeader() {
260           return this.getViaHeader();
261    }
262
263}
264