more error handling for jingle connections

This commit is contained in:
iNPUTmice 2014-06-29 13:44:59 +02:00
parent 8eedc1a57f
commit d58d428874
10 changed files with 90 additions and 57 deletions

View file

@ -248,4 +248,5 @@
<string name="edit_conference_details">Touch to edit conference details</string>
<string name="openpgp_messages_found">OpenPGP encrypted messages found</string>
<string name="openpgp_click_to_decrypt">Click here to enter passphrase and decrypt messages</string>
<string name="reception_failed">Reception failed</string>
</resources>

View file

@ -12,6 +12,7 @@ public class Message extends AbstractEntity {
public static final String TABLENAME = "messages";
public static final int STATUS_RECEPTION_FAILED = -3;
public static final int STATUS_RECEIVED_OFFER = -2;
public static final int STATUS_RECIEVING = -1;
public static final int STATUS_RECIEVED = 0;

View file

@ -232,6 +232,7 @@ public class XmppConnectionService extends Service {
accountChangedListener.onAccountListChangedListener();
}
if (account.getStatus() == Account.STATUS_ONLINE) {
mJingleConnectionManager.cancelInTransmission();
List<Conversation> conversations = getConversations();
for (int i = 0; i < conversations.size(); ++i) {
if (conversations.get(i).getAccount() == account) {

View file

@ -252,6 +252,9 @@ public class ConversationFragment extends Fragment {
info = getString(R.string.send_rejected);
error = true;
break;
case Message.STATUS_RECEPTION_FAILED:
info = getString(R.string.reception_failed);
error = true;
default:
if (multiReceived) {
info = message.getCounterpart();

View file

@ -75,7 +75,7 @@ public class JingleConnection {
}
};
final OnFileTransmitted onFileTransmitted = new OnFileTransmitted() {
final OnFileTransmissionStatusChanged onFileTransmissionSatusChanged = new OnFileTransmissionStatusChanged() {
@Override
public void onFileTransmitted(JingleFile file) {
@ -96,6 +96,11 @@ public class JingleConnection {
}
Log.d("xmppService","sucessfully transmitted file:"+file.getAbsolutePath());
}
@Override
public void onFileTransferAborted() {
JingleConnection.this.cancel();
}
};
private OnProxyActivated onProxyActivated = new OnProxyActivated() {
@ -104,9 +109,9 @@ public class JingleConnection {
public void success() {
if (initiator.equals(account.getFullJid())) {
Log.d("xmppService","we were initiating. sending file");
transport.send(file,onFileTransmitted);
transport.send(file,onFileTransmissionSatusChanged);
} else {
transport.receive(file,onFileTransmitted);
transport.receive(file,onFileTransmissionSatusChanged);
Log.d("xmppService","we were responding. receiving file");
}
}
@ -140,14 +145,14 @@ public class JingleConnection {
Reason reason = packet.getReason();
if (reason!=null) {
if (reason.hasChild("cancel")) {
this.receiveCancel();
this.cancel();
} else if (reason.hasChild("success")) {
this.receiveSuccess();
} else {
this.receiveCancel();
this.cancel();
}
} else {
this.receiveCancel();
this.cancel();
}
} else if (packet.isAction("session-accept")) {
returnResult = receiveAccept(packet);
@ -279,13 +284,13 @@ public class JingleConnection {
}
this.file.setExpectedSize(size);
} else {
this.sendCancel();
this.cancel();
}
} else {
this.sendCancel();
this.cancel();
}
} else {
this.sendCancel();
this.cancel();
}
}
@ -405,7 +410,7 @@ public class JingleConnection {
connection.setActivated(true);
} else {
Log.d("xmppService","activated connection not found");
this.sendCancel();
this.cancel();
}
}
return true;
@ -479,10 +484,10 @@ public class JingleConnection {
} else {
if (initiator.equals(account.getFullJid())) {
Log.d("xmppService","we were initiating. sending file");
connection.send(file,onFileTransmitted);
connection.send(file,onFileTransmissionSatusChanged);
} else {
Log.d("xmppService","we were responding. receiving file");
connection.receive(file,onFileTransmitted);
connection.receive(file,onFileTransmissionSatusChanged);
}
}
}
@ -553,7 +558,7 @@ public class JingleConnection {
}
this.transportId = packet.getJingleContent().getTransportId();
this.transport = new JingleInbandTransport(this.account,this.responder,this.transportId,this.ibbBlockSize);
this.transport.receive(file, onFileTransmitted);
this.transport.receive(file, onFileTransmissionSatusChanged);
JinglePacket answer = bootstrapPacket("transport-accept");
Content content = new Content("initiator", "a-file-offer");
content.setTransportId(this.transportId);
@ -582,7 +587,7 @@ public class JingleConnection {
@Override
public void established() {
JingleConnection.this.transport.send(file, onFileTransmitted);
JingleConnection.this.transport.send(file, onFileTransmissionSatusChanged);
}
});
return true;
@ -598,10 +603,21 @@ public class JingleConnection {
this.mJingleConnectionManager.finishConnection(this);
}
private void receiveCancel() {
void cancel() {
this.sendCancel();
this.disconnect();
if (this.message!=null) {
if (this.responder.equals(account.getFullJid())) {
this.mXmppConnectionService.markMessage(this.message, Message.STATUS_RECEPTION_FAILED);
} else {
if (this.status == STATUS_INITIATED) {
this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_REJECTED);
} else {
this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_FAILED);
}
}
}
this.status = STATUS_CANCELED;
this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_REJECTED);
this.mJingleConnectionManager.finishConnection(this);
}

