tried to fix some race conditions. not adding duplicate candidates. needs more checks though

Daniel Gultsch created

Change summary

src/eu/siacs/conversations/services/XmppConnectionService.java      |  3 
src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java        | 43 
src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java |  9 
src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java         | 10 
4 files changed, 45 insertions(+), 20 deletions(-)

Detailed changes

src/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -134,8 +134,7 @@ public class XmppConnectionService extends Service {
 					message = MessageParser.parsePgpChat(pgpBody, packet,
 							account, service);
 					message.markUnread();
-				} else if (packet.hasChild("body")
-						&& (packet.getBody().startsWith("?OTR"))) {
+				} else if ((packet.getBody()!=null) && (packet.getBody().startsWith("?OTR"))) {
 					message = MessageParser.parseOtrChat(packet, account,
 							service);
 					if (message != null) {

src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java 🔗

@@ -142,7 +142,6 @@ public class JingleConnection {
 		} else {
 			Log.d("xmppService","no file offer was attached. aborting");
 		}
-		Log.d("xmppService","session Id "+getSessionId());
 	}
 	
 	private void sendInitRequest() {
@@ -168,7 +167,8 @@ public class JingleConnection {
 			@Override
 			public void onPrimaryCandidateFound(boolean success, Element candidate) {
 				if (success) {
-					if (mergeCandidate(candidate)) {
+					if (!equalCandidateExists(candidate)) {
+						mergeCandidate(candidate);
 						content.addCandidate(candidate);
 					}
 				}
@@ -202,7 +202,7 @@ public class JingleConnection {
 	private void accept(JinglePacket packet) {
 		Log.d("xmppService","session-accept: "+packet.toString());
 		Content content = packet.getJingleContent();
-		this.mergeCandidates(content.getCanditates());
+		mergeCandidates(content.getCanditates());
 		this.status = STATUS_ACCEPTED;
 		this.connectWithCandidates();
 		IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
@@ -322,14 +322,25 @@ public class JingleConnection {
 	    }
 	}
 	
-	private void sendCandidateUsed(String cid) {
+	private void sendCandidateUsed(final String cid) {
 		JinglePacket packet = bootstrapPacket();
 		packet.setAction("transport-info");
 		Content content = new Content();
 		content.setUsedCandidate(this.content.getTransportId(), cid);
 		packet.setContent(content);
-		Log.d("xmppService","send using candidate: "+packet.toString());
-		this.account.getXmppConnection().sendIqPacket(packet, responseListener);
+		Log.d("xmppService","send using candidate: "+cid);
+		this.account.getXmppConnection().sendIqPacket(packet, new OnIqPacketReceived() {
+			
+			@Override
+			public void onIqPacketReceived(Account account, IqPacket packet) {
+				Log.d("xmppService","got ack for our candidate used");
+				if (status!=STATUS_TRANSMITTING) {
+					connect(connections.get(cid));
+				} else {
+					Log.d("xmppService","ignoring cuz already transmitting");
+				}
+			}
+		});
 	}
 
 	public String getInitiator() {
@@ -344,19 +355,27 @@ public class JingleConnection {
 		return this.status;
 	}
 	
-	private boolean mergeCandidate(Element candidate) {
+	private boolean equalCandidateExists(Element candidate) {
 		for(Element c : this.candidates) {
 			if (c.getAttribute("host").equals(candidate.getAttribute("host"))&&(c.getAttribute("port").equals(candidate.getAttribute("port")))) {
-				return false;
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	private void mergeCandidate(Element candidate) {
+		for(Element c : this.candidates) {
+			if (c.getAttribute("cid").equals(candidate.getAttribute("cid"))) {
+				return;
 			}
 		}
 		this.candidates.add(candidate);
-		return true;
 	}
 	
-	private void mergeCandidates(List<Element> canditates) {
-		for(Element c : canditates) {
-			this.mergeCandidate(c);
+	private void mergeCandidates(List<Element> candidates) {
+		for(Element c : candidates) {
+			mergeCandidate(c);
 		}
 	}
 }

src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java 🔗

@@ -43,8 +43,6 @@ public class JingleConnectionManager {
 						.getCounterPart().equals(packet.getFrom())) {
 					connection.deliverPacket(packet);
 					return;
-				} else {
-					Log.d("xmppService","no match sid:"+connection.getSessionId()+"="+packet.getSessionId()+" counterpart:"+connection.getCounterPart()+"="+packet.getFrom()+" account:"+connection.getAccountJid()+"="+packet.getTo());
 				}
 			}
 			Log.d("xmppService","delivering packet failed "+packet.toString());
@@ -135,6 +133,11 @@ public class JingleConnectionManager {
 	}
 	
 	public long getAutoAcceptFileSize() {
-		return this.xmppConnectionService.getPreferences().getLong("auto_accept_file_size", 0);
+		String config = this.xmppConnectionService.getPreferences().getString("auto_accept_file_size", "0");
+		try {
+			return Long.parseLong(config);
+		} catch (NumberFormatException e) {
+			return 0;
+		}
 	}
 }

src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java 🔗

@@ -160,9 +160,13 @@ public class SocksConnection {
 							count = (int) remainingSize;
 						}
 						count = inputStream.read(buffer, 0, count);
-						fileOutputStream.write(buffer, 0, count);
-						digest.update(buffer, 0, count);
-						remainingSize-=count;
+						if (count==-1) {
+							Log.d("xmppService","end of stream");
+						} else {
+							fileOutputStream.write(buffer, 0, count);
+							digest.update(buffer, 0, count);
+							remainingSize-=count;
+						}
 					}
 					fileOutputStream.flush();
 					fileOutputStream.close();