2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package android.net.sip;
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 import android.text.TextUtils;
23 import java.io.ObjectStreamException;
24 import java.io.Serializable;
25 import java.text.ParseException;
26 import javax.sip.InvalidArgumentException;
27 import javax.sip.ListeningPoint;
28 import javax.sip.PeerUnavailableException;
29 import javax.sip.SipFactory;
30 import javax.sip.address.Address;
31 import javax.sip.address.AddressFactory;
32 import javax.sip.address.SipURI;
33 import javax.sip.address.URI;
36 * Defines a SIP profile, including a SIP account, domain and server information.
37 * <p>You can create a {@link SipProfile} using {@link
38 * SipProfile.Builder}. You can also retrieve one from a {@link SipSession}, using {@link
39 * SipSession#getLocalProfile} and {@link SipSession#getPeerProfile}.</p>
41 * <div class="special reference">
42 * <h3>Developer Guides</h3>
43 * <p>For more information about using SIP, read the
44 * <a href="{@docRoot}guide/topics/network/sip.html">Session Initiation Protocol</a>
45 * developer guide.</p>
48 public class SipProfile implements Parcelable, Serializable, Cloneable {
49 private static final long serialVersionUID = 1L;
50 private static final int DEFAULT_PORT = 5060;
51 private static final String TCP = "TCP";
52 private static final String UDP = "UDP";
53 private Address mAddress;
54 private String mProxyAddress;
55 private String mPassword;
56 private String mDomain;
57 private String mProtocol = UDP;
58 private String mProfileName;
59 private String mAuthUserName;
60 private int mPort = DEFAULT_PORT;
61 private boolean mSendKeepAlive = false;
62 private boolean mAutoRegistration = true;
63 private transient int mCallingUid = 0;
65 public static final Parcelable.Creator<SipProfile> CREATOR =
66 new Parcelable.Creator<SipProfile>() {
67 public SipProfile createFromParcel(Parcel in) {
68 return new SipProfile(in);
71 public SipProfile[] newArray(int size) {
72 return new SipProfile[size];
77 * Helper class for creating a {@link SipProfile}.
79 public static class Builder {
80 private AddressFactory mAddressFactory;
81 private SipProfile mProfile = new SipProfile();
83 private String mDisplayName;
84 private String mProxyAddress;
89 SipFactory.getInstance().createAddressFactory();
90 } catch (PeerUnavailableException e) {
91 throw new RuntimeException(e);
96 * Creates a builder based on the given profile.
98 public Builder(SipProfile profile) {
99 if (profile == null) throw new NullPointerException();
101 mProfile = (SipProfile) profile.clone();
102 } catch (CloneNotSupportedException e) {
103 throw new RuntimeException("should not occur", e);
105 mProfile.mAddress = null;
106 mUri = profile.getUri();
107 mUri.setUserPassword(profile.getPassword());
108 mDisplayName = profile.getDisplayName();
109 mProxyAddress = profile.getProxyAddress();
110 mProfile.mPort = profile.getPort();
116 * @param uriString the URI string as "sip:<user_name>@<domain>"
117 * @throws ParseException if the string is not a valid URI
119 public Builder(String uriString) throws ParseException {
120 if (uriString == null) {
121 throw new NullPointerException("uriString cannot be null");
123 URI uri = mAddressFactory.createURI(fix(uriString));
124 if (uri instanceof SipURI) {
127 throw new ParseException(uriString + " is not a SIP URI", 0);
129 mProfile.mDomain = mUri.getHost();
135 * @param username username of the SIP account
136 * @param serverDomain the SIP server domain; if the network address
137 * is different from the domain, use {@link #setOutboundProxy} to
139 * @throws ParseException if the parameters are not valid
141 public Builder(String username, String serverDomain)
142 throws ParseException {
143 if ((username == null) || (serverDomain == null)) {
144 throw new NullPointerException(
145 "username and serverDomain cannot be null");
147 mUri = mAddressFactory.createSipURI(username, serverDomain);
148 mProfile.mDomain = serverDomain;
151 private String fix(String uriString) {
152 return (uriString.trim().toLowerCase().startsWith("sip:")
154 : "sip:" + uriString);
158 * Sets the username used for authentication.
160 * @param name authentication username of the profile
161 * @return this builder object
163 public Builder setAuthUserName(String name) {
164 mProfile.mAuthUserName = name;
169 * Sets the name of the profile. This name is given by user.
171 * @param name name of the profile
172 * @return this builder object
174 public Builder setProfileName(String name) {
175 mProfile.mProfileName = name;
180 * Sets the password of the SIP account
182 * @param password password of the SIP account
183 * @return this builder object
185 public Builder setPassword(String password) {
186 mUri.setUserPassword(password);
191 * Sets the port number of the server. By default, it is 5060.
193 * @param port port number of the server
194 * @return this builder object
195 * @throws IllegalArgumentException if the port number is out of range
197 public Builder setPort(int port) throws IllegalArgumentException {
198 if ((port > 65535) || (port < 1000)) {
199 throw new IllegalArgumentException("incorrect port arugment: " + port);
201 mProfile.mPort = port;
206 * Sets the protocol used to connect to the SIP server. Currently,
207 * only "UDP" and "TCP" are supported.
209 * @param protocol the protocol string
210 * @return this builder object
211 * @throws IllegalArgumentException if the protocol is not recognized
213 public Builder setProtocol(String protocol)
214 throws IllegalArgumentException {
215 if (protocol == null) {
216 throw new NullPointerException("protocol cannot be null");
218 protocol = protocol.toUpperCase();
219 if (!protocol.equals(UDP) && !protocol.equals(TCP)) {
220 throw new IllegalArgumentException(
221 "unsupported protocol: " + protocol);
223 mProfile.mProtocol = protocol;
228 * Sets the outbound proxy of the SIP server.
230 * @param outboundProxy the network address of the outbound proxy
231 * @return this builder object
233 public Builder setOutboundProxy(String outboundProxy) {
234 mProxyAddress = outboundProxy;
239 * Sets the display name of the user.
241 * @param displayName display name of the user
242 * @return this builder object
244 public Builder setDisplayName(String displayName) {
245 mDisplayName = displayName;
250 * Sets the send keep-alive flag.
252 * @param flag true if sending keep-alive message is required,
254 * @return this builder object
256 public Builder setSendKeepAlive(boolean flag) {
257 mProfile.mSendKeepAlive = flag;
263 * Sets the auto. registration flag.
265 * @param flag true if the profile will be registered automatically,
267 * @return this builder object
269 public Builder setAutoRegistration(boolean flag) {
270 mProfile.mAutoRegistration = flag;
275 * Builds and returns the SIP profile object.
277 * @return the profile object created
279 public SipProfile build() {
280 // remove password from URI
281 mProfile.mPassword = mUri.getUserPassword();
282 mUri.setUserPassword(null);
284 if (!TextUtils.isEmpty(mProxyAddress)) {
285 SipURI uri = (SipURI)
286 mAddressFactory.createURI(fix(mProxyAddress));
287 mProfile.mProxyAddress = uri.getHost();
289 if (!mProfile.mProtocol.equals(UDP)) {
290 mUri.setTransportParam(mProfile.mProtocol);
292 if (mProfile.mPort != DEFAULT_PORT) {
293 mUri.setPort(mProfile.mPort);
296 mProfile.mAddress = mAddressFactory.createAddress(
298 } catch (InvalidArgumentException e) {
299 throw new RuntimeException(e);
300 } catch (ParseException e) {
302 throw new RuntimeException(e);
308 private SipProfile() {
311 private SipProfile(Parcel in) {
312 mAddress = (Address) in.readSerializable();
313 mProxyAddress = in.readString();
314 mPassword = in.readString();
315 mDomain = in.readString();
316 mProtocol = in.readString();
317 mProfileName = in.readString();
318 mSendKeepAlive = (in.readInt() == 0) ? false : true;
319 mAutoRegistration = (in.readInt() == 0) ? false : true;
320 mCallingUid = in.readInt();
321 mPort = in.readInt();
322 mAuthUserName = in.readString();
326 public void writeToParcel(Parcel out, int flags) {
327 out.writeSerializable(mAddress);
328 out.writeString(mProxyAddress);
329 out.writeString(mPassword);
330 out.writeString(mDomain);
331 out.writeString(mProtocol);
332 out.writeString(mProfileName);
333 out.writeInt(mSendKeepAlive ? 1 : 0);
334 out.writeInt(mAutoRegistration ? 1 : 0);
335 out.writeInt(mCallingUid);
337 out.writeString(mAuthUserName);
341 public int describeContents() {
346 * Gets the SIP URI of this profile.
348 * @return the SIP URI of this profile
351 public SipURI getUri() {
352 return (SipURI) mAddress.getURI();
356 * Gets the SIP URI string of this profile.
358 * @return the SIP URI string of this profile
360 public String getUriString() {
361 // We need to return the sip uri domain instead of
362 // the SIP URI with transport, port information if
363 // the outbound proxy address exists.
364 if (!TextUtils.isEmpty(mProxyAddress)) {
365 return "sip:" + getUserName() + "@" + mDomain;
367 return getUri().toString();
371 * Gets the SIP address of this profile.
373 * @return the SIP address of this profile
376 public Address getSipAddress() {
381 * Gets the display name of the user.
383 * @return the display name of the user
385 public String getDisplayName() {
386 return mAddress.getDisplayName();
392 * @return the username
394 public String getUserName() {
395 return getUri().getUser();
399 * Gets the username for authentication. If it is null, then the username
400 * is used in authentication instead.
402 * @return the authentication username
405 public String getAuthUserName() {
406 return mAuthUserName;
412 * @return the password
414 public String getPassword() {
419 * Gets the SIP domain.
421 * @return the SIP domain
423 public String getSipDomain() {
428 * Gets the port number of the SIP server.
430 * @return the port number of the SIP server
432 public int getPort() {
437 * Gets the protocol used to connect to the server.
439 * @return the protocol
441 public String getProtocol() {
446 * Gets the network address of the server outbound proxy.
448 * @return the network address of the server outbound proxy
450 public String getProxyAddress() {
451 return mProxyAddress;
455 * Gets the (user-defined) name of the profile.
457 * @return name of the profile
459 public String getProfileName() {
464 * Gets the flag of 'Sending keep-alive'.
466 * @return the flag of sending SIP keep-alive messages.
468 public boolean getSendKeepAlive() {
469 return mSendKeepAlive;
473 * Gets the flag of 'Auto Registration'.
475 * @return the flag of registering the profile automatically.
477 public boolean getAutoRegistration() {
478 return mAutoRegistration;
482 * Sets the calling process's Uid in the sip service.
485 public void setCallingUid(int uid) {
490 * Gets the calling process's Uid in the sip settings.
493 public int getCallingUid() {
497 private Object readResolve() throws ObjectStreamException {
498 // For compatibility.
499 if (mPort == 0) mPort = DEFAULT_PORT;