1 /* 2 * Copyright (C) 2010 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.net.rtp; 18 19 import java.net.InetAddress; 20 import java.net.Inet4Address; 21 import java.net.Inet6Address; 22 import java.net.SocketException; 23 24 /** 25 * RtpStream represents the base class of streams which send and receive network 26 * packets with media payloads over Real-time Transport Protocol (RTP). 27 * @hide 28 */ 29 public class RtpStream { 30 /** 31 * This mode indicates that the stream sends and receives packets at the 32 * same time. This is the initial mode for new streams. 33 */ 34 public static final int MODE_NORMAL = 0; 35 36 /** 37 * This mode indicates that the stream only sends packets. 38 */ 39 public static final int MODE_SEND_ONLY = 1; 40 41 /** 42 * This mode indicates that the stream only receives packets. 43 */ 44 public static final int MODE_RECEIVE_ONLY = 2; 45 46 private final InetAddress mLocalAddress; 47 private final int mLocalPort; 48 49 private InetAddress mRemoteAddress; 50 private int mRemotePort = -1; 51 private int mMode = MODE_NORMAL; 52 53 private int mNative; 54 static { 55 System.loadLibrary("rtp_jni"); 56 } 57 58 /** 59 * Creates a RtpStream on the given local address. Note that the local 60 * port is assigned automatically to conform with RFC 3550. 61 * 62 * @param address The network address of the local host to bind to. 63 * @throws SocketException if the address cannot be bound or a problem 64 * occurs during binding. 65 */ 66 RtpStream(InetAddress address) throws SocketException { 67 mLocalPort = create(address.getHostAddress()); 68 mLocalAddress = address; 69 } 70 71 private native int create(String address) throws SocketException; 72 73 /** 74 * Returns the network address of the local host. 75 */ 76 public InetAddress getLocalAddress() { 77 return mLocalAddress; 78 } 79 80 /** 81 * Returns the network port of the local host. 82 */ 83 public int getLocalPort() { 84 return mLocalPort; 85 } 86 87 /** 88 * Returns the network address of the remote host or {@code null} if the 89 * stream is not associated. 90 */ 91 public InetAddress getRemoteAddress() { 92 return mRemoteAddress; 93 } 94 95 /** 96 * Returns the network port of the remote host or {@code -1} if the stream 97 * is not associated. 98 */ 99 public int getRemotePort() { 100 return mRemotePort; 101 } 102 103 /** 104 * Returns {@code true} if the stream is busy. In this case most of the 105 * setter methods are disabled. This method is intended to be overridden 106 * by subclasses. 107 */ 108 public boolean isBusy() { 109 return false; 110 } 111 112 /** 113 * Returns the current mode. 114 */ 115 public int getMode() { 116 return mMode; 117 } 118 119 /** 120 * Changes the current mode. It must be one of {@link #MODE_NORMAL}, 121 * {@link #MODE_SEND_ONLY}, and {@link #MODE_RECEIVE_ONLY}. 122 * 123 * @param mode The mode to change to. 124 * @throws IllegalArgumentException if the mode is invalid. 125 * @throws IllegalStateException if the stream is busy. 126 * @see #isBusy() 127 */ 128 public void setMode(int mode) { 129 if (isBusy()) { 130 throw new IllegalStateException("Busy"); 131 } 132 if (mode != MODE_NORMAL && mode != MODE_SEND_ONLY && mode != MODE_RECEIVE_ONLY) { 133 throw new IllegalArgumentException("Invalid mode"); 134 } 135 mMode = mode; 136 } 137 138 /** 139 * Associates with a remote host. This defines the destination of the 140 * outgoing packets. 141 * 142 * @param address The network address of the remote host. 143 * @param port The network port of the remote host. 144 * @throws IllegalArgumentException if the address is not supported or the 145 * port is invalid. 146 * @throws IllegalStateException if the stream is busy. 147 * @see #isBusy() 148 */ 149 public void associate(InetAddress address, int port) { 150 if (isBusy()) { 151 throw new IllegalStateException("Busy"); 152 } 153 if (!(address instanceof Inet4Address && mLocalAddress instanceof Inet4Address) && 154 !(address instanceof Inet6Address && mLocalAddress instanceof Inet6Address)) { 155 throw new IllegalArgumentException("Unsupported address"); 156 } 157 if (port < 0 || port > 65535) { 158 throw new IllegalArgumentException("Invalid port"); 159 } 160 mRemoteAddress = address; 161 mRemotePort = port; 162 } 163 164 synchronized native int dup(); 165 166 /** 167 * Releases allocated resources. The stream becomes inoperable after calling 168 * this method. 169 * 170 * @throws IllegalStateException if the stream is busy. 171 * @see #isBusy() 172 */ 173 public void release() { 174 if (isBusy()) { 175 throw new IllegalStateException("Busy"); 176 } 177 close(); 178 } 179 180 private synchronized native void close(); 181 182 @Override 183 protected void finalize() throws Throwable { 184 close(); 185 super.finalize(); 186 } 187 } 188