aboutsummaryrefslogtreecommitdiff
path: root/client/src/service/connection_manager.vala
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/service/connection_manager.vala')
-rw-r--r--client/src/service/connection_manager.vala222
1 files changed, 0 insertions, 222 deletions
diff --git a/client/src/service/connection_manager.vala b/client/src/service/connection_manager.vala
deleted file mode 100644
index 92827296..00000000
--- a/client/src/service/connection_manager.vala
+++ /dev/null
@@ -1,222 +0,0 @@
-using Gee;
-
-using Xmpp;
-using Dino.Entities;
-
-namespace Dino {
-
-public class ConnectionManager {
-
- public signal void stream_opened(Account account, Core.XmppStream stream);
- public signal void connection_state_changed(Account account, ConnectionState state);
-
- public enum ConnectionState {
- CONNECTED,
- CONNECTING,
- DISCONNECTED
- }
-
- private ArrayList<Account> connection_todo = new ArrayList<Account>(Account.equals_func);
- private HashMap<Account, Connection> stream_states = new HashMap<Account, Connection>(Account.hash_func, Account.equals_func);
- private NetworkManager? network_manager;
- private Login1Manager? login1;
- private ModuleManager module_manager;
-
- private class Connection {
- public Core.XmppStream stream { get; set; }
- public ConnectionState connection_state { get; set; default = ConnectionState.DISCONNECTED; }
- public DateTime established { get; set; }
- public class Connection(Core.XmppStream stream, DateTime established) {
- this.stream = stream;
- this.established = established;
- }
- }
-
- public ConnectionManager(ModuleManager module_manager) {
- this.module_manager = module_manager;
- network_manager = get_network_manager();
- if (network_manager != null) {
- network_manager.StateChanged.connect(on_nm_state_changed);
- }
- login1 = get_login1();
- if (login1 != null) {
- login1.PrepareForSleep.connect(on_prepare_for_sleep);
- }
- }
-
- public Core.XmppStream? get_stream(Account account) {
- if (get_connection_state(account) == ConnectionState.CONNECTED) {
- return stream_states[account].stream;
- }
- return null;
- }
-
- public ConnectionState get_connection_state(Account account) {
- if (stream_states.has_key(account)){
- return stream_states[account].connection_state;
- }
- return ConnectionState.DISCONNECTED;
- }
-
- public ArrayList<Account> get_managed_accounts() {
- return connection_todo;
- }
-
- public Core.XmppStream? connect(Account account) {
- if (!connection_todo.contains(account)) connection_todo.add(account);
- if (!stream_states.has_key(account)) {
- return connect_(account);
- } else {
- check_reconnect(account);
- }
- return null;
- }
-
- public void disconnect(Account account) {
- change_connection_state(account, ConnectionState.DISCONNECTED);
- if (stream_states.has_key(account)) {
- try {
- stream_states[account].stream.disconnect();
- } catch (Error e) { }
- }
- connection_todo.remove(account);
- }
-
- private Core.XmppStream? connect_(Account account, string? resource = null) {
- if (resource == null) resource = account.resourcepart;
- if (stream_states.has_key(account)) {
- stream_states[account].stream.remove_modules();
- }
-
- Core.XmppStream stream = new Core.XmppStream();
- foreach (Core.XmppStreamModule module in module_manager.get_modules(account, resource)) {
- stream.add_module(module);
- }
- stream.debug = false;
-
- Connection connection = new Connection(stream, new DateTime.now_local());
- stream_states[account] = connection;
- change_connection_state(account, ConnectionState.CONNECTING);
- stream.stream_negotiated.connect((stream) => {
- change_connection_state(account, ConnectionState.CONNECTED);
- });
- new Thread<void*> (null, () => {
- try {
- stream.connect(account.domainpart);
- } catch (Error e) {
- stderr.printf("Stream Error: %s\n", e.message);
- change_connection_state(account, ConnectionState.DISCONNECTED);
- interpret_reconnect_flags(account, StreamError.Flag.get_flag(stream) ??
- new StreamError.Flag() { reconnection_recomendation = StreamError.Flag.Reconnect.NOW });
- }
- return null;
- });
- stream_opened(account, stream);
-
- return stream;
- }
-
- private void interpret_reconnect_flags(Account account, StreamError.Flag stream_error_flag) {
- if (!connection_todo.contains(account)) return;
- int wait_sec = 10;
- if (network_manager != null && network_manager.State != NetworkManager.CONNECTED_GLOBAL) {
- wait_sec = 60;
- }
- switch (stream_error_flag.reconnection_recomendation) {
- case StreamError.Flag.Reconnect.NOW:
- wait_sec = 10;
- break;
- case StreamError.Flag.Reconnect.LATER:
- case StreamError.Flag.Reconnect.UNKNOWN:
- wait_sec = 60;
- break;
- case StreamError.Flag.Reconnect.NEVER:
- return;
- }
- print(@"recovering in $wait_sec\n");
- Timeout.add_seconds(wait_sec, () => {
- if (stream_error_flag.resource_rejected) {
- connect_(account, account.resourcepart + "-" + random_uuid());
- } else {
- connect_(account);
- }
- return false;
- });
- }
-
- private void check_reconnects() {
- foreach (Account account in connection_todo) {
- check_reconnect(account);
- }
- }
-
- private void check_reconnect(Account account) {
- PingResponseListenerImpl ping_response_listener = new PingResponseListenerImpl(this, account);
- Core.XmppStream stream = stream_states[account].stream;
- Xep.Ping.Module.get_module(stream).send_ping(stream, account.domainpart, ping_response_listener);
-
- Timeout.add_seconds(5, () => {
- if (stream_states[account].stream != stream) return false;
- if (ping_response_listener.acked) return false;
-
- change_connection_state(account, ConnectionState.DISCONNECTED);
- try {
- stream_states[account].stream.disconnect();
- } catch (Error e) { }
- return false;
- });
- }
-
- private class PingResponseListenerImpl : Xep.Ping.ResponseListener, Object {
- public bool acked = false;
- ConnectionManager outer;
- Account account;
- public PingResponseListenerImpl(ConnectionManager outer, Account account) {
- this.outer = outer;
- this.account = account;
- }
- public void on_result(Core.XmppStream stream) {
- print("ping ok\n");
- acked = true;
- outer.change_connection_state(account, ConnectionState.CONNECTED);
- }
- }
-
- private void on_nm_state_changed(uint32 state) {
- print("nm " + state.to_string() + "\n");
- if (state == NetworkManager.CONNECTED_GLOBAL) {
- check_reconnects();
- } else {
- foreach (Account account in connection_todo) {
- change_connection_state(account, ConnectionState.DISCONNECTED);
- }
- }
- }
-
- private void on_prepare_for_sleep(bool suspend) {
- foreach (Account account in connection_todo) {
- change_connection_state(account, ConnectionState.DISCONNECTED);
- }
- if (suspend) {
- print("suspend\n");
- foreach (Account account in connection_todo) {
- Xmpp.Presence.Stanza presence = new Xmpp.Presence.Stanza();
- presence.type_ = Xmpp.Presence.Stanza.TYPE_UNAVAILABLE;
- try {
- Presence.Module.get_module(stream_states[account].stream).send_presence(stream_states[account].stream, presence);
- stream_states[account].stream.disconnect();
- } catch (Error e) { print(@"on_prepare_for_sleep error $(e.message)\n"); }
- }
- } else {
- print("un-suspend\n");
- check_reconnects();
- }
- }
-
- private void change_connection_state(Account account, ConnectionState state) {
- stream_states[account].connection_state = state;
- connection_state_changed(account, state);
- }
-}
-
-}