1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 package android.telephony.ims; 18 19 import android.annotation.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SystemApi; 24 import android.net.InetAddresses; 25 import android.net.Uri; 26 import android.os.Parcel; 27 import android.os.Parcelable; 28 import android.telephony.ims.stub.SipDelegate; 29 import android.util.Log; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 import java.net.InetAddress; 34 import java.net.InetSocketAddress; 35 import java.net.UnknownHostException; 36 import java.util.Objects; 37 38 /** 39 * The IMS registration and other attributes that the {@link SipDelegateConnection} used by the 40 * IMS application will need to be aware of to correctly generate outgoing {@link SipMessage}s. 41 * <p> 42 * The IMS service must generate new instances of this configuration as the IMS configuration 43 * managed by the IMS service changes. Along with each {@link SipDelegateConfiguration} instance 44 * containing the configuration is the "version", which should be incremented every time a new 45 * {@link SipDelegateConfiguration} instance is created. The {@link SipDelegateConnection} will 46 * include the version of the {@link SipDelegateConfiguration} instance that it used in order for 47 * the {@link SipDelegate} to easily identify if the IMS application used a now stale configuration 48 * to generate the {@link SipMessage} and return 49 * {@link SipDelegateManager#MESSAGE_FAILURE_REASON_STALE_IMS_CONFIGURATION} in 50 * {@link DelegateMessageCallback#onMessageSendFailure(String, int)} so that the IMS application can 51 * regenerate that {@link SipMessage} using the correct {@link SipDelegateConfiguration} 52 * instance. 53 * <p> 54 * Every time the IMS configuration state changes in the IMS service, a full configuration should 55 * be generated. The new {@link SipDelegateConfiguration} instance should not be an incremental 56 * update. 57 * @see Builder 58 * @hide 59 */ 60 @SystemApi 61 public final class SipDelegateConfiguration implements Parcelable { 62 63 /** 64 * The SIP transport uses UDP. 65 */ 66 public static final int SIP_TRANSPORT_UDP = 0; 67 68 /** 69 * The SIP transport uses TCP. 70 */ 71 public static final int SIP_TRANSPORT_TCP = 1; 72 73 /**@hide*/ 74 @IntDef(prefix = "SIP_TRANSPORT_", value = { 75 SIP_TRANSPORT_UDP, 76 SIP_TRANSPORT_TCP 77 }) 78 @Retention(RetentionPolicy.SOURCE) 79 public @interface TransportType {} 80 81 /** 82 * The value returned by {@link #getMaxUdpPayloadSizeBytes()} when it is not defined. 83 */ 84 public static final int UDP_PAYLOAD_SIZE_UNDEFINED = -1; 85 86 /** 87 * SIP over IPSec configuration 88 */ 89 public static final class IpSecConfiguration { 90 private final int mLocalTxPort; 91 private final int mLocalRxPort; 92 private final int mLastLocalTxPort; 93 private final int mRemoteTxPort; 94 private final int mRemoteRxPort; 95 private final int mLastRemoteTxPort; 96 private final String mSecurityHeader; 97 98 /** 99 * Describes the SIP over IPSec configuration the SipDelegate will need to use. 100 * 101 * @param localTxPort Local SIP port number used to send traffic. 102 * @param localRxPort Local SIP port number used to receive traffic. 103 * @param lastLocalTxPort Local SIP port number used for the previous IPsec security 104 * association. 105 * @param remoteTxPort Remote port number used by the SIP server to send SIP traffic. 106 * @param remoteRxPort Remote port number used by the SIP server to receive incoming SIP 107 * traffic. 108 * @param lastRemoteTxPort Remote port number used by the SIP server to send SIP traffic on 109 * the previous IPSec security association. 110 * @param securityHeader The value of the SIP security verify header. 111 */ IpSecConfiguration(int localTxPort, int localRxPort, int lastLocalTxPort, int remoteTxPort, int remoteRxPort, int lastRemoteTxPort, @NonNull String securityHeader)112 public IpSecConfiguration(int localTxPort, int localRxPort, int lastLocalTxPort, 113 int remoteTxPort, int remoteRxPort, int lastRemoteTxPort, 114 @NonNull String securityHeader) { 115 mLocalTxPort = localTxPort; 116 mLocalRxPort = localRxPort; 117 mLastLocalTxPort = lastLocalTxPort; 118 mRemoteTxPort = remoteTxPort; 119 mRemoteRxPort = remoteRxPort; 120 mLastRemoteTxPort = lastRemoteTxPort; 121 mSecurityHeader = securityHeader; 122 } 123 124 /** 125 * @return The local SIP port number used to send traffic. 126 */ getLocalTxPort()127 public int getLocalTxPort() { 128 return mLocalTxPort; 129 } 130 131 /** 132 * @return The Local SIP port number used to receive traffic. 133 */ getLocalRxPort()134 public int getLocalRxPort() { 135 return mLocalRxPort; 136 } 137 138 /** 139 * @return The last local SIP port number used for the previous IPsec security association. 140 */ getLastLocalTxPort()141 public int getLastLocalTxPort() { 142 return mLastLocalTxPort; 143 } 144 145 /** 146 * @return The remote port number used by the SIP server to send SIP traffic. 147 */ getRemoteTxPort()148 public int getRemoteTxPort() { 149 return mRemoteTxPort; 150 } 151 152 /** 153 * @return the remote port number used by the SIP server to receive incoming SIP traffic. 154 */ getRemoteRxPort()155 public int getRemoteRxPort() { 156 return mRemoteRxPort; 157 } 158 159 /** 160 * @return the remote port number used by the SIP server to send SIP traffic on the previous 161 * IPSec security association. 162 */ getLastRemoteTxPort()163 public int getLastRemoteTxPort() { 164 return mLastRemoteTxPort; 165 } 166 167 /** 168 * @return The value of the SIP security verify header. 169 */ getSipSecurityVerifyHeader()170 public @NonNull String getSipSecurityVerifyHeader() { 171 return mSecurityHeader; 172 } 173 174 /** 175 * Helper for parcelling this object. 176 * @hide 177 */ addToParcel(Parcel dest)178 public void addToParcel(Parcel dest) { 179 dest.writeInt(mLocalTxPort); 180 dest.writeInt(mLocalRxPort); 181 dest.writeInt(mLastLocalTxPort); 182 dest.writeInt(mRemoteTxPort); 183 dest.writeInt(mRemoteRxPort); 184 dest.writeInt(mLastRemoteTxPort); 185 dest.writeString(mSecurityHeader); 186 } 187 188 /** 189 * Helper for unparcelling this object. 190 * @hide 191 */ fromParcel(Parcel source)192 public static IpSecConfiguration fromParcel(Parcel source) { 193 return new IpSecConfiguration(source.readInt(), source.readInt(), source.readInt(), 194 source.readInt(), source.readInt(), source.readInt(), source.readString()); 195 } 196 197 @Override toString()198 public String toString() { 199 return "IpSecConfiguration{" + "localTx=" + mLocalTxPort + ", localRx=" + mLocalRxPort 200 + ", lastLocalTx=" + mLastLocalTxPort + ", remoteTx=" + mRemoteTxPort 201 + ", remoteRx=" + mRemoteRxPort + ", lastRemoteTx=" + mLastRemoteTxPort 202 + ", securityHeader=" + mSecurityHeader + '}'; 203 } 204 205 @Override equals(Object o)206 public boolean equals(Object o) { 207 if (this == o) return true; 208 if (o == null || getClass() != o.getClass()) return false; 209 IpSecConfiguration that = (IpSecConfiguration) o; 210 return mLocalTxPort == that.mLocalTxPort 211 && mLocalRxPort == that.mLocalRxPort 212 && mLastLocalTxPort == that.mLastLocalTxPort 213 && mRemoteTxPort == that.mRemoteTxPort 214 && mRemoteRxPort == that.mRemoteRxPort 215 && mLastRemoteTxPort == that.mLastRemoteTxPort 216 && Objects.equals(mSecurityHeader, that.mSecurityHeader); 217 } 218 219 @Override hashCode()220 public int hashCode() { 221 return Objects.hash(mLocalTxPort, mLocalRxPort, mLastLocalTxPort, mRemoteTxPort, 222 mRemoteRxPort, mLastRemoteTxPort, mSecurityHeader); 223 } 224 } 225 226 /** 227 * Creates a new instance of {@link SipDelegateConfiguration} composed from optional 228 * configuration items. 229 */ 230 public static final class Builder { 231 private final SipDelegateConfiguration mConfig; 232 233 /** 234 * 235 * @param version The version associated with the {@link SipDelegateConfiguration} instance 236 * being built. See {@link #getVersion()} for more information. 237 * @param transportType The transport type to use for SIP signalling. 238 * @param localAddr The local socket address used for SIP traffic. 239 * @param serverAddr The SIP server or P-CSCF default IP address for sip traffic. 240 * @see InetAddresses#parseNumericAddress(String) for how to create an 241 * {@link InetAddress} without requiring a DNS lookup. 242 */ Builder(@ntRangefrom = 0) long version, @TransportType int transportType, @NonNull InetSocketAddress localAddr, @NonNull InetSocketAddress serverAddr)243 public Builder(@IntRange(from = 0) long version, @TransportType int transportType, 244 @NonNull InetSocketAddress localAddr, @NonNull InetSocketAddress serverAddr) { 245 mConfig = new SipDelegateConfiguration(version, transportType, localAddr, 246 serverAddr); 247 } 248 249 /** 250 * Create a new {@link SipDelegateConfiguration} instance with the same exact configuration 251 * as the passed in instance, except for the version parameter, which will be incremented 252 * by 1. 253 * <p> 254 * This method is useful for cases where only a small subset of configurations have changed 255 * and the new configuration is based off of the old configuration. 256 * @param c The older {@link SipDelegateConfiguration} instance to base this instance's 257 * configuration off of. 258 */ Builder(@onNull SipDelegateConfiguration c)259 public Builder(@NonNull SipDelegateConfiguration c) { 260 mConfig = c.copyAndIncrementVersion(); 261 } 262 263 /** 264 * Sets whether or not SIP compact form is enabled for the associated SIP delegate. 265 * <p> 266 * If unset, this configuration defaults to {@code false}. 267 * @param isEnabled {@code true} if SIP compact form is enabled for the associated SIP 268 * Delegate, {@code false} if it is not. 269 * @return this Builder instance with the compact form configuration set. 270 */ setSipCompactFormEnabled(boolean isEnabled)271 public @NonNull Builder setSipCompactFormEnabled(boolean isEnabled) { 272 mConfig.mIsSipCompactFormEnabled = isEnabled; 273 return this; 274 } 275 276 /** 277 * Sets whether or not underlying SIP keepalives are enabled for the associated SIP 278 * delegate. 279 * <p> 280 * If unset, this configuration defaults to {@code false}. 281 * @param isEnabled {@code true} if SIP keepalives are enabled for the associated SIP 282 * Delegate, {@code false} if it is not. 283 * @return this Builder instance with the new configuration set. 284 */ setSipKeepaliveEnabled(boolean isEnabled)285 public @NonNull Builder setSipKeepaliveEnabled(boolean isEnabled) { 286 mConfig.mIsSipKeepaliveEnabled = isEnabled; 287 return this; 288 } 289 290 /** 291 * Sets the max SIP payload size in bytes to be sent on UDP. If the SIP message payload is 292 * greater than the max UDP payload size, then TCP must be used. 293 * <p> 294 * If unset, this configuration defaults to {@link #UDP_PAYLOAD_SIZE_UNDEFINED}, or no 295 * size specified. 296 * @param size The maximum SIP payload size in bytes for UDP. 297 * @return this Builder instance with the new configuration set. 298 */ setMaxUdpPayloadSizeBytes(@ntRangefrom = 1) int size)299 public @NonNull Builder setMaxUdpPayloadSizeBytes(@IntRange(from = 1) int size) { 300 mConfig.mMaxUdpPayloadSize = size; 301 return this; 302 } 303 304 /** 305 * Sets the IMS public user identifier. 306 * <p> 307 * If unset, this configuration defaults to {@code null}, or no identifier specified. 308 * @param id The IMS public user identifier. 309 * @return this Builder instance with the new configuration set. 310 */ setPublicUserIdentifier(@ullable String id)311 public @NonNull Builder setPublicUserIdentifier(@Nullable String id) { 312 mConfig.mPublicUserIdentifier = id; 313 return this; 314 } 315 316 /** 317 * Sets the IMS private user identifier. 318 * <p> 319 * If unset, this configuration defaults to {@code null}, or no identifier specified. 320 * @param id The IMS private user identifier. 321 * @return this Builder instance with the new configuration set. 322 */ setPrivateUserIdentifier(@ullable String id)323 public @NonNull Builder setPrivateUserIdentifier(@Nullable String id) { 324 mConfig.mPrivateUserIdentifier = id; 325 return this; 326 } 327 328 /** 329 * Sets the IMS home domain. 330 * <p> 331 * If unset, this configuration defaults to {@code null}, or no domain specified. 332 * @param domain The IMS home domain. 333 * @return this Builder instance with the new configuration set. 334 */ setHomeDomain(@ullable String domain)335 public @NonNull Builder setHomeDomain(@Nullable String domain) { 336 mConfig.mHomeDomain = domain; 337 return this; 338 } 339 340 /** 341 * Sets the IMEI of the associated device. 342 * <p> 343 * Application can include the Instance-ID feature tag {@code "+sip.instance"} in the 344 * Contact header with a value of the device IMEI in the form 345 * {@code "urn:gsma:imei:<device IMEI>"}. 346 * <p> 347 * If unset, this configuration defaults to {@code null}, or no IMEI string specified. 348 * @param imei The IMEI of the device. 349 * @return this Builder instance with the new configuration set. 350 */ setImei(@ullable String imei)351 public @NonNull Builder setImei(@Nullable String imei) { 352 mConfig.mImei = imei; 353 return this; 354 } 355 356 /** 357 * Set the optional {@link IpSecConfiguration} instance used if the associated SipDelegate 358 * is communicating over IPSec. 359 * <p> 360 * If unset, this configuration defaults to {@code null} 361 * @param c The IpSecConfiguration instance to set. 362 * @return this Builder instance with IPSec configuration set. 363 */ setIpSecConfiguration(@ullable IpSecConfiguration c)364 public @NonNull Builder setIpSecConfiguration(@Nullable IpSecConfiguration c) { 365 mConfig.mIpSecConfiguration = c; 366 return this; 367 } 368 369 /** 370 * Describes the Device's Public IP Address and port that is set when Network Address 371 * Translation is enabled and the device is behind a NAT. 372 * <p> 373 * If unset, this configuration defaults to {@code null} 374 * @param addr The {@link InetAddress} representing the device's public IP address and port 375 * when behind a NAT. 376 * @return this Builder instance with the new configuration set. 377 * @see InetAddresses#parseNumericAddress(String) For an example of how to create an 378 * instance of {@link InetAddress} without causing a DNS lookup. 379 */ setNatSocketAddress(@ullable InetSocketAddress addr)380 public @NonNull Builder setNatSocketAddress(@Nullable InetSocketAddress addr) { 381 mConfig.mNatAddress = addr; 382 return this; 383 } 384 385 /** 386 * Sets the optional URI of the device's Globally routable user-agent URI (GRUU) if this 387 * feature is enabled for the SIP delegate. 388 * <p> 389 * If unset, this configuration defaults to {@code null} 390 * @param uri The GRUU to set. 391 * @return this builder instance with the new configuration set. 392 */ setPublicGruuUri(@ullable Uri uri)393 public @NonNull Builder setPublicGruuUri(@Nullable Uri uri) { 394 mConfig.mGruu = uri; 395 return this; 396 } 397 398 /** 399 * Sets the SIP authentication header value. 400 * <p> 401 * If unset, this configuration defaults to {@code null}. 402 * @param header The SIP authentication header's value. 403 * @return this builder instance with the new configuration set. 404 */ setSipAuthenticationHeader(@ullable String header)405 public @NonNull Builder setSipAuthenticationHeader(@Nullable String header) { 406 mConfig.mSipAuthHeader = header; 407 return this; 408 } 409 410 /** 411 * Sets the SIP authentication nonce. 412 * <p> 413 * If unset, this configuration defaults to {@code null}. 414 * @param nonce The SIP authentication nonce. 415 * @return this builder instance with the new configuration set. 416 */ setSipAuthenticationNonce(@ullable String nonce)417 public @NonNull Builder setSipAuthenticationNonce(@Nullable String nonce) { 418 mConfig.mSipAuthNonce = nonce; 419 return this; 420 } 421 422 /** 423 * Sets the SIP service route header value. 424 * <p> 425 * If unset, this configuration defaults to {@code null}. 426 * @param header The SIP service route header value. 427 * @return this builder instance with the new configuration set. 428 */ setSipServiceRouteHeader(@ullable String header)429 public @NonNull Builder setSipServiceRouteHeader(@Nullable String header) { 430 mConfig.mServiceRouteHeader = header; 431 return this; 432 } 433 434 /** 435 * Sets the SIP path header value. 436 * <p> 437 * If unset, this configuration defaults to {@code null}. 438 * @param header The SIP path header value. 439 * @return this builder instance with the new configuration set. 440 */ setSipPathHeader(@ullable String header)441 public @NonNull Builder setSipPathHeader(@Nullable String header) { 442 mConfig.mPathHeader = header; 443 return this; 444 } 445 446 /** 447 * Sets the SIP User-Agent header value. 448 * <p> 449 * If unset, this configuration defaults to {@code null}. 450 * @param header The SIP User-Agent header value. 451 * @return this builder instance with the new configuration set. 452 */ setSipUserAgentHeader(@ullable String header)453 public @NonNull Builder setSipUserAgentHeader(@Nullable String header) { 454 mConfig.mUserAgentHeader = header; 455 return this; 456 } 457 458 /** 459 * Sets the SIP Contact header's User parameter value. 460 * <p> 461 * If unset, this configuration defaults to {@code null}. 462 * @param param The SIP Contact header's User parameter value. 463 * @return this builder instance with the new configuration set. 464 */ setSipContactUserParameter(@ullable String param)465 public @NonNull Builder setSipContactUserParameter(@Nullable String param) { 466 mConfig.mContactUserParam = param; 467 return this; 468 } 469 470 /** 471 * Sets the SIP P-Access-Network-Info (P-ANI) header value. Populated for networks that 472 * require this information to be provided as part of outgoing SIP messages. 473 * <p> 474 * If unset, this configuration defaults to {@code null}. 475 * @param header The SIP P-ANI header value. 476 * @return this builder instance with the new configuration set. 477 */ setSipPaniHeader(@ullable String header)478 public @NonNull Builder setSipPaniHeader(@Nullable String header) { 479 mConfig.mPaniHeader = header; 480 return this; 481 } 482 483 /** 484 * Sets the SIP P-Last-Access-Network-Info (P-LANI) header value. Populated for 485 * networks that require this information to be provided as part of outgoing SIP messages. 486 * <p> 487 * If unset, this configuration defaults to {@code null}. 488 * @param header The SIP P-LANI header value. 489 * @return this builder instance with the new configuration set. 490 */ setSipPlaniHeader(@ullable String header)491 public @NonNull Builder setSipPlaniHeader(@Nullable String header) { 492 mConfig.mPlaniHeader = header; 493 return this; 494 } 495 496 /** 497 * Sets the SIP Cellular-Network-Info (CNI) header value (See 3GPP 24.229, section 7.2.15), 498 * populated for networks that require this information to be provided as part of outgoing 499 * SIP messages. 500 * <p> 501 * If unset, this configuration defaults to {@code null}. 502 * @param header The SIP P-LANI header value. 503 * @return this builder instance with the new configuration set. 504 */ setSipCniHeader(@ullable String header)505 public @NonNull Builder setSipCniHeader(@Nullable String header) { 506 mConfig.mCniHeader = header; 507 return this; 508 } 509 510 /** 511 * Sets the SIP P-associated-uri header value. 512 * <p> 513 * If unset, this configuration defaults to {@code null}. 514 * @param header The SIP P-associated-uri header value. 515 * @return this builder instance with the new configuration set. 516 */ setSipAssociatedUriHeader(@ullable String header)517 public @NonNull Builder setSipAssociatedUriHeader(@Nullable String header) { 518 mConfig.mAssociatedUriHeader = header; 519 return this; 520 } 521 522 /** 523 * @return A {@link SipDelegateConfiguration} instance with the optional configurations set. 524 */ build()525 public @NonNull SipDelegateConfiguration build() { 526 return mConfig; 527 } 528 } 529 530 private final long mVersion; 531 private final int mTransportType; 532 private final InetSocketAddress mLocalAddress; 533 private final InetSocketAddress mSipServerAddress; 534 private boolean mIsSipCompactFormEnabled = false; 535 private boolean mIsSipKeepaliveEnabled = false; 536 private int mMaxUdpPayloadSize = -1; 537 private String mPublicUserIdentifier = null; 538 private String mPrivateUserIdentifier = null; 539 private String mHomeDomain = null; 540 private String mImei = null; 541 private Uri mGruu = null; 542 private String mSipAuthHeader = null; 543 private String mSipAuthNonce = null; 544 private String mServiceRouteHeader = null; 545 private String mPathHeader = null; 546 private String mUserAgentHeader = null; 547 private String mContactUserParam = null; 548 private String mPaniHeader = null; 549 private String mPlaniHeader = null; 550 private String mCniHeader = null; 551 private String mAssociatedUriHeader = null; 552 private IpSecConfiguration mIpSecConfiguration = null; 553 private InetSocketAddress mNatAddress = null; 554 555 SipDelegateConfiguration(long version, int transportType, InetSocketAddress localAddress, InetSocketAddress sipServerAddress)556 private SipDelegateConfiguration(long version, int transportType, 557 InetSocketAddress localAddress, InetSocketAddress sipServerAddress) { 558 mVersion = version; 559 mTransportType = transportType; 560 mLocalAddress = localAddress; 561 mSipServerAddress = sipServerAddress; 562 } 563 SipDelegateConfiguration(Parcel source)564 private SipDelegateConfiguration(Parcel source) { 565 mVersion = source.readLong(); 566 mTransportType = source.readInt(); 567 mLocalAddress = readAddressFromParcel(source); 568 mSipServerAddress = readAddressFromParcel(source); 569 mIsSipCompactFormEnabled = source.readBoolean(); 570 mIsSipKeepaliveEnabled = source.readBoolean(); 571 mMaxUdpPayloadSize = source.readInt(); 572 mPublicUserIdentifier = source.readString(); 573 mPrivateUserIdentifier = source.readString(); 574 mHomeDomain = source.readString(); 575 mImei = source.readString(); 576 mGruu = source.readParcelable(null); 577 mSipAuthHeader = source.readString(); 578 mSipAuthNonce = source.readString(); 579 mServiceRouteHeader = source.readString(); 580 mPathHeader = source.readString(); 581 mUserAgentHeader = source.readString(); 582 mContactUserParam = source.readString(); 583 mPaniHeader = source.readString(); 584 mPlaniHeader = source.readString(); 585 mCniHeader = source.readString(); 586 mAssociatedUriHeader = source.readString(); 587 boolean isIpsecConfigAvailable = source.readBoolean(); 588 if (isIpsecConfigAvailable) { 589 mIpSecConfiguration = IpSecConfiguration.fromParcel(source); 590 } 591 boolean isNatConfigAvailable = source.readBoolean(); 592 if (isNatConfigAvailable) { 593 mNatAddress = readAddressFromParcel(source); 594 } 595 } 596 597 @Override writeToParcel(@onNull Parcel dest, int flags)598 public void writeToParcel(@NonNull Parcel dest, int flags) { 599 dest.writeLong(mVersion); 600 dest.writeInt(mTransportType); 601 writeAddressToParcel(mLocalAddress, dest); 602 writeAddressToParcel(mSipServerAddress, dest); 603 dest.writeBoolean(mIsSipCompactFormEnabled); 604 dest.writeBoolean(mIsSipKeepaliveEnabled); 605 dest.writeInt(mMaxUdpPayloadSize); 606 dest.writeString(mPublicUserIdentifier); 607 dest.writeString(mPrivateUserIdentifier); 608 dest.writeString(mHomeDomain); 609 dest.writeString(mImei); 610 dest.writeParcelable(mGruu, flags); 611 dest.writeString(mSipAuthHeader); 612 dest.writeString(mSipAuthNonce); 613 dest.writeString(mServiceRouteHeader); 614 dest.writeString(mPathHeader); 615 dest.writeString(mUserAgentHeader); 616 dest.writeString(mContactUserParam); 617 dest.writeString(mPaniHeader); 618 dest.writeString(mPlaniHeader); 619 dest.writeString(mCniHeader); 620 dest.writeString(mAssociatedUriHeader); 621 dest.writeBoolean(mIpSecConfiguration != null); 622 if (mIpSecConfiguration != null) { 623 mIpSecConfiguration.addToParcel(dest); 624 } 625 dest.writeBoolean(mNatAddress != null); 626 if (mNatAddress != null) { 627 writeAddressToParcel(mNatAddress, dest); 628 } 629 } 630 631 /** 632 * @return A copy of this instance with an incremented version. 633 * @hide 634 */ copyAndIncrementVersion()635 public SipDelegateConfiguration copyAndIncrementVersion() { 636 SipDelegateConfiguration c = new SipDelegateConfiguration(getVersion() + 1, mTransportType, 637 mLocalAddress, mSipServerAddress); 638 c.mIsSipCompactFormEnabled = mIsSipCompactFormEnabled; 639 c.mIsSipKeepaliveEnabled = mIsSipKeepaliveEnabled; 640 c.mMaxUdpPayloadSize = mMaxUdpPayloadSize; 641 c.mIpSecConfiguration = mIpSecConfiguration; 642 c.mNatAddress = mNatAddress; 643 c.mPublicUserIdentifier = mPublicUserIdentifier; 644 c.mPrivateUserIdentifier = mPrivateUserIdentifier; 645 c.mHomeDomain = mHomeDomain; 646 c.mImei = mImei; 647 c.mGruu = mGruu; 648 c.mSipAuthHeader = mSipAuthHeader; 649 c.mSipAuthNonce = mSipAuthNonce; 650 c.mServiceRouteHeader = mServiceRouteHeader; 651 c.mPathHeader = mPathHeader; 652 c.mUserAgentHeader = mUserAgentHeader; 653 c.mContactUserParam = mContactUserParam; 654 c.mPaniHeader = mPaniHeader; 655 c.mPlaniHeader = mPlaniHeader; 656 c.mCniHeader = mCniHeader; 657 c.mAssociatedUriHeader = mAssociatedUriHeader; 658 return c; 659 } 660 661 /** 662 * An integer representing the version number of this SipDelegateImsConfiguration. 663 * {@link SipMessage}s that are created using this configuration will also have a this 664 * version number associated with them, which will allow the IMS service to validate that the 665 * {@link SipMessage} was using the latest configuration during creation and not a stale 666 * configuration due to race conditions between the configuration being updated and the RCS 667 * application not receiving the updated configuration before generating a new message. 668 * <p> 669 * The version number should be a positive number that starts at 0 and increments sequentially 670 * as new {@link SipDelegateConfiguration} instances are created to update the IMS 671 * configuration state. 672 * 673 * @return the version number associated with this {@link SipDelegateConfiguration}. 674 */ getVersion()675 public @IntRange(from = 0) long getVersion() { 676 return mVersion; 677 } 678 679 /** 680 * @return The Transport type of the SIP delegate. 681 */ getTransportType()682 public @TransportType int getTransportType() { 683 return mTransportType; 684 } 685 686 /** 687 * @return The local IP address and port used for SIP traffic. 688 */ getLocalAddress()689 public @NonNull InetSocketAddress getLocalAddress() { 690 return mLocalAddress; 691 } 692 693 /** 694 * @return The default IP Address and port of the SIP server or P-CSCF used for SIP traffic. 695 */ getSipServerAddress()696 public @NonNull InetSocketAddress getSipServerAddress() { 697 return mSipServerAddress; 698 } 699 700 /** 701 * @return {@code true} if SIP compact form is enabled for the associated SIP Delegate, 702 * {@code false} if it is not. 703 */ isSipCompactFormEnabled()704 public boolean isSipCompactFormEnabled() { 705 return mIsSipCompactFormEnabled; 706 } 707 708 /** 709 * @return {@code true} if SIP keepalives are enabled for the associated SIP Delegate, 710 * {@code false} if it is not. 711 */ isSipKeepaliveEnabled()712 public boolean isSipKeepaliveEnabled() { 713 return mIsSipKeepaliveEnabled; 714 } 715 716 /** 717 * @return The maximum SIP payload size in bytes for UDP or {code -1} if no value was set. 718 */ getMaxUdpPayloadSizeBytes()719 public int getMaxUdpPayloadSizeBytes() { 720 return mMaxUdpPayloadSize; 721 } 722 723 /** 724 * @return The IMS public user identifier or {@code null} if it was not set. 725 */ getPublicUserIdentifier()726 public @Nullable String getPublicUserIdentifier() { 727 return mPublicUserIdentifier; 728 } 729 730 /** 731 * @return The IMS private user identifier or {@code null} if it was not set. 732 */ getPrivateUserIdentifier()733 public @Nullable String getPrivateUserIdentifier() { 734 return mPrivateUserIdentifier; 735 } 736 737 /** 738 * @return The IMS home domain or {@code null} if it was not set. 739 */ getHomeDomain()740 public @Nullable String getHomeDomain() { 741 return mHomeDomain; 742 } 743 744 /** 745 * get the IMEI of the associated device. 746 * <p> 747 * Application can include the Instance-ID feature tag {@code "+sip.instance"} in the Contact 748 * header with a value of the device IMEI in the form {@code "urn:gsma:imei:<device IMEI>"}. 749 * @return The IMEI of the device or {@code null} if it was not set. 750 */ getImei()751 public @Nullable String getImei() { 752 return mImei; 753 } 754 755 /** 756 * @return The IPSec configuration that must be used because SIP is communicating over IPSec. 757 * This returns {@code null} SIP is not communicating over IPSec. 758 */ getIpSecConfiguration()759 public @Nullable IpSecConfiguration getIpSecConfiguration() { 760 return mIpSecConfiguration; 761 } 762 763 /** 764 * @return The public IP address and port of the device due to it being behind a NAT. 765 * This returns {@code null} if the device is not behind a NAT. 766 */ getNatSocketAddress()767 public @Nullable InetSocketAddress getNatSocketAddress() { 768 return mNatAddress; 769 } 770 771 /** 772 * @return The device's Globally routable user-agent URI (GRUU) or {@code null} if this feature 773 * is not enabled for the SIP delegate. 774 */ getPublicGruuUri()775 public @Nullable Uri getPublicGruuUri() { 776 return mGruu; 777 } 778 779 /** 780 * @return The value of the SIP authentication header or {@code null} if there is none set. 781 */ getSipAuthenticationHeader()782 public @Nullable String getSipAuthenticationHeader() { 783 return mSipAuthHeader; 784 } 785 786 /** 787 * @return The value of the SIP authentication nonce or {@code null} if there is none set. 788 */ getSipAuthenticationNonce()789 public @Nullable String getSipAuthenticationNonce() { 790 return mSipAuthNonce; 791 } 792 793 /** 794 * @return The value of the SIP service route header or {@code null} if there is none set. 795 */ getSipServiceRouteHeader()796 public @Nullable String getSipServiceRouteHeader() { 797 return mServiceRouteHeader; 798 } 799 800 /** 801 * @return The value of the SIP path header or {@code null} if there is none set. 802 */ getSipPathHeader()803 public @Nullable String getSipPathHeader() { 804 return mPathHeader; 805 } 806 807 /** 808 * @return The value of the SIP User-Agent header or {@code null} if there is none set. 809 */ getSipUserAgentHeader()810 public @Nullable String getSipUserAgentHeader() { 811 return mUserAgentHeader; 812 } 813 /** 814 * @return The value of the SIP Contact header's User parameter or {@code null} if there is 815 * none set. 816 */ getSipContactUserParameter()817 public @Nullable String getSipContactUserParameter() { 818 return mContactUserParam; 819 } 820 821 /** 822 * @return The value of the SIP P-Access-Network-Info (P-ANI) header or {@code null} if there is 823 * none set. 824 */ getSipPaniHeader()825 public @Nullable String getSipPaniHeader() { 826 return mPaniHeader; 827 } 828 /** 829 * @return The value of the SIP P-Last-Access-Network-Info (P-LANI) header or {@code null} if 830 * there is none set. 831 */ getSipPlaniHeader()832 public @Nullable String getSipPlaniHeader() { 833 return mPlaniHeader; 834 } 835 836 /** 837 * @return The value of the SIP Cellular-Network-Info (CNI) header or {@code null} if there is 838 * none set. 839 */ getSipCniHeader()840 public @Nullable String getSipCniHeader() { 841 return mCniHeader; 842 } 843 844 /** 845 * @return The value of the SIP P-associated-uri header or {@code null} if there is none set. 846 */ getSipAssociatedUriHeader()847 public @Nullable String getSipAssociatedUriHeader() { 848 return mAssociatedUriHeader; 849 } 850 writeAddressToParcel(InetSocketAddress addr, Parcel dest)851 private void writeAddressToParcel(InetSocketAddress addr, Parcel dest) { 852 dest.writeByteArray(addr.getAddress().getAddress()); 853 dest.writeInt(addr.getPort()); 854 } 855 readAddressFromParcel(Parcel source)856 private InetSocketAddress readAddressFromParcel(Parcel source) { 857 final byte[] addressBytes = source.createByteArray(); 858 final int port = source.readInt(); 859 try { 860 return new InetSocketAddress(InetAddress.getByAddress(addressBytes), port); 861 } catch (UnknownHostException e) { 862 // Should not happen, as length of array was verified before parcelling. 863 Log.e("SipDelegateConfiguration", "exception reading address, returning null"); 864 return null; 865 } 866 } 867 868 @Override describeContents()869 public int describeContents() { 870 return 0; 871 } 872 873 public static final @NonNull Creator<SipDelegateConfiguration> CREATOR = 874 new Creator<SipDelegateConfiguration>() { 875 @Override 876 public SipDelegateConfiguration createFromParcel(Parcel source) { 877 return new SipDelegateConfiguration(source); 878 } 879 880 @Override 881 public SipDelegateConfiguration[] newArray(int size) { 882 return new SipDelegateConfiguration[size]; 883 } 884 }; 885 886 @Override equals(Object o)887 public boolean equals(Object o) { 888 if (this == o) return true; 889 if (o == null || getClass() != o.getClass()) return false; 890 SipDelegateConfiguration that = (SipDelegateConfiguration) o; 891 return mVersion == that.mVersion 892 && mTransportType == that.mTransportType 893 && mIsSipCompactFormEnabled == that.mIsSipCompactFormEnabled 894 && mIsSipKeepaliveEnabled == that.mIsSipKeepaliveEnabled 895 && mMaxUdpPayloadSize == that.mMaxUdpPayloadSize 896 && Objects.equals(mLocalAddress, that.mLocalAddress) 897 && Objects.equals(mSipServerAddress, that.mSipServerAddress) 898 && Objects.equals(mPublicUserIdentifier, that.mPublicUserIdentifier) 899 && Objects.equals(mPrivateUserIdentifier, that.mPrivateUserIdentifier) 900 && Objects.equals(mHomeDomain, that.mHomeDomain) 901 && Objects.equals(mImei, that.mImei) 902 && Objects.equals(mGruu, that.mGruu) 903 && Objects.equals(mSipAuthHeader, that.mSipAuthHeader) 904 && Objects.equals(mSipAuthNonce, that.mSipAuthNonce) 905 && Objects.equals(mServiceRouteHeader, that.mServiceRouteHeader) 906 && Objects.equals(mPathHeader, that.mPathHeader) 907 && Objects.equals(mUserAgentHeader, that.mUserAgentHeader) 908 && Objects.equals(mContactUserParam, that.mContactUserParam) 909 && Objects.equals(mPaniHeader, that.mPaniHeader) 910 && Objects.equals(mPlaniHeader, that.mPlaniHeader) 911 && Objects.equals(mCniHeader, that.mCniHeader) 912 && Objects.equals(mAssociatedUriHeader, that.mAssociatedUriHeader) 913 && Objects.equals(mIpSecConfiguration, that.mIpSecConfiguration) 914 && Objects.equals(mNatAddress, that.mNatAddress); 915 } 916 917 @Override hashCode()918 public int hashCode() { 919 return Objects.hash(mVersion, mTransportType, mLocalAddress, mSipServerAddress, 920 mIsSipCompactFormEnabled, mIsSipKeepaliveEnabled, mMaxUdpPayloadSize, 921 mPublicUserIdentifier, mPrivateUserIdentifier, mHomeDomain, mImei, mGruu, 922 mSipAuthHeader, mSipAuthNonce, mServiceRouteHeader, mPathHeader, mUserAgentHeader, 923 mContactUserParam, mPaniHeader, mPlaniHeader, mCniHeader, mAssociatedUriHeader, 924 mIpSecConfiguration, mNatAddress); 925 } 926 927 @Override toString()928 public String toString() { 929 return "SipDelegateConfiguration{ mVersion=" + mVersion + ", mTransportType=" 930 + mTransportType + '}'; 931 } 932 } 933