aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java
blob: 972489d0e53961f25891dd112f07c751a2e3cdb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package eu.siacs.conversations.xmpp.jingle;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import android.util.Log;

import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;

public class JingleConnectionManager {

	private XmppConnectionService xmppConnectionService;

	private List<JingleConnection> connections = new ArrayList<JingleConnection>(); // make
																					// concurrent

	private ConcurrentHashMap<String, Element> primaryCandidates = new ConcurrentHashMap<String, Element>();

	private SecureRandom random = new SecureRandom();

	public JingleConnectionManager(XmppConnectionService service) {
		this.xmppConnectionService = service;
	}

	public void deliverPacket(Account account, JinglePacket packet) {
		if (packet.isAction("session-initiate")) {
			JingleConnection connection = new JingleConnection(this);
			connection.init(account,packet);
			connections.add(connection);
		} else {
			for (JingleConnection connection : connections) {
				if (connection.getAccountJid().equals(account.getFullJid()) && connection
						.getSessionId().equals(packet.getSessionId()) && connection
						.getCounterPart().equals(packet.getFrom())) {
					connection.deliverPacket(packet);
					return;
				} else {
					Log.d("xmppService","no match sid:"+connection.getSessionId()+"="+packet.getSessionId()+" counterpart:"+connection.getCounterPart()+"="+packet.getFrom()+" account:"+connection.getAccountJid()+"="+packet.getTo());
				}
			}
			Log.d("xmppService","delivering packet failed "+packet.toString());
		}
	}

	public JingleConnection createNewConnection(Message message) {
		JingleConnection connection = new JingleConnection(this);
		connection.init(message);
		connections.add(connection);
		return connection;
	}

	public JingleConnection createNewConnection(JinglePacket packet) {
		JingleConnection connection = new JingleConnection(this);
		connections.add(connection);
		return connection;
	}

	public XmppConnectionService getXmppConnectionService() {
		return this.xmppConnectionService;
	}

	public void getPrimaryCandidate(Account account,
			final OnPrimaryCandidateFound listener) {
		if (!this.primaryCandidates.containsKey(account.getJid())) {
			String xmlns = "http://jabber.org/protocol/bytestreams";
			final String proxy = account.getXmppConnection()
					.findDiscoItemByFeature(xmlns);
			if (proxy != null) {
				IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
				iq.setTo(proxy);
				iq.query(xmlns);
				account.getXmppConnection().sendIqPacket(iq,
						new OnIqPacketReceived() {

							@Override
							public void onIqPacketReceived(Account account,
									IqPacket packet) {
								Element streamhost = packet
										.query()
										.findChild("streamhost",
												"http://jabber.org/protocol/bytestreams");
								if (streamhost != null) {
									Log.d("xmppService", "streamhost found "
											+ streamhost.toString());
									Element candidate = new Element("candidate");
									candidate.setAttribute("cid",
											nextRandomId());
									candidate.setAttribute("host",
											streamhost.getAttribute("host"));
									candidate.setAttribute("port",
											streamhost.getAttribute("port"));
									candidate.setAttribute("type", "proxy");
									candidate.setAttribute("jid", proxy);
									candidate
											.setAttribute("priority", "655360");
									primaryCandidates.put(account.getJid(),
											candidate);
									listener.onPrimaryCandidateFound(true,
											candidate);
								} else {
									listener.onPrimaryCandidateFound(false,
											null);
								}
							}
						});
			} else {
				listener.onPrimaryCandidateFound(false, null);
			}

		} else {
			listener.onPrimaryCandidateFound(true,
					this.primaryCandidates.get(account.getJid()));
		}
	}
	
	public String getPrimaryCandidateId(Account account) {
		if (this.primaryCandidates.containsKey(account.getJid())) {
			return this.primaryCandidates.get(account.getJid()).getAttribute("cid");
		} else {
			return null;
		}
	}

	public String nextRandomId() {
		return new BigInteger(50, random).toString(32);
	}
	
	public long getAutoAcceptFileSize() {
		return this.xmppConnectionService.getPreferences().getLong("auto_accept_file_size", 0);
	}
}