summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-chi Yeh <chiachi@android.com>2010-07-07 15:17:11 +0800
committerChia-chi Yeh <chiachi@android.com>2010-07-07 15:17:11 +0800
commitb02696ab928fbd6ea3a6d6caba34b66541f80afc (patch)
tree431981cb434d03c0aec45fb1fae50ed3dee80b79
parent7be5d9aa7d13c5b8386a011b8d20e6e3ed8dbe56 (diff)
downloadnist-sip-b02696ab928fbd6ea3a6d6caba34b66541f80afc.tar.gz
RTP: refactor out the network part from AudioStream to RtpStream.
Change-Id: Ie0922a46be3202f2a19fb3b90fd01562ea2514b3
-rw-r--r--src/android/net/rtp/AudioStream.java135
-rw-r--r--src/android/net/rtp/RtpStream.java172
2 files changed, 307 insertions, 0 deletions
diff --git a/src/android/net/rtp/AudioStream.java b/src/android/net/rtp/AudioStream.java
new file mode 100644
index 0000000..c1da7ba
--- /dev/null
+++ b/src/android/net/rtp/AudioStream.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.rtp;
+
+import java.net.InetAddress;
+import java.net.SocketException;
+
+/**
+ * AudioStream represents a RTP stream carrying audio payloads.
+ */
+public class AudioStream extends RtpStream {
+ private AudioCodec mCodec;
+ private int mCodecType = -1;
+ private int mDtmfType = -1;
+ private AudioGroup mGroup;
+
+ /**
+ * Creates an AudioStream on the given local address. Note that the local
+ * port is assigned automatically to conform with RFC 3550.
+ *
+ * @param address The network address of the local host to bind to.
+ * @throws SocketException if the address cannot be bound or a problem
+ * occurs during binding.
+ */
+ public AudioStream(InetAddress address) throws SocketException {
+ super(address);
+ }
+
+ /**
+ * Returns {@code true} if the stream already joined an {@link AudioGroup}.
+ */
+ @Override
+ public final boolean isBusy() {
+ return mGroup != null;
+ }
+
+ /**
+ * Returns the joined {@link AudioGroup}.
+ */
+ public AudioGroup getAudioGroup() {
+ return mGroup;
+ }
+
+ /**
+ * Joins an {@link AudioGroup}. Each stream can join only one group at a
+ * time. The group can be changed by passing a different one or removed
+ * by calling this method with {@code null}.
+ *
+ * @param group The AudioGroup to join or {@code null} to leave.
+ * @throws IllegalStateException if the stream is not properly configured.
+ * @see AudioGroup
+ */
+ public void join(AudioGroup group) {
+ if (mGroup == group) {
+ return;
+ }
+ if (mGroup != null) {
+ mGroup.remove(this);
+ mGroup = null;
+ }
+ if (group != null) {
+ group.add(this, mCodec, mCodecType, mDtmfType);
+ mGroup = group;
+ }
+ }
+
+ /**
+ * Sets the {@link AudioCodec} and its RTP payload type. According to RFC
+ * 3551, the type must be in the range of 0 and 127, where 96 and above are
+ * dynamic types. For codecs with static mappings (non-negative
+ * {@link AudioCodec#defaultType}), assigning a different non-dynamic type
+ * is disallowed.
+ *
+ * @param codec The AudioCodec to be used.
+ * @param type The RTP payload type.
+ * @throws IllegalArgumentException if the type is invalid or used by DTMF.
+ * @throws IllegalStateException if the stream is busy.
+ */
+ public void setCodec(AudioCodec codec, int type) {
+ if (isBusy()) {
+ throw new IllegalStateException("Busy");
+ }
+ if (type < 0 || type > 127 || (type != codec.defaultType && type < 96)) {
+ throw new IllegalArgumentException("Invalid type");
+ }
+ if (type == mDtmfType) {
+ throw new IllegalArgumentException("The type is used by DTMF");
+ }
+ mCodec = codec;
+ mCodecType = type;
+ }
+
+ /**
+ * Sets the RTP payload type for dual-tone multi-frequency (DTMF) digits.
+ * The primary usage is to send digits to the remote gateway to perform
+ * certain tasks, such as second-stage dialing. According to RFC 2833, the
+ * RTP payload type for DTMF is assigned dynamically, so it must be in the
+ * range of 96 and 127. One can use {@code -1} to disable DTMF and free up
+ * the previous assigned value. This method cannot be called when the stream
+ * already joined an {@link AudioGroup}.
+ *
+ * @param type The RTP payload type to be used or {@code -1} to disable it.
+ * @throws IllegalArgumentException if the type is invalid or used by codec.
+ * @throws IllegalStateException if the stream is busy.
+ * @see AudioGroup#sendDtmf(int)
+ */
+ public void setDtmfType(int type) {
+ if (isBusy()) {
+ throw new IllegalStateException("Busy");
+ }
+ if (type != -1) {
+ if (type < 96 || type > 127) {
+ throw new IllegalArgumentException("Invalid type");
+ }
+ if (type == mCodecType) {
+ throw new IllegalArgumentException("The type is used by codec");
+ }
+ }
+ mDtmfType = type;
+ }
+}
diff --git a/src/android/net/rtp/RtpStream.java b/src/android/net/rtp/RtpStream.java
new file mode 100644
index 0000000..b542ca7
--- /dev/null
+++ b/src/android/net/rtp/RtpStream.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.rtp;
+
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.SocketException;
+
+/**
+ * RtpStream represents a base class of media streams running over
+ * Real-time Transport Protocol (RTP).
+ */
+public class RtpStream {
+ public static final int MODE_NORMAL = 0;
+ public static final int MODE_SEND_ONLY = 1;
+ public static final int MODE_RECEIVE_ONLY = 2;
+
+ private final InetAddress mLocalAddress;
+ private final int mLocalPort;
+
+ private InetAddress mRemoteAddress;
+ private int mRemotePort = -1;
+ private int mMode = MODE_NORMAL;
+
+ private int mNative;
+ static {
+ System.loadLibrary("rtp_jni");
+ }
+
+ /**
+ * Creates a RtpStream on the given local address. Note that the local
+ * port is assigned automatically to conform with RFC 3550.
+ *
+ * @param address The network address of the local host to bind to.
+ * @throws SocketException if the address cannot be bound or a problem
+ * occurs during binding.
+ */
+ RtpStream(InetAddress address) throws SocketException {
+ mLocalPort = create(address.getHostAddress());
+ mLocalAddress = address;
+ }
+
+ private native int create(String address) throws SocketException;
+
+ /**
+ * Returns the network address of the local host.
+ */
+ public InetAddress getLocalAddress() {
+ return mLocalAddress;
+ }
+
+ /**
+ * Returns the network port of the local host.
+ */
+ public int getLocalPort() {
+ return mLocalPort;
+ }
+
+ /**
+ * Returns the network address of the remote host or {@code null} if the
+ * stream is not associated.
+ */
+ public InetAddress getRemoteAddress() {
+ return mRemoteAddress;
+ }
+
+ /**
+ * Returns the network port of the remote host or {@code -1} if the stream
+ * is not associated.
+ */
+ public int getRemotePort() {
+ return mRemotePort;
+ }
+
+ /**
+ * Returns {@code true} if the stream is busy. This method is intended to be
+ * overridden by subclasses.
+ */
+ public boolean isBusy() {
+ return false;
+ }
+
+ /**
+ * Returns the current mode. The initial mode is {@link #MODE_NORMAL}.
+ */
+ public int getMode() {
+ return mMode;
+ }
+
+ /**
+ * Changes the current mode. It must be one of {@link #MODE_NORMAL},
+ * {@link #MODE_SEND_ONLY}, and {@link #MODE_RECEIVE_ONLY}.
+ *
+ * @param mode The mode to change to.
+ * @throws IllegalArgumentException if the mode is invalid.
+ * @throws IllegalStateException if the stream is busy.
+ * @see #isBusy()
+ */
+ public void setMode(int mode) {
+ if (isBusy()) {
+ throw new IllegalStateException("Busy");
+ }
+ if (mode != MODE_NORMAL && mode != MODE_SEND_ONLY && mode != MODE_RECEIVE_ONLY) {
+ throw new IllegalArgumentException("Invalid mode");
+ }
+ mMode = mode;
+ }
+
+ /**
+ * Associates with a remote host.
+ *
+ * @param address The network address of the remote host.
+ * @param port The network port of the remote host.
+ * @throws IllegalArgumentException if the address is not supported or the
+ * port is invalid.
+ * @throws IllegalStateException if the stream is busy.
+ * @see #isBusy()
+ */
+ public void associate(InetAddress address, int port) {
+ if (isBusy()) {
+ throw new IllegalStateException("Busy");
+ }
+ if (!(address instanceof Inet4Address && mLocalAddress instanceof Inet4Address) &&
+ !(address instanceof Inet6Address && mLocalAddress instanceof Inet6Address)) {
+ throw new IllegalArgumentException("Unsupported address");
+ }
+ if (port < 0 || port > 65535) {
+ throw new IllegalArgumentException("Invalid port");
+ }
+ mRemoteAddress = address;
+ mRemotePort = port;
+ }
+
+ synchronized native int dup();
+
+ /**
+ * Releases allocated resources. The stream becomes inoperable after calling
+ * this method.
+ *
+ * @throws IllegalStateException if the stream is busy.
+ * @see #isBusy()
+ */
+ public void release() {
+ if (isBusy()) {
+ throw new IllegalStateException("Busy");
+ }
+ close();
+ }
+
+ private synchronized native void close();
+
+ @Override
+ protected void finalize() throws Throwable {
+ close();
+ super.finalize();
+ }
+}