javax.microedition.sip
Interface SipConnection

All Superinterfaces:
javax.microedition.io.Connection
All Known Subinterfaces:
SipClientConnection, SipServerConnection

public interface SipConnection
extends javax.microedition.io.Connection

SipConnection is the base interface for SIP connections. SipConnection holds the common properties and methods for subinterfaces SipClientConnection and SipServerConnection.

Integration to Generic Connection Framework

Integration to javax.microedition.io.Connector

A new SIP connection is instantiated by a call to Connector.open(). An application SHOULD call close() when it is finished with the connection. It should be noticed that the Connector.open() returns a client mode connection (SipClientConnection) or server mode connection (SipConnectionNotifier) depending on the string (SIP URI) passed to the Connector.open(). The SIP URI is specified in RFC3261 [1] and here it takes general form of:
      {scheme}:[{target}][{params}]
where:

Opening new client connection (SipClientConnection)

If the target host is included a, SipClientConnection will be returned.
Examples:

 sip:[email protected]
 sip:[email protected]:5060
 sips:[email protected]:5060;transport=tcp
 sip:+358-555-1234567;[email protected];user=phone
 

Opening new server connection (SipConnectionNotifier)

The server mode is detected by missing target host in the SIP URI. The server connection can be opened in two modes shared and dedicated (see also
SIP Identity chapter). This specification defines a special URI format for opening the SIP server mode connections:
      {scheme}:[{port}][{params}]
where:

Opening server connection in shared mode

Opening server connection in dedicated mode

Examples of opening a SIP server connection:

 // Shared mode, the application MIME type identifier is application/vnd.company.x-game
 SipConnectionNotifier scn = 
    (SipConnectionNotifier) Connector.open("sip:*;type=\"application/vnd.company.x-game\"");

 // Dedicated mode, port number 5060 opened for the application
 SipConnectionNotifier scn = (SipConnectionNotifier) Connector.open("sip:5060");

 // Dedicated mode, port number 5080, using secure transport
 // the application identifier is "application/messenger"
 SipConnectionNotifier scn = 
    (SipConnectionNotifier) Connector.open("sips:5080;type=\"application/messenger\"");

 // Dedicated mode, dedicated port number selected by the system
 SipConnectionNotifier scn = (SipConnectionNotifier) Connector.open("sip:");   
 

Connector.open(String name, String mode)

The optional second parameter 'mode' in Connector.open() specifies the access mode. This is ignored in SIP API. This is because both connection modes: client mode connection and server mode connection can send and receive messages.

Connector.open(String name, String mode, boolean timeouts)

The optional third parameter is a boolean flag that indicates if the calling code can handle timeout exceptions. That parameter is also ignored by the SIP API.

Convenience methods for opening streams

The Connector convenience methods to gain access to a specific input or output stream directly are not supported by the SIP API. The implementations MUST throw IOException if these methods are called with SIP URIs.

The Exceptions when calling Connector.open()

IllegalArgumentException
- If a parameter is invalid.
ConnectionNotFoundException
- If the requested connection cannot be created, or the protocol type does not exist.
IOException
- If some other kind of I/O error occurs. For example the port number for server mode connection is already reserved.
SecurityException
- May be thrown if access to the protocol handler is prohibited.
SipException
- TRANSACTION_UNAVAILABLE if the system can not open new SIP transactions. TRANSPORT_NOT_SUPPORTED if the requested transport is not supported. See above transport URI parameter.

SIP Identity

SIP identity is a logical identity (address-of-record, AOR), a type of Uniform Resource Identifier (URI) called a SIP URI. SIP identity is frequently thought of as the "public address" of the user. (see RFC 3261 [1], 6 Definitions, p.20). SIP terminal is typically configured for one user at the time (in SIP settings). The AOR is associated (inside the terminal) with one listening port e.g. 5060 (udp/tcp). So, all incoming SIP requests to that particular address-of-record are received through that port.

Now it is still possible to have several applications that want to share the same SIP identity, without specifying own listening ports (audio/video, instant message/presence and e.g. game applications). It is not feasible, or even possible, for every application to reserve own listening port and register that to the SIP registrar. This is particularly not feasible in resource-constrained terminals/networks.
On the other hand, some applications can still use their own SIP identity (for that particular service), which does not share the system SIP properties.

In SIP terms: if the request is targeted to specific application (and it is sent outside an existing dialog) it is not possible to always route incoming SIP requests using: port number, SDP media type or SIP method name (INVITE, MESSAGE, SUBSCRIBE, ...).

The issue falls to the decisions on how the initial SIP requests are routed (inside the terminal) to the User Agents (applications). This kind of functionality is specified in SIP Working Group as callee capabilities RFC3840 [4] and caller preferences RFC3841 [5]. The JSR180 specification utilizes similar functinality und uses the media feature tag 'type' for specifying the application identifier, which is used to route the incoming requests for correct applications.

