aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs/conversations/xmpp/jingle
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel@gultsch.de>2014-04-20 22:34:27 +0200
committerDaniel Gultsch <daniel@gultsch.de>2014-04-20 22:34:27 +0200
commit4d730fd1edb6cab210c035b5f0f692a37dada5e9 (patch)
tree65331d142e327cd02bb2f44ea8ec7643ccf353a4 /src/eu/siacs/conversations/xmpp/jingle
parent04418484a2eadca43772d2d63db300068fc7feca (diff)
added proxy activate and a lot of code clean up. totatly untested
Diffstat (limited to 'src/eu/siacs/conversations/xmpp/jingle')
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java171
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java6
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java2
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java109
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java18
5 files changed, 161 insertions, 145 deletions
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
index ad2d94f8..b40bf6dd 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
@@ -48,6 +48,8 @@ public class JingleConnection {
private boolean receivedCandidate = false;
private boolean sentCandidate = false;
+ private JingleTransport transport = null;
+
private OnIqPacketReceived responseListener = new OnIqPacketReceived() {
@Override
@@ -59,6 +61,37 @@ public class JingleConnection {
}
};
+ final OnFileTransmitted onFileTransmitted = new OnFileTransmitted() {
+
+ @Override
+ public void onFileTransmitted(JingleFile file) {
+ if (responder.equals(account.getFullJid())) {
+ sendSuccess();
+ mXmppConnectionService.markMessage(message, Message.STATUS_RECIEVED);
+ }
+ Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum());
+ }
+ };
+
+ private OnProxyActivated onProxyActivated = new OnProxyActivated() {
+
+ @Override
+ public void success() {
+ if (initiator.equals(account.getFullJid())) {
+ Log.d("xmppService","we were initiating. sending file");
+ transport.send(file,onFileTransmitted);
+ } else {
+ transport.receive(file,onFileTransmitted);
+ Log.d("xmppService","we were responding. receiving file");
+ }
+ }
+
+ @Override
+ public void failed() {
+ Log.d("xmppService","proxy activation failed");
+ }
+ };
+
public JingleConnection(JingleConnectionManager mJingleConnectionManager) {
this.mJingleConnectionManager = mJingleConnectionManager;
this.mXmppConnectionService = mJingleConnectionManager.getXmppConnectionService();
@@ -155,7 +188,7 @@ public class JingleConnection {
this.sessionId = packet.getSessionId();
Content content = packet.getJingleContent();
this.transportId = content.getTransportId();
- this.mergeCandidates(JingleCandidate.parse(content.getCanditates()));
+ this.mergeCandidates(JingleCandidate.parse(content.socks5transport().getChildren()));
this.fileOffer = packet.getJingleContent().getFileOffer();
if (fileOffer!=null) {
this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message);
@@ -184,10 +217,11 @@ public class JingleConnection {
if (message.getType() == Message.TYPE_IMAGE) {
content.setAttribute("creator", "initiator");
content.setAttribute("name", "a-file-offer");
+ content.setTransportId(this.transportId);
this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message);
content.setFileOffer(this.file);
this.transportId = this.mJingleConnectionManager.nextRandomId();
- content.setCandidates(this.transportId,getCandidatesAsElements());
+ content.socks5transport().setChildren(getCandidatesAsElements());
packet.setContent(content);
this.sendJinglePacket(packet);
this.status = STATUS_INITIATED;
@@ -212,6 +246,7 @@ public class JingleConnection {
final JinglePacket packet = bootstrapPacket("session-accept");
final Content content = new Content();
content.setFileOffer(fileOffer);
+ content.setTransportId(transportId);
if ((success)&&(!equalCandidateExists(candidate))) {
final SocksConnection socksConnection = new SocksConnection(JingleConnection.this, candidate);
connections.put(candidate.getCid(), socksConnection);
@@ -220,7 +255,7 @@ public class JingleConnection {
@Override
public void failed() {
Log.d("xmppService","connection to our own primary candidate failed");
- content.setCandidates(transportId, getCandidatesAsElements());
+ content.socks5transport().setChildren(getCandidatesAsElements());
packet.setContent(content);
sendJinglePacket(packet);
}
@@ -229,14 +264,14 @@ public class JingleConnection {
public void established() {
Log.d("xmppService","connected to primary candidate");
mergeCandidate(candidate);
- content.setCandidates(transportId, getCandidatesAsElements());
+ content.socks5transport().setChildren(getCandidatesAsElements());
packet.setContent(content);
sendJinglePacket(packet);
}
});
} else {
Log.d("xmppService","did not find a primary candidate for ourself");
- content.setCandidates(transportId, getCandidatesAsElements());
+ content.socks5transport().setChildren(getCandidatesAsElements());
packet.setContent(content);
sendJinglePacket(packet);
}
@@ -256,13 +291,13 @@ public class JingleConnection {
}
private void sendJinglePacket(JinglePacket packet) {
- Log.d("xmppService",packet.toPrettyString());
+ //Log.d("xmppService",packet.toString());
account.getXmppConnection().sendIqPacket(packet,responseListener);
}
private void accept(JinglePacket packet) {
Content content = packet.getJingleContent();
- mergeCandidates(JingleCandidate.parse(content.getCanditates()));
+ mergeCandidates(JingleCandidate.parse(content.socks5transport().getChildren()));
this.status = STATUS_ACCEPTED;
this.connectNextCandidate();
IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
@@ -271,30 +306,44 @@ public class JingleConnection {
private void transportInfo(JinglePacket packet) {
Content content = packet.getJingleContent();
- String cid = content.getUsedCandidate();
- IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
- if (cid!=null) {
- Log.d("xmppService","candidate used by counterpart:"+cid);
- JingleCandidate candidate = getCandidate(cid);
- candidate.flagAsUsedByCounterpart();
- this.receivedCandidate = true;
- if ((status == STATUS_ACCEPTED)&&(this.sentCandidate)) {
- this.connect();
+ if (content.hasSocks5Transport()) {
+ if (content.socks5transport().hasChild("activated")) {
+ onProxyActivated.success();
+ } else if (content.socks5transport().hasChild("activated")) {
+ onProxyActivated.failed();
+ } else if (content.socks5transport().hasChild("candidate-error")) {
+ Log.d("xmppService","received candidate error");
+ this.receivedCandidate = true;
+ if (status == STATUS_ACCEPTED) {
+ this.connect();
+ }
+ } else if (content.socks5transport().hasChild("candidate-used")){
+ String cid = content.socks5transport().findChild("candidate-used").getAttribute("cid");
+ if (cid!=null) {
+ Log.d("xmppService","candidate used by counterpart:"+cid);
+ JingleCandidate candidate = getCandidate(cid);
+ candidate.flagAsUsedByCounterpart();
+ this.receivedCandidate = true;
+ if ((status == STATUS_ACCEPTED)&&(this.sentCandidate)) {
+ this.connect();
+ } else {
+ Log.d("xmppService","ignoring because file is already in transmission or we havent sent our candidate yet");
+ }
+ } else {
+ Log.d("xmppService","couldn't read used candidate");
+ }
} else {
- Log.d("xmppService","ignoring because file is already in transmission or we havent sent our candidate yet");
- }
- } else if (content.hasCandidateError()) {
- Log.d("xmppService","received candidate error");
- this.receivedCandidate = true;
- if (status == STATUS_ACCEPTED) {
- this.connect();
+ Log.d("xmppService","empty transport");
}
}
+
+ IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
account.getXmppConnection().sendIqPacket(response, null);
}
private void connect() {
final SocksConnection connection = chooseConnection();
+ this.transport = connection;
if (connection==null) {
Log.d("xmppService","could not find suitable candidate");
this.disconnect();
@@ -302,44 +351,33 @@ public class JingleConnection {
this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_FAILED);
} else {
this.status = STATUS_TRANSMITTING;
- final OnFileTransmitted callback = new OnFileTransmitted() {
-
- @Override
- public void onFileTransmitted(JingleFile file) {
- if (responder.equals(account.getFullJid())) {
- sendSuccess();
- mXmppConnectionService.markMessage(message, Message.STATUS_RECIEVED);
- }
- Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum());
- }
- };
- if (connection.isProxy()&&(connection.getCandidate().isOurs())) {
- Log.d("xmppService","candidate "+connection.getCandidate().getCid()+" was our proxy and needs activation");
- IqPacket activation = new IqPacket(IqPacket.TYPE_SET);
- activation.setTo(connection.getCandidate().getJid());
- activation.query("http://jabber.org/protocol/bytestreams").setAttribute("sid", this.getSessionId());
- activation.query().addChild("activate").setContent(this.getCounterPart());
- this.account.getXmppConnection().sendIqPacket(activation, new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- Log.d("xmppService","activation result: "+packet.toString());
- if (initiator.equals(account.getFullJid())) {
- Log.d("xmppService","we were initiating. sending file");
- connection.send(file,callback);
- } else {
- connection.receive(file,callback);
- Log.d("xmppService","we were responding. receiving file");
+ if (connection.isProxy()) {
+ if (connection.getCandidate().isOurs()) {
+ Log.d("xmppService","candidate "+connection.getCandidate().getCid()+" was our proxy and needs activation");
+ IqPacket activation = new IqPacket(IqPacket.TYPE_SET);
+ activation.setTo(connection.getCandidate().getJid());
+ activation.query("http://jabber.org/protocol/bytestreams").setAttribute("sid", this.getSessionId());
+ activation.query().addChild("activate").setContent(this.getCounterPart());
+ this.account.getXmppConnection().sendIqPacket(activation, new OnIqPacketReceived() {
+
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket packet) {
+ if (packet.getType()==IqPacket.TYPE_ERROR) {
+ onProxyActivated.failed();
+ } else {
+ onProxyActivated.success();
+ sendProxyActivated(connection.getCandidate().getCid());
+ }
}
- }
- });
+ });
+ }
} else {
if (initiator.equals(account.getFullJid())) {
Log.d("xmppService","we were initiating. sending file");
- connection.send(file,callback);
+ connection.send(file,onFileTransmitted);
} else {
Log.d("xmppService","we were responding. receiving file");
- connection.receive(file,callback);
+ connection.receive(file,onFileTransmitted);
}
}
}
@@ -439,13 +477,26 @@ public class JingleConnection {
}
}
+ private void sendProxyActivated(String cid) {
+ JinglePacket packet = bootstrapPacket("transport-info");
+ Content content = new Content();
+ //TODO: put these into actual variables
+ content.setAttribute("creator", "initiator");
+ content.setAttribute("name", "a-file-offer");
+ content.setTransportId(this.transportId);
+ content.socks5transport().addChild("activated").setAttribute("cid", cid);
+ packet.setContent(content);
+ this.sendJinglePacket(packet);
+ }
+
private void sendCandidateUsed(final String cid) {
JinglePacket packet = bootstrapPacket("transport-info");
Content content = new Content();
//TODO: put these into actual variables
content.setAttribute("creator", "initiator");
content.setAttribute("name", "a-file-offer");
- content.setUsedCandidate(this.transportId, cid);
+ content.setTransportId(this.transportId);
+ content.setUsedCandidate(cid);
packet.setContent(content);
this.sendJinglePacket(packet);
this.sentCandidate = true;
@@ -460,7 +511,8 @@ public class JingleConnection {
//TODO: put these into actual variables
content.setAttribute("creator", "initiator");
content.setAttribute("name", "a-file-offer");
- content.setCandidateError(this.transportId);
+ content.setTransportId(this.transportId);
+ content.setCandidateError();
packet.setContent(content);
this.sendJinglePacket(packet);
this.sentCandidate = true;
@@ -513,4 +565,9 @@ public class JingleConnection {
}
return null;
}
+
+ interface OnProxyActivated {
+ public void success();
+ public void failed();
+ }
}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java
new file mode 100644
index 00000000..347824f1
--- /dev/null
+++ b/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java
@@ -0,0 +1,6 @@
+package eu.siacs.conversations.xmpp.jingle;
+
+public abstract class JingleTransport {
+ public abstract void receive(final JingleFile file, final OnFileTransmitted callback);
+ public abstract void send(final JingleFile file, final OnFileTransmitted callback);
+}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java b/src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java
index 897c202f..1a945a65 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java
@@ -18,7 +18,7 @@ import eu.siacs.conversations.xml.Element;
import android.util.Log;
import android.widget.Button;
-public class SocksConnection {
+public class SocksConnection extends JingleTransport {
private JingleCandidate candidate;
private String destination;
private OutputStream outputStream;
diff --git a/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java b/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java
index 3cd30251..dbd2a9fc 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java
@@ -1,12 +1,12 @@
package eu.siacs.conversations.xmpp.jingle.stanzas;
-import java.util.ArrayList;
-import java.util.List;
-
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jingle.JingleFile;
public class Content extends Element {
+
+ private String transportId;
+
private Content(String name) {
super(name);
}
@@ -15,6 +15,10 @@ public class Content extends Element {
super("content");
}
+ public void setTransportId(String sid) {
+ this.transportId = sid;
+ }
+
public void setFileOffer(JingleFile actualFile) {
Element description = this.addChild("description", "urn:xmpp:jingle:apps:file-transfer:3");
Element offer = description.addChild("offer");
@@ -34,91 +38,58 @@ public class Content extends Element {
}
return offer.findChild("file");
}
-
- public void setCandidates(String transportId, List<Element> canditates) {
- Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- if (transport==null) {
- transport = this.addChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- }
- transport.setAttribute("sid", transportId);
- transport.clearChildren();
- for(Element canditate : canditates) {
- transport.addChild(canditate);
- }
- }
- public List<Element> getCanditates() {
- Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- if (transport==null) {
- return new ArrayList<Element>();
- } else {
- return transport.getChildren();
+ public void setFileOffer(Element fileOffer) {
+ Element description = this.findChild("description", "urn:xmpp:jingle:apps:file-transfer:3");
+ if (description==null) {
+ description = this.addChild("description", "urn:xmpp:jingle:apps:file-transfer:3");
}
+ description.addChild(fileOffer);
}
public String getTransportId() {
- Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- if (transport==null) {
- return null;
+ if (hasSocks5Transport()) {
+ this.transportId = socks5transport().getAttribute("sid");
+ } else if (hasIbbTransport()) {
+ this.transportId = ibbTransport().getAttribute("sid");
}
- return transport.getAttribute("sid");
+ return this.transportId;
}
- public String getUsedCandidate() {
- Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- if (transport==null) {
- return null;
- }
- Element usedCandidate = transport.findChild("candidate-used");
- if (usedCandidate==null) {
- return null;
- } else {
- return usedCandidate.getAttribute("cid");
- }
+ public void setUsedCandidate(String cid) {
+ socks5transport().clearChildren();
+ Element usedCandidate = socks5transport().addChild("candidate-used");
+ usedCandidate.setAttribute("cid",cid);
}
-
- public boolean hasCandidateError() {
- Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- if (transport==null) {
- return false;
- }
- return transport.hasChild("candidate-error");
+
+ public void setCandidateError() {
+ socks5transport().clearChildren();
+ socks5transport().addChild("candidate-error");
}
- public void setUsedCandidate(String transportId, String cid) {
+ public Element socks5transport() {
Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
if (transport==null) {
transport = this.addChild("transport", "urn:xmpp:jingle:transports:s5b:1");
+ transport.setAttribute("sid", this.transportId);
}
- transport.setAttribute("sid", transportId);
- transport.clearChildren();
- Element usedCandidate = transport.addChild("candidate-used");
- usedCandidate.setAttribute("cid",cid);
+ return transport;
}
-
- public void addCandidate(Element candidate) {
- Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
+
+ public Element ibbTransport() {
+ Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:ibb:1");
if (transport==null) {
- transport = this.addChild("transport", "urn:xmpp:jingle:transports:s5b:1");
+ transport = this.addChild("transport", "urn:xmpp:jingle:transports:ibb:1");
+ transport.setAttribute("sid", this.transportId);
}
- transport.addChild(candidate);
+ return transport;
}
-
- public void setFileOffer(Element fileOffer) {
- Element description = this.findChild("description", "urn:xmpp:jingle:apps:file-transfer:3");
- if (description==null) {
- description = this.addChild("description", "urn:xmpp:jingle:apps:file-transfer:3");
- }
- description.addChild(fileOffer);
+
+ public boolean hasSocks5Transport() {
+ return this.hasChild("transport", "urn:xmpp:jingle:transports:s5b:1");
}
-
- public void setCandidateError(String transportId) {
- Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- if (transport==null) {
- transport = this.addChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- }
- transport.setAttribute("sid", transportId);
- transport.clearChildren();
- transport.addChild("candidate-error");
+
+ public boolean hasIbbTransport() {
+ return this.hasChild("transport","urn:xmpp:jingle:transports:ibb:1");
}
}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java b/src/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java
index fdb53b36..55700609 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/stanzas/JinglePacket.java
@@ -92,22 +92,4 @@ public class JinglePacket extends IqPacket {
public boolean isAction(String action) {
return action.equalsIgnoreCase(this.getAction());
}
-
- public String toPrettyString() {
- StringBuilder output = new StringBuilder();
- output.append("["+getAction()+ " to:"+getTo());
- if (this.content!=null) {
- if (this.content.getUsedCandidate()!=null) {
- output.append(" [used-candidate="+this.content.getUsedCandidate()+"]");
- } else if (this.content.hasCandidateError()) {
- output.append(" [candidate-error]");
- } else {
- for(Element c : this.content.getCanditates()) {
- output.append(" ["+c.getAttribute("host")+":"+c.getAttribute("port")+"]");
- }
- }
- }
- output.append("]");
- return output.toString();
- }
}