1package eu.siacs.conversations.xmpp.jingle;
2
3import com.google.common.base.MoreObjects;
4import com.google.common.base.Objects;
5import com.google.common.base.Preconditions;
6
7import eu.siacs.conversations.entities.Account;
8import eu.siacs.conversations.entities.Contact;
9import eu.siacs.conversations.entities.Message;
10import eu.siacs.conversations.services.XmppConnectionService;
11import eu.siacs.conversations.xmpp.Jid;
12import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
13
14public abstract class AbstractJingleConnection {
15
16 public static final String JINGLE_MESSAGE_PROPOSE_ID_PREFIX = "jm-propose-";
17 public static final String JINGLE_MESSAGE_PROCEED_ID_PREFIX = "jm-proceed-";
18
19 final JingleConnectionManager jingleConnectionManager;
20 protected final XmppConnectionService xmppConnectionService;
21 protected final Id id;
22 private final Jid initiator;
23
24 AbstractJingleConnection(final JingleConnectionManager jingleConnectionManager, final Id id, final Jid initiator) {
25 this.jingleConnectionManager = jingleConnectionManager;
26 this.xmppConnectionService = jingleConnectionManager.getXmppConnectionService();
27 this.id = id;
28 this.initiator = initiator;
29 }
30
31 boolean isInitiator() {
32 return initiator.equals(id.account.getJid());
33 }
34
35 abstract void deliverPacket(JinglePacket jinglePacket);
36
37 public Id getId() {
38 return id;
39 }
40
41 abstract void notifyRebound();
42
43
44 public static class Id implements OngoingRtpSession {
45 public final Account account;
46 public final Jid with;
47 public final String sessionId;
48
49 private Id(final Account account, final Jid with, final String sessionId) {
50 Preconditions.checkNotNull(account);
51 Preconditions.checkNotNull(with);
52 Preconditions.checkNotNull(sessionId);
53 this.account = account;
54 this.with = with;
55 this.sessionId = sessionId;
56 }
57
58 public static Id of(Account account, JinglePacket jinglePacket) {
59 return new Id(account, jinglePacket.getFrom(), jinglePacket.getSessionId());
60 }
61
62 public static Id of(Account account, Jid with, final String sessionId) {
63 return new Id(account, with, sessionId);
64 }
65
66 public static Id of(Account account, Jid with) {
67 return new Id(account, with, JingleConnectionManager.nextRandomId());
68 }
69
70 public static Id of(Message message) {
71 return new Id(
72 message.getConversation().getAccount(),
73 message.getCounterpart(),
74 JingleConnectionManager.nextRandomId()
75 );
76 }
77
78 public Contact getContact() {
79 return account.getRoster().getContact(with);
80 }
81
82 @Override
83 public boolean equals(Object o) {
84 if (this == o) return true;
85 if (o == null || getClass() != o.getClass()) return false;
86 Id id = (Id) o;
87 return Objects.equal(account.getUuid(), id.account.getUuid()) &&
88 Objects.equal(with, id.with) &&
89 Objects.equal(sessionId, id.sessionId);
90 }
91
92 @Override
93 public int hashCode() {
94 return Objects.hashCode(account.getUuid(), with, sessionId);
95 }
96
97 @Override
98 public Account getAccount() {
99 return account;
100 }
101
102 @Override
103 public Jid getWith() {
104 return with;
105 }
106
107 @Override
108 public String getSessionId() {
109 return sessionId;
110 }
111
112 @Override
113 public String toString() {
114 return MoreObjects.toStringHelper(this)
115 .add("account", account.getJid())
116 .add("with", with)
117 .add("sessionId", sessionId)
118 .toString();
119 }
120 }
121
122
123 public enum State {
124 NULL, //default value; nothing has been sent or received yet
125 PROPOSED,
126 ACCEPTED,
127 PROCEED,
128 REJECTED,
129 REJECTED_RACED, //used when we want to reject but haven’t received session init yet
130 RETRACTED,
131 RETRACTED_RACED, //used when receiving a retract after we already asked to proceed
132 SESSION_INITIALIZED, //equal to 'PENDING'
133 SESSION_INITIALIZED_PRE_APPROVED,
134 SESSION_ACCEPTED, //equal to 'ACTIVE'
135 TERMINATED_SUCCESS, //equal to 'ENDED' (after successful call) ui will just close
136 TERMINATED_DECLINED_OR_BUSY, //equal to 'ENDED' (after other party declined the call)
137 TERMINATED_CONNECTIVITY_ERROR, //equal to 'ENDED' (but after network failures; ui will display retry button)
138 TERMINATED_CANCEL_OR_TIMEOUT, //more or less the same as retracted; caller pressed end call before session was accepted
139 TERMINATED_APPLICATION_FAILURE,
140 TERMINATED_SECURITY_ERROR
141 }
142}