aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs/conversations/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/eu/siacs/conversations/xmpp')
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java138
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java209
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java27
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java4
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java42
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java26
6 files changed, 326 insertions, 120 deletions
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java b/src/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java
new file mode 100644
index 00000000..80ffeaaa
--- /dev/null
+++ b/src/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java
@@ -0,0 +1,138 @@
+package eu.siacs.conversations.xmpp.jingle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.siacs.conversations.xml.Element;
+
+public class JingleCandidate {
+
+ public static int TYPE_UNKNOWN;
+ public static int TYPE_DIRECT = 0;
+ public static int TYPE_PROXY = 1;
+
+ private boolean ours;
+ private boolean usedByCounterpart = false;
+ private String cid;
+ private String host;
+ private int port;
+ private int type;
+ private String jid;
+ private int priority;
+
+ public JingleCandidate(String cid,boolean ours) {
+ this.ours = ours;
+ this.cid = cid;
+ }
+
+ public String getCid() {
+ return cid;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public String getHost() {
+ return this.host;
+ }
+
+ public void setJid(String jid) {
+ this.jid = jid;
+ }
+
+ public String getJid() {
+ return this.jid;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public int getPort() {
+ return this.port;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public void setType(String type) {
+ if ("proxy".equals(type)) {
+ this.type = TYPE_PROXY;
+ } else if ("direct".equals(type)) {
+ this.type = TYPE_DIRECT;
+ } else {
+ this.type = TYPE_UNKNOWN;
+ }
+ }
+
+ public void setPriority(int i) {
+ this.priority = i;
+ }
+
+ public int getPriority() {
+ return this.priority;
+ }
+
+ public boolean equals(JingleCandidate other) {
+ return this.getCid().equals(other.getCid());
+ }
+
+ public boolean equalValues(JingleCandidate other) {
+ return other.getHost().equals(this.getHost())&&(other.getPort()==this.getPort());
+ }
+
+ public boolean isOurs() {
+ return ours;
+ }
+
+ public int getType() {
+ return this.type;
+ }
+
+ public static List<JingleCandidate> parse(List<Element> canditates) {
+ List<JingleCandidate> parsedCandidates = new ArrayList<JingleCandidate>();
+ for(Element c : canditates) {
+ parsedCandidates.add(JingleCandidate.parse(c));
+ }
+ return parsedCandidates;
+ }
+
+ public static JingleCandidate parse(Element candidate) {
+ JingleCandidate parsedCandidate = new JingleCandidate(candidate.getAttribute("cid"), false);
+ parsedCandidate.setHost(candidate.getAttribute("host"));
+ parsedCandidate.setJid(candidate.getAttribute("jid"));
+ parsedCandidate.setType(candidate.getAttribute("type"));
+ parsedCandidate.setPriority(Integer.parseInt(candidate.getAttribute("priority")));
+ parsedCandidate.setPort(Integer.parseInt(candidate.getAttribute("port")));
+ return parsedCandidate;
+ }
+
+ public Element toElement() {
+ Element element = new Element("candidate");
+ element.setAttribute("cid", this.getCid());
+ element.setAttribute("host", this.getHost());
+ element.setAttribute("port", ""+this.getPort());
+ element.setAttribute("jid", this.getJid());
+ element.setAttribute("priority",""+this.getPriority());
+ if (this.getType()==TYPE_DIRECT) {
+ element.setAttribute("type","direct");
+ } else if (this.getType()==TYPE_PROXY) {
+ element.setAttribute("type","proxy");
+ }
+ return element;
+ }
+
+ public void flagAsUsedByCounterpart() {
+ this.usedByCounterpart = true;
+ }
+
+ public boolean isUsedByCounterpart() {
+ return this.usedByCounterpart;
+ }
+
+ public String toString() {
+ return this.getHost()+":"+this.getPort()+" (prio="+this.getPriority()+")";
+ }
+}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
index 75c2c8e0..a7fd367d 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
@@ -38,12 +38,15 @@ public class JingleConnection {
private Account account;
private String initiator;
private String responder;
- private List<Element> candidates = new ArrayList<Element>();
- private List<String> candidatesUsedByCounterpart = new ArrayList<String>();
+ private List<JingleCandidate> candidates = new ArrayList<JingleCandidate>();
private HashMap<String, SocksConnection> connections = new HashMap<String, SocksConnection>();
- private Content content = new Content();
+
+ private String transportId;
+ private Element fileOffer;
private JingleFile file = null;
+ private boolean receivedCandidateError = false;
+
private OnIqPacketReceived responseListener = new OnIqPacketReceived() {
@Override
@@ -107,10 +110,11 @@ public class JingleConnection {
this.mJingleConnectionManager.getPrimaryCandidate(account, new OnPrimaryCandidateFound() {
@Override
- public void onPrimaryCandidateFound(boolean success, Element candidate) {
+ public void onPrimaryCandidateFound(boolean success, JingleCandidate candidate) {
if (success) {
mergeCandidate(candidate);
}
+ openOurCandidates();
sendInitRequest();
}
});
@@ -130,9 +134,10 @@ public class JingleConnection {
this.initiator = packet.getFrom();
this.responder = this.account.getFullJid();
this.sessionId = packet.getSessionId();
- this.content = packet.getJingleContent();
- this.mergeCandidates(this.content.getCanditates());
- Element fileOffer = packet.getJingleContent().getFileOffer();
+ Content content = packet.getJingleContent();
+ this.transportId = content.getTransportId();
+ this.mergeCandidates(JingleCandidate.parse(content.getCanditates()));
+ this.fileOffer = packet.getJingleContent().getFileOffer();
if (fileOffer!=null) {
this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message);
Element fileSize = fileOffer.findChild("size");
@@ -156,13 +161,14 @@ public class JingleConnection {
private void sendInitRequest() {
JinglePacket packet = this.bootstrapPacket("session-initiate");
- this.content = new Content();
+ Content content = new Content();
if (message.getType() == Message.TYPE_IMAGE) {
content.setAttribute("creator", "initiator");
content.setAttribute("name", "a-file-offer");
this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message);
content.setFileOffer(this.file);
- content.setCandidates(this.mJingleConnectionManager.nextRandomId(),this.candidates);
+ this.transportId = this.mJingleConnectionManager.nextRandomId();
+ content.setCandidates(this.transportId,getCandidatesAsElements());
packet.setContent(content);
Log.d("xmppService",packet.toString());
account.getXmppConnection().sendIqPacket(packet, this.responseListener);
@@ -170,17 +176,28 @@ public class JingleConnection {
}
}
+ private List<Element> getCandidatesAsElements() {
+ List<Element> elements = new ArrayList<Element>();
+ for(JingleCandidate c : this.candidates) {
+ elements.add(c.toElement());
+ }
+ return elements;
+ }
+
private void sendAccept() {
this.mJingleConnectionManager.getPrimaryCandidate(this.account, new OnPrimaryCandidateFound() {
@Override
- public void onPrimaryCandidateFound(boolean success, Element candidate) {
+ public void onPrimaryCandidateFound(boolean success, JingleCandidate candidate) {
+ Content content = new Content();
+ content.setFileOffer(fileOffer);
if (success) {
if (!equalCandidateExists(candidate)) {
mergeCandidate(candidate);
- content.addCandidate(candidate);
}
}
+ openOurCandidates();
+ content.setCandidates(transportId, getCandidatesAsElements());
JinglePacket packet = bootstrapPacket("session-accept");
packet.setContent(content);
account.getXmppConnection().sendIqPacket(packet, new OnIqPacketReceived() {
@@ -211,7 +228,7 @@ public class JingleConnection {
private void accept(JinglePacket packet) {
Log.d("xmppService","session-accept: "+packet.toString());
Content content = packet.getJingleContent();
- mergeCandidates(content.getCanditates());
+ mergeCandidates(JingleCandidate.parse(content.getCanditates()));
this.status = STATUS_ACCEPTED;
this.connectNextCandidate();
IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
@@ -224,26 +241,25 @@ public class JingleConnection {
IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
if (cid!=null) {
Log.d("xmppService","candidate used by counterpart:"+cid);
- this.candidatesUsedByCounterpart.add(cid);
- if (this.connections.containsKey(cid)) {
- SocksConnection connection = this.connections.get(cid);
- if (connection.isEstablished()) {
- if (status==STATUS_ACCEPTED) {
- this.connect(connection);
- } else {
- Log.d("xmppService","ignoring canditate used because we are already transmitting");
- }
- } else {
- Log.d("xmppService","not yet connected. check when callback comes back");
- }
+ JingleCandidate candidate = getCandidate(cid);
+ candidate.flagAsUsedByCounterpart();
+ if (status == STATUS_ACCEPTED) {
+ this.connect();
} else {
- Log.d("xmppService","candidate not yet in list of connections");
+ Log.d("xmppService","ignoring because file is already in transmission");
+ }
+ } else if (content.hasCandidateError()) {
+ Log.d("xmppService","received candidate error");
+ this.receivedCandidateError = true;
+ if (status == STATUS_ACCEPTED) {
+ this.connect();
}
}
account.getXmppConnection().sendIqPacket(response, null);
}
- private void connect(final SocksConnection connection) {
+ private void connect() {
+ final SocksConnection connection = chooseConnection();
this.status = STATUS_TRANSMITTING;
final OnFileTransmitted callback = new OnFileTransmitted() {
@@ -256,10 +272,10 @@ public class JingleConnection {
Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum());
}
};
- if ((connection.isProxy()&&(connection.getCid().equals(mJingleConnectionManager.getPrimaryCandidateId(account))))) {
- Log.d("xmppService","candidate "+connection.getCid()+" was our proxy and needs activation");
+ 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.getJid());
+ 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() {
@@ -287,6 +303,41 @@ public class JingleConnection {
}
}
+ private SocksConnection chooseConnection() {
+ Log.d("xmppService","choosing connection from "+this.connections.size()+" possibilties");
+ SocksConnection connection = null;
+ Iterator<Entry<String, SocksConnection>> it = this.connections.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<String, SocksConnection> pairs = it.next();
+ SocksConnection currentConnection = pairs.getValue();
+ Log.d("xmppService","comparing candidate: "+currentConnection.getCandidate().toString());
+ if (currentConnection.isEstablished()&&(currentConnection.getCandidate().isUsedByCounterpart()||(!currentConnection.getCandidate().isOurs()))) {
+ Log.d("xmppService","is usable");
+ if (connection==null) {
+ connection = currentConnection;
+ } else {
+ if (connection.getCandidate().getPriority()<currentConnection.getCandidate().getPriority()) {
+ connection = currentConnection;
+ } else if (connection.getCandidate().getPriority()==currentConnection.getCandidate().getPriority()) {
+ Log.d("xmppService","found two candidates with same priority");
+ if (initiator.equals(account.getFullJid())) {
+ if (currentConnection.getCandidate().isOurs()) {
+ connection = currentConnection;
+ }
+ } else {
+ if (!currentConnection.getCandidate().isOurs()) {
+ connection = currentConnection;
+ }
+ }
+ }
+ }
+ }
+ it.remove();
+ }
+ Log.d("xmppService","chose candidate: "+connection.getCandidate().getHost());
+ return connection;
+ }
+
private void sendSuccess() {
JinglePacket packet = bootstrapPacket("session-terminate");
Reason reason = new Reason();
@@ -311,20 +362,40 @@ public class JingleConnection {
this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_REJECTED);
}
+ private void openOurCandidates() {
+ for(JingleCandidate candidate : this.candidates) {
+ if (candidate.isOurs()) {
+ final SocksConnection socksConnection = new SocksConnection(this,candidate);
+ connections.put(candidate.getCid(), socksConnection);
+ socksConnection.connect(new OnSocksConnection() {
+
+ @Override
+ public void failed() {
+ Log.d("xmppService","connection to our candidate failed");
+ }
+
+ @Override
+ public void established() {
+ Log.d("xmppService","connection to our candidate was successful");
+ }
+ });
+ }
+ }
+ }
+
private void connectNextCandidate() {
- for(Element candidate : this.candidates) {
- String cid = candidate.getAttribute("cid");
- if (!connections.containsKey(cid)) {
+ for(JingleCandidate candidate : this.candidates) {
+ if ((!connections.containsKey(candidate.getCid())&&(!candidate.isOurs()))) {
this.connectWithCandidate(candidate);
- break;
+ return;
}
}
+ this.sendCandidateError();
}
- private void connectWithCandidate(Element candidate) {
- boolean initating = candidate.getAttribute("cid").equals(mJingleConnectionManager.getPrimaryCandidateId(account));
- final SocksConnection socksConnection = new SocksConnection(this,candidate,initating);
- connections.put(socksConnection.getCid(), socksConnection);
+ private void connectWithCandidate(final JingleCandidate candidate) {
+ final SocksConnection socksConnection = new SocksConnection(this,candidate);
+ connections.put(candidate.getCid(), socksConnection);
socksConnection.connect(new OnSocksConnection() {
@Override
@@ -334,14 +405,10 @@ public class JingleConnection {
@Override
public void established() {
- if (candidatesUsedByCounterpart.contains(socksConnection.getCid())) {
- if (status==STATUS_ACCEPTED) {
- connect(socksConnection);
- } else {
- Log.d("xmppService","ignoring cuz already transmitting");
- }
- } else {
- sendCandidateUsed(socksConnection.getCid());
+ sendCandidateUsed(candidate.getCid());
+ if ((receivedCandidateError)&&(status == STATUS_ACCEPTED)) {
+ Log.d("xmppService","received candidate error before. trying to connect");
+ connect();
}
}
});
@@ -359,21 +426,25 @@ public class JingleConnection {
private void sendCandidateUsed(final String cid) {
JinglePacket packet = bootstrapPacket("transport-info");
Content content = new Content();
- content.setUsedCandidate(this.content.getTransportId(), cid);
+ //TODO: put these into actual variables
+ content.setAttribute("creator", "initiator");
+ content.setAttribute("name", "a-file-offer");
+ content.setUsedCandidate(this.transportId, cid);
packet.setContent(content);
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_ACCEPTED) {
- connect(connections.get(cid));
- } else {
- Log.d("xmppService","ignoring cuz already transmitting");
- }
- }
- });
+ this.account.getXmppConnection().sendIqPacket(packet,responseListener);
+ }
+
+ private void sendCandidateError() {
+ 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.setCandidateError(this.transportId);
+ packet.setContent(content);
+ Log.d("xmppService","send candidate error");
+ this.account.getXmppConnection().sendIqPacket(packet,responseListener);
}
public String getInitiator() {
@@ -388,33 +459,33 @@ public class JingleConnection {
return this.status;
}
- 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")))) {
+ private boolean equalCandidateExists(JingleCandidate candidate) {
+ for(JingleCandidate c : this.candidates) {
+ if (c.equalValues(candidate)) {
return true;
}
}
return false;
}
- private void mergeCandidate(Element candidate) {
- for(Element c : this.candidates) {
- if (c.getAttribute("cid").equals(candidate.getAttribute("cid"))) {
+ private void mergeCandidate(JingleCandidate candidate) {
+ for(JingleCandidate c : this.candidates) {
+ if (c.equals(candidate)) {
return;
}
}
this.candidates.add(candidate);
}
- private void mergeCandidates(List<Element> candidates) {
- for(Element c : candidates) {
+ private void mergeCandidates(List<JingleCandidate> candidates) {
+ for(JingleCandidate c : candidates) {
mergeCandidate(c);
}
}
- private Element getCandidate(String cid) {
- for(Element c : this.candidates) {
- if (c.getAttribute("cid").equals(cid)) {
+ private JingleCandidate getCandidate(String cid) {
+ for(JingleCandidate c : this.candidates) {
+ if (c.getCid().equals(cid)) {
return c;
}
}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java
index 924674a7..44af51a3 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java
@@ -23,7 +23,7 @@ public class JingleConnectionManager {
private List<JingleConnection> connections = new ArrayList<JingleConnection>(); // make
// concurrent
- private ConcurrentHashMap<String, Element> primaryCandidates = new ConcurrentHashMap<String, Element>();
+ private ConcurrentHashMap<String, JingleCandidate> primaryCandidates = new ConcurrentHashMap<String, JingleCandidate>();
private SecureRandom random = new SecureRandom();
@@ -89,17 +89,12 @@ public class JingleConnectionManager {
if (streamhost != null) {
Log.d("xmppService", "streamhost found "
+ streamhost.toString());
- Element candidate = new Element("candidate");
- candidate.setAttribute("cid",
- nextRandomId());
- candidate.setAttribute("host",
- streamhost.getAttribute("host"));
- candidate.setAttribute("port",
- streamhost.getAttribute("port"));
- candidate.setAttribute("type", "proxy");
- candidate.setAttribute("jid", proxy);
- candidate
- .setAttribute("priority", "655360");
+ JingleCandidate candidate = new JingleCandidate(nextRandomId(),true);
+ candidate.setHost(streamhost.getAttribute("host"));
+ candidate.setPort(Integer.parseInt(streamhost.getAttribute("port")));
+ candidate.setType(JingleCandidate.TYPE_PROXY);
+ candidate.setJid(proxy);
+ candidate.setPriority(655360+65535);
primaryCandidates.put(account.getJid(),
candidate);
listener.onPrimaryCandidateFound(true,
@@ -119,14 +114,6 @@ public class JingleConnectionManager {
this.primaryCandidates.get(account.getJid()));
}
}
-
- public String getPrimaryCandidateId(Account account) {
- if (this.primaryCandidates.containsKey(account.getJid())) {
- return this.primaryCandidates.get(account.getJid()).getAttribute("cid");
- } else {
- return null;
- }
- }
public String nextRandomId() {
return new BigInteger(50, random).toString(32);
diff --git a/src/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java b/src/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java
index 9e00954f..b91a90ff 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/OnPrimaryCandidateFound.java
@@ -1,7 +1,5 @@
package eu.siacs.conversations.xmpp.jingle;
-import eu.siacs.conversations.xml.Element;
-
public interface OnPrimaryCandidateFound {
- public void onPrimaryCandidateFound(boolean success, Element canditate);
+ public void onPrimaryCandidateFound(boolean success, JingleCandidate canditate);
}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java b/src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java
index affbb5f3..197b9424 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/SocksConnection.java
@@ -19,29 +19,20 @@ import android.util.Log;
import android.widget.Button;
public class SocksConnection {
- private Socket socket;
- private String host;
- private String jid;
- private String cid;
- private int port;
- private boolean isProxy = false;
+ private JingleCandidate candidate;
private String destination;
private OutputStream outputStream;
private InputStream inputStream;
private boolean isEstablished = false;
+ protected Socket socket;
- public SocksConnection(JingleConnection jingleConnection, Element candidate, boolean initating) {
- this.cid = candidate.getAttribute("cid");
- this.host = candidate.getAttribute("host");
- this.port = Integer.parseInt(candidate.getAttribute("port"));
- String type = candidate.getAttribute("type");
- this.jid = candidate.getAttribute("jid");
- this.isProxy = "proxy".equalsIgnoreCase(type);
+ public SocksConnection(JingleConnection jingleConnection, JingleCandidate candidate) {
+ this.candidate = candidate;
try {
MessageDigest mDigest = MessageDigest.getInstance("SHA-1");
StringBuilder destBuilder = new StringBuilder();
destBuilder.append(jingleConnection.getSessionId());
- if (initating) {
+ if (candidate.isOurs()) {
destBuilder.append(jingleConnection.getAccountJid());
destBuilder.append(jingleConnection.getCounterPart());
} else {
@@ -62,7 +53,7 @@ public class SocksConnection {
@Override
public void run() {
try {
- socket = new Socket(host, port);
+ socket = new Socket(candidate.getHost(), candidate.getPort());
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
byte[] login = { 0x05, 0x01, 0x00 };
@@ -78,8 +69,7 @@ public class SocksConnection {
inputStream.read(result);
int status = result[1];
if (status == 0) {
- Log.d("xmppService", "established connection with "+host + ":" + port
- + "/" + destination);
+ Log.d("xmppService", "established connection with "+candidate.getHost()+":"+candidate.getPort()+ "/" + destination);
isEstablished = true;
callback.established();
} else {
@@ -193,24 +183,16 @@ public class SocksConnection {
}
public boolean isProxy() {
- return this.isProxy;
- }
-
- public String getJid() {
- return this.jid;
- }
-
- public String getCid() {
- return this.cid;
+ return this.candidate.getType() == JingleCandidate.TYPE_PROXY;
}
public void disconnect() {
if (this.socket!=null) {
try {
this.socket.close();
- Log.d("xmppService","cloesd socket with "+this.host);
+ Log.d("xmppService","cloesd socket with "+candidate.getHost()+":"+candidate.getPort());
} catch (IOException e) {
- Log.d("xmppService","error closing socket with "+this.host);
+ Log.d("xmppService","error closing socket with "+candidate.getHost()+":"+candidate.getPort());
}
}
}
@@ -218,4 +200,8 @@ public class SocksConnection {
public boolean isEstablished() {
return this.isEstablished;
}
+
+ public JingleCandidate getCandidate() {
+ return this.candidate;
+ }
}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java b/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java
index 79e04610..3cd30251 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java
@@ -77,6 +77,14 @@ public class Content extends Element {
}
}
+ 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 setUsedCandidate(String transportId, String cid) {
Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
if (transport==null) {
@@ -95,4 +103,22 @@ public class Content extends Element {
}
transport.addChild(candidate);
}
+
+ 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 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");
+ }
}