Applications can use the MIME type feature tag first to register locally to the SIP system and second to indicate that in a caller preference header Accept-Contact. Each application is mapped to a certain MIME type. JSR180 SIP API provides the way to utilize this functionality as specified below.

To allow the Java SIP API to share the system SIP identity or use application's own identity, the following rules are defined when the SIP server connection is opened with Connector.open():

Connector SIP URI SIP Identity Request routing
1) sip:*;type=
"application/subtype"
- share system SIP port
- share system SIP identity
- SIP register done by the system
- route incoming SIP requests with MIME type feature tag "application/subtype" to this SipConnectionNotifier
2) sip:5080[;type=
"application/subtype"]
- use dedicated port number 5080
- use identity set by the application
- application does the SIP register
- route all incoming SIP requests on port 5080 to this SipConnectionNotifier. If the optional MIME type feature tag "application/subtype" is set, route only the requests with the matching tag.
3) sip: - use dedicated port selected by the system
- use identity set by the application
- application does the SIP register
- route all incoming SIP requests to the selected port to this SipConnectionNotifier

Routing the incoming request

The following routing rules are based on the information available in the incoming request. The implementations may define local policy that overrides any of these rules for security reasons. The incoming request is routed based on following information:

The request is routed according to the following rules, based on which of the information above is available. Every request may include Accept-Contact and Reject-Contact headers. INVITE request can also have SDP payload.

Accept-Contact SDP media Routing
1) yes - Header field contains feature sets that describe UAs that the caller would like to reach. In this specification the minimum requirement is the application MIME type indicated by the Accept-Contact parameter 'type'
2) yes yes Same as case 1)
3) - yes (OPTIONAL) The request is routed based on SDP media information.

The rule 1) defines the minimum required operation for this specification. The SIP dispatcher should implement the decision rules defined in caller prefs [RFC3841] specification. For security reasons the dispatcher implementation may define routing rules that cannot be overridden by other applications.

If matching application is not found a suitable error response is sent e.g.

Examples of Accept-Contact header and incoming request

The format of the Accept-Contact header is:
    Accept-Contact: *;<feature_set>
 
Where "*" is purely there to match the SIP extensions syntax and <feature_set> is a list of feature parameters.
Examples:
    Accept-Contact: *;type="application/vnd.company.battleships"
    Accept-Contact: *;type="application/x-chess";
    Accept-Contact: *;audio;voice;mobility="mobile";
 
Example of an incoming request with Accept-Contact header, matching the application MIME type "application/x-chess":
    INVITE sip:[email protected] SIP/2.0
    From: sip:[email protected]
    To: sip:[email protected]
    Accept-Contact: *;type="application/x-chess";explicit
    Content-Type: application/sdp

    ...SDP...
 

Identification of the SIP API

To enable applications to test for the presence of the SIP API and its version during runtime, a system property is defined. Platforms where this API is implemented according to this specification shall include a system property with a key "microedition.sip.version". When System.getProperty is called with this key, implementations conforming to this specification shall return the version string "1.0.1".

See Also:
SipClientConnection, SipServerConnection, SipConnectionNotifier

Method Summary
 void addHeader(java.lang.String name, java.lang.String value)
          Adds a header to the SIP message.
 SipDialog getDialog()
          Returns the current SIP dialog.
 java.lang.String getHeader(java.lang.String name)
          Gets the header field value of specified header type.
 java.lang.String[] getHeaders(java.lang.String name)
          Gets the header field value(s) of specified header type.
 java.lang.String getMethod()
          Gets the SIP method.
 java.lang.String getReasonPhrase()
          Gets SIP response reason phrase.
 java.lang.String getRequestURI()
          Gets Request-URI.
 int getStatusCode()
          Gets SIP response status code.
 java.io.InputStream openContentInputStream()
          Returns InputStream to read SIP message body content.
 java.io.OutputStream openContentOutputStream()
          Returns OutputStream to fill the SIP message body content.
 void removeHeader(java.lang.String name)
          Removes header from the message.
 void send()
          Sends the SIP message.
 void setHeader(java.lang.String name, java.lang.String value)
          Sets header value in SIP message.
 
Methods inherited from interface javax.microedition.io.Connection
close
 

Method Detail

send

public void send()
          throws java.io.IOException,
                 SipException
Sends the SIP message. Send must also close the OutputStream if it was opened. Calling send() is asynchronous. Any kind of immediate failure will throw IOException or SipException.

With SipServerConnection it is possible to resend 2xx responses in Completed state, by calling directly send().

Throws:
java.io.IOException - if the message could not be sent or because of network failure.
SipException - INVALID_STATE if the message can not be sent in this state. INVALID_MESSAGE there was an error in message format.

setHeader

public void setHeader(java.lang.String name,
                      java.lang.String value)
               throws SipException,
                      java.lang.IllegalArgumentException
Sets header value in SIP message. If the header does not exist it will be added to the message, otherwise the existing header is overwritten. If multiple header field values exist the topmost is overwritten. The implementations MAY restrict the access to some headers according to RFC 3261 [1].

