summaryrefslogtreecommitdiffstats
path: root/src/presence/buddy.h
blob: c72cc7431f95e0920b9767319ae5f4b5d16a7866 (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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*
    Copyright (C) 2005-2009  Michel de Boer <michel@twinklephone.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

/**
 * @file
 * Buddy list
 */

#ifndef _BUDDY_H
#define _BUDDY_H

#include <string>
#include <set>

#include "presence_state.h"
#include "presence_dialog.h"

#include "sockets/url.h"
#include "utils/record_file.h"
#include "patterns/observer.h"

// Forward declaration
class t_phone_user;
class t_buddy_list;

#define BUDDY_FILE_EXT		".bud"

using namespace std;

/** Buddy */
class t_buddy : public utils::t_record, public patterns::t_subject {
private:
	/** Phone user owning this buddy. */
	t_phone_user	*phone_user;

	/** Name of buddy (for display only) */
	string	name;
	
	/** SIP address of the buddy. */
	string	sip_address;
	
	/** Indicates if the user may subscribe to the presence state of the buddy. */
	bool	may_subscribe_presence;
	
	/** Presence state. */
	t_presence_state	presence_state;
	
	/** Presence subscription dialog. */
	t_presence_dialog	*presence_dialog;
	
	/** Subscribe to presence after STUN transaction completed. */
	bool	subscribe_after_stun;
	
	/**
	 * Indicates if presence must be automatically resubscribed to, if the
	 * subscription terminates with a reason telling that resubscription
	 * is possible.
	 */
	bool	presence_auto_resubscribe;
	
	/** 
	 * Indicates if the buddy must be deleted after the presence subscription
	 * has been terminated.
	 */
	bool	delete_after_presence_terminated;
	
	/** Handle presence dialog termination. */
	void cleanup_presence_dialog(void);
	
public:
	/** Interval before trying to resubscribe to presence after a failure. */
	t_object_id	id_resubscribe_presence;
	
	/** Constructor. */
	t_buddy();

	/** Constructor. */
	t_buddy(t_phone_user *_phone_user);

	/** Constructor. */
	t_buddy(t_phone_user *_phone_user, const string _name, const string &_sip_address);
	
	/** Copy constructor. */
	t_buddy(const t_buddy &other);
	
	/** Destructor. */
	virtual ~t_buddy();
	
	/** @name Getters */
	//@{
	string get_name(void) const;
	string get_sip_address(void) const;
	bool get_may_subscribe_presence(void) const;
	const t_presence_state *get_presence_state(void) const;
	//@}
	
	/**
	 * Get user profile for the user owning this buddy.
	 * @return User profile.
	 */
	t_user *get_user_profile(void);
	
	/**
	 * Get the buddy list containing this buddy.
	 * @return Buddy list
	 */
	t_buddy_list *get_buddy_list(void);
	
	/** @name Setters */
	//@{
	void set_phone_user(t_phone_user *_phone_user);
	void set_name(const string &_name);
	void set_sip_address(const string &_sip_address);
	void set_may_subscribe_presence(bool _may_subscribe_presence);
	//@}
	
	/**
	 * Match response with a buddy. It matches if the buddy
	 * has a presence dialog that matches with the response.
	 * @param r [in] The response.
	 * @param tuid [in] Transaction user id.
	 * @return True if the response matches, otherwise false.
	 */
	bool match_response(t_response *r, t_tuid tuid) const;
	
	/**
	 * Match request with buddy list. It matches if a buddy in the list
	 * has a presence dialog that matches with the request.
	 * @param r [in] The request.
	 * @return True if the request matches, otherwise false.
	 */
	bool match_request(t_request *r) const;
	
	/**
	 * Match a timer id with a running timer.
	 * @param timer [in] The running timer.
	 * @param id_timer [in] The timer id.
	 * @return true, if timer id matches with timer.
	 * @return false, otherwise.
	 */
	bool match_timer(t_subscribe_timer timer, t_object_id id_timer) const;
	
	/**
	 * Process timeout.
	 * @param timer [in] The timer that expired.
	 * @param id_timer [in] The timer id.
	 */
	void timeout(t_subscribe_timer timer, t_object_id id_timer);

	/**
	 * Handle received response.
	 * @param r [in] The response.
	 * @param tuid [in] Transaction user id.
	 * @param tid [in] Transaction id.
	 */
	void recvd_response(t_response *r, t_tuid tuid, t_tid tid);
	
	/**
	 * Handle received request.
	 * @param r [in] The request.
	 * @param tuid [in] Transaction user id.
	 * @param tid [in] Transaction id.
	 */
	void recvd_request(t_request *r, t_tuid tuid, t_tid tid);
	
	/**
	 * Start the re-subscribe timer after a presence subscription failure.
	 * @param duration [in] Duration before trying a re-subscribe (s)
	 */
	void start_resubscribe_presence_timer(unsigned long duration);
	
	/** Stop presence re-subscribe timer. */
	void stop_resubscribe_presence_timer(void);
	
	/**
	 * By calling this method, successful STUN completion is signalled to
	 * the buddy. It will subscribe to presence if it was waiting for STUN.
	 */
	void stun_completed(void);
	
	/**
	 * By calling this method, a STUN failure is signalled to
	 * the buddy. It will reschedule a presence subscription if it is
	 * waiting for STUN to complete.
	 */
	void stun_failed(void);
	
	/** Subscribe to presence of the buddy if we may do so. */
	void subscribe_presence(void);
	
	/** Unsubscribe to presence.
	 * @param remove [in] Indicates if the buddy must be deleted after unsubscription.
	 */
	void unsubscribe_presence(bool remove = false);
	
	virtual bool create_file_record(vector<string> &v) const;
	virtual bool populate_from_file_record(const vector<string> &v);
	
	/** Compare 2 buddies for equality (same SIP address) */
	bool operator==(const t_buddy &other) const;
	
	/** Clear presence state. */
	void clear_presence(void);
	
	/**
	 * Check if presence subscription is terminated.
	 * @return true, if presence subscriptions is terminated.
	 * @return false, otherwise
	 */
	bool is_presence_terminated(void) const;
	
	/**
	 * Check if buddy must be deleted.
	 * @return true, if the buddy must be deleted immediately.
	 * @return false, otherwise.
	 */
	bool must_delete_now(void) const;
};

/** List of buddies for a particular account. */
class t_buddy_list : public utils::t_record_file<t_buddy> {
private:
	/** Phone user owning this buddy list. */
	t_phone_user	*phone_user;
	
	/** 
	 * Indicates if subscribe is done. This indicator will be set to false
	 * when you call unsubscribe.
	 */
	bool		is_subscribed;

protected:
	virtual void add_record(const t_buddy &record);
	
public:
	/** Constructor. */
	t_buddy_list(t_phone_user *_phone_user);
	
	/**
	 * Get the user profile for this buddy list.
	 * @return User profile.
	 */
	t_user *get_user_profile(void);

	/**
	 * Add a buddy.
	 * @param buddy [in] Buddy to add.
	 * @return Pointer to added buddy.
	 * @note This method adds a copy of the buddy. It returns a pointer to this copy.
	 */
	t_buddy *add_buddy(const t_buddy &buddy);
	
	/**
	 * Delete a buddy.
	 * @param buddy [in] Buddy to delete.
	 */
	void del_buddy(const t_buddy &buddy);
	
	/**
	 * Match response with buddy list. It matches if a buddy in the list
	 * has a presence dialog that matches with the response.
	 * @param r [in] The response.
	 * @param tuid [in] Transaction user id.
	 * @param buddy [out] On a match, this parameter contains the matching buddy.
	 * @return True if the response matches, otherwise false.
	 */
	bool match_response(t_response *r, t_tuid tuid, t_buddy **buddy);
	
	/**
	 * Match request with buddy list. It matches if a buddy in the list
	 * has a presence dialog that matches with the request.
	 * @param r [in] The request.
	 * @param buddy [out] On a match, this parameter contains the matching buddy.
	 * @return True if the request matches, otherwise false.
	 */
	bool match_request(t_request *r, t_buddy **buddy);
	
	/**
	 * Match a timer id with a running timer. A timer id matches with the
	 * buddy list if it matches with one of the buddies in the list.
	 * @param timer [in] The running timer.
	 * @param id_timer [in] The timer id.
	 * @param buddy [out] On a match, this parameter contains the matching buddy.
	 * @return true, if timer id matches with timer.
	 * @return false, otherwise.
	 */
	bool match_timer(t_subscribe_timer timer, t_object_id id_timer, t_buddy **buddy);
	
	/**
	 * By calling this method, successful STUN completion is signalled to the buddy
	 * list. The buddy list will now start presence subscriptions that were waiting
	 * for STUN to complete.
	 */
	void stun_completed(void);
	
	/**
	 * By calling this method, a STUN failure is signalled to the buddy list.
	 * The buddy list will reschedule presence subscriptions that were waiting
	 * for STUN to complete.
	 */
	void stun_failed(void);
	
	/** Subscribe to presence of all buddies in the list. */
	void subscribe_presence(void);
	
	/** Unsubscribe to presence of all buddies in the list. */
	void unsubscribe_presence(void);
	
	/**
	 * Check if user is subcribed to buddy list presence.
	 * @return True if subscribed, otherwise false.
	 */
	bool get_is_subscribed() const;
	
	/** Clear presence state of all buddies. */
	void clear_presence(void);
	
	/**
	 * Check if all presence subscriptions are terminated.
	 * @return true, if all presence subscriptions are terminated.
	 * @return false, otherwise
	 */
	bool is_presence_terminated(void) const;
};

#endif