fixed some issues around ibb

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/parser/IqParser.java                     |  3 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java        | 51 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java |  3 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java   | 22 
4 files changed, 61 insertions(+), 18 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/parser/IqParser.java 🔗

@@ -358,7 +358,8 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
 			final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
 			mXmppConnectionService.sendIqPacket(account, response, null);
 		} else if (packet.hasChild("open", "http://jabber.org/protocol/ibb")
-				|| packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
+				|| packet.hasChild("data", "http://jabber.org/protocol/ibb")
+				|| packet.hasChild("close","http://jabber.org/protocol/ibb")) {
 			mXmppConnectionService.getJingleConnectionManager()
 				.deliverIbbPacket(account, packet);
 		} else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {

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

@@ -756,7 +756,7 @@ public class JingleConnection implements Transferable {
 	}
 
 	private void sendFallbackToIbb() {
-		Log.d(Config.LOGTAG, "sending fallback to ibb");
+		Log.d(Config.LOGTAG, account.getJid().toBareJid()+": sending fallback to ibb");
 		JinglePacket packet = this.bootstrapPacket("transport-replace");
 		Content content = new Content(this.contentCreator, this.contentName);
 		this.transportId = this.mJingleConnectionManager.nextRandomId();
@@ -767,6 +767,18 @@ public class JingleConnection implements Transferable {
 		this.sendJinglePacket(packet);
 	}
 
+	OnTransportConnected onIbbTransportConnected = new OnTransportConnected() {
+		@Override
+		public void failed() {
+			Log.d(Config.LOGTAG, "ibb open failed");
+		}
+
+		@Override
+		public void established() {
+			JingleConnection.this.transport.send(file, onFileTransmissionSatusChanged);
+		}
+	};
+
 	private boolean receiveFallbackToIbb(JinglePacket packet) {
 		Log.d(Config.LOGTAG, "receiving fallack to ibb");
 		String receivedBlockSize = packet.getJingleContent().ibbTransport()
@@ -779,13 +791,28 @@ public class JingleConnection implements Transferable {
 		}
 		this.transportId = packet.getJingleContent().getTransportId();
 		this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize);
-		this.transport.receive(file, onFileTransmissionSatusChanged);
+
 		JinglePacket answer = bootstrapPacket("transport-accept");
 		Content content = new Content("initiator", "a-file-offer");
 		content.setTransportId(this.transportId);
 		content.ibbTransport().setAttribute("block-size",this.ibbBlockSize);
 		answer.setContent(content);
-		this.sendJinglePacket(answer);
+
+
+		if (initiator.equals(account.getJid())) {
+			this.sendJinglePacket(answer, new OnIqPacketReceived() {
+				@Override
+				public void onIqPacketReceived(Account account, IqPacket packet) {
+					if (packet.getType() == IqPacket.TYPE.RESULT) {
+						Log.d(Config.LOGTAG, account.getJid().toBareJid() + " recipient ACKed our transport-accept. creating ibb");
+						transport.connect(onIbbTransportConnected);
+					}
+				}
+			});
+		} else {
+			this.transport.receive(file, onFileTransmissionSatusChanged);
+			this.sendJinglePacket(answer);
+		}
 		return true;
 	}
 
@@ -800,19 +827,13 @@ public class JingleConnection implements Transferable {
 				}
 			}
 			this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize);
-			this.transport.connect(new OnTransportConnected() {
-
-				@Override
-				public void failed() {
-					Log.d(Config.LOGTAG, "ibb open failed");
-				}
 
-				@Override
-				public void established() {
-					JingleConnection.this.transport.send(file,
-							onFileTransmissionSatusChanged);
-				}
-			});
+			//might be receive instead if we are not initiating
+			if (initiator.equals(account.getJid())) {
+				this.transport.connect(onIbbTransportConnected);
+			} else {
+				this.transport.receive(file,onFileTransmissionSatusChanged);
+			}
 			return true;
 		} else {
 			return false;

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

@@ -142,6 +142,9 @@ public class JingleConnectionManager extends AbstractConnectionManager {
 		} else if (packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
 			payload = packet.findChild("data", "http://jabber.org/protocol/ibb");
 			sid = payload.getAttribute("sid");
+		} else if (packet.hasChild("close","http://jabber.org/protocol/ibb")) {
+			payload = packet.findChild("close", "http://jabber.org/protocol/ibb");
+			sid = payload.getAttribute("sid");
 		}
 		if (sid != null) {
 			for (JingleConnection connection : connections) {

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java 🔗

@@ -47,7 +47,9 @@ public class JingleInbandTransport extends JingleTransport {
 		@Override
 		public void onIqPacketReceived(Account account, IqPacket packet) {
 			if (connected && packet.getType() == IqPacket.TYPE.RESULT) {
-				sendNextBlock();
+				if (remainingSize > 0) {
+					sendNextBlock();
+				}
 			}
 		}
 	};
@@ -60,6 +62,14 @@ public class JingleInbandTransport extends JingleTransport {
 		this.sessionId = sid;
 	}
 
+	private void sendClose() {
+		IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
+		iq.setTo(this.counterpart);
+		Element close = iq.addChild("close", "http://jabber.org/protocol/ibb");
+		close.setAttribute("sid", this.sessionId);
+		this.account.getXmppConnection().sendIqPacket(iq, null);
+	}
+
 	public void connect(final OnTransportConnected callback) {
 		IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
 		iq.setTo(this.counterpart);
@@ -155,6 +165,7 @@ public class JingleInbandTransport extends JingleTransport {
 		try {
 			int count = fileInputStream.read(buffer);
 			if (count == -1) {
+				sendClose();
 				file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
 				this.onFileTransmissionStatusChanged.onFileTransmitted(file);
 				fileInputStream.close();
@@ -181,12 +192,13 @@ public class JingleInbandTransport extends JingleTransport {
 			if (this.remainingSize > 0) {
 				connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100));
 			} else {
+				sendClose();
 				file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
 				this.onFileTransmissionStatusChanged.onFileTransmitted(file);
 				fileInputStream.close();
 			}
 		} catch (IOException e) {
-			Log.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage());
+			Log.d(Config.LOGTAG,account.getJid().toBareJid()+": io exception during sendNextBlock() "+e.getMessage());
 			FileBackend.close(fileInputStream);
 			this.onFileTransmissionStatusChanged.onFileTransferAborted();
 		}
@@ -232,7 +244,13 @@ public class JingleInbandTransport extends JingleTransport {
 			this.receiveNextBlock(payload.getContent());
 			this.account.getXmppConnection().sendIqPacket(
 					packet.generateResponse(IqPacket.TYPE.RESULT), null);
+		} else if (connected && payload.getName().equals("close")) {
+			this.connected = false;
+			this.account.getXmppConnection().sendIqPacket(
+					packet.generateResponse(IqPacket.TYPE.RESULT), null);
+			Log.d(Config.LOGTAG,account.getJid().toBareJid()+": received ibb close");
 		} else {
+			Log.d(Config.LOGTAG,payload.toString());
 			// TODO some sort of exception
 		}
 	}