1 /** 2 * Copyright (C) 2023 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.imsmedia; 18 19 import android.os.Parcel; 20 import android.os.Parcelable; 21 22 import androidx.annotation.NonNull; 23 import androidx.annotation.Nullable; 24 25 import java.util.Objects; 26 27 /** 28 * Class to encapsulate RTP (Real-time Transport Protocol) parameters 29 * required for RTP context transfer to maintain RTP stream continuity 30 * 31 * @hide 32 */ 33 34 public final class RtpContextParams implements Parcelable { 35 /** Synchronization source (SSRC) identifier of RTP stream **/ 36 private final long mSsrc; 37 /** The timestamp reflects the sampling instant of the last RTP packet sent **/ 38 private final long mTimestamp; 39 /** The sequence number of last RTP packet sent **/ 40 private final int mSequenceNumber; 41 /** Maximum 32bit value **/ 42 private static final long MAX_VALUE_32BIT = 4294967295L; 43 /** Maximum 16bit value **/ 44 private static final int MAX_VALUE_16BIT = 65535; 45 46 /** @hide **/ RtpContextParams(Parcel in)47 public RtpContextParams(Parcel in) { 48 mSsrc = in.readLong(); 49 mTimestamp = in.readLong(); 50 mSequenceNumber = in.readInt(); 51 } 52 RtpContextParams(long ssrc, long timestamp, int sequenceNumber)53 private RtpContextParams(long ssrc, long timestamp, int sequenceNumber) { 54 this.mSsrc = ssrc; 55 this.mTimestamp = timestamp; 56 this.mSequenceNumber = sequenceNumber; 57 } 58 59 /** @hide **/ getSsrc()60 public long getSsrc() { 61 return mSsrc; 62 } 63 64 /** @hide **/ getTimestamp()65 public long getTimestamp() { 66 return mTimestamp; 67 } 68 69 /** @hide **/ getSequenceNumber()70 public int getSequenceNumber() { 71 return mSequenceNumber; 72 } 73 74 @NonNull 75 @Override toString()76 public String toString() { 77 return "RtpContextParams: {mSsrc=" + Long.toHexString(mSsrc) 78 + ", mTimestamp=" + Long.toHexString(mTimestamp) 79 + ", mSequenceNumber=" + Integer.toHexString(mSequenceNumber) 80 + " }"; 81 } 82 83 @Override hashCode()84 public int hashCode() { 85 return Objects.hash(mSsrc, mTimestamp, mSequenceNumber); 86 } 87 88 @Override equals(@ullable Object o)89 public boolean equals(@Nullable Object o) { 90 if (o == null || !(o instanceof RtpContextParams) || hashCode() != o.hashCode()) { 91 return false; 92 } 93 94 if (this == o) { 95 return true; 96 } 97 98 RtpContextParams s = (RtpContextParams) o; 99 100 return (mSsrc == s.mSsrc 101 && mTimestamp == s.mTimestamp 102 && mSequenceNumber == s.mSequenceNumber); 103 } 104 105 /** 106 * {@link Parcelable#describeContents} 107 */ describeContents()108 public int describeContents() { 109 return 0; 110 } 111 112 /** 113 * {@link Parcelable#writeToParcel} 114 */ writeToParcel(Parcel dest, int flags)115 public void writeToParcel(Parcel dest, int flags) { 116 dest.writeLong(mSsrc); 117 dest.writeLong(mTimestamp); 118 dest.writeInt(mSequenceNumber); 119 } 120 121 public static final @NonNull Parcelable.Creator<RtpContextParams> 122 CREATOR = new Parcelable.Creator() { 123 public RtpContextParams createFromParcel(Parcel in) { 124 // TODO use builder class so it will validate 125 return new RtpContextParams(in); 126 } 127 128 public RtpContextParams[] newArray(int size) { 129 return new RtpContextParams[size]; 130 } 131 }; 132 133 /** 134 * Provides a convenient way to set the fields of a {@link RtpContextParams} 135 * when creating a new instance. 136 */ 137 public static final class Builder { 138 private long mSsrc; 139 private long mTimestamp; 140 private int mSequenceNumber; 141 142 /** 143 * Default constructor for Builder. 144 */ Builder()145 public Builder() { 146 } 147 148 /** 149 * Set the Synchronization source (SSRC) identifier of RTP stream 150 * Throws IllegalArgumentException if SSRC is set greater than maximum 32bit value 151 * 152 * @param ssrc ssrc of RTP stream 153 * @return The same instance of the builder. 154 */ setSsrc(final long ssrc)155 public @NonNull Builder setSsrc(final long ssrc) { 156 if (Long.compareUnsigned(ssrc, MAX_VALUE_32BIT) > 0) { 157 throw new IllegalArgumentException("Invalid ssrc value: " + ssrc); 158 } else { 159 this.mSsrc = ssrc; 160 } 161 return this; 162 } 163 164 /** 165 * Set the timestamp 166 * Throws IllegalArgumentException if timestamp is set greater than maximum 32bit value 167 * 168 * @param timestamp The timestamp of last RTP packet sent 169 * @return The same instance of the builder. 170 */ setTimestamp(final long timestamp)171 public @NonNull Builder setTimestamp(final long timestamp) { 172 if (Long.compareUnsigned(timestamp, MAX_VALUE_32BIT) > 0) { 173 throw new IllegalArgumentException("Invalid timestamp value: " + timestamp); 174 } else { 175 this.mTimestamp = timestamp; 176 } 177 return this; 178 } 179 180 /** 181 * Set the Sequence Number 182 * Throws IllegalArgumentException if sequenceNumber is set greater than maximum 16bit value 183 * 184 * @param sequenceNumber The sequence number of last RTP packet sent 185 * @return The same instance of the builder. 186 */ setSequenceNumber(final int sequenceNumber)187 public @NonNull Builder setSequenceNumber(final int sequenceNumber) { 188 if (Integer.compareUnsigned(sequenceNumber, MAX_VALUE_16BIT) > 0) { 189 throw new IllegalArgumentException( 190 "Invalid sequenceNumber value: " + sequenceNumber); 191 } else { 192 this.mSequenceNumber = sequenceNumber; 193 } 194 return this; 195 } 196 197 /** 198 * Build the RtpContextParams. 199 * 200 * @return the RtpContextParams object. 201 */ build()202 public @NonNull RtpContextParams build() { 203 // TODO validation 204 return new RtpContextParams(mSsrc, mTimestamp, mSequenceNumber); 205 } 206 } 207 } 208