View file

@ -155,4 +155,12 @@ public class JingleConnectionManager {
Log.d("xmppService","no sid found in incomming ibb packet");
}
}
public void cancelInTransmission() {
for(JingleConnection connection : this.connections) {
if (connection.getStatus() == JingleConnection.STATUS_TRANSMITTING) {
connection.cancel();
}
}
}
}

View file

@ -33,7 +33,7 @@ public class JingleInbandTransport extends JingleTransport {
private long remainingSize;
private MessageDigest digest;
private OnFileTransmitted onFileTransmitted;
private OnFileTransmissionStatusChanged onFileTransmissionStatusChanged;
private OnIqPacketReceived onAckReceived = new OnIqPacketReceived() {
@Override
@ -77,8 +77,8 @@ public class JingleInbandTransport extends JingleTransport {
}
@Override
public void receive(JingleFile file, OnFileTransmitted callback) {
this.onFileTransmitted = callback;
public void receive(JingleFile file, OnFileTransmissionStatusChanged callback) {
this.onFileTransmissionStatusChanged = callback;
this.file = file;
try {
this.digest = MessageDigest.getInstance("SHA-1");
@ -86,27 +86,35 @@ public class JingleInbandTransport extends JingleTransport {
file.getParentFile().mkdirs();
file.createNewFile();
this.fileOutputStream = getOutputStream(file);
if (this.fileOutputStream==null) {
callback.onFileTransferAborted();
return;
}
this.remainingSize = file.getExpectedSize();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
callback.onFileTransferAborted();
} catch (IOException e) {
e.printStackTrace();
callback.onFileTransferAborted();
}
}
@Override
public void send(JingleFile file, OnFileTransmitted callback) {
this.onFileTransmitted = callback;
public void send(JingleFile file, OnFileTransmissionStatusChanged callback) {
this.onFileTransmissionStatusChanged = callback;
this.file = file;
try {
this.digest = MessageDigest.getInstance("SHA-1");
this.digest.reset();
fileInputStream = this.getInputStream(file);
if (fileInputStream==null) {
callback.onFileTransferAborted();
return;
}
this.sendNextBlock();
} catch (FileNotFoundException e) {
e.printStackTrace();
callback.onFileTransferAborted();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
callback.onFileTransferAborted();
}
}
@ -117,7 +125,7 @@ public class JingleInbandTransport extends JingleTransport {
if (count == -1) {
file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
fileInputStream.close();
this.onFileTransmitted.onFileTransmitted(file);
this.onFileTransmissionStatusChanged.onFileTransmitted(file);
} else {
this.digest.update(buffer);
String base64 = Base64.encodeToString(buffer, Base64.NO_WRAP);
@ -134,8 +142,7 @@ public class JingleInbandTransport extends JingleTransport {
this.seq++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.onFileTransmissionStatusChanged.onFileTransferAborted();
}
}
@ -154,10 +161,10 @@ public class JingleInbandTransport extends JingleTransport {
file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
fileOutputStream.flush();
fileOutputStream.close();
this.onFileTransmitted.onFileTransmitted(file);
this.onFileTransmissionStatusChanged.onFileTransmitted(file);
}
} catch (IOException e) {
e.printStackTrace();
this.onFileTransmissionStatusChanged.onFileTransferAborted();
}
}

View file

@ -10,7 +10,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import android.util.Log;
import eu.siacs.conversations.utils.CryptoHelper;
public class JingleSocks5Transport extends JingleTransport {
@ -84,7 +83,7 @@ public class JingleSocks5Transport extends JingleTransport {
}
public void send(final JingleFile file, final OnFileTransmitted callback) {
public void send(final JingleFile file, final OnFileTransmissionStatusChanged callback) {
new Thread(new Runnable() {
@Override
@ -94,37 +93,34 @@ public class JingleSocks5Transport extends JingleTransport {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.reset();
fileInputStream = getInputStream(file);
if (fileInputStream==null) {
callback.onFileTransferAborted();
return;
}
int count;
long txBytes = 0;
byte[] buffer = new byte[8192];
while ((count = fileInputStream.read(buffer)) > 0) {
txBytes += count;
outputStream.write(buffer, 0, count);
digest.update(buffer, 0, count);
}
Log.d("xmppService","txBytes="+txBytes);
outputStream.flush();
file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
if (callback!=null) {
callback.onFileTransmitted(file);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
callback.onFileTransferAborted();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
callback.onFileTransferAborted();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
callback.onFileTransferAborted();
} finally {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
callback.onFileTransferAborted();
}
}
}
@ -132,7 +128,7 @@ public class JingleSocks5Transport extends JingleTransport {
}
public void receive(final JingleFile file, final OnFileTransmitted callback) {
public void receive(final JingleFile file, final OnFileTransmissionStatusChanged callback) {
new Thread(new Runnable() {
@Override
@ -144,35 +140,34 @@ public class JingleSocks5Transport extends JingleTransport {
file.getParentFile().mkdirs();
file.createNewFile();
OutputStream fileOutputStream = getOutputStream(file);
if (fileOutputStream==null) {
callback.onFileTransferAborted();
return;
}
long remainingSize = file.getExpectedSize();
byte[] buffer = new byte[8192];
int count = buffer.length;
long rxBytes = 0;
while(remainingSize > 0) {
count = inputStream.read(buffer);
if (count==-1) {
Log.d("xmppService","read end");
callback.onFileTransferAborted();
return;
} else {
rxBytes += count;
fileOutputStream.write(buffer, 0, count);
digest.update(buffer, 0, count);
remainingSize-=count;
}
}
Log.d("xmppService","rx bytes="+rxBytes);
fileOutputStream.flush();
fileOutputStream.close();
file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
callback.onFileTransmitted(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
callback.onFileTransferAborted();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
callback.onFileTransferAborted();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
callback.onFileTransferAborted();
}
}
}).start();

View file

@ -19,8 +19,8 @@ import android.util.Log;
public abstract class JingleTransport {
public abstract void connect(final OnTransportConnected callback);
public abstract void receive(final JingleFile file, final OnFileTransmitted callback);
public abstract void send(final JingleFile file, final OnFileTransmitted callback);
public abstract void receive(final JingleFile file, final OnFileTransmissionStatusChanged callback);
public abstract void send(final JingleFile file, final OnFileTransmissionStatusChanged callback);
private byte[] iv = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0xf};
protected InputStream getInputStream(JingleFile file) throws FileNotFoundException {

View file

@ -1,5 +1,6 @@
package eu.siacs.conversations.xmpp.jingle;
public interface OnFileTransmitted {
public interface OnFileTransmissionStatusChanged {
public void onFileTransmitted(JingleFile file);
public void onFileTransferAborted();
}