summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode/stroke/filetransfer/IBBReceiveSession.java')
-rw-r--r--src/com/isode/stroke/filetransfer/IBBReceiveSession.java131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/com/isode/stroke/filetransfer/IBBReceiveSession.java b/src/com/isode/stroke/filetransfer/IBBReceiveSession.java
new file mode 100644
index 0000000..d5e831a
--- /dev/null
+++ b/src/com/isode/stroke/filetransfer/IBBReceiveSession.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2010-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.filetransfer;
+
+import com.isode.stroke.queries.GenericRequest;
+import com.isode.stroke.queries.IQRouter;
+import com.isode.stroke.queries.SetResponder;
+import com.isode.stroke.elements.ErrorPayload;
+import com.isode.stroke.elements.IBB;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.signals.Signal1;
+import java.util.logging.Logger;
+
+public class IBBReceiveSession {
+
+ class IBBResponder extends SetResponder<IBB> {
+
+ public IBBResponder(IBBReceiveSession session, IQRouter router) {
+ super(new IBB(), router);
+ this.session = session;
+ this.sequenceNumber = 0;
+ this.receivedSize = 0;
+ setFinal(false);
+ }
+
+ public boolean handleSetRequest(final JID from, final JID to, final String id, IBB ibb) {
+ if (from.equals(session.from) && ibb.getStreamID().equals(session.id)) {
+ if (IBB.Action.Data.equals(ibb.getAction())) {
+ if (sequenceNumber == ibb.getSequenceNumber()) {
+ session.bytestream.write(ibb.getData());
+ receivedSize += ibb.getData().getSize();
+ sequenceNumber++;
+ sendResponse(from, id, null);
+ if (receivedSize >= session.size) {
+ if (receivedSize > session.size) {
+ logger_.warning("Received more data than expected");
+ }
+ session.finish(null);
+ }
+ }
+ else {
+ logger_.warning("Received data out of order");
+ sendError(from, id, ErrorPayload.Condition.NotAcceptable, ErrorPayload.Type.Cancel);
+ session.finish(new FileTransferError(FileTransferError.Type.ClosedError));
+ }
+ }
+ else if (IBB.Action.Open.equals(ibb.getAction())) {
+ logger_.fine("IBB open received");
+ sendResponse(from, id, null);
+ }
+ else if (IBB.Action.Close.equals(ibb.getAction())) {
+ logger_.fine("IBB close received");
+ sendResponse(from, id, null);
+ session.finish(new FileTransferError(FileTransferError.Type.ClosedError));
+ }
+ return true;
+ }
+ logger_.fine("wrong from/sessionID: " + from + " == " + session.from + " / " + ibb.getStreamID() + " == " + session.id);
+ return false;
+ }
+
+ private IBBReceiveSession session;
+ private int sequenceNumber;
+ private long receivedSize;
+ private Logger logger_ = Logger.getLogger(this.getClass().getName());
+ };
+
+ private String id = "";
+ private JID from = new JID();
+ private JID to = new JID();
+ private long size;
+ private WriteBytestream bytestream;
+ private IQRouter router;
+ private IBBResponder responder;
+ private boolean active;
+ private Logger logger_ = Logger.getLogger(this.getClass().getName());
+
+ public IBBReceiveSession(final String id, final JID from, final JID to, long size, WriteBytestream bytestream, IQRouter router) {
+ this.id = id;
+ this.from = from;
+ this.to = to;
+ this.size = size;
+ this.bytestream = bytestream;
+ this.router = router;
+ this.active = false;
+ assert(!id.isEmpty());
+ assert(from.isValid());
+ responder = new IBBResponder(this, router);
+ }
+
+ public void start() {
+ logger_.fine("receive session started");
+ active = true;
+ responder.start();
+ }
+
+ public void stop() {
+ logger_.fine("receive session stopped");
+ responder.stop();
+ if (active) {
+ if (router.isAvailable()) {
+ IBBRequest.create(to, from, IBB.createIBBClose(id), router).send();
+ }
+ finish(null);
+ }
+ }
+
+ public JID getSender() {
+ return from;
+ }
+
+ public JID getReceiver() {
+ return to;
+ }
+
+ public final Signal1<FileTransferError> onFinished = new Signal1<FileTransferError>();
+
+ private void finish(FileTransferError error) {
+ active = false;
+ onFinished.emit(error);
+ }
+} \ No newline at end of file