Parameters:
name - name of the header, either in full or compact form see [1] p.32
value - the header value
Throws:
java.lang.IllegalArgumentException - MAY be thrown if the header or value is invalid.
SipException - INVALID_STATE if header can not be set in this state. INVALID_OPERATION if the system does not allow to set this header.

addHeader

public void addHeader(java.lang.String name,
                      java.lang.String value)
               throws SipException,
                      java.lang.IllegalArgumentException
Adds a header to the SIP message. If multiple header field values exist the header value is added topmost of this type of headers. The implementations MAY restrict the access to some headers according to RFC 3261 [1].

Parameters:
name - name of the header, either in full or compact form see [1] p.32
value - the header value
Throws:
java.lang.IllegalArgumentException - MAY be thrown if the header or value is invalid.
SipException - INVALID_STATE if header can not be added in this state. INVALID_OPERATION if the system does not allow to add this header.

removeHeader

public void removeHeader(java.lang.String name)
                  throws SipException
Removes header from the message. If multiple header field values exist the topmost is removed. The implementations MAY restrict the access to some headers according to RFC 3261 [1]. If the named header is not found this method does nothing.

Parameters:
name - name of the header to be removed, either in full or compact form see [1] p.32
Throws:
SipException - INVALID_STATE if header can not be removed in this state. INVALID_OPERATION if the system does not allow to remove this header.

getHeaders

public java.lang.String[] getHeaders(java.lang.String name)
Gets the header field value(s) of specified header type.

Parameters:
name - name of the header type, either in full or compact form see [1] p.32
Returns:
array of header field values (topmost first), or null if the current message does not have such a header or the header is for other reason not available (e.g. message not initialized).

getHeader

public java.lang.String getHeader(java.lang.String name)
Gets the header field value of specified header type.

Parameters:
name - name of the header type, either in full or compact form see [1] p.32
Returns:
topmost header field value, or null if the current message does not have such a header or the header is for other reason not available (e.g. message not initialized).

getMethod

public java.lang.String getMethod()
Gets the SIP method. Applicable when a message has been initialized or received.

Returns:
SIP method name REGISTER, INVITE, NOTIFY, etc. Returns null if the method is not available.

getRequestURI

public java.lang.String getRequestURI()
Gets Request-URI. Available when SipClientConnection is in Initialized state or when SipServerConnection is in Request Received state. Built from the original URI given in Connector.open(). See RFC 3261 p.35 (8.1.1.1 Request-URI)

Returns:
Request-URI of the message. Returns null if the Request-URI is not available.

getStatusCode

public int getStatusCode()
Gets SIP response status code. Available when SipClientConnection is in Proceeding or Completed state or when SipServerConnection is in Initialized state.

Returns:
status code 1xx, 2xx, 3xx, 4xx, ... Returns 0 if the status code is not available.

getReasonPhrase

public java.lang.String getReasonPhrase()
Gets SIP response reason phrase. Available when SipClientConnection is in Proceeding or Completed state or when SipServerConnection is in Initialized state.

Returns:
reason phrase. Returns null if the reason phrase is not available.

getDialog

public SipDialog getDialog()
Returns the current SIP dialog. This is available when the SipConnection belongs to a created SipDialog, which is in Early or Confirmed state (see SipDialog).

The SipDialog returned from the SipConnection defines always the peer-to-peer association created by the latest sent or received request or response.

Returns:
SipDialog object if this connection belongs to a dialog, otherwise returns null.
See Also:
SipDialog

openContentInputStream

public java.io.InputStream openContentInputStream()
                                           throws java.io.IOException,
                                                  SipException
Returns InputStream to read SIP message body content.

Returns:
InputStream to read body content
Throws:
java.io.IOException - if the InputStream can not be opened, because of an I/O error occurred.
SipException - INVALID_STATE the InputStream can not be opened in this state (e.g. no message received).

openContentOutputStream

public java.io.OutputStream openContentOutputStream()
                                             throws java.io.IOException,
                                                    SipException
Returns OutputStream to fill the SIP message body content. When calling close() on OutputStream the message will be sent to the network. So it is equivalent to call send(). Again send() must not be called after closing the OutputStream, since it will throw Exception because of calling the method in wrong state.
Before opening OutputStream the Content-Length and Content-Type headers has to se set. If not SipException.UNKNOWN_LENGTH or SipException.UNKNOWN_TYPE will be thrown respectively.

Returns:
OutputStream to write body content
Throws:
java.io.IOException - if the OutputStream can not be opened, because of an I/O error occurred.
SipException - INVALID_STATE the OutputStream can not be opened in this state (e.g. no message initialized). UNKNOWN_LENGTH Content-Length header not set. UNKNOWN_TYPE Content-Type header not set.
See Also:
send()


Copyright © 2004 Nokia Corporation. All Rights Reserved.
Java is a trademark of Sun Microsystems, Inc.