/** * The default constructor for the In-Band Bytestream Negotiator. * * @param connection The connection which this negotiator works on. */ protected IBBTransferNegotiator(XMPPConnection connection) { super(connection); this.manager = InBandBytestreamManager.getByteStreamManager(connection); }
@Override public void initiateOutgoingSession(JingleTransportInitiationCallback callback) { LOGGER.log(Level.INFO, "Initiate Jingle InBandBytestream session."); BytestreamSession session; try { session = InBandBytestreamManager.getByteStreamManager(jingleSession.getConnection()) .establishSession(jingleSession.getRemote(), theirProposal.getSessionId()); callback.onSessionInitiated(session); } catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { callback.onException(e); } }
if (ibbRequest.getBlockSize() > this.manager.getMaximumBlockSize()) { this.manager.replyResourceConstraintPacket(ibbRequest); return; if (this.manager.getIgnoredBytestreamRequests().remove(ibbRequest.getSessionID())) return; BytestreamListener userListener = this.manager.getUserListener(ibbRequest.getFrom()); if (userListener != null) { userListener.incomingBytestreamRequest(request); else if (!this.manager.getAllRequestListeners().isEmpty()) { for (BytestreamListener listener : this.manager.getAllRequestListeners()) { listener.incomingBytestreamRequest(request); this.manager.replyRejectPacket(ibbRequest);
/** * Establishes an In-Band Bytestream with the given user and returns the session to send/receive * data to/from the user. * <p> * Use this method to establish In-Band Bytestreams to users accepting all incoming In-Band * Bytestream requests since this method doesn't provide a way to tell the user something about * the data to be sent. * <p> * To establish an In-Band Bytestream after negotiation the kind of data to be sent (e.g. file * transfer) use {@link #establishSession(Jid, String)}. * * @param targetJID the JID of the user an In-Band Bytestream should be established * @return the session to send/receive data to/from the user * @throws XMPPException if the user doesn't support or accept in-band bytestreams, or if the * user prefers smaller block sizes * @throws SmackException if there was no response from the server. * @throws InterruptedException */ @Override public InBandBytestreamSession establishSession(Jid targetJID) throws XMPPException, SmackException, InterruptedException { String sessionID = getNextSessionID(); return establishSession(targetJID, sessionID); }
@Override public void initiateIncomingSession(final JingleTransportInitiationCallback callback) { LOGGER.log(Level.INFO, "Await Jingle InBandBytestream session."); InBandBytestreamManager.getByteStreamManager(jingleSession.getConnection()).addIncomingBytestreamListener(new BytestreamListener() { @Override public void incomingBytestreamRequest(BytestreamRequest request) { if (request.getFrom().asFullJidIfPossible().equals(jingleSession.getRemote()) && request.getSessionID().equals(theirProposal.getSessionId())) { BytestreamSession session; try { session = request.accept(); } catch (InterruptedException | SmackException | XMPPException.XMPPErrorException e) { callback.onException(e); return; } callback.onSessionInitiated(session); } } }); }
@Override public IQ handleIQRequest(IQ iqRequest) { Close closeRequest = (Close) iqRequest; InBandBytestreamSession ibbSession = this.manager.getSessions().get( closeRequest.getSessionID()); if (ibbSession == null) { try { this.manager.replyItemNotFoundPacket(closeRequest); } catch (InterruptedException | NotConnectedException e) { return null; } } else { try { ibbSession.closeByPeer(closeRequest); } catch (InterruptedException | NotConnectedException e) { return null; } this.manager.getSessions().remove(closeRequest.getSessionID()); } return null; }
InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(byteStreamRequest.getSessionID());
/** * Accepts the In-Band Bytestream open request and returns the session to * send/receive data. * * @return the session to send/receive data * @throws NotConnectedException * @throws InterruptedException */ @Override public InBandBytestreamSession accept() throws NotConnectedException, InterruptedException { XMPPConnection connection = this.manager.getConnection(); // create In-Band Bytestream session and store it InBandBytestreamSession ibbSession = new InBandBytestreamSession(connection, this.byteStreamRequest, this.byteStreamRequest.getFrom()); this.manager.getSessions().put(this.byteStreamRequest.getSessionID(), ibbSession); // acknowledge request IQ resultIQ = IQ.createResultIQ(this.byteStreamRequest); connection.sendStanza(resultIQ); return ibbSession; }
@Test public void shouldCorrectlySetMaximumBlockSize() { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); byteStreamManager.setMaximumBlockSize(1024); assertEquals(1024, byteStreamManager.getMaximumBlockSize()); }
@Test public void shouldUseConfiguredStanzaType() throws SmackException, InterruptedException, XMPPException { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); byteStreamManager.setStanza(StanzaType.MESSAGE); protocol.addResponse(null, new Verification<Open, IQ>() { @Override public void verify(Open request, IQ response) { assertEquals(StanzaType.MESSAGE, request.getStanza()); } }); // start In-Band Bytestream byteStreamManager.establishSession(targetJID); protocol.verifyAll(); }
@Override public void newStreamInitiation(Jid from, String streamID) { /* * this method is always called prior to #negotiateIncomingStream() so * the In-Band Bytestream initiation listener must ignore the next * In-Band Bytestream request with the given session ID */ this.manager.ignoreBytestreamRequestOnce(streamID); }
@Test public void shouldCorrectlySetDefaultBlockSize() { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); byteStreamManager.setDefaultBlockSize(1024); assertEquals(1024, byteStreamManager.getDefaultBlockSize()); }
@Test(expected = IllegalArgumentException.class) public void shouldNotAllowTooBigDefaultBlockSize() { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); byteStreamManager.setDefaultBlockSize(1000000); }
@Override public OutputStream createOutgoingStream(String streamID, Jid initiator, Jid target) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { InBandBytestreamSession session = this.manager.establishSession(target, streamID); session.setCloseBothStreamsEnabled(true); return session.getOutputStream(); }
@Test(expected = IllegalArgumentException.class) public void shouldNotAllowTooBigMaximumBlockSize() { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); byteStreamManager.setMaximumBlockSize(1000000); }
/** * Returns the InBandBytestreamManager to handle In-Band Bytestreams for a given * {@link XMPPConnection}. * * @param connection the XMPP connection * @return the InBandBytestreamManager for the given XMPP connection */ public static synchronized InBandBytestreamManager getByteStreamManager(XMPPConnection connection) { if (connection == null) return null; InBandBytestreamManager manager = managers.get(connection); if (manager == null) { manager = new InBandBytestreamManager(connection); managers.put(connection, manager); } return manager; }
byteStreamManager.addIncomingBytestreamListener(allRequestsListener); byteStreamManager.addIncomingBytestreamListener(userRequestsListener, initiatorJID); byteStreamManager.ignoreBytestreamRequestOnce(sessionID);
@Override public IQ handleIQRequest(IQ iqRequest) { Data data = (Data) iqRequest; InBandBytestreamSession ibbSession = this.manager.getSessions().get( data.getDataPacketExtension().getSessionID()); try { if (ibbSession == null) { this.manager.replyItemNotFoundPacket(data); } else { ibbSession.processIQPacket(data); } } catch (NotConnectedException | InterruptedException | NotLoggedInException e) { return null; } return null; }
InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(this);
/** * Establishes an In-Band Bytestream with the given user and returns the session to send/receive * data to/from the user. * <p> * Use this method to establish In-Band Bytestreams to users accepting all incoming In-Band * Bytestream requests since this method doesn't provide a way to tell the user something about * the data to be sent. * <p> * To establish an In-Band Bytestream after negotiation the kind of data to be sent (e.g. file * transfer) use {@link #establishSession(String, String)}. * * @param targetJID the JID of the user an In-Band Bytestream should be established * @return the session to send/receive data to/from the user * @throws XMPPException if the user doesn't support or accept in-band bytestreams, or if the * user prefers smaller block sizes */ public InBandBytestreamSession establishSession(String targetJID) throws XMPPException { String sessionID = getNextSessionID(); return establishSession(targetJID, sessionID); }