Home | History | Annotate | Download | only in rtp
      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      */
     70     RtpStream(InetAddress address) throws SocketException {
     71         mLocalPort = create(address.getHostAddress());
     72         mLocalAddress = address;
     73     }
     74 
     75     private native int create(String address) throws SocketException;
     76 
     77     /**
     78      * Returns the network address of the local host.
     79      */
     80     public InetAddress getLocalAddress() {
     81         return mLocalAddress;
     82     }
     83 
     84     /**
     85      * Returns the network port of the local host.
     86      */
     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      */
     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      */
    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      */
    112     public boolean isBusy() {
    113         return false;
    114     }
    115 
    116     /**
    117      * Returns the current mode.
    118      */
    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      */
    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      */
    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 
    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      */
    179     public void release() {
    180         synchronized (this) {
    181             if (isBusy()) {
    182                 throw new IllegalStateException("Busy");
    183             }
    184             close();
    185         }
    186     }
    187 
    188     private native void close();
    189 
    190     @Override
    191     protected void finalize() throws Throwable {
    192         close();
    193         super.finalize();
    194     }
    195 }
    196