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