some code cleanup. added setting to auto accept files. socks5 connections are now threaded
This commit is contained in:
parent
27d5966ac3
commit
7dfe4ae082
|
@ -7,4 +7,16 @@
|
||||||
<item>Conversations</item>
|
<item>Conversations</item>
|
||||||
<item>Android</item>
|
<item>Android</item>
|
||||||
</array>
|
</array>
|
||||||
|
<string-array name="filesizes">
|
||||||
|
<item>never</item>
|
||||||
|
<item>256 KB</item>
|
||||||
|
<item>512 KB</item>
|
||||||
|
<item>1 MB</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="filesizes_values">
|
||||||
|
<item>0</item>
|
||||||
|
<item>262144</item>
|
||||||
|
<item>524288</item>
|
||||||
|
<item>1048576</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -15,6 +15,13 @@
|
||||||
android:entries="@array/resources"
|
android:entries="@array/resources"
|
||||||
android:entryValues="@array/resources"
|
android:entryValues="@array/resources"
|
||||||
android:defaultValue="Mobile"/>
|
android:defaultValue="Mobile"/>
|
||||||
|
<ListPreference
|
||||||
|
android:key="auto_accept_file_size"
|
||||||
|
android:title="Accept files"
|
||||||
|
android:summary="Automatically accept files smaller than"
|
||||||
|
android:entries="@array/filesizes"
|
||||||
|
android:entryValues="@array/filesizes_values"
|
||||||
|
android:defaultValue="524288"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="Notification Settings">
|
android:title="Notification Settings">
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class FileBackend {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JingleFile getImageFile(Message message) {
|
public JingleFile getJingleFile(Message message) {
|
||||||
Conversation conversation = message.getConversation();
|
Conversation conversation = message.getConversation();
|
||||||
String prefix = context.getFilesDir().getAbsolutePath();
|
String prefix = context.getFilesDir().getAbsolutePath();
|
||||||
String path = prefix + "/" + conversation.getAccount().getJid() + "/"
|
String path = prefix + "/" + conversation.getAccount().getJid() + "/"
|
||||||
|
@ -72,7 +72,7 @@ public class FileBackend {
|
||||||
try {
|
try {
|
||||||
InputStream is = context.getContentResolver()
|
InputStream is = context.getContentResolver()
|
||||||
.openInputStream(image);
|
.openInputStream(image);
|
||||||
JingleFile file = getImageFile(message);
|
JingleFile file = getJingleFile(message);
|
||||||
file.getParentFile().mkdirs();
|
file.getParentFile().mkdirs();
|
||||||
file.createNewFile();
|
file.createNewFile();
|
||||||
OutputStream os = new FileOutputStream(file);
|
OutputStream os = new FileOutputStream(file);
|
||||||
|
@ -98,14 +98,14 @@ public class FileBackend {
|
||||||
|
|
||||||
public Bitmap getImageFromMessage(Message message) {
|
public Bitmap getImageFromMessage(Message message) {
|
||||||
return BitmapFactory
|
return BitmapFactory
|
||||||
.decodeFile(getImageFile(message).getAbsolutePath());
|
.decodeFile(getJingleFile(message).getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap getThumbnailFromMessage(Message message, int size) {
|
public Bitmap getThumbnailFromMessage(Message message, int size) {
|
||||||
Bitmap thumbnail = thumbnailCache.get(message.getUuid());
|
Bitmap thumbnail = thumbnailCache.get(message.getUuid());
|
||||||
if (thumbnail==null) {
|
if (thumbnail==null) {
|
||||||
Log.d("xmppService","creating new thumbnail" + message.getUuid());
|
Log.d("xmppService","creating new thumbnail" + message.getUuid());
|
||||||
Bitmap fullsize = BitmapFactory.decodeFile(getImageFile(message)
|
Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message)
|
||||||
.getAbsolutePath());
|
.getAbsolutePath());
|
||||||
thumbnail = resize(fullsize, size);
|
thumbnail = resize(fullsize, size);
|
||||||
this.thumbnailCache.put(message.getUuid(), thumbnail);
|
this.thumbnailCache.put(message.getUuid(), thumbnail);
|
||||||
|
|
|
@ -124,9 +124,7 @@ public class XmppConnectionService extends Service {
|
||||||
MessagePacket packet) {
|
MessagePacket packet) {
|
||||||
Message message = null;
|
Message message = null;
|
||||||
boolean notify = true;
|
boolean notify = true;
|
||||||
if(PreferenceManager
|
if(getPreferences().getBoolean("notification_grace_period_after_carbon_received", true)){
|
||||||
.getDefaultSharedPreferences(getApplicationContext())
|
|
||||||
.getBoolean("notification_grace_period_after_carbon_received", true)){
|
|
||||||
notify=(SystemClock.elapsedRealtime() - lastCarbonMessageReceived) > CARBON_GRACE_PERIOD;
|
notify=(SystemClock.elapsedRealtime() - lastCarbonMessageReceived) > CARBON_GRACE_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,8 +623,7 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmppConnection createConnection(Account account) {
|
public XmppConnection createConnection(Account account) {
|
||||||
SharedPreferences sharedPref = PreferenceManager
|
SharedPreferences sharedPref = getPreferences();
|
||||||
.getDefaultSharedPreferences(getApplicationContext());
|
|
||||||
account.setResource(sharedPref.getString("resource", "mobile").toLowerCase(Locale.getDefault()));
|
account.setResource(sharedPref.getString("resource", "mobile").toLowerCase(Locale.getDefault()));
|
||||||
XmppConnection connection = new XmppConnection(account, this.pm);
|
XmppConnection connection = new XmppConnection(account, this.pm);
|
||||||
connection.setOnMessagePacketReceivedListener(this.messageListener);
|
connection.setOnMessagePacketReceivedListener(this.messageListener);
|
||||||
|
@ -1204,8 +1201,7 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createContact(Contact contact) {
|
public void createContact(Contact contact) {
|
||||||
SharedPreferences sharedPref = PreferenceManager
|
SharedPreferences sharedPref = getPreferences();
|
||||||
.getDefaultSharedPreferences(getApplicationContext());
|
|
||||||
boolean autoGrant = sharedPref.getBoolean("grant_new_contacts", true);
|
boolean autoGrant = sharedPref.getBoolean("grant_new_contacts", true);
|
||||||
if (autoGrant) {
|
if (autoGrant) {
|
||||||
contact.setSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
|
contact.setSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT);
|
||||||
|
@ -1396,4 +1392,8 @@ public class XmppConnectionService extends Service {
|
||||||
convChangedListener.onConversationListChanged();
|
convChangedListener.onConversationListChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SharedPreferences getPreferences() {
|
||||||
|
return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,7 +419,7 @@ public class UIHelper {
|
||||||
mBuilder.setContentText(names.toString());
|
mBuilder.setContentText(names.toString());
|
||||||
mBuilder.setStyle(style);
|
mBuilder.setStyle(style);
|
||||||
}
|
}
|
||||||
if (currentCon!=null) {
|
if ((currentCon!=null)&&(notify)) {
|
||||||
targetUuid=currentCon.getUuid();
|
targetUuid=currentCon.getUuid();
|
||||||
}
|
}
|
||||||
if (unread.size() != 0) {
|
if (unread.size() != 0) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -39,7 +38,9 @@ public class JingleConnection {
|
||||||
private String initiator;
|
private String initiator;
|
||||||
private String responder;
|
private String responder;
|
||||||
private List<Element> candidates = new ArrayList<Element>();
|
private List<Element> candidates = new ArrayList<Element>();
|
||||||
|
private List<String> candidatesUsedByCounterpart = new ArrayList<String>();
|
||||||
private HashMap<String, SocksConnection> connections = new HashMap<String, SocksConnection>();
|
private HashMap<String, SocksConnection> connections = new HashMap<String, SocksConnection>();
|
||||||
|
private Content content = new Content();
|
||||||
private JingleFile file = null;
|
private JingleFile file = null;
|
||||||
|
|
||||||
private OnIqPacketReceived responseListener = new OnIqPacketReceived() {
|
private OnIqPacketReceived responseListener = new OnIqPacketReceived() {
|
||||||
|
@ -100,9 +101,9 @@ public class JingleConnection {
|
||||||
this.mJingleConnectionManager.getPrimaryCandidate(account, new OnPrimaryCandidateFound() {
|
this.mJingleConnectionManager.getPrimaryCandidate(account, new OnPrimaryCandidateFound() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrimaryCandidateFound(boolean success, Element canditate) {
|
public void onPrimaryCandidateFound(boolean success, Element candidate) {
|
||||||
if (success) {
|
if (success) {
|
||||||
candidates.add(canditate);
|
mergeCandidate(candidate);
|
||||||
}
|
}
|
||||||
sendInitRequest();
|
sendInitRequest();
|
||||||
}
|
}
|
||||||
|
@ -116,24 +117,40 @@ public class JingleConnection {
|
||||||
this.message = new Message(conversation, "receiving image file", Message.ENCRYPTION_NONE);
|
this.message = new Message(conversation, "receiving image file", Message.ENCRYPTION_NONE);
|
||||||
this.message.setType(Message.TYPE_IMAGE);
|
this.message.setType(Message.TYPE_IMAGE);
|
||||||
this.message.setStatus(Message.STATUS_RECIEVING);
|
this.message.setStatus(Message.STATUS_RECIEVING);
|
||||||
|
String[] fromParts = packet.getFrom().split("/");
|
||||||
|
this.message.setPresence(fromParts[1]);
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.initiator = packet.getFrom();
|
this.initiator = packet.getFrom();
|
||||||
this.responder = this.account.getFullJid();
|
this.responder = this.account.getFullJid();
|
||||||
this.sessionId = packet.getSessionId();
|
this.sessionId = packet.getSessionId();
|
||||||
this.candidates.addAll(packet.getJingleContent().getCanditates());
|
this.content = packet.getJingleContent();
|
||||||
Log.d("xmppService","new incomming jingle session "+this.sessionId+" num canditaes:"+this.candidates.size());
|
this.mergeCandidates(this.content.getCanditates());
|
||||||
|
Element fileOffer = packet.getJingleContent().getFileOffer();
|
||||||
|
if (fileOffer!=null) {
|
||||||
|
this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message);
|
||||||
|
Element fileSize = fileOffer.findChild("size");
|
||||||
|
Element fileName = fileOffer.findChild("name");
|
||||||
|
this.file.setExpectedSize(Long.parseLong(fileSize.getContent()));
|
||||||
|
if (this.file.getExpectedSize()>=this.mJingleConnectionManager.getAutoAcceptFileSize()) {
|
||||||
|
Log.d("xmppService","auto accepting file from "+packet.getFrom());
|
||||||
|
this.sendAccept();
|
||||||
|
} else {
|
||||||
|
Log.d("xmppService","not auto accepting new file offer with size: "+this.file.getExpectedSize()+" allowed size:"+this.mJingleConnectionManager.getAutoAcceptFileSize());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d("xmppService","no file offer was attached. aborting");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendInitRequest() {
|
private void sendInitRequest() {
|
||||||
JinglePacket packet = this.bootstrapPacket();
|
JinglePacket packet = this.bootstrapPacket();
|
||||||
packet.setAction("session-initiate");
|
packet.setAction("session-initiate");
|
||||||
packet.setInitiator(this.account.getFullJid());
|
this.content = new Content();
|
||||||
Content content = new Content();
|
|
||||||
if (message.getType() == Message.TYPE_IMAGE) {
|
if (message.getType() == Message.TYPE_IMAGE) {
|
||||||
content.setAttribute("creator", "initiator");
|
content.setAttribute("creator", "initiator");
|
||||||
content.setAttribute("name", "a-file-offer");
|
content.setAttribute("name", "a-file-offer");
|
||||||
this.file = this.mXmppConnectionService.getFileBackend().getImageFile(message);
|
this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message);
|
||||||
content.offerFile(file,message.getBody());
|
content.setFileOffer(this.file);
|
||||||
content.setCandidates(this.mJingleConnectionManager.nextRandomId(),this.candidates);
|
content.setCandidates(this.mJingleConnectionManager.nextRandomId(),this.candidates);
|
||||||
packet.setContent(content);
|
packet.setContent(content);
|
||||||
Log.d("xmppService",packet.toString());
|
Log.d("xmppService",packet.toString());
|
||||||
|
@ -142,58 +159,103 @@ public class JingleConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendAccept() {
|
||||||
|
this.mJingleConnectionManager.getPrimaryCandidate(this.account, new OnPrimaryCandidateFound() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrimaryCandidateFound(boolean success, Element candidate) {
|
||||||
|
if (success) {
|
||||||
|
if (mergeCandidate(candidate)) {
|
||||||
|
content.addCandidate(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JinglePacket packet = bootstrapPacket();
|
||||||
|
packet.setAction("session-accept");
|
||||||
|
packet.setContent(content);
|
||||||
|
Log.d("xmppService","sending session accept: "+packet.toString());
|
||||||
|
account.getXmppConnection().sendIqPacket(packet, new OnIqPacketReceived() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onIqPacketReceived(Account account, IqPacket packet) {
|
||||||
|
if (packet.getType() != IqPacket.TYPE_ERROR) {
|
||||||
|
Log.d("xmppService","opsing side has acked our session-accept");
|
||||||
|
connectWithCandidates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private JinglePacket bootstrapPacket() {
|
private JinglePacket bootstrapPacket() {
|
||||||
JinglePacket packet = new JinglePacket();
|
JinglePacket packet = new JinglePacket();
|
||||||
packet.setFrom(account.getFullJid());
|
packet.setFrom(account.getFullJid());
|
||||||
packet.setTo(this.message.getCounterpart()); //fixme, not right in all cases;
|
packet.setTo(this.message.getCounterpart()); //fixme, not right in all cases;
|
||||||
packet.setSessionId(this.sessionId);
|
packet.setSessionId(this.sessionId);
|
||||||
|
packet.setInitiator(this.initiator);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void accept(JinglePacket packet) {
|
private void accept(JinglePacket packet) {
|
||||||
Log.d("xmppService","session-accept: "+packet.toString());
|
Log.d("xmppService","session-accept: "+packet.toString());
|
||||||
Content content = packet.getJingleContent();
|
Content content = packet.getJingleContent();
|
||||||
this.candidates.addAll(content.getCanditates());
|
this.mergeCandidates(content.getCanditates());
|
||||||
this.status = STATUS_ACCEPTED;
|
this.status = STATUS_ACCEPTED;
|
||||||
this.connectWithCandidates();
|
this.connectWithCandidates();
|
||||||
IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
|
IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
|
||||||
Log.d("xmppService","response "+response.toString());
|
|
||||||
account.getXmppConnection().sendIqPacket(response, null);
|
account.getXmppConnection().sendIqPacket(response, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transportInfo(JinglePacket packet) {
|
private void transportInfo(JinglePacket packet) {
|
||||||
Content content = packet.getJingleContent();
|
Content content = packet.getJingleContent();
|
||||||
Log.d("xmppService","transport info : "+content.toString());
|
Log.d("xmppService","transport info : "+content.toString());
|
||||||
String cid = content.getUsedCandidate();
|
String cid = content.getUsedCandidate();
|
||||||
if (cid!=null) {
|
if (cid!=null) {
|
||||||
final JingleFile file = this.mXmppConnectionService.getFileBackend().getImageFile(this.message);
|
Log.d("xmppService","candidate used by counterpart:"+cid);
|
||||||
final SocksConnection connection = this.connections.get(cid);
|
this.candidatesUsedByCounterpart.add(cid);
|
||||||
final OnFileTransmitted callback = new OnFileTransmitted() {
|
if (this.connections.containsKey(cid)) {
|
||||||
|
this.connect(this.connections.get(cid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
|
||||||
|
account.getXmppConnection().sendIqPacket(response, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void connect(final SocksConnection connection) {
|
||||||
|
final OnFileTransmitted callback = new OnFileTransmitted() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFileTransmitted(JingleFile file) {
|
||||||
|
Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (connection.isProxy()) {
|
||||||
|
IqPacket activation = new IqPacket(IqPacket.TYPE_SET);
|
||||||
|
activation.setTo(connection.getJid());
|
||||||
|
activation.query("http://jabber.org/protocol/bytestreams").setAttribute("sid", this.getSessionId());
|
||||||
|
activation.query().addChild("activate").setContent(this.getResponder());
|
||||||
|
Log.d("xmppService","connection is proxy. need to activate "+activation.toString());
|
||||||
|
this.account.getXmppConnection().sendIqPacket(activation, new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFileTransmitted(JingleFile file) {
|
public void onIqPacketReceived(Account account, IqPacket packet) {
|
||||||
Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum());
|
Log.d("xmppService","activation result: "+packet.toString());
|
||||||
}
|
if (initiator.equals(account.getFullJid())) {
|
||||||
};
|
Log.d("xmppService","we were initiating. sending file");
|
||||||
final IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
|
|
||||||
if (connection.isProxy()) {
|
|
||||||
IqPacket activation = new IqPacket(IqPacket.TYPE_SET);
|
|
||||||
activation.setTo(connection.getJid());
|
|
||||||
activation.query("http://jabber.org/protocol/bytestreams").setAttribute("sid", this.getSessionId());
|
|
||||||
activation.query().addChild("activate").setContent(this.getResponder());
|
|
||||||
Log.d("xmppService","connection is proxy. need to activate "+activation.toString());
|
|
||||||
this.account.getXmppConnection().sendIqPacket(activation, new OnIqPacketReceived() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
|
||||||
account.getXmppConnection().sendIqPacket(response, null);
|
|
||||||
Log.d("xmppService","activation result: "+packet.toString());
|
|
||||||
connection.send(file,callback);
|
connection.send(file,callback);
|
||||||
|
} else {
|
||||||
|
Log.d("xmppService","we were responding. receiving file");
|
||||||
}
|
}
|
||||||
});
|
|
||||||
} else {
|
}
|
||||||
account.getXmppConnection().sendIqPacket(response, null);
|
});
|
||||||
|
} else {
|
||||||
|
if (initiator.equals(account.getFullJid())) {
|
||||||
|
Log.d("xmppService","we were initiating. sending file");
|
||||||
connection.send(file,callback);
|
connection.send(file,callback);
|
||||||
|
} else {
|
||||||
|
Log.d("xmppService","we were responding. receiving file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,13 +274,25 @@ public class JingleConnection {
|
||||||
|
|
||||||
private void connectWithCandidates() {
|
private void connectWithCandidates() {
|
||||||
for(Element canditate : this.candidates) {
|
for(Element canditate : this.candidates) {
|
||||||
|
|
||||||
String host = canditate.getAttribute("host");
|
String host = canditate.getAttribute("host");
|
||||||
int port = Integer.parseInt(canditate.getAttribute("port"));
|
int port = Integer.parseInt(canditate.getAttribute("port"));
|
||||||
String type = canditate.getAttribute("type");
|
String type = canditate.getAttribute("type");
|
||||||
String jid = canditate.getAttribute("jid");
|
String jid = canditate.getAttribute("jid");
|
||||||
SocksConnection socksConnection = new SocksConnection(this, host, jid, port,type);
|
SocksConnection socksConnection = new SocksConnection(this, host, jid, port,type);
|
||||||
socksConnection.connect();
|
connections.put(canditate.getAttribute("cid"), socksConnection);
|
||||||
this.connections.put(canditate.getAttribute("cid"), socksConnection);
|
socksConnection.connect(new OnSocksConnection() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed() {
|
||||||
|
Log.d("xmppService","socks5 failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void established() {
|
||||||
|
Log.d("xmppService","established socks5");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,4 +320,20 @@ public class JingleConnection {
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean mergeCandidate(Element candidate) {
|
||||||
|
for(Element c : this.candidates) {
|
||||||
|
if (c.getAttribute("host").equals(candidate.getAttribute("host"))&&(c.getAttribute("port").equals(candidate.getAttribute("port")))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.candidates.add(candidate);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mergeCandidates(List<Element> canditates) {
|
||||||
|
for(Element c : canditates) {
|
||||||
|
this.mergeCandidate(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,4 +122,8 @@ public class JingleConnectionManager {
|
||||||
public String nextRandomId() {
|
public String nextRandomId() {
|
||||||
return new BigInteger(50, random).toString(32);
|
return new BigInteger(50, random).toString(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getAutoAcceptFileSize() {
|
||||||
|
return this.xmppConnectionService.getPreferences().getLong("auto_accept_file_size", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package eu.siacs.conversations.xmpp.jingle;
|
||||||
|
|
||||||
|
public interface OnSocksConnection {
|
||||||
|
public void failed();
|
||||||
|
public void established();
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ public class SocksConnection {
|
||||||
private boolean isProxy = false;
|
private boolean isProxy = false;
|
||||||
private String destination;
|
private String destination;
|
||||||
private OutputStream outputStream;
|
private OutputStream outputStream;
|
||||||
|
private boolean isEstablished = false;
|
||||||
|
|
||||||
public SocksConnection(JingleConnection jingleConnection, String host,
|
public SocksConnection(JingleConnection jingleConnection, String host,
|
||||||
String jid, int port, String type) {
|
String jid, int port, String type) {
|
||||||
|
@ -42,40 +43,52 @@ public class SocksConnection {
|
||||||
mDigest.reset();
|
mDigest.reset();
|
||||||
this.destination = CryptoHelper.bytesToHex(mDigest
|
this.destination = CryptoHelper.bytesToHex(mDigest
|
||||||
.digest(destBuilder.toString().getBytes()));
|
.digest(destBuilder.toString().getBytes()));
|
||||||
Log.d("xmppService", "host=" + host + ", port=" + port
|
|
||||||
+ ", destination: " + destination);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean connect() {
|
public void connect(final OnSocksConnection callback) {
|
||||||
try {
|
new Thread(new Runnable() {
|
||||||
this.socket = new Socket(this.host, this.port);
|
|
||||||
InputStream is = socket.getInputStream();
|
@Override
|
||||||
this.outputStream = socket.getOutputStream();
|
public void run() {
|
||||||
byte[] login = { 0x05, 0x01, 0x00 };
|
try {
|
||||||
byte[] expectedReply = { 0x05, 0x00 };
|
socket = new Socket(host, port);
|
||||||
byte[] reply = new byte[2];
|
InputStream is = socket.getInputStream();
|
||||||
this.outputStream.write(login);
|
outputStream = socket.getOutputStream();
|
||||||
is.read(reply);
|
byte[] login = { 0x05, 0x01, 0x00 };
|
||||||
if (Arrays.equals(reply, expectedReply)) {
|
byte[] expectedReply = { 0x05, 0x00 };
|
||||||
String connect = "" + '\u0005' + '\u0001' + '\u0000' + '\u0003'
|
byte[] reply = new byte[2];
|
||||||
+ '\u0028' + this.destination + '\u0000' + '\u0000';
|
outputStream.write(login);
|
||||||
this.outputStream.write(connect.getBytes());
|
is.read(reply);
|
||||||
byte[] result = new byte[2];
|
if (Arrays.equals(reply, expectedReply)) {
|
||||||
is.read(result);
|
String connect = "" + '\u0005' + '\u0001' + '\u0000' + '\u0003'
|
||||||
int status = result[0];
|
+ '\u0028' + destination + '\u0000' + '\u0000';
|
||||||
return (status == 0);
|
outputStream.write(connect.getBytes());
|
||||||
} else {
|
byte[] result = new byte[2];
|
||||||
socket.close();
|
is.read(result);
|
||||||
return false;
|
int status = result[1];
|
||||||
|
if (status == 0) {
|
||||||
|
Log.d("xmppService", "established connection with "+host + ":" + port
|
||||||
|
+ "/" + destination);
|
||||||
|
isEstablished = true;
|
||||||
|
callback.established();
|
||||||
|
} else {
|
||||||
|
callback.failed();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
socket.close();
|
||||||
|
callback.failed();
|
||||||
|
}
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
callback.failed();
|
||||||
|
} catch (IOException e) {
|
||||||
|
callback.failed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (UnknownHostException e) {
|
}).start();
|
||||||
return false;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(final JingleFile file, final OnFileTransmitted callback) {
|
public void send(final JingleFile file, final OnFileTransmitted callback) {
|
||||||
|
@ -141,4 +154,8 @@ public class SocksConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEstablished() {
|
||||||
|
return this.isEstablished;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,25 @@ public class Content extends Element {
|
||||||
super("content");
|
super("content");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void offerFile(JingleFile actualFile, String hash) {
|
public void setFileOffer(JingleFile actualFile) {
|
||||||
Element description = this.addChild("description", "urn:xmpp:jingle:apps:file-transfer:3");
|
Element description = this.addChild("description", "urn:xmpp:jingle:apps:file-transfer:3");
|
||||||
Element offer = description.addChild("offer");
|
Element offer = description.addChild("offer");
|
||||||
Element file = offer.addChild("file");
|
Element file = offer.addChild("file");
|
||||||
file.addChild("size").setContent(""+actualFile.getSize());
|
file.addChild("size").setContent(""+actualFile.getSize());
|
||||||
file.addChild("name").setContent(actualFile.getName());
|
file.addChild("name").setContent(actualFile.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Element getFileOffer() {
|
||||||
|
Element description = this.findChild("description", "urn:xmpp:jingle:apps:file-transfer:3");
|
||||||
|
if (description==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Element offer = description.findChild("offer");
|
||||||
|
if (offer==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return offer.findChild("file");
|
||||||
|
}
|
||||||
|
|
||||||
public void setCandidates(String transportId, List<Element> canditates) {
|
public void setCandidates(String transportId, List<Element> canditates) {
|
||||||
Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
|
Element transport = this.findChild("transport", "urn:xmpp:jingle:transports:s5b:1");
|
||||||
|
@ -56,4 +68,12 @@ public class Content extends Element {
|
||||||
return usedCandidate.getAttribute("cid");
|
return usedCandidate.getAttribute("cid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addCandidate(Element candidate) {
|
||||||
|
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.addChild(candidate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue