diff --git a/voip/jni/rtp/Android.mk b/voip/jni/rtp/Android.mk
new file mode 100644
index 0000000..a364355
--- /dev/null
+++ b/voip/jni/rtp/Android.mk
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := librtp_jni
+
+LOCAL_SRC_FILES := \
+	AudioCodec.cpp \
+	AudioGroup.cpp \
+	RtpStream.cpp \
+	util.cpp \
+	rtp_jni.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libnativehelper \
+	libcutils \
+	libutils \
+	libmedia
+
+LOCAL_STATIC_LIBRARIES :=
+
+LOCAL_C_INCLUDES += \
+	$(JNI_H_INCLUDE)
+
+LOCAL_CFLAGS += -fvisibility=hidden
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/voip/jni/rtp/AudioCodec.cpp b/voip/jni/rtp/AudioCodec.cpp
new file mode 100644
index 0000000..ddd07fc
--- /dev/null
+++ b/voip/jni/rtp/AudioCodec.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyrightm (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.
+ */
+
+#include <string.h>
+
+#include "AudioCodec.h"
+
+namespace {
+
+int8_t gExponents[128] = {
+    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+//------------------------------------------------------------------------------
+
+class UlawCodec : public AudioCodec
+{
+public:
+    bool set(int sampleRate, int sampleCount) {
+        mSampleCount = sampleCount;
+        return sampleCount > 0;
+    }
+    int encode(void *payload, int16_t *samples);
+    int decode(int16_t *samples, void *payload, int length);
+private:
+    int mSampleCount;
+};
+
+int UlawCodec::encode(void *payload, int16_t *samples)
+{
+    int8_t *ulaws = (int8_t *)payload;
+    for (int i = 0; i < mSampleCount; ++i) {
+        int sample = samples[i];
+        int sign = (sample >> 8) & 0x80;
+        if (sample < 0) {
+            sample = -sample;
+        }
+        sample += 132;
+        if (sample > 32767) {
+            sample = 32767;
+        }
+        int exponent = gExponents[sample >> 8];
+        int mantissa = (sample >> (exponent + 3)) & 0x0F;
+        ulaws[i] = ~(sign | (exponent << 4) | mantissa);
+    }
+    return mSampleCount;
+}
+
+int UlawCodec::decode(int16_t *samples, void *payload, int length)
+{
+    int8_t *ulaws = (int8_t *)payload;
+    for (int i = 0; i < length; ++i) {
+        int ulaw = ~ulaws[i];
+        int exponent = (ulaw >> 4) & 0x07;
+        int mantissa = ulaw & 0x0F;
+        int sample = (((mantissa << 3) + 132) << exponent) - 132;
+        samples[i] = (ulaw < 0 ? -sample : sample);
+    }
+    return length;
+}
+
+AudioCodec *newUlawCodec()
+{
+    return new UlawCodec;
+}
+
+//------------------------------------------------------------------------------
+
+class AlawCodec : public AudioCodec
+{
+public:
+    bool set(int sampleRate, int sampleCount) {
+        mSampleCount = sampleCount;
+        return sampleCount > 0;
+    }
+    int encode(void *payload, int16_t *samples);
+    int decode(int16_t *samples, void *payload, int length);
+private:
+    int mSampleCount;
+};
+
+int AlawCodec::encode(void *payload, int16_t *samples)
+{
+    int8_t *alaws = (int8_t *)payload;
+    for (int i = 0; i < mSampleCount; ++i) {
+        int sample = samples[i];
+        int sign = (sample >> 8) & 0x80;
+        if (sample < 0) {
+            sample = -sample;
+        }
+        if (sample > 32767) {
+            sample = 32767;
+        }
+        int exponent = gExponents[sample >> 8];
+        int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F;
+        alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5;
+    }
+    return mSampleCount;
+}
+
+int AlawCodec::decode(int16_t *samples, void *payload, int length)
+{
+    int8_t *alaws = (int8_t *)payload;
+    for (int i = 0; i < length; ++i) {
+        int alaw = alaws[i] ^ 0x55;
+        int exponent = (alaw >> 4) & 0x07;
+        int mantissa = alaw & 0x0F;
+        int sample = (exponent == 0 ? (mantissa << 4) + 8 :
+            ((mantissa << 3) + 132) << exponent);
+        samples[i] = (alaw < 0 ? sample : -sample);
+    }
+    return length;
+}
+
+AudioCodec *newAlawCodec()
+{
+    return new AlawCodec;
+}
+
+struct AudioCodecType {
+    const char *name;
+    AudioCodec *(*create)();
+} gAudioCodecTypes[] = {
+    {"PCMA", newAlawCodec},
+    {"PCMU", newUlawCodec},
+    {NULL, NULL},
+};
+
+} // namespace
+
+AudioCodec *newAudioCodec(const char *codecName)
+{
+    AudioCodecType *type = gAudioCodecTypes;
+    while (type->name != NULL) {
+        if (strcmp(codecName, type->name) == 0) {
+            return type->create();
+        }
+        ++type;
+    }
+    return NULL;
+}
diff --git a/voip/jni/rtp/AudioCodec.h b/voip/jni/rtp/AudioCodec.h
new file mode 100644
index 0000000..797494c
--- /dev/null
+++ b/voip/jni/rtp/AudioCodec.h
@@ -0,0 +1,36 @@
+/*
+ * Copyrightm (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.
+ */
+
+#include <stdint.h>
+
+#ifndef __AUDIO_CODEC_H__
+#define __AUDIO_CODEC_H__
+
+class AudioCodec
+{
+public:
+    virtual ~AudioCodec() {}
+    // Returns true if initialization succeeds.
+    virtual bool set(int sampleRate, int sampleCount) = 0;
+    // Returns the length of payload in bytes.
+    virtual int encode(void *payload, int16_t *samples) = 0;
+    // Returns the number of decoded samples.
+    virtual int decode(int16_t *samples, void *payload, int length) = 0;
+};
+
+AudioCodec *newAudioCodec(const char *codecName);
+
+#endif
diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp
new file mode 100644
index 0000000..fc1ed9b
--- /dev/null
+++ b/voip/jni/rtp/AudioGroup.cpp
@@ -0,0 +1,1004 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define LOG_TAG "AudioGroup"
+#include <cutils/atomic.h>
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <utils/SystemClock.h>
+#include <media/AudioSystem.h>
+#include <media/AudioRecord.h>
+#include <media/AudioTrack.h>
+#include <media/mediarecorder.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "AudioCodec.h"
+
+extern int parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss);
+
+namespace {
+
+using namespace android;
+
+int gRandom = -1;
+
+// We use a circular array to implement jitter buffer. The simplest way is doing
+// a modulo operation on the index while accessing the array. However modulo can
+// be expensive on some platforms, such as ARM. Thus we round up the size of the
+// array to the nearest power of 2 and then use bitwise-and instead of modulo.
+// Currently we make it 256ms long and assume packet interval is 32ms or less.
+// The first 64ms is the place where samples get mixed. The rest 192ms is the
+// real jitter buffer. For a stream at 8000Hz it takes 4096 bytes. These numbers
+// are chosen by experiments and each of them can be adjusted as needed.
+
+// Other notes:
+// + We use elapsedRealtime() to get the time. Since we use 32bit variables
+//   instead of 64bit ones, comparison must be done by subtraction.
+// + Sampling rate must be multiple of 1000Hz, and packet length must be in
+//   milliseconds. No floating points.
+// + If we cannot get enough CPU, we drop samples and simulate packet loss.
+// + Resampling is not done yet, so streams in one group must use the same rate.
+//   For the first release we might only support 8kHz and 16kHz.
+
+class AudioStream
+{
+public:
+    AudioStream();
+    ~AudioStream();
+    bool set(int mode, int socket, sockaddr_storage *remote,
+        const char *codecName, int sampleRate, int sampleCount,
+        int codecType, int dtmfType);
+
+    void sendDtmf(int event);
+    bool mix(int32_t *output, int head, int tail, int sampleRate);
+    void encode(int tick, AudioStream *chain);
+    void decode(int tick);
+
+private:
+    enum {
+        NORMAL = 0,
+        SEND_ONLY = 1,
+        RECEIVE_ONLY = 2,
+        LAST_MODE = 2,
+    };
+
+    int mMode;
+    int mSocket;
+    sockaddr_storage mRemote;
+    AudioCodec *mCodec;
+    uint32_t mCodecMagic;
+    uint32_t mDtmfMagic;
+
+    int mTick;
+    int mSampleRate;
+    int mSampleCount;
+    int mInterval;
+
+    int16_t *mBuffer;
+    int mBufferMask;
+    int mBufferHead;
+    int mBufferTail;
+    int mLatencyScore;
+
+    uint16_t mSequence;
+    uint32_t mTimestamp;
+    uint32_t mSsrc;
+
+    int mDtmfEvent;
+    int mDtmfStart;
+
+    AudioStream *mNext;
+
+    friend class AudioGroup;
+};
+
+AudioStream::AudioStream()
+{
+    mSocket = -1;
+    mCodec = NULL;
+    mBuffer = NULL;
+    mNext = NULL;
+}
+
+AudioStream::~AudioStream()
+{
+    close(mSocket);
+    delete mCodec;
+    delete [] mBuffer;
+    LOGD("stream[%d] is dead", mSocket);
+}
+
+bool AudioStream::set(int mode, int socket, sockaddr_storage *remote,
+    const char *codecName, int sampleRate, int sampleCount,
+    int codecType, int dtmfType)
+{
+    if (mode < 0 || mode > LAST_MODE) {
+        return false;
+    }
+    mMode = mode;
+
+    if (codecName) {
+        mRemote = *remote;
+        mCodec = newAudioCodec(codecName);
+        if (!mCodec || !mCodec->set(sampleRate, sampleCount)) {
+            return false;
+        }
+    }
+
+    mCodecMagic = (0x8000 | codecType) << 16;
+    mDtmfMagic = (dtmfType == -1) ? 0 : (0x8000 | dtmfType) << 16;
+
+    mTick = elapsedRealtime();
+    mSampleRate = sampleRate / 1000;
+    mSampleCount = sampleCount;
+    mInterval = mSampleCount / mSampleRate;
+
+    // Allocate jitter buffer.
+    for (mBufferMask = 8192; mBufferMask < sampleRate; mBufferMask <<= 1);
+    mBufferMask >>= 2;
+    mBuffer = new int16_t[mBufferMask];
+    --mBufferMask;
+    mBufferHead = 0;
+    mBufferTail = 0;
+    mLatencyScore = 0;
+
+    // Initialize random bits.
+    read(gRandom, &mSequence, sizeof(mSequence));
+    read(gRandom, &mTimestamp, sizeof(mTimestamp));
+    read(gRandom, &mSsrc, sizeof(mSsrc));
+
+    mDtmfEvent = -1;
+    mDtmfStart = 0;
+
+    // Only take over the socket when succeeded.
+    mSocket = socket;
+
+    LOGD("stream[%d] is configured as %s %dkHz %dms", mSocket,
+        (codecName ? codecName : "RAW"), mSampleRate, mInterval);
+    return true;
+}
+
+void AudioStream::sendDtmf(int event)
+{
+    if (mDtmfMagic != 0) {
+        mDtmfEvent = event << 24;
+        mDtmfStart = mTimestamp + mSampleCount;
+    }
+}
+
+bool AudioStream::mix(int32_t *output, int head, int tail, int sampleRate)
+{
+    if (mMode == SEND_ONLY) {
+        return false;
+    }
+
+    if (head - mBufferHead < 0) {
+        head = mBufferHead;
+    }
+    if (tail - mBufferTail > 0) {
+        tail = mBufferTail;
+    }
+    if (tail - head <= 0) {
+        return false;
+    }
+
+    head *= mSampleRate;
+    tail *= mSampleRate;
+
+    if (sampleRate == mSampleRate) {
+        for (int i = head; i - tail < 0; ++i) {
+            output[i - head] += mBuffer[i & mBufferMask];
+        }
+    } else {
+        // TODO: implement resampling.
+        return false;
+    }
+    return true;
+}
+
+void AudioStream::encode(int tick, AudioStream *chain)
+{
+    if (tick - mTick >= mInterval) {
+        // We just missed the train. Pretend that packets in between are lost.
+        int skipped = (tick - mTick) / mInterval;
+        mTick += skipped * mInterval;
+        mSequence += skipped;
+        mTimestamp += skipped * mSampleCount;
+        LOGD("stream[%d] skips %d packets", mSocket, skipped);
+    }
+
+    tick = mTick;
+    mTick += mInterval;
+    ++mSequence;
+    mTimestamp += mSampleCount;
+
+    if (mMode == RECEIVE_ONLY) {
+        return;
+    }
+
+    // If there is an ongoing DTMF event, send it now.
+    if (mDtmfEvent != -1) {
+        int duration = mTimestamp - mDtmfStart;
+        // Make sure duration is reasonable.
+        if (duration >= 0 && duration < mSampleRate * 100) {
+            duration += mSampleCount;
+            int32_t buffer[4] = {
+                htonl(mDtmfMagic | mSequence),
+                htonl(mDtmfStart),
+                mSsrc,
+                htonl(mDtmfEvent | duration),
+            };
+            if (duration >= mSampleRate * 100) {
+                buffer[3] |= htonl(1 << 23);
+                mDtmfEvent = -1;
+            }
+            sendto(mSocket, buffer, sizeof(buffer), MSG_DONTWAIT,
+                (sockaddr *)&mRemote, sizeof(mRemote));
+            return;
+        }
+        mDtmfEvent = -1;
+    }
+
+    // It is time to mix streams.
+    bool mixed = false;
+    int32_t buffer[mSampleCount + 3];
+    memset(buffer, 0, sizeof(buffer));
+    while (chain) {
+        if (chain != this &&
+            chain->mix(buffer, tick - mInterval, tick, mSampleRate)) {
+            mixed = true;
+        }
+        chain = chain->mNext;
+    }
+    if (!mixed) {
+        LOGD("stream[%d] no data", mSocket);
+        return;
+    }
+
+    // Cook the packet and send it out.
+    int16_t samples[mSampleCount];
+    for (int i = 0; i < mSampleCount; ++i) {
+        int32_t sample = buffer[i];
+        if (sample < -32768) {
+            sample = -32768;
+        }
+        if (sample > 32767) {
+            sample = 32767;
+        }
+        samples[i] = sample;
+    }
+    if (!mCodec) {
+        // Special case for device stream.
+        send(mSocket, samples, sizeof(samples), MSG_DONTWAIT);
+        return;
+    }
+
+    buffer[0] = htonl(mCodecMagic | mSequence);
+    buffer[1] = htonl(mTimestamp);
+    buffer[2] = mSsrc;
+    int length = mCodec->encode(&buffer[3], samples);
+    if (length <= 0) {
+        LOGD("stream[%d] encoder error", mSocket);
+        return;
+    }
+    sendto(mSocket, buffer, length + 12, MSG_DONTWAIT, (sockaddr *)&mRemote,
+        sizeof(mRemote));
+}
+
+void AudioStream::decode(int tick)
+{
+    char c;
+    if (mMode == SEND_ONLY) {
+        recv(mSocket, &c, 1, MSG_DONTWAIT);
+        return;
+    }
+
+    // Make sure mBufferHead and mBufferTail are reasonable.
+    if ((unsigned int)(tick + 256 - mBufferHead) > 1024) {
+        mBufferHead = tick - 64;
+        mBufferTail = mBufferHead;
+    }
+
+    if (tick - mBufferHead > 64) {
+        // Throw away outdated samples.
+        mBufferHead = tick - 64;
+        if (mBufferTail - mBufferHead < 0) {
+            mBufferTail = mBufferHead;
+        }
+    }
+
+    if (mBufferTail - tick <= 80) {
+        mLatencyScore = tick;
+    } else if (tick - mLatencyScore >= 5000) {
+        // Reset the jitter buffer to 40ms if the latency keeps larger than 80ms
+        // in the past 5s. This rarely happens, so let us just keep it simple.
+        LOGD("stream[%d] latency control", mSocket);
+        mBufferTail = tick + 40;
+    }
+
+    if (mBufferTail - mBufferHead > 256 - mInterval) {
+        // Buffer overflow. Drop the packet.
+        LOGD("stream[%d] buffer overflow", mSocket);
+        recv(mSocket, &c, 1, MSG_DONTWAIT);
+        return;
+    }
+
+    // Receive the packet and decode it.
+    int16_t samples[mSampleCount];
+    int length = 0;
+    if (!mCodec) {
+        // Special case for device stream.
+        length = recv(mSocket, samples, sizeof(samples),
+            MSG_TRUNC | MSG_DONTWAIT) >> 1;
+    } else {
+        __attribute__((aligned(4))) uint8_t buffer[2048];
+        length = recv(mSocket, buffer, sizeof(buffer),
+            MSG_TRUNC | MSG_DONTWAIT);
+
+        // Do we need to check SSRC, sequence, and timestamp? They are not
+        // reliable but at least they can be used to identity duplicates?
+        if (length < 12 || length > (int)sizeof(buffer) ||
+            (ntohl(*(uint32_t *)buffer) & 0xC07F0000) != mCodecMagic) {
+            LOGD("stream[%d] malformed packet", mSocket);
+            return;
+        }
+        int offset = 12 + ((buffer[0] & 0x0F) << 2);
+        if ((buffer[0] & 0x10) != 0) {
+            offset += 4 + (ntohs(*(uint16_t *)&buffer[offset + 2]) << 2);
+        }
+        if ((buffer[0] & 0x20) != 0) {
+            length -= buffer[length - 1];
+        }
+        length -= offset;
+        if (length >= 0) {
+            length = mCodec->decode(samples, &buffer[offset], length);
+        }
+    }
+    if (length != mSampleCount) {
+        LOGD("stream[%d] decoder error", mSocket);
+        return;
+    }
+
+    if (tick - mBufferTail > 0) {
+        // Buffer underrun. Reset the jitter buffer to 40ms.
+        LOGD("stream[%d] buffer underrun", mSocket);
+        if (mBufferTail - mBufferHead <= 0) {
+            mBufferHead = tick + 40;
+            mBufferTail = mBufferHead;
+        } else {
+            int tail = (tick + 40) * mSampleRate;
+            for (int i = mBufferTail * mSampleRate; i - tail < 0; ++i) {
+                mBuffer[i & mBufferMask] = 0;
+            }
+            mBufferTail = tick + 40;
+        }
+    }
+
+    // Append to the jitter buffer.
+    int tail = mBufferTail * mSampleRate;
+    for (int i = 0; i < mSampleCount; ++i) {
+        mBuffer[tail & mBufferMask] = samples[i];
+        ++tail;
+    }
+    mBufferTail += mInterval;
+}
+
+//------------------------------------------------------------------------------
+
+class AudioGroup
+{
+public:
+    AudioGroup();
+    ~AudioGroup();
+    bool set(int sampleRate, int sampleCount);
+
+    bool setMode(int mode);
+    bool sendDtmf(int event);
+    bool add(AudioStream *stream);
+    bool remove(int socket);
+
+private:
+    enum {
+        ON_HOLD = 0,
+        MUTED = 1,
+        NORMAL = 2,
+        EC_ENABLED = 3,
+        LAST_MODE = 3,
+    };
+    int mMode;
+    AudioStream *mChain;
+    int mEventQueue;
+    volatile int mDtmfEvent;
+
+    int mSampleCount;
+    int mDeviceSocket;
+    AudioTrack mTrack;
+    AudioRecord mRecord;
+
+    bool networkLoop();
+    bool deviceLoop();
+
+    class NetworkThread : public Thread
+    {
+    public:
+        NetworkThread(AudioGroup *group) : Thread(false), mGroup(group) {}
+
+        bool start()
+        {
+            if (run("Network", ANDROID_PRIORITY_AUDIO) != NO_ERROR) {
+                LOGE("cannot start network thread");
+                return false;
+            }
+            return true;
+        }
+
+    private:
+        AudioGroup *mGroup;
+        bool threadLoop()
+        {
+            return mGroup->networkLoop();
+        }
+    };
+    sp<NetworkThread> mNetworkThread;
+
+    class DeviceThread : public Thread
+    {
+    public:
+        DeviceThread(AudioGroup *group) : Thread(false), mGroup(group) {}
+
+        bool start()
+        {
+            char c;
+            while (recv(mGroup->mDeviceSocket, &c, 1, MSG_DONTWAIT) == 1);
+
+            if (run("Device", ANDROID_PRIORITY_AUDIO) != NO_ERROR) {
+                LOGE("cannot start device thread");
+                return false;
+            }
+            return true;
+        }
+
+    private:
+        AudioGroup *mGroup;
+        bool threadLoop()
+        {
+            return mGroup->deviceLoop();
+        }
+    };
+    sp<DeviceThread> mDeviceThread;
+};
+
+AudioGroup::AudioGroup()
+{
+    mMode = ON_HOLD;
+    mChain = NULL;
+    mEventQueue = -1;
+    mDtmfEvent = -1;
+    mDeviceSocket = -1;
+    mNetworkThread = new NetworkThread(this);
+    mDeviceThread = new DeviceThread(this);
+}
+
+AudioGroup::~AudioGroup()
+{
+    mNetworkThread->requestExitAndWait();
+    mDeviceThread->requestExitAndWait();
+    mTrack.stop();
+    mRecord.stop();
+    close(mEventQueue);
+    close(mDeviceSocket);
+    while (mChain) {
+        AudioStream *next = mChain->mNext;
+        delete mChain;
+        mChain = next;
+    }
+    LOGD("group[%d] is dead", mDeviceSocket);
+}
+
+#define FROYO_COMPATIBLE
+#ifdef FROYO_COMPATIBLE
+
+// Copied from AudioRecord.cpp.
+status_t AudioRecord_getMinFrameCount(
+        int* frameCount,
+        uint32_t sampleRate,
+        int format,
+        int channelCount)
+{
+    size_t size = 0;
+    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
+            != NO_ERROR) {
+        LOGE("AudioSystem could not query the input buffer size.");
+        return NO_INIT;
+    }
+
+    if (size == 0) {
+        LOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
+            sampleRate, format, channelCount);
+        return BAD_VALUE;
+    }
+
+    // We double the size of input buffer for ping pong use of record buffer.
+    size <<= 1;
+
+    if (AudioSystem::isLinearPCM(format)) {
+        size /= channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
+    }
+
+    *frameCount = size;
+    return NO_ERROR;
+}
+
+// Copied from AudioTrack.cpp.
+status_t AudioTrack_getMinFrameCount(
+        int* frameCount,
+        int streamType,
+        uint32_t sampleRate)
+{
+    int afSampleRate;
+    if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
+        return NO_INIT;
+    }
+    int afFrameCount;
+    if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
+        return NO_INIT;
+    }
+    uint32_t afLatency;
+    if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
+        return NO_INIT;
+    }
+
+    // Ensure that buffer depth covers at least audio hardware latency
+    uint32_t minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate);
+    if (minBufCount < 2) minBufCount = 2;
+
+    *frameCount = (sampleRate == 0) ? afFrameCount * minBufCount :
+              afFrameCount * minBufCount * sampleRate / afSampleRate;
+    return NO_ERROR;
+}
+
+#endif
+
+bool AudioGroup::set(int sampleRate, int sampleCount)
+{
+    mEventQueue = epoll_create(2);
+    if (mEventQueue == -1) {
+        LOGE("epoll_create: %s", strerror(errno));
+        return false;
+    }
+
+    mSampleCount = sampleCount;
+
+    // Find out the frame count for AudioTrack and AudioRecord.
+    int output = 0;
+    int input = 0;
+#ifdef FROYO_COMPATIBLE
+    if (AudioTrack_getMinFrameCount(&output, AudioSystem::VOICE_CALL,
+        sampleRate) != NO_ERROR || output <= 0 ||
+        AudioRecord_getMinFrameCount(&input, sampleRate,
+        AudioSystem::PCM_16_BIT, 1) != NO_ERROR || input <= 0) {
+        LOGE("cannot compute frame count");
+        return false;
+    }
+#else
+    if (AudioTrack::getMinFrameCount(&output, AudioSystem::VOICE_CALL,
+        sampleRate) != NO_ERROR || output <= 0 ||
+        AudioRecord::getMinFrameCount(&input, sampleRate,
+        AudioSystem::PCM_16_BIT, 1) != NO_ERROR || input <= 0) {
+        LOGE("cannot compute frame count");
+        return false;
+    }
+#endif
+    LOGD("reported frame count: output %d, input %d", output, input);
+
+    output = (output + sampleCount - 1) / sampleCount * sampleCount;
+    input = (input + sampleCount - 1) / sampleCount * sampleCount;
+    if (input < output * 2) {
+        input = output * 2;
+    }
+    LOGD("adjusted frame count: output %d, input %d", output, input);
+
+    // Initialize AudioTrack and AudioRecord.
+    if (mTrack.set(AudioSystem::VOICE_CALL, sampleRate, AudioSystem::PCM_16_BIT,
+        AudioSystem::CHANNEL_OUT_MONO, output) != NO_ERROR ||
+        mRecord.set(AUDIO_SOURCE_MIC, sampleRate, AudioSystem::PCM_16_BIT,
+        AudioSystem::CHANNEL_IN_MONO, input) != NO_ERROR) {
+        LOGE("cannot initialize audio device");
+        return false;
+    }
+    LOGD("latency: output %d, input %d", mTrack.latency(), mRecord.latency());
+
+    // TODO: initialize echo canceler here.
+
+    // Create device socket.
+    int pair[2];
+    if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair)) {
+        LOGE("socketpair: %s", strerror(errno));
+        return false;
+    }
+    mDeviceSocket = pair[0];
+
+    // Create device stream.
+    mChain = new AudioStream;
+    if (!mChain->set(AudioStream::NORMAL, pair[1], NULL, NULL,
+        sampleRate, sampleCount, -1, -1)) {
+        close(pair[1]);
+        LOGE("cannot initialize device stream");
+        return false;
+    }
+
+    // Give device socket a reasonable timeout and buffer size.
+    timeval tv;
+    tv.tv_sec = 0;
+    tv.tv_usec = 1000 * sampleCount / sampleRate * 500;
+    if (setsockopt(pair[0], SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) ||
+        setsockopt(pair[0], SOL_SOCKET, SO_RCVBUF, &output, sizeof(output)) ||
+        setsockopt(pair[1], SOL_SOCKET, SO_SNDBUF, &output, sizeof(output))) {
+        LOGE("setsockopt: %s", strerror(errno));
+        return false;
+    }
+
+    // Add device stream into event queue.
+    epoll_event event;
+    event.events = EPOLLIN;
+    event.data.ptr = mChain;
+    if (epoll_ctl(mEventQueue, EPOLL_CTL_ADD, pair[1], &event)) {
+        LOGE("epoll_ctl: %s", strerror(errno));
+        return false;
+    }
+
+    // Anything else?
+    LOGD("stream[%d] joins group[%d]", pair[1], pair[0]);
+    return true;
+}
+
+bool AudioGroup::setMode(int mode)
+{
+    if (mode < 0 || mode > LAST_MODE) {
+        return false;
+    }
+    if (mMode == mode) {
+        return true;
+    }
+
+    LOGD("group[%d] switches from mode %d to %d", mDeviceSocket, mMode, mode);
+    mMode = mode;
+
+    mDeviceThread->requestExitAndWait();
+    if (mode == ON_HOLD) {
+        mTrack.stop();
+        mRecord.stop();
+        return true;
+    }
+
+    mTrack.start();
+    if (mode == MUTED) {
+        mRecord.stop();
+    } else {
+        mRecord.start();
+    }
+
+    if (!mDeviceThread->start()) {
+        mTrack.stop();
+        mRecord.stop();
+        return false;
+    }
+    return true;
+}
+
+bool AudioGroup::sendDtmf(int event)
+{
+    if (event < 0 || event > 15) {
+        return false;
+    }
+
+    // DTMF is rarely used, so we try to make it as lightweight as possible.
+    // Using volatile might be dodgy, but using a pipe or pthread primitives
+    // or stop-set-restart threads seems too heavy. Will investigate later.
+    timespec ts;
+    ts.tv_sec = 0;
+    ts.tv_nsec = 100000000;
+    for (int i = 0; mDtmfEvent != -1 && i < 20; ++i) {
+        nanosleep(&ts, NULL);
+    }
+    if (mDtmfEvent != -1) {
+        return false;
+    }
+    mDtmfEvent = event;
+    nanosleep(&ts, NULL);
+    return true;
+}
+
+bool AudioGroup::add(AudioStream *stream)
+{
+    mNetworkThread->requestExitAndWait();
+
+    epoll_event event;
+    event.events = EPOLLIN;
+    event.data.ptr = stream;
+    if (epoll_ctl(mEventQueue, EPOLL_CTL_ADD, stream->mSocket, &event)) {
+        LOGE("epoll_ctl: %s", strerror(errno));
+        return false;
+    }
+
+    stream->mNext = mChain->mNext;
+    mChain->mNext = stream;
+    if (!mNetworkThread->start()) {
+        // Only take over the stream when succeeded.
+        mChain->mNext = stream->mNext;
+        return false;
+    }
+
+    LOGD("stream[%d] joins group[%d]", stream->mSocket, mDeviceSocket);
+    return true;
+}
+
+bool AudioGroup::remove(int socket)
+{
+    mNetworkThread->requestExitAndWait();
+
+    for (AudioStream *stream = mChain; stream->mNext; stream = stream->mNext) {
+        AudioStream *target = stream->mNext;
+        if (target->mSocket == socket) {
+            stream->mNext = target->mNext;
+            LOGD("stream[%d] leaves group[%d]", socket, mDeviceSocket);
+            delete target;
+            break;
+        }
+    }
+
+    // Do not start network thread if there is only one stream.
+    if (!mChain->mNext || !mNetworkThread->start()) {
+        return false;
+    }
+    return true;
+}
+
+bool AudioGroup::networkLoop()
+{
+    int tick = elapsedRealtime();
+    int deadline = tick + 10;
+    int count = 0;
+
+    for (AudioStream *stream = mChain; stream; stream = stream->mNext) {
+        if (!stream->mTick || tick - stream->mTick >= 0) {
+            stream->encode(tick, mChain);
+        }
+        if (deadline - stream->mTick > 0) {
+            deadline = stream->mTick;
+        }
+        ++count;
+    }
+
+    if (mDtmfEvent != -1) {
+        int event = mDtmfEvent;
+        for (AudioStream *stream = mChain; stream; stream = stream->mNext) {
+            stream->sendDtmf(event);
+        }
+        mDtmfEvent = -1;
+    }
+
+    deadline -= tick;
+    if (deadline < 1) {
+        deadline = 1;
+    }
+
+    epoll_event events[count];
+    count = epoll_wait(mEventQueue, events, count, deadline);
+    if (count == -1) {
+        LOGE("epoll_wait: %s", strerror(errno));
+        return false;
+    }
+    for (int i = 0; i < count; ++i) {
+        ((AudioStream *)events[i].data.ptr)->decode(tick);
+    }
+
+    return true;
+}
+
+bool AudioGroup::deviceLoop()
+{
+    int16_t output[mSampleCount];
+
+    if (recv(mDeviceSocket, output, sizeof(output), 0) <= 0) {
+        memset(output, 0, sizeof(output));
+    }
+    if (mTrack.write(output, sizeof(output)) != (int)sizeof(output)) {
+        LOGE("cannot write to AudioTrack");
+        return false;
+    }
+
+    if (mMode != MUTED) {
+        uint32_t frameCount = mRecord.frameCount();
+        AudioRecord::Buffer input;
+        input.frameCount = frameCount;
+
+        if (mRecord.obtainBuffer(&input, -1) != NO_ERROR) {
+            LOGE("cannot read from AudioRecord");
+            return false;
+        }
+
+        if (input.frameCount < (uint32_t)mSampleCount) {
+            input.frameCount = 0;
+        } else {
+            if (mMode == NORMAL) {
+                send(mDeviceSocket, input.i8, sizeof(output), MSG_DONTWAIT);
+            } else {
+                // TODO: Echo canceller runs here.
+                send(mDeviceSocket, input.i8, sizeof(output), MSG_DONTWAIT);
+            }
+            if (input.frameCount < frameCount) {
+                input.frameCount = mSampleCount;
+            }
+        }
+
+        mRecord.releaseBuffer(&input);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+static jfieldID gNative;
+static jfieldID gMode;
+
+jint add(JNIEnv *env, jobject thiz, jint mode,
+    jint socket, jstring jRemoteAddress, jint remotePort,
+    jstring jCodecName, jint sampleRate, jint sampleCount,
+    jint codecType, jint dtmfType)
+{
+    const char *codecName = NULL;
+    AudioStream *stream = NULL;
+    AudioGroup *group = NULL;
+
+    // Sanity check.
+    sockaddr_storage remote;
+    if (parse(env, jRemoteAddress, remotePort, &remote) < 0) {
+        // Exception already thrown.
+        return -1;
+    }
+    if (sampleRate < 0 || sampleCount < 0 || codecType < 0 || codecType > 127) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        goto error;
+    }
+    if (!jCodecName) {
+        jniThrowNullPointerException(env, "codecName");
+        return -1;
+    }
+    codecName = env->GetStringUTFChars(jCodecName, NULL);
+    if (!codecName) {
+        // Exception already thrown.
+        return -1;
+    }
+
+    // Create audio stream.
+    stream = new AudioStream;
+    if (!stream->set(mode, socket, &remote, codecName, sampleRate, sampleCount,
+        codecType, dtmfType)) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "cannot initialize audio stream");
+        goto error;
+    }
+    socket = -1;
+
+    // Create audio group.
+    group = (AudioGroup *)env->GetIntField(thiz, gNative);
+    if (!group) {
+        int mode = env->GetIntField(thiz, gMode);
+        group = new AudioGroup;
+        if (!group->set(8000, 256) || !group->setMode(mode)) {
+            jniThrowException(env, "java/lang/IllegalStateException",
+                "cannot initialize audio group");
+            goto error;
+        }
+    }
+
+    // Add audio stream into audio group.
+    if (!group->add(stream)) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "cannot add audio stream");
+        goto error;
+    }
+
+    // Succeed.
+    env->SetIntField(thiz, gNative, (int)group);
+    env->ReleaseStringUTFChars(jCodecName, codecName);
+    return socket;
+
+error:
+    delete group;
+    delete stream;
+    close(socket);
+    env->SetIntField(thiz, gNative, NULL);
+    env->ReleaseStringUTFChars(jCodecName, codecName);
+    return -1;
+}
+
+void remove(JNIEnv *env, jobject thiz, jint socket)
+{
+    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
+    if (group) {
+        if (socket == -1 || !group->remove(socket)) {
+            delete group;
+            env->SetIntField(thiz, gNative, NULL);
+        }
+    }
+}
+
+void setMode(JNIEnv *env, jobject thiz, jint mode)
+{
+    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
+    if (group && !group->setMode(mode)) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return;
+    }
+    env->SetIntField(thiz, gMode, mode);
+}
+
+void sendDtmf(JNIEnv *env, jobject thiz, jint event)
+{
+    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
+    if (group && !group->sendDtmf(event)) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+    }
+}
+
+JNINativeMethod gMethods[] = {
+    {"add", "(IILjava/lang/String;ILjava/lang/String;IIII)I", (void *)add},
+    {"remove", "(I)V", (void *)remove},
+    {"setMode", "(I)V", (void *)setMode},
+    {"sendDtmf", "(I)V", (void *)sendDtmf},
+};
+
+} // namespace
+
+int registerAudioGroup(JNIEnv *env)
+{
+    gRandom = open("/dev/urandom", O_RDONLY);
+    if (gRandom == -1) {
+        LOGE("urandom: %s", strerror(errno));
+        return -1;
+    }
+
+    jclass clazz;
+    if ((clazz = env->FindClass("android/net/rtp/AudioGroup")) == NULL ||
+        (gNative = env->GetFieldID(clazz, "mNative", "I")) == NULL ||
+        (gMode = env->GetFieldID(clazz, "mMode", "I")) == NULL ||
+        env->RegisterNatives(clazz, gMethods, NELEM(gMethods)) < 0) {
+        LOGE("JNI registration failed");
+        return -1;
+    }
+    return 0;
+}
diff --git a/voip/jni/rtp/RtpStream.cpp b/voip/jni/rtp/RtpStream.cpp
new file mode 100644
index 0000000..33b88e43
--- /dev/null
+++ b/voip/jni/rtp/RtpStream.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define LOG_TAG "RtpStream"
+#include <utils/Log.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+extern int parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss);
+
+namespace {
+
+jfieldID gNative;
+
+jint create(JNIEnv *env, jobject thiz, jstring jAddress)
+{
+    env->SetIntField(thiz, gNative, -1);
+
+    sockaddr_storage ss;
+    if (parse(env, jAddress, 0, &ss) < 0) {
+        // Exception already thrown.
+        return -1;
+    }
+
+    int socket = ::socket(ss.ss_family, SOCK_DGRAM, 0);
+    socklen_t len = sizeof(ss);
+    if (socket == -1 || bind(socket, (sockaddr *)&ss, sizeof(ss)) != 0 ||
+        getsockname(socket, (sockaddr *)&ss, &len) != 0) {
+        jniThrowException(env, "java/net/SocketException", strerror(errno));
+        ::close(socket);
+        return -1;
+    }
+
+    uint16_t *p = (ss.ss_family == AF_INET) ?
+        &((sockaddr_in *)&ss)->sin_port : &((sockaddr_in6 *)&ss)->sin6_port;
+    uint16_t port = ntohs(*p);
+    if ((port & 1) == 0) {
+        env->SetIntField(thiz, gNative, socket);
+        return port;
+    }
+    ::close(socket);
+
+    socket = ::socket(ss.ss_family, SOCK_DGRAM, 0);
+    if (socket != -1) {
+        uint16_t delta = port << 1;
+        ++port;
+
+        for (int i = 0; i < 1000; ++i) {
+            do {
+                port += delta;
+            } while (port < 1024);
+            *p = htons(port);
+
+            if (bind(socket, (sockaddr *)&ss, sizeof(ss)) == 0) {
+                env->SetIntField(thiz, gNative, socket);
+                return port;
+            }
+        }
+    }
+
+    jniThrowException(env, "java/net/SocketException", strerror(errno));
+    ::close(socket);
+    return -1;
+}
+
+jint dup(JNIEnv *env, jobject thiz)
+{
+    int socket1 = env->GetIntField(thiz, gNative);
+    int socket2 = ::dup(socket1);
+    if (socket2 == -1) {
+        jniThrowException(env, "java/lang/IllegalStateException", strerror(errno));
+    }
+    LOGD("dup %d to %d", socket1, socket2);
+    return socket2;
+}
+
+void close(JNIEnv *env, jobject thiz)
+{
+    int socket = env->GetIntField(thiz, gNative);
+    ::close(socket);
+    env->SetIntField(thiz, gNative, -1);
+    LOGD("close %d", socket);
+}
+
+JNINativeMethod gMethods[] = {
+    {"create", "(Ljava/lang/String;)I", (void *)create},
+    {"dup", "()I", (void *)dup},
+    {"close", "()V", (void *)close},
+};
+
+} // namespace
+
+int registerRtpStream(JNIEnv *env)
+{
+    jclass clazz;
+    if ((clazz = env->FindClass("android/net/rtp/RtpStream")) == NULL ||
+        (gNative = env->GetFieldID(clazz, "mNative", "I")) == NULL ||
+        env->RegisterNatives(clazz, gMethods, NELEM(gMethods)) < 0) {
+        LOGE("JNI registration failed");
+        return -1;
+    }
+    return 0;
+}
diff --git a/voip/jni/rtp/rtp_jni.cpp b/voip/jni/rtp/rtp_jni.cpp
new file mode 100644
index 0000000..9f4bff9
--- /dev/null
+++ b/voip/jni/rtp/rtp_jni.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "jni.h"
+
+extern int registerRtpStream(JNIEnv *env);
+extern int registerAudioGroup(JNIEnv *env);
+
+__attribute__((visibility("default"))) jint JNI_OnLoad(JavaVM *vm, void *unused)
+{
+    JNIEnv *env = NULL;
+    if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK ||
+        registerRtpStream(env) < 0 || registerAudioGroup(env) < 0) {
+        return -1;
+    }
+    return JNI_VERSION_1_4;
+}
diff --git a/voip/jni/rtp/util.cpp b/voip/jni/rtp/util.cpp
new file mode 100644
index 0000000..1d702fc
--- /dev/null
+++ b/voip/jni/rtp/util.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+int parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss)
+{
+    if (!jAddress) {
+        jniThrowNullPointerException(env, "address");
+        return -1;
+    }
+    if (port < 0 || port > 65535) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "port");
+        return -1;
+    }
+    const char *address = env->GetStringUTFChars(jAddress, NULL);
+    if (!address) {
+        // Exception already thrown.
+        return -1;
+    }
+    memset(ss, 0, sizeof(*ss));
+
+    sockaddr_in *sin = (sockaddr_in *)ss;
+    if (inet_pton(AF_INET, address, &(sin->sin_addr)) > 0) {
+        sin->sin_family = AF_INET;
+        sin->sin_port = htons(port);
+        env->ReleaseStringUTFChars(jAddress, address);
+        return 0;
+    }
+
+    sockaddr_in6 *sin6 = (sockaddr_in6 *)ss;
+    if (inet_pton(AF_INET6, address, &(sin6->sin6_addr)) > 0) {
+        sin6->sin6_family = AF_INET6;
+        sin6->sin6_port = htons(port);
+        env->ReleaseStringUTFChars(jAddress, address);
+        return 0;
+    }
+
+    env->ReleaseStringUTFChars(jAddress, address);
+    jniThrowException(env, "java/lang/IllegalArgumentException", "address");
+    return -1;
+}
