summaryrefslogtreecommitdiffstats
path: root/src/epa.h
blob: 7da7b05de7ba34cf83dfe97596855659d251e0da (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
/*
    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
 * Event Publication Agent (EPA) [RFC 3903]
 */
 
#ifndef _EPA_H
#define _EPA_H

#include <queue>
#include <string>

#include "id_object.h"
#include "phone_user.h"
#include "sockets/url.h"
#include "parser/sip_body.h"
#include "protocol.h"

using namespace std;


/** Event Publication Agent (EPA) [RFC 3903] */
class t_epa {
public:
	/** State of the EPA */
	enum t_epa_state {
		EPA_UNPUBLISHED, /**< The event has not been published. */
		EPA_PUBLISHED,	 /**< The event has been published. */
		EPA_FAILED,	 /**< Failed to publish the event. */
	};
	
private:
	/**
	 * Queue of pending outgoing PUBLISH requests. A next PUBLISH
	 * will only be sent after the previous PUBLISH has been
	 * answered.
	 */
	queue<t_request *>	queue_publish;
	
	/**
	 * Enqueue a request.
	 * @param r [in] Request to enqueue.
	 */
	void		enqueue_request(t_request *r);

protected:
	/** Phone user for whom publications are issued. */
	t_phone_user	*phone_user;
	
	/** EPA state. */
	t_epa_state	epa_state;
	
	/** Detailed failure message when @ref epa_state == @ref EPA_FAILED */
	string		failure_msg;

	/** 
	 * Entity tag associated with the publication.
	 * For an initial publication there is no entity tag yet.
	 */
	string		etag;

	/** Event for which the event state is published. */
	string		event_type;
	
	/** Request-URI for the publish request. */
	t_url		request_uri;
	
	/** Timer indicating when a publication must be refreshed. */
	t_object_id	id_publication_timeout;
	
	/** Expiry duration (sec) of a publication. */
	unsigned long	publication_expiry;
	
	/** Default duration for a publication/ */
	unsigned long	default_duration;
	
	/** Indicates if an unpublish is in progress. */
	bool		is_unpublishing;
	
	/** Cached body of last publication. */
	t_sip_body	*cached_body;
	
	/** Log the publication details */
	void log_publication(void) const;
	
	/**
	 * Remove a pending request. Pass one of the client request pointers.
	 * @param cr [in] Client request to remove.
	 */
	void remove_client_request(t_client_request **cr);
	
	/**
	 * Create a PUBLISH request.
	 * @param expires [in] Expiry time in seconds.
	 * @param body [in] Body for the request. The body will be destroyed when
	 * the request will be destroyed.
	 */
	virtual t_request *create_publish(unsigned long expires, t_sip_body *body) const;

	/**
	 * Send request.
	 * @param r [in] Request to send.
	 * @param tuid [in] Transaction user id.
	 */
	void send_request(t_request *r, t_tuid tuid) const;
	
	/**
	 * Send the next PUBLISH request from the queue.
	 * If the queue is empty, then this method does nothing.
	 */
	void send_publish_from_queue(void);

	/** 
	 * Start a publication timer.
	 * @param timer [in] Type of publication timer.
	 * @param duration [in] Duration of timer in ms
	 */
	void start_timer(t_publish_timer timer, long duration);
	
	/**
	 * Stop a publication timer.
	 * @param timer [in] Type of publication timer.
	 */
	void stop_timer(t_publish_timer timer);
	
public:
	/** Pending request */
	t_client_request	*req_out;

	/** Constructor. */
	t_epa(t_phone_user *pu, const string &_event_type, const t_url _request_uri);
	
	/** Destructor. */
	virtual ~t_epa();
	
	/** @name Getters */
	//@{
	t_epa_state get_epa_state(void) const;
	string get_failure_msg(void) const;
	t_phone_user *get_phone_user(void) const;
	//@}
	
	/**
	 * Get the user profile of the user.
	 * @return The user profile.
	 */
	t_user *get_user_profile(void) const;
	
	/**
	 * Receive PUBLISH response.
	 * @param r [in] Received response.
	 * @param tuid [in] Transaction user id.
	 * @param tid [in] Transaction id.
	 * @return The return value indicates if processing is finished.
	 */
	virtual bool recv_response(t_response *r, t_tuid tuid, t_tid tid);
	
	/**
	 * Match response with a pending publish.
	 * @param r [in] The response.
	 * @param tuid [in] Transaction user id.
	 * @return True if the response matches, otherwise false.
	 */
	virtual bool match_response(t_response *r, t_tuid tuid) const;
	
	/**
	 * Process timeouts
	 * @param timer [in] Type of publication timer.
	 * @return The return value indicates if processing is finished.
	 */
	virtual bool timeout(t_publish_timer timer);
	
	/**
	 * Match timer id with a running timer.
	 * @param timer [in] Type of publication timer.
	 * @return True, if id matches, otherwise false.
	 */
	virtual bool match_timer(t_publish_timer timer, t_object_id id_timer) const;
	
	/**
	 * Publish event state.
	 * @param expired [in] Duration of publication in seconds.
	 * @param body [in] Body for PUBLISH request.
	 * @note The body will be deleted when the PUBLISH has been sent.
	 * The caller of this method should *not* delete the body.
	 */
	virtual void publish(unsigned long expires, t_sip_body *body);
	
	/** Terminate publication. */
	virtual void unpublish(void);
	
	/** Refresh publication. */
	virtual void refresh_publication(void);
	
	/** Clear all state */
	virtual void clear(void);
};

#endif