497 lines
15 KiB
Java
497 lines
15 KiB
Java
/*
|
|
* Copyright (C) 2010 The Android Open Source Project
|
|
*
|
|
* 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 android.net.sip;
|
|
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.text.TextUtils;
|
|
|
|
import java.io.ObjectStreamException;
|
|
import java.io.Serializable;
|
|
import java.text.ParseException;
|
|
import javax.sip.InvalidArgumentException;
|
|
import javax.sip.ListeningPoint;
|
|
import javax.sip.PeerUnavailableException;
|
|
import javax.sip.SipFactory;
|
|
import javax.sip.address.Address;
|
|
import javax.sip.address.AddressFactory;
|
|
import javax.sip.address.SipURI;
|
|
import javax.sip.address.URI;
|
|
|
|
/**
|
|
* Defines a SIP profile, including a SIP account, domain and server information.
|
|
* <p>You can create a {@link SipProfile} using {@link
|
|
* SipProfile.Builder}. You can also retrieve one from a {@link SipSession}, using {@link
|
|
* SipSession#getLocalProfile} and {@link SipSession#getPeerProfile}.</p>
|
|
*/
|
|
public class SipProfile implements Parcelable, Serializable, Cloneable {
|
|
private static final long serialVersionUID = 1L;
|
|
private static final int DEFAULT_PORT = 5060;
|
|
private static final String TCP = "TCP";
|
|
private static final String UDP = "UDP";
|
|
private Address mAddress;
|
|
private String mProxyAddress;
|
|
private String mPassword;
|
|
private String mDomain;
|
|
private String mProtocol = UDP;
|
|
private String mProfileName;
|
|
private String mAuthUserName;
|
|
private int mPort = DEFAULT_PORT;
|
|
private boolean mSendKeepAlive = false;
|
|
private boolean mAutoRegistration = true;
|
|
private transient int mCallingUid = 0;
|
|
|
|
public static final Parcelable.Creator<SipProfile> CREATOR =
|
|
new Parcelable.Creator<SipProfile>() {
|
|
public SipProfile createFromParcel(Parcel in) {
|
|
return new SipProfile(in);
|
|
}
|
|
|
|
public SipProfile[] newArray(int size) {
|
|
return new SipProfile[size];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Helper class for creating a {@link SipProfile}.
|
|
*/
|
|
public static class Builder {
|
|
private AddressFactory mAddressFactory;
|
|
private SipProfile mProfile = new SipProfile();
|
|
private SipURI mUri;
|
|
private String mDisplayName;
|
|
private String mProxyAddress;
|
|
|
|
{
|
|
try {
|
|
mAddressFactory =
|
|
SipFactory.getInstance().createAddressFactory();
|
|
} catch (PeerUnavailableException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a builder based on the given profile.
|
|
*/
|
|
public Builder(SipProfile profile) {
|
|
if (profile == null) throw new NullPointerException();
|
|
try {
|
|
mProfile = (SipProfile) profile.clone();
|
|
} catch (CloneNotSupportedException e) {
|
|
throw new RuntimeException("should not occur", e);
|
|
}
|
|
mProfile.mAddress = null;
|
|
mUri = profile.getUri();
|
|
mUri.setUserPassword(profile.getPassword());
|
|
mDisplayName = profile.getDisplayName();
|
|
mProxyAddress = profile.getProxyAddress();
|
|
mProfile.mPort = profile.getPort();
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param uriString the URI string as "sip:<user_name>@<domain>"
|
|
* @throws ParseException if the string is not a valid URI
|
|
*/
|
|
public Builder(String uriString) throws ParseException {
|
|
if (uriString == null) {
|
|
throw new NullPointerException("uriString cannot be null");
|
|
}
|
|
URI uri = mAddressFactory.createURI(fix(uriString));
|
|
if (uri instanceof SipURI) {
|
|
mUri = (SipURI) uri;
|
|
} else {
|
|
throw new ParseException(uriString + " is not a SIP URI", 0);
|
|
}
|
|
mProfile.mDomain = mUri.getHost();
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param username username of the SIP account
|
|
* @param serverDomain the SIP server domain; if the network address
|
|
* is different from the domain, use {@link #setOutboundProxy} to
|
|
* set server address
|
|
* @throws ParseException if the parameters are not valid
|
|
*/
|
|
public Builder(String username, String serverDomain)
|
|
throws ParseException {
|
|
if ((username == null) || (serverDomain == null)) {
|
|
throw new NullPointerException(
|
|
"username and serverDomain cannot be null");
|
|
}
|
|
mUri = mAddressFactory.createSipURI(username, serverDomain);
|
|
mProfile.mDomain = serverDomain;
|
|
}
|
|
|
|
private String fix(String uriString) {
|
|
return (uriString.trim().toLowerCase().startsWith("sip:")
|
|
? uriString
|
|
: "sip:" + uriString);
|
|
}
|
|
|
|
/**
|
|
* Sets the username used for authentication.
|
|
*
|
|
* @param name auth. name of the profile
|
|
* @return this builder object
|
|
* @hide // TODO: remove when we make it public
|
|
*/
|
|
public Builder setAuthUserName(String name) {
|
|
mProfile.mAuthUserName = name;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the name of the profile. This name is given by user.
|
|
*
|
|
* @param name name of the profile
|
|
* @return this builder object
|
|
*/
|
|
public Builder setProfileName(String name) {
|
|
mProfile.mProfileName = name;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the password of the SIP account
|
|
*
|
|
* @param password password of the SIP account
|
|
* @return this builder object
|
|
*/
|
|
public Builder setPassword(String password) {
|
|
mUri.setUserPassword(password);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the port number of the server. By default, it is 5060.
|
|
*
|
|
* @param port port number of the server
|
|
* @return this builder object
|
|
* @throws IllegalArgumentException if the port number is out of range
|
|
*/
|
|
public Builder setPort(int port) throws IllegalArgumentException {
|
|
if ((port > 65535) || (port < 1000)) {
|
|
throw new IllegalArgumentException("incorrect port arugment: " + port);
|
|
}
|
|
mProfile.mPort = port;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the protocol used to connect to the SIP server. Currently,
|
|
* only "UDP" and "TCP" are supported.
|
|
*
|
|
* @param protocol the protocol string
|
|
* @return this builder object
|
|
* @throws IllegalArgumentException if the protocol is not recognized
|
|
*/
|
|
public Builder setProtocol(String protocol)
|
|
throws IllegalArgumentException {
|
|
if (protocol == null) {
|
|
throw new NullPointerException("protocol cannot be null");
|
|
}
|
|
protocol = protocol.toUpperCase();
|
|
if (!protocol.equals(UDP) && !protocol.equals(TCP)) {
|
|
throw new IllegalArgumentException(
|
|
"unsupported protocol: " + protocol);
|
|
}
|
|
mProfile.mProtocol = protocol;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the outbound proxy of the SIP server.
|
|
*
|
|
* @param outboundProxy the network address of the outbound proxy
|
|
* @return this builder object
|
|
*/
|
|
public Builder setOutboundProxy(String outboundProxy) {
|
|
mProxyAddress = outboundProxy;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the display name of the user.
|
|
*
|
|
* @param displayName display name of the user
|
|
* @return this builder object
|
|
*/
|
|
public Builder setDisplayName(String displayName) {
|
|
mDisplayName = displayName;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the send keep-alive flag.
|
|
*
|
|
* @param flag true if sending keep-alive message is required,
|
|
* false otherwise
|
|
* @return this builder object
|
|
*/
|
|
public Builder setSendKeepAlive(boolean flag) {
|
|
mProfile.mSendKeepAlive = flag;
|
|
return this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Sets the auto. registration flag.
|
|
*
|
|
* @param flag true if the profile will be registered automatically,
|
|
* false otherwise
|
|
* @return this builder object
|
|
*/
|
|
public Builder setAutoRegistration(boolean flag) {
|
|
mProfile.mAutoRegistration = flag;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Builds and returns the SIP profile object.
|
|
*
|
|
* @return the profile object created
|
|
*/
|
|
public SipProfile build() {
|
|
// remove password from URI
|
|
mProfile.mPassword = mUri.getUserPassword();
|
|
mUri.setUserPassword(null);
|
|
try {
|
|
if (!TextUtils.isEmpty(mProxyAddress)) {
|
|
SipURI uri = (SipURI)
|
|
mAddressFactory.createURI(fix(mProxyAddress));
|
|
mProfile.mProxyAddress = uri.getHost();
|
|
} else {
|
|
if (!mProfile.mProtocol.equals(UDP)) {
|
|
mUri.setTransportParam(mProfile.mProtocol);
|
|
}
|
|
if (mProfile.mPort != DEFAULT_PORT) {
|
|
mUri.setPort(mProfile.mPort);
|
|
}
|
|
}
|
|
mProfile.mAddress = mAddressFactory.createAddress(
|
|
mDisplayName, mUri);
|
|
} catch (InvalidArgumentException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (ParseException e) {
|
|
// must not occur
|
|
throw new RuntimeException(e);
|
|
}
|
|
return mProfile;
|
|
}
|
|
}
|
|
|
|
private SipProfile() {
|
|
}
|
|
|
|
private SipProfile(Parcel in) {
|
|
mAddress = (Address) in.readSerializable();
|
|
mProxyAddress = in.readString();
|
|
mPassword = in.readString();
|
|
mDomain = in.readString();
|
|
mProtocol = in.readString();
|
|
mProfileName = in.readString();
|
|
mSendKeepAlive = (in.readInt() == 0) ? false : true;
|
|
mAutoRegistration = (in.readInt() == 0) ? false : true;
|
|
mCallingUid = in.readInt();
|
|
mPort = in.readInt();
|
|
mAuthUserName = in.readString();
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(Parcel out, int flags) {
|
|
out.writeSerializable(mAddress);
|
|
out.writeString(mProxyAddress);
|
|
out.writeString(mPassword);
|
|
out.writeString(mDomain);
|
|
out.writeString(mProtocol);
|
|
out.writeString(mProfileName);
|
|
out.writeInt(mSendKeepAlive ? 1 : 0);
|
|
out.writeInt(mAutoRegistration ? 1 : 0);
|
|
out.writeInt(mCallingUid);
|
|
out.writeInt(mPort);
|
|
out.writeString(mAuthUserName);
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Gets the SIP URI of this profile.
|
|
*
|
|
* @return the SIP URI of this profile
|
|
* @hide
|
|
*/
|
|
public SipURI getUri() {
|
|
return (SipURI) mAddress.getURI();
|
|
}
|
|
|
|
/**
|
|
* Gets the SIP URI string of this profile.
|
|
*
|
|
* @return the SIP URI string of this profile
|
|
*/
|
|
public String getUriString() {
|
|
// We need to return the sip uri domain instead of
|
|
// the SIP URI with transport, port information if
|
|
// the outbound proxy address exists.
|
|
if (!TextUtils.isEmpty(mProxyAddress)) {
|
|
return "sip:" + getUserName() + "@" + mDomain;
|
|
}
|
|
return getUri().toString();
|
|
}
|
|
|
|
/**
|
|
* Gets the SIP address of this profile.
|
|
*
|
|
* @return the SIP address of this profile
|
|
* @hide
|
|
*/
|
|
public Address getSipAddress() {
|
|
return mAddress;
|
|
}
|
|
|
|
/**
|
|
* Gets the display name of the user.
|
|
*
|
|
* @return the display name of the user
|
|
*/
|
|
public String getDisplayName() {
|
|
return mAddress.getDisplayName();
|
|
}
|
|
|
|
/**
|
|
* Gets the username.
|
|
*
|
|
* @return the username
|
|
*/
|
|
public String getUserName() {
|
|
return getUri().getUser();
|
|
}
|
|
|
|
/**
|
|
* Gets the username for authentication. If it is null, then the username
|
|
* should be used in authentication instead.
|
|
*
|
|
* @return the auth. username
|
|
* @hide // TODO: remove when we make it public
|
|
*/
|
|
public String getAuthUserName() {
|
|
return mAuthUserName;
|
|
}
|
|
|
|
/**
|
|
* Gets the password.
|
|
*
|
|
* @return the password
|
|
*/
|
|
public String getPassword() {
|
|
return mPassword;
|
|
}
|
|
|
|
/**
|
|
* Gets the SIP domain.
|
|
*
|
|
* @return the SIP domain
|
|
*/
|
|
public String getSipDomain() {
|
|
return mDomain;
|
|
}
|
|
|
|
/**
|
|
* Gets the port number of the SIP server.
|
|
*
|
|
* @return the port number of the SIP server
|
|
*/
|
|
public int getPort() {
|
|
return mPort;
|
|
}
|
|
|
|
/**
|
|
* Gets the protocol used to connect to the server.
|
|
*
|
|
* @return the protocol
|
|
*/
|
|
public String getProtocol() {
|
|
return mProtocol;
|
|
}
|
|
|
|
/**
|
|
* Gets the network address of the server outbound proxy.
|
|
*
|
|
* @return the network address of the server outbound proxy
|
|
*/
|
|
public String getProxyAddress() {
|
|
return mProxyAddress;
|
|
}
|
|
|
|
/**
|
|
* Gets the (user-defined) name of the profile.
|
|
*
|
|
* @return name of the profile
|
|
*/
|
|
public String getProfileName() {
|
|
return mProfileName;
|
|
}
|
|
|
|
/**
|
|
* Gets the flag of 'Sending keep-alive'.
|
|
*
|
|
* @return the flag of sending SIP keep-alive messages.
|
|
*/
|
|
public boolean getSendKeepAlive() {
|
|
return mSendKeepAlive;
|
|
}
|
|
|
|
/**
|
|
* Gets the flag of 'Auto Registration'.
|
|
*
|
|
* @return the flag of registering the profile automatically.
|
|
*/
|
|
public boolean getAutoRegistration() {
|
|
return mAutoRegistration;
|
|
}
|
|
|
|
/**
|
|
* Sets the calling process's Uid in the sip service.
|
|
* @hide
|
|
*/
|
|
public void setCallingUid(int uid) {
|
|
mCallingUid = uid;
|
|
}
|
|
|
|
/**
|
|
* Gets the calling process's Uid in the sip settings.
|
|
* @hide
|
|
*/
|
|
public int getCallingUid() {
|
|
return mCallingUid;
|
|
}
|
|
|
|
private Object readResolve() throws ObjectStreamException {
|
|
// For compatibility.
|
|
if (mPort == 0) mPort = DEFAULT_PORT;
|
|
return this;
|
|
}
|
|
}
|