mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-12-24 19:47:58 +01:00
Do not store peers proposal as transport
This commit is contained in:
parent
bfc2561fb2
commit
ff2f66fa67
8 changed files with 126 additions and 83 deletions
|
@ -18,6 +18,7 @@ package org.jivesoftware.smackx.jingle;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -225,7 +226,12 @@ public final class JingleManager extends Manager {
|
|||
remaining.add(transportManagers.get(namespace));
|
||||
}
|
||||
|
||||
Collections.sort(remaining);
|
||||
Collections.sort(remaining, new Comparator<JingleTransportManager>() {
|
||||
@Override
|
||||
public int compare(JingleTransportManager t0, JingleTransportManager t1) {
|
||||
return t1.compareTo(t0); //Invert otherwise ascending order to descending.
|
||||
}
|
||||
});
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
@ -236,7 +242,6 @@ public final class JingleManager extends Manager {
|
|||
|
||||
public JingleTransportManager getBestAvailableTransportManager(Set<String> except) {
|
||||
List<JingleTransportManager> managers = getAvailableTransportManagers(except);
|
||||
Collections.sort(managers);
|
||||
|
||||
if (managers.size() > 0) {
|
||||
return managers.get(0);
|
||||
|
|
|
@ -161,6 +161,13 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
|
|||
|
||||
public IQ handleSessionAccept(JingleElement request, XMPPConnection connection) {
|
||||
LOGGER.log(Level.INFO, "RECEIVED SESSION ACCEPT!");
|
||||
for (JingleContentElement contentElement : request.getContents()) {
|
||||
if (contentElement.getName().equals(getName())) {
|
||||
JingleContent content = fromElement(contentElement);
|
||||
getTransport().setPeersProposal(content.getTransport());
|
||||
break;
|
||||
}
|
||||
}
|
||||
onAccept(connection);
|
||||
return IQ.createResultIQ(request);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.jivesoftware.smackx.jingle.components;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
|
@ -39,29 +38,26 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
|
|||
private static final Logger LOGGER = Logger.getLogger(JingleTransport.class.getName());
|
||||
|
||||
private JingleContent parent;
|
||||
private final ArrayList<JingleTransportCandidate<?>> candidates = new ArrayList<>();
|
||||
|
||||
private JingleTransport<?> peersProposal;
|
||||
private boolean isPeersProposal;
|
||||
private final ArrayList<JingleTransportCandidate<?>> ourCandidates = new ArrayList<>();
|
||||
private final ArrayList<JingleTransportCandidate<?>> theirCandidates = new ArrayList<>();
|
||||
|
||||
protected BytestreamSession bytestreamSession;
|
||||
|
||||
public abstract D getElement();
|
||||
|
||||
public void addCandidate(JingleTransportCandidate<?> candidate) {
|
||||
LOGGER.log(Level.INFO, "Insert candidate.");
|
||||
// Insert sorted by descending priority
|
||||
public void addOurCandidate(JingleTransportCandidate<?> candidate) {
|
||||
|
||||
// Insert sorted by descending priority
|
||||
// Empty list -> insert
|
||||
if (candidates.isEmpty()) {
|
||||
candidates.add(candidate);
|
||||
if (ourCandidates.isEmpty()) {
|
||||
ourCandidates.add(candidate);
|
||||
candidate.setParent(this);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find appropriate index
|
||||
for (int i = 0; i < candidates.size(); i++) {
|
||||
JingleTransportCandidate<?> c = candidates.get(i);
|
||||
for (int i = 0; i < ourCandidates.size(); i++) {
|
||||
JingleTransportCandidate<?> c = ourCandidates.get(i);
|
||||
|
||||
// list already contains element -> return
|
||||
if (c == candidate || c.equals(candidate)) {
|
||||
|
@ -70,15 +66,46 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
|
|||
|
||||
//Found the index
|
||||
if (c.getPriority() <= candidate.getPriority()) {
|
||||
candidates.add(i, candidate);
|
||||
ourCandidates.add(i, candidate);
|
||||
candidate.setParent(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<JingleTransportCandidate<?>> getCandidates() {
|
||||
return candidates;
|
||||
public void addTheirCandidate(JingleTransportCandidate<?> candidate) {
|
||||
// Insert sorted by descending priority
|
||||
// Empty list -> insert
|
||||
if (theirCandidates.isEmpty()) {
|
||||
theirCandidates.add(candidate);
|
||||
candidate.setParent(this);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find appropriate index
|
||||
for (int i = 0; i < theirCandidates.size(); i++) {
|
||||
JingleTransportCandidate<?> c = theirCandidates.get(i);
|
||||
|
||||
// list already contains element -> return
|
||||
if (c == candidate || c.equals(candidate)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Found the index
|
||||
if (c.getPriority() <= candidate.getPriority()) {
|
||||
theirCandidates.add(i, candidate);
|
||||
candidate.setParent(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<JingleTransportCandidate<?>> getOurCandidates() {
|
||||
return ourCandidates;
|
||||
}
|
||||
|
||||
public List<JingleTransportCandidate<?>> getTheirCandidates() {
|
||||
return theirCandidates;
|
||||
}
|
||||
|
||||
public abstract String getNamespace();
|
||||
|
@ -89,19 +116,7 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
|
|||
public abstract void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session)
|
||||
throws SmackException.NotConnectedException, InterruptedException;
|
||||
|
||||
public void setPeersProposal(JingleTransport<?> peersProposal) {
|
||||
this.peersProposal = peersProposal;
|
||||
peersProposal.setParent(getParent());
|
||||
peersProposal.isPeersProposal = true;
|
||||
}
|
||||
|
||||
public boolean isPeersProposal() {
|
||||
return isPeersProposal;
|
||||
}
|
||||
|
||||
public JingleTransport<?> getPeersProposal() {
|
||||
return peersProposal;
|
||||
}
|
||||
public abstract void setPeersProposal(JingleTransport<?> peersProposal);
|
||||
|
||||
public abstract IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
|
|||
public static final String NAMESPACE = NAMESPACE_V1;
|
||||
|
||||
private final String streamId;
|
||||
private final Short blockSize;
|
||||
private Short blockSize;
|
||||
|
||||
public JingleIBBTransport(String streamId, Short blockSize) {
|
||||
this.streamId = streamId;
|
||||
|
@ -120,7 +120,14 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addCandidate(JingleTransportCandidate<?> candidate) {
|
||||
public void setPeersProposal(JingleTransport<?> peersProposal) {
|
||||
JingleIBBTransport transport = (JingleIBBTransport) peersProposal;
|
||||
//Respect peers wish for smaller block size.
|
||||
blockSize = (blockSize < transport.blockSize ? blockSize : transport.blockSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOurCandidate(JingleTransportCandidate<?> candidate) {
|
||||
// Sorry, we don't want any candidates.
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
private Bytestream.Mode mode;
|
||||
|
||||
// PEERS candidate of OUR choice.
|
||||
private JingleS5BTransportCandidate selectedCandidate;
|
||||
private JingleS5BTransportCandidate ourSelectedCandidate;
|
||||
private JingleS5BTransportCandidate theirSelectedCandidate;
|
||||
|
||||
private JingleTransportCallback callback;
|
||||
|
||||
|
@ -75,8 +76,8 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
* @param initiator initiator.
|
||||
* @param responder responder.
|
||||
*/
|
||||
public JingleS5BTransport(FullJid initiator, FullJid responder, String sid, List<JingleTransportCandidate<?>> candidates) {
|
||||
this(sid, Socks5Utils.createDigest(sid, initiator, responder), Bytestream.Mode.tcp, candidates);
|
||||
public JingleS5BTransport(FullJid initiator, FullJid responder, String sid, List<JingleTransportCandidate<?>> ourCandidates, List<JingleTransportCandidate<?>> theirCandidates) {
|
||||
this(sid, Socks5Utils.createDigest(sid, initiator, responder), Bytestream.Mode.tcp, ourCandidates, theirCandidates);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,7 +89,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
public JingleS5BTransport(JingleContent content, JingleS5BTransport other, List<JingleTransportCandidate<?>> candidates) {
|
||||
this(other.getSid(),
|
||||
Socks5Utils.createDigest(other.getSid(), content.getParent().getInitiator(), content.getParent().getResponder()),
|
||||
other.mode, candidates);
|
||||
other.mode, candidates, other.getOurCandidates());
|
||||
setPeersProposal(other);
|
||||
}
|
||||
|
||||
|
@ -99,14 +100,19 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
* @param mode
|
||||
* @param candidates
|
||||
*/
|
||||
public JingleS5BTransport(String sid, String dstAddr, Bytestream.Mode mode, List<JingleTransportCandidate<?>> candidates) {
|
||||
public JingleS5BTransport(String sid, String dstAddr, Bytestream.Mode mode, List<JingleTransportCandidate<?>> candidates, List<JingleTransportCandidate<?>> theirCandidates) {
|
||||
this.sid = sid;
|
||||
this.dstAddr = dstAddr;
|
||||
this.mode = mode;
|
||||
|
||||
for (JingleTransportCandidate<?> c : (candidates != null ?
|
||||
candidates : Collections.<JingleS5BTransportCandidate>emptySet())) {
|
||||
addCandidate(c);
|
||||
addOurCandidate(c);
|
||||
}
|
||||
|
||||
for (JingleTransportCandidate<?> c : (theirCandidates != null ?
|
||||
theirCandidates : Collections.<JingleS5BTransportCandidate>emptySet())) {
|
||||
addTheirCandidate(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,9 +121,9 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
* @param transport which will be copied.
|
||||
*/
|
||||
public JingleS5BTransport(JingleS5BTransport transport) {
|
||||
this(transport.sid, transport.dstAddr, transport.mode, null);
|
||||
for (JingleTransportCandidate<?> c : transport.getCandidates()) {
|
||||
this.addCandidate(new JingleS5BTransportCandidate((JingleS5BTransportCandidate) c));
|
||||
this(transport.sid, transport.dstAddr, transport.mode, null, null);
|
||||
for (JingleTransportCandidate<?> c : transport.getOurCandidates()) {
|
||||
this.addOurCandidate(new JingleS5BTransportCandidate((JingleS5BTransportCandidate) c));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,7 +134,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
.setDestinationAddress(dstAddr)
|
||||
.setMode(mode);
|
||||
|
||||
for (JingleTransportCandidate<?> candidate : getCandidates()) {
|
||||
for (JingleTransportCandidate<?> candidate : getOurCandidates()) {
|
||||
builder.addTransportCandidate((JingleS5BTransportCandidateElement) candidate.getElement());
|
||||
}
|
||||
|
||||
|
@ -166,30 +172,45 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
establishBytestreamSession(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPeersProposal(JingleTransport<?> peersProposal) {
|
||||
JingleS5BTransport transport = (JingleS5BTransport) peersProposal;
|
||||
getTheirCandidates().clear();
|
||||
for (JingleTransportCandidate<?> c : transport.getOurCandidates()) {
|
||||
addTheirCandidate(c);
|
||||
}
|
||||
}
|
||||
|
||||
void establishBytestreamSession(XMPPConnection connection)
|
||||
throws SmackException.NotConnectedException, InterruptedException {
|
||||
Socks5Proxy.getSocks5Proxy().addTransfer(dstAddr);
|
||||
JingleS5BTransportManager transportManager = JingleS5BTransportManager.getInstanceFor(connection);
|
||||
this.selectedCandidate = connectToCandidates(MAX_TIMEOUT);
|
||||
this.ourSelectedCandidate = connectToCandidates(MAX_TIMEOUT);
|
||||
|
||||
if (selectedCandidate == CANDIDATE_FAILURE) {
|
||||
if (ourSelectedCandidate == CANDIDATE_FAILURE) {
|
||||
connection.createStanzaCollectorAndSend(transportManager.createCandidateError(this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedCandidate == null) {
|
||||
if (ourSelectedCandidate == null) {
|
||||
throw new AssertionError("MUST NOT BE NULL.");
|
||||
}
|
||||
|
||||
connection.createStanzaCollectorAndSend(transportManager.createCandidateUsed(this, selectedCandidate));
|
||||
connection.createStanzaCollectorAndSend(transportManager.createCandidateUsed(this, ourSelectedCandidate));
|
||||
connectIfReady();
|
||||
}
|
||||
|
||||
public JingleS5BTransportCandidate connectToCandidates(int timeout) {
|
||||
for (JingleTransportCandidate<?> c : getPeersProposal().getCandidates()) {
|
||||
int _timeout = timeout / getCandidates().size(); //TODO: Wise?
|
||||
|
||||
if (getTheirCandidates().size() == 0) {
|
||||
return CANDIDATE_FAILURE;
|
||||
}
|
||||
|
||||
int _timeout = timeout / getTheirCandidates().size(); //TODO: Wise?
|
||||
for (JingleTransportCandidate<?> c : getTheirCandidates()) {
|
||||
JingleS5BTransportCandidate candidate = (JingleS5BTransportCandidate) c;
|
||||
try {
|
||||
return ((JingleS5BTransportCandidate) c).connect(_timeout, true);
|
||||
return candidate.connect(_timeout, true);
|
||||
} catch (IOException | TimeoutException | InterruptedException | SmackException | XMPPException e) {
|
||||
LOGGER.log(Level.WARNING, "Exception while connecting to candidate: " + e, e);
|
||||
}
|
||||
|
@ -201,16 +222,15 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
|
||||
void connectIfReady() {
|
||||
JingleS5BTransportManager jingleS5BTransportManager = JingleS5BTransportManager.getInstanceFor(getParent().getParent().getJingleManager().getConnection());
|
||||
JingleS5BTransport peers = (JingleS5BTransport) getPeersProposal();
|
||||
JingleSession session = getParent().getParent();
|
||||
|
||||
if (getSelectedCandidate() == null || peers == null || peers.getSelectedCandidate() == null) {
|
||||
if (ourSelectedCandidate == null || theirSelectedCandidate == null) {
|
||||
// Not yet ready if we or peer did not yet decide on a candidate.
|
||||
LOGGER.log(Level.INFO, "Not ready.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSelectedCandidate() == CANDIDATE_FAILURE && peers.getSelectedCandidate() == CANDIDATE_FAILURE) {
|
||||
if (ourSelectedCandidate == CANDIDATE_FAILURE && theirSelectedCandidate == CANDIDATE_FAILURE) {
|
||||
LOGGER.log(Level.INFO, "Failure.");
|
||||
callback.onTransportFailed(new FailedTransportException(null));
|
||||
return;
|
||||
|
@ -220,23 +240,23 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
|
||||
//Determine nominated candidate.
|
||||
JingleS5BTransportCandidate nominated;
|
||||
if (getSelectedCandidate() != CANDIDATE_FAILURE && peers.getSelectedCandidate() != CANDIDATE_FAILURE) {
|
||||
if (ourSelectedCandidate != CANDIDATE_FAILURE && theirSelectedCandidate != CANDIDATE_FAILURE) {
|
||||
|
||||
if (getSelectedCandidate().getPriority() > peers.getSelectedCandidate().getPriority()) {
|
||||
nominated = getSelectedCandidate();
|
||||
} else if (getSelectedCandidate().getPriority() < peers.getSelectedCandidate().getPriority()) {
|
||||
nominated = peers.getSelectedCandidate();
|
||||
if (ourSelectedCandidate.getPriority() > theirSelectedCandidate.getPriority()) {
|
||||
nominated = ourSelectedCandidate;
|
||||
} else if (ourSelectedCandidate.getPriority() < theirSelectedCandidate.getPriority()) {
|
||||
nominated = theirSelectedCandidate;
|
||||
} else {
|
||||
nominated = getParent().getParent().isInitiator() ? getSelectedCandidate() : peers.getSelectedCandidate();
|
||||
nominated = getParent().getParent().isInitiator() ? ourSelectedCandidate : theirSelectedCandidate;
|
||||
}
|
||||
|
||||
} else if (getSelectedCandidate() != CANDIDATE_FAILURE) {
|
||||
nominated = getSelectedCandidate();
|
||||
} else if (ourSelectedCandidate != CANDIDATE_FAILURE) {
|
||||
nominated = ourSelectedCandidate;
|
||||
} else {
|
||||
nominated = peers.getSelectedCandidate();
|
||||
nominated = theirSelectedCandidate;
|
||||
}
|
||||
|
||||
if (nominated == peers.getSelectedCandidate()) {
|
||||
if (nominated == theirSelectedCandidate) {
|
||||
|
||||
LOGGER.log(Level.INFO, "Their choice, so our proposed candidate is used.");
|
||||
|
||||
|
@ -325,10 +345,8 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
JingleManager jingleManager = getParent().getParent().getJingleManager();
|
||||
String candidateId = ((JingleS5BTransportInfoElement.CandidateUsed) info).getCandidateId();
|
||||
|
||||
JingleS5BTransport peers = (JingleS5BTransport) getPeersProposal();
|
||||
|
||||
// Received second candidate-used -> out-of-order!
|
||||
if (peers.getSelectedCandidate() != null) {
|
||||
if (theirSelectedCandidate != null) {
|
||||
try {
|
||||
jingleManager.getConnection().sendStanza(JingleElement.createJingleErrorOutOfOrder(wrapping));
|
||||
//jingleManager.getConnection().createStanzaCollectorAndSend(JingleElement.createJingleErrorOutOfOrder(wrapping));
|
||||
|
@ -338,15 +356,15 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
return;
|
||||
}
|
||||
|
||||
Iterator<JingleTransportCandidate<?>> ourCandidates = getCandidates().iterator();
|
||||
Iterator<JingleTransportCandidate<?>> ourCandidates = getOurCandidates().iterator();
|
||||
while (ourCandidates.hasNext()) {
|
||||
JingleS5BTransportCandidate candidate = (JingleS5BTransportCandidate) ourCandidates.next();
|
||||
if (candidate.getCandidateId().equals(candidateId)) {
|
||||
peers.setSelectedCandidate(candidate);
|
||||
theirSelectedCandidate = candidate;
|
||||
}
|
||||
}
|
||||
|
||||
if (peers.getSelectedCandidate() == null) {
|
||||
if (theirSelectedCandidate == null) {
|
||||
LOGGER.log(Level.SEVERE, "ILLEGAL CANDIDATE ID!!!");
|
||||
//TODO: Alert! Illegal candidateId!
|
||||
}
|
||||
|
@ -355,28 +373,19 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
|||
}
|
||||
|
||||
private void handleCandidateActivate(JingleS5BTransportInfoElement info) {
|
||||
this.bytestreamSession = new Socks5BytestreamSession(getSelectedCandidate().getSocket(),
|
||||
getSelectedCandidate().getStreamHost().getJID().asBareJid().equals(getParent().getParent().getPeer().asBareJid()));
|
||||
this.bytestreamSession = new Socks5BytestreamSession(ourSelectedCandidate.getSocket(),
|
||||
ourSelectedCandidate.getStreamHost().getJID().asBareJid().equals(getParent().getParent().getPeer().asBareJid()));
|
||||
callback.onTransportReady(this.bytestreamSession);
|
||||
}
|
||||
|
||||
private void handleCandidateError(JingleS5BTransportInfoElement info) {
|
||||
((JingleS5BTransport) getPeersProposal()).setSelectedCandidate(CANDIDATE_FAILURE);
|
||||
theirSelectedCandidate = CANDIDATE_FAILURE;
|
||||
connectIfReady();
|
||||
}
|
||||
|
||||
private void handleProxyError(JingleS5BTransportInfoElement info) {
|
||||
callback.onTransportFailed(new S5BTransportException.ProxyError(null));
|
||||
}
|
||||
|
||||
public void setSelectedCandidate(JingleS5BTransportCandidate candidate) {
|
||||
selectedCandidate = candidate;
|
||||
}
|
||||
|
||||
public JingleS5BTransportCandidate getSelectedCandidate() {
|
||||
return selectedCandidate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal dummy candidate used to represent failure.
|
||||
* Kinda depressing, isn't it?
|
||||
|
|
|
@ -39,7 +39,7 @@ public class JingleS5BTransportAdapter implements JingleTransportAdapter<JingleS
|
|||
candidates.add(JingleS5BTransportCandidate.fromElement((JingleS5BTransportCandidateElement) e));
|
||||
}
|
||||
|
||||
return new JingleS5BTransport(s5b.getSid(), s5b.getDestinationAddress(), s5b.getMode(), candidates);
|
||||
return new JingleS5BTransport(s5b.getSid(), s5b.getDestinationAddress(), s5b.getMode(), null, candidates);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -99,7 +99,7 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
|
|||
public JingleTransport<?> createTransport(JingleContent content) {
|
||||
JingleSession session = content.getParent();
|
||||
List<JingleTransportCandidate<?>> candidates = collectCandidates();
|
||||
return new JingleS5BTransport(session.getInitiator(), session.getResponder(), StringUtils.randomString(24), candidates);
|
||||
return new JingleS5BTransport(session.getInitiator(), session.getResponder(), StringUtils.randomString(24), candidates, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -55,7 +55,7 @@ public class JingleTransportTest extends AbstractSmackIntegrationTest {
|
|||
super(environment);
|
||||
}
|
||||
|
||||
//@SmackIntegrationTest
|
||||
@SmackIntegrationTest
|
||||
public void JingleIBBTest() throws Exception {
|
||||
XMPPConnection sender = conOne;
|
||||
XMPPConnection receiver = conTwo;
|
||||
|
|
Loading…
Reference in a new issue