diff options
author | Andrew Comminos <andrewcomminos@gmail.com> | 2013-12-03 09:32:51 +0400 |
---|---|---|
committer | Andrew Comminos <andrewcomminos@gmail.com> | 2013-12-03 09:32:51 +0400 |
commit | 0e549c360c3bea4d335c97cdd10a939816e145f7 (patch) | |
tree | 5c49338e583c39d4aa4f65a12059b3f577ee7817 /src/main/java | |
parent | 2961a81d8fd62393924a24415a4b2a496845b1f1 (diff) |
Removed database support, integrated access tokens into initial
bundle, connection tweaks.
Diffstat (limited to 'src/main/java')
6 files changed, 130 insertions, 173 deletions
diff --git a/src/main/java/com/morlunk/jumble/JumbleService.java b/src/main/java/com/morlunk/jumble/JumbleService.java index 827f429..85d30ee 100644 --- a/src/main/java/com/morlunk/jumble/JumbleService.java +++ b/src/main/java/com/morlunk/jumble/JumbleService.java @@ -28,7 +28,6 @@ import android.util.Log; import com.morlunk.jumble.audio.AudioInput; import com.morlunk.jumble.audio.AudioOutput; -import com.morlunk.jumble.db.Database; import com.morlunk.jumble.model.Channel; import com.morlunk.jumble.model.Server; import com.morlunk.jumble.model.User; @@ -69,6 +68,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon public static final String EXTRAS_FORCE_TCP = "force_tcp"; public static final String EXTRAS_USE_TOR = "use_tor"; public static final String EXTRAS_CLIENT_NAME = "client_name"; + public static final String EXTRAS_ACCESS_TOKENS = "access_tokens"; public static final String ACTION_DISCONNECT = "com.morlunk.jumble.DISCONNECT"; @@ -84,9 +84,9 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon public boolean mForceTcp; public boolean mUseTor; public String mClientName; + public List<String> mAccessTokens; private JumbleConnection mConnection; - private Database mDatabase; private ChannelHandler mChannelHandler; private UserHandler mUserHandler; private TextMessageHandler mTextMessageHandler; @@ -162,6 +162,36 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon } @Override + public long getTCPLatency() throws RemoteException { + return mConnection.getTCPLatency(); + } + + @Override + public long getUDPLatency() throws RemoteException { + return mConnection.getUDPLatency(); + } + + @Override + public int getServerVersion() throws RemoteException { + return mConnection.getServerVersion(); + } + + @Override + public String getServerRelease() throws RemoteException { + return mConnection.getServerRelease(); + } + + @Override + public String getServerOSName() throws RemoteException { + return mConnection.getServerOSName(); + } + + @Override + public String getServerOSVersion() throws RemoteException { + return mConnection.getServerOSVersion(); + } + + @Override public int getSession() throws RemoteException { return mConnection.getSession(); } @@ -284,12 +314,6 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon Mumble.Authenticate.Builder ab = Mumble.Authenticate.newBuilder(); ab.addAllTokens(tokens); mConnection.sendTCPMessage(ab.build(), JumbleTCPMessageType.Authenticate); - mDatabase.setTokens(mServer.getId(), tokens); - } - - @Override - public List getAccessTokens() throws RemoteException { - return mDatabase.getTokens(mServer.getId()); } @Override @@ -443,6 +467,7 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon mUseTor = extras.getBoolean(EXTRAS_USE_TOR, false); mForceTcp = extras.getBoolean(EXTRAS_FORCE_TCP, false) || mUseTor; // Tor requires TCP connections to work- if it's on, force TCP. mClientName = extras.containsKey(EXTRAS_CLIENT_NAME) ? extras.getString(EXTRAS_CLIENT_NAME) : "Jumble"; + mAccessTokens = extras.getStringArrayList(EXTRAS_ACCESS_TOKENS); connect(); } return START_NOT_STICKY; @@ -451,13 +476,11 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon @Override public void onCreate() { super.onCreate(); - mDatabase = new Database(this); } @Override public void onDestroy() { mObservers.kill(); - mDatabase.close(); super.onDestroy(); } @@ -511,17 +534,15 @@ public class JumbleService extends Service implements JumbleConnection.JumbleCon public void onConnectionEstablished() { Log.v(Constants.TAG, "Connected"); + // Send access tokens + Mumble.Authenticate.Builder ab = Mumble.Authenticate.newBuilder(); + ab.addAllTokens(mAccessTokens); + mConnection.sendTCPMessage(ab.build(), JumbleTCPMessageType.Authenticate); + mAudioOutput.startPlaying(); if(mTransmitMode == Constants.TRANSMIT_CONTINUOUS || mTransmitMode == Constants.TRANSMIT_VOICE_ACTIVITY) mAudioInput.startRecording(); - if(mServer.getId() != -1) { - // Send access tokens - Mumble.Authenticate.Builder ab = Mumble.Authenticate.newBuilder(); - ab.addAllTokens(mDatabase.getTokens(mServer.getId())); - mConnection.sendTCPMessage(ab.build(), JumbleTCPMessageType.Authenticate); - } - notifyObservers(new ObserverRunnable() { @Override public void run(IJumbleObserver observer) throws RemoteException { diff --git a/src/main/java/com/morlunk/jumble/audio/AudioInput.java b/src/main/java/com/morlunk/jumble/audio/AudioInput.java index e5f8580..9eebe64 100644 --- a/src/main/java/com/morlunk/jumble/audio/AudioInput.java +++ b/src/main/java/com/morlunk/jumble/audio/AudioInput.java @@ -37,6 +37,8 @@ import com.morlunk.jumble.protobuf.Mumble; import com.morlunk.jumble.protocol.ProtocolHandler; import java.util.Arrays; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; /** * Created by andrew on 23/08/13. @@ -82,12 +84,12 @@ public class AudioInput extends ProtocolHandler implements Runnable { private int mMicFrameSize = Audio.FRAME_SIZE; private int mFramesPerPacket = 6; - // Energy-based VAD - private int mMinAmplitude = -1; - private int mMaxAmplitude = -1; - // Temporary encoder state private final short[] mOpusBuffer = new short[mFrameSize*mFramesPerPacket]; + + // CELT encoded frame buffer + private final byte[][] mCELTBuffer = new byte[mFramesPerPacket][1024]; + private final byte[] mEncodedBuffer = new byte[OPUS_MAX_BYTES]; private final byte[] mPacketBuffer = new byte[1024]; private final PacketDataStream mPacketDataStream = new PacketDataStream(mPacketBuffer, 1024); @@ -179,7 +181,14 @@ public class AudioInput extends ProtocolHandler implements Runnable { return; mCodec = codec; - destroy(); // Deallocate old native objects + if(mOpusEncoder != null) + Opus.opus_encoder_destroy(mOpusEncoder); + if(mCELTBetaEncoder != null) + CELT11.celt_encoder_destroy(mCELTBetaEncoder); + if(mCELTAlphaEncoder != null) + CELT7.celt_encoder_destroy(mCELTAlphaEncoder); + if(mCELTAlphaMode != null) + CELT7.celt_mode_destroy(mCELTAlphaMode); IntPointer error = new IntPointer(1); switch (codec) { @@ -321,19 +330,25 @@ public class AudioInput extends ProtocolHandler implements Runnable { } break; case UDPVoiceCELTBeta: - int betaResult = CELT11.celt_encode(mCELTBetaEncoder, audioData, mFrameSize, mEncodedBuffer, OPUS_MAX_BYTES); - encoded = betaResult == 0; + int betaResult = CELT11.celt_encode(mCELTBetaEncoder, audioData, mFrameSize, mCELTBuffer[mBufferedFrames], OPUS_MAX_BYTES); + if(betaResult == 0) { + mBufferedFrames++; + encoded = mBufferedFrames >= mFramesPerPacket; + } break; case UDPVoiceCELTAlpha: - int alphaResult = CELT7.celt_encode(mCELTAlphaEncoder, audioData, null, mEncodedBuffer, OPUS_MAX_BYTES); - encoded = alphaResult == 0; + int alphaResult = CELT7.celt_encode(mCELTAlphaEncoder, audioData, null, mCELTBuffer[mBufferedFrames], OPUS_MAX_BYTES); + if(alphaResult == 0) { + mBufferedFrames++; + encoded = mBufferedFrames >= mFramesPerPacket; + } break; case UDPVoiceSpeex: break; } if(encoded) - sendFrame(mEncodedBuffer, !talking || !mRecording); + sendFrame(!talking || !mRecording); } else { Log.e(Constants.TAG, "Error fetching audio! AudioRecord error "+shortsRead); mBufferedFrames = 0; @@ -353,7 +368,7 @@ public class AudioInput extends ProtocolHandler implements Runnable { * Sends the encoded frame to the server. * Volatile; depends on class state and must not be called concurrently. */ - private void sendFrame(byte[] frame, boolean terminator) { + private void sendFrame(boolean terminator) { int frames = mBufferedFrames; mBufferedFrames = 0; @@ -367,13 +382,21 @@ public class AudioInput extends ProtocolHandler implements Runnable { mPacketDataStream.writeLong(mFrameCounter - frames); if(mCodec == JumbleUDPMessageType.UDPVoiceOpus) { + byte[] frame = mEncodedBuffer; long size = frame.length; if(terminator) size |= 1 << 13; mPacketDataStream.writeLong(size); mPacketDataStream.append(frame, frame.length); } else { - + for (int x=0;x<frames;x++) { + byte[] frame = mCELTBuffer[x]; + int head = frame.length; + if(x < frames-1) + head |= 0x80; + mPacketDataStream.append(head); + mPacketDataStream.append(frame, frame.length); + } } mListener.onFrameEncoded(mPacketBuffer, mPacketDataStream.size(), mCodec); @@ -403,8 +426,8 @@ public class AudioInput extends ProtocolHandler implements Runnable { switchCodec(JumbleUDPMessageType.UDPVoiceOpus); // else if(msg.getPreferAlpha()) // switchCodec(JumbleUDPMessageType.UDPVoiceCELTAlpha); -// else -// switchCodec(JumbleUDPMessageType.UDPVoiceCELTBeta); + else + switchCodec(JumbleUDPMessageType.UDPVoiceCELTBeta); } } diff --git a/src/main/java/com/morlunk/jumble/audio/AudioOutput.java b/src/main/java/com/morlunk/jumble/audio/AudioOutput.java index 8c75ea1..8db90cd 100644 --- a/src/main/java/com/morlunk/jumble/audio/AudioOutput.java +++ b/src/main/java/com/morlunk/jumble/audio/AudioOutput.java @@ -50,11 +50,12 @@ public class AudioOutput extends ProtocolHandler implements Runnable, AudioOutpu private ConcurrentHashMap<Integer, AudioOutputSpeech> mAudioOutputs = new ConcurrentHashMap<Integer, AudioOutputSpeech>(); private AudioTrack mAudioTrack; - private Thread mThread; private Object mInactiveLock = new Object(); // Lock that the audio thread waits on when there's no audio to play. Wake when we get a frame. private boolean mRunning = false; private long mLastPacket; // Time that the last packet was received, in nanoseconds + private List<AudioOutputSpeech> mMixBuffer = new ArrayList<AudioOutputSpeech>(); + private List<AudioOutputSpeech> mDelBuffer = new ArrayList<AudioOutputSpeech>(); public AudioOutput(JumbleService service) { super(service); @@ -116,33 +117,32 @@ public class AudioOutput extends ProtocolHandler implements Runnable, AudioOutpu } private boolean mix(short[] outBuffer, int bufferSize) { - List<AudioOutputSpeech> mix = new ArrayList<AudioOutputSpeech>(); - List<AudioOutputSpeech> del = new ArrayList<AudioOutputSpeech>(); - + mMixBuffer.clear(); + mDelBuffer.clear(); // TODO add priority speaker support for(AudioOutputSpeech speech : mAudioOutputs.values()) { if(!speech.needSamples(bufferSize)) - del.add(speech); + mDelBuffer.add(speech); else - mix.add(speech); + mMixBuffer.add(speech); } - if(!mix.isEmpty()) { - for(AudioOutputSpeech speech : mix) { + if(!mMixBuffer.isEmpty()) { + for(AudioOutputSpeech speech : mMixBuffer) { float[] buffer = speech.getBuffer(); for(int i = 0; i < bufferSize; i++) { short pcm = (short) (buffer[i]*Short.MAX_VALUE); // Convert float to short - pcm = (short) Math.max(Math.min(pcm, Short.MAX_VALUE), Short.MIN_VALUE); // Clip audio + pcm = pcm <= Short.MAX_VALUE ? (pcm >= Short.MIN_VALUE ? pcm : Short.MIN_VALUE) : Short.MIN_VALUE; // Clip audio outBuffer[i] += pcm; } } } - for(AudioOutputSpeech speech : del) + for(AudioOutputSpeech speech : mDelBuffer) mAudioOutputs.remove(speech.getSession()); - return !mix.isEmpty(); + return !mMixBuffer.isEmpty(); } @Override @@ -152,10 +152,8 @@ public class AudioOutput extends ProtocolHandler implements Runnable, AudioOutpu JumbleUDPMessageType dataType = JumbleUDPMessageType.values()[data[0] >> 5 & 0x7]; int msgFlags = data[0] & 0x1f; - byte[] voiceData = new byte[data.length-1]; - System.arraycopy(data, 1, voiceData, 0, voiceData.length); - - PacketDataStream pds = new PacketDataStream(voiceData, voiceData.length); + PacketDataStream pds = new PacketDataStream(data, data.length); + pds.skip(1); int session = (int) pds.readLong(); User user = getService().getUserHandler().getUser(session); if(user != null && !user.isLocalMuted()) { diff --git a/src/main/java/com/morlunk/jumble/audio/AudioOutputSpeech.java b/src/main/java/com/morlunk/jumble/audio/AudioOutputSpeech.java index da0a7c0..ab97a13 100644 --- a/src/main/java/com/morlunk/jumble/audio/AudioOutputSpeech.java +++ b/src/main/java/com/morlunk/jumble/audio/AudioOutputSpeech.java @@ -339,8 +339,10 @@ public class AudioOutputSpeech { } public void resizeBuffer(int newSize) { - if(newSize > mBuffer.length) - mBuffer = Arrays.copyOf(mBuffer, newSize); + if(newSize > mBuffer.length) { + float[] newBuffer = Arrays.copyOf(mBuffer, newSize); + mBuffer = newBuffer; + } } public float[] getBuffer() { diff --git a/src/main/java/com/morlunk/jumble/db/Database.java b/src/main/java/com/morlunk/jumble/db/Database.java deleted file mode 100644 index 7e4efdd..0000000 --- a/src/main/java/com/morlunk/jumble/db/Database.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2013 Andrew Comminos - * - * 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 com.morlunk.jumble.db; - -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; - -import java.util.ArrayList; -import java.util.List; - -/** - * Jumble's database is desinged to hold server-specific state information, such as comment blobs. - * Actual server objects should be stored in the client's DB implementation. - * Created by andrew on 20/07/13. - */ -public class Database extends SQLiteOpenHelper { - - public static final int DATABASE_VERSION = 1; - public static final String DATABASE_NAME = "jumble.db"; - - public Database(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL("CREATE TABLE IF NOT EXISTS `comments` (`who` TEXT, `comment` BLOB, `seen` DATE)"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `comments_comment` ON `comments`(`who`, `comment`)"); - db.execSQL("CREATE INDEX IF NOT EXISTS `comments_seen` ON `comments`(`seen`)"); - - db.execSQL("CREATE TABLE IF NOT EXISTS `blobs` (`hash` TEXT, `data` BLOB, `seen` DATE)"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `blobs_hash` ON `blobs`(`hash`)"); - db.execSQL("CREATE INDEX IF NOT EXISTS `blobs_seen` ON `blobs`(`seen`)"); - - db.execSQL("CREATE TABLE IF NOT EXISTS `tokens` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `server` INTEGER, `token` TEXT)"); - db.execSQL("CREATE INDEX IF NOT EXISTS `tokens_host_port` ON `tokens`(`server`)"); - - db.execSQL("CREATE TABLE IF NOT EXISTS `friends` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `hash` TEXT)"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `friends_name` ON `friends`(`name`)"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `friends_hash` ON `friends`(`hash`)"); - - db.execSQL("CREATE TABLE IF NOT EXISTS `ignored` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT)"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `ignored_hash` ON `ignored`(`hash`)"); - - db.execSQL("CREATE TABLE IF NOT EXISTS `muted` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT)"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `muted_hash` ON `muted`(`hash`)"); - - db.execSQL("CREATE TABLE IF NOT EXISTS `hidden` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hash` TEXT)"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `hidden_hash` ON `hidden`(`hash`)"); - - db.execSQL("CREATE TABLE IF NOT EXISTS `pingcache` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `hostname` TEXT, `port` INTEGER, `ping` INTEGER)"); - db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `pingcache_host_port` ON `pingcache`(`hostname`,`port`)"); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - // Nothing, yet! - } - - @Override - public void onOpen(SQLiteDatabase db) { - // Clean out old blobs - db.execSQL("DELETE FROM `comments` WHERE `seen` < datetime('now', '-1 years')"); - db.execSQL("DELETE FROM `blobs` WHERE `seen` < datetime('now', '-1 months')"); - } - - public void setTokens(long server, List<String> tokens) { - getWritableDatabase().delete("tokens", "server=?", new String[] { Long.toString(server) }); - - ContentValues values = new ContentValues(); - values.put("server", server); - for(String token : tokens) { - values.put("token", token); - getWritableDatabase().insert("tokens", null, values); - } - } - - public List<String> getTokens(long server) { - Cursor cursor = getReadableDatabase().query("tokens", new String[] { "token" }, "server=?", new String[] { Long.toString(server) }, null, null, null); - cursor.moveToFirst(); - List<String> tokens = new ArrayList<String>(); - while(!cursor.isAfterLast()) { - tokens.add(cursor.getString(0)); - cursor.moveToNext(); - } - cursor.close(); - return tokens; - } -} diff --git a/src/main/java/com/morlunk/jumble/net/JumbleConnection.java b/src/main/java/com/morlunk/jumble/net/JumbleConnection.java index e7b4286..9da8440 100644 --- a/src/main/java/com/morlunk/jumble/net/JumbleConnection.java +++ b/src/main/java/com/morlunk/jumble/net/JumbleConnection.java @@ -37,7 +37,6 @@ import java.net.*; import java.nio.ByteBuffer; import java.security.*; import java.security.cert.CertificateException; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; @@ -77,9 +76,9 @@ public class JumbleConnection { // Threading private ExecutorService mExecutorService; private ScheduledExecutorService mPingExecutorService; - private NetworkSendThread mNetworkThread; + private NetworkSendThread mNetworkSendThread; private Handler mMainHandler; - private Handler mNetworkHandler; + private Handler mNetworkSendHandler; // Networking and protocols private InetAddress mHost; @@ -94,6 +93,9 @@ public class JumbleConnection { private CryptState mCryptState = new CryptState(); private long mStartTimestamp; // Time that the connection was initiated in nanoseconds + // Latency + private long mLastUDPPing; + // Server private Server mServer; private int mServerVersion; @@ -214,12 +216,14 @@ public class JumbleConnection { public void messageUDPPing(byte[] data) { Log.v(Constants.TAG, "IN: UDP Ping"); byte[] timedata = new byte[8]; - System.arraycopy(data, 0, timedata, 0, 8); + System.arraycopy(data, 1, timedata, 0, 8); ByteBuffer buffer = ByteBuffer.allocate(8); buffer.put(timedata); buffer.flip(); - long timestamp = buffer.getLong(); + long timestamp = (long) (buffer.getLong() * Math.pow(10, 3)); // um -> nm + long now = System.nanoTime()-mStartTimestamp; + mLastUDPPing = now-timestamp; // TODO refresh UDP? } }; @@ -285,14 +289,14 @@ public class JumbleConnection { mUsingUDP = !mForceTCP; mStartTimestamp = System.nanoTime(); - mExecutorService = Executors.newFixedThreadPool(mForceTCP ? 2 : 3); // One TCP thread, one UDP thread (if not forcing TCP), one network send thread. + mExecutorService = Executors.newFixedThreadPool(mForceTCP ? 2 : 3); // One TCP receive thread, one UDP receive thread (if not forcing TCP), one network send thread mPingExecutorService = Executors.newSingleThreadScheduledExecutor(); mTCP = new JumbleTCP(); if(!mForceTCP) mUDP = new JumbleUDP(); - mNetworkThread = new NetworkSendThread(); - mExecutorService.submit(mNetworkThread); + mNetworkSendThread = new NetworkSendThread(); + mExecutorService.submit(mNetworkSendThread); mExecutorService.submit(mTCP); // We'll start UDP thread after TCP is established. FIXME? } @@ -339,6 +343,14 @@ public class JumbleConnection { return mServerOSVersion; } + public long getTCPLatency() { + return 0; + } + + public long getUDPLatency() { + return mLastUDPPing; + } + public int getSession() { return mSession; } @@ -349,12 +361,12 @@ public class JumbleConnection { public void disconnect() { mConnected = false; mSynchronized = false; - mNetworkHandler.postAtFrontOfQueue(new Runnable() { + mNetworkSendHandler.postAtFrontOfQueue(new Runnable() { @Override public void run() { try { mTCP.disconnect(); - if(mUDP != null) mUDP.disconnect(); + if (mUDP != null) mUDP.disconnect(); } catch (IOException e) { e.printStackTrace(); } @@ -447,7 +459,7 @@ public class JumbleConnection { } public void sendTCPMessage(final Message message, final JumbleTCPMessageType messageType) { - mNetworkHandler.post(new Runnable() { + mNetworkSendHandler.post(new Runnable() { @Override public void run() { try { @@ -460,13 +472,13 @@ public class JumbleConnection { } public void sendUDPMessage(final byte[] data, final int length, final boolean force) { - mNetworkHandler.post(new Runnable() { + mNetworkSendHandler.post(new Runnable() { @Override public void run() { try { - if(!force && (mForceTCP || !mUsingUDP)) + if (!force && (mForceTCP || !mUsingUDP)) mTCP.sendMessage(data, length, JumbleTCPMessageType.UDPTunnel); - else if(!mForceTCP) + else if (!mForceTCP) mUDP.sendMessage(data, length); } catch (IOException e) { e.printStackTrace(); // TODO handle me @@ -830,8 +842,7 @@ public class JumbleConnection { return; } mUDPSocket.connect(mHost, mServer.getPort()); - - DatagramPacket packet = new DatagramPacket(new byte[BUFFER_SIZE], BUFFER_SIZE); + final DatagramPacket packet = new DatagramPacket(new byte[BUFFER_SIZE], BUFFER_SIZE); Log.v(Constants.TAG, "Created UDP socket"); @@ -840,7 +851,8 @@ public class JumbleConnection { mUDPSocket.receive(packet); // Decrypt UDP packet using OCB-AES128 final byte[] decryptedData = mCryptState.decrypt(packet.getData(), packet.getLength()); - if(decryptedData == null && + /* + if (decryptedData == null && mCryptState.getLastGoodElapsed() > 5000000 && mCryptState.getLastRequestElapsed() > 5000000) { // If decryption fails, request resync @@ -848,7 +860,14 @@ public class JumbleConnection { Mumble.CryptSetup.Builder csb = Mumble.CryptSetup.newBuilder(); mTCP.sendMessage(csb.build(), JumbleTCPMessageType.CryptSetup); } - handleUDPMessage(decryptedData); + */ + mMainHandler.post(new Runnable() { + @Override + public void run() { + if(decryptedData != null) + handleUDPMessage(decryptedData); + } + }); } catch (IOException e) { e.printStackTrace(); break; @@ -875,7 +894,7 @@ public class JumbleConnection { @Override public void run() { Looper.prepare(); - mNetworkHandler = new Handler(); + mNetworkSendHandler = new Handler(); Looper.loop(); } } |