summaryrefslogtreecommitdiffstats
path: root/src/call_history.h
blob: 6b8c967e84dc2e295bb91d682a5a0fd2f5b42eae (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
/*
    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
 * Call history
 */

#ifndef _CALL_HISTORY_H
#define _CALL_HISTORY_H

#include <list>
#include <string>
#include <sys/time.h>
#include "parser/request.h"
#include "parser/response.h"
#include "sockets/url.h"
#include "threads/mutex.h"
#include "utils/record_file.h"

using namespace std;

/** Call detail record. */
class t_call_record : public utils::t_record {
public:

/** Release cause of a call. */
enum t_rel_cause {
	CS_LOCAL_USER,	/**< Released by the local user. */
	CS_REMOTE_USER, /**< Released by the remote user. */
	CS_FAILURE	/**< Call ended due to failure. */
};

/** Direction of the call as seen from the user. */
enum t_direction {
	DIR_IN,		/**< Incoming call. */
	DIR_OUT		/**< Outgoing call. */
};

private:
	static t_mutex		mtx_class; 	/**< Protect static members. */
	static unsigned short	next_id;   	/**< Next id to be used. */
	
	unsigned short		id; 		/**< Record id. */

public:
	time_t		time_start;		/**< Timestamp of start of call. */
	time_t		time_answer;		/**< Timestamp when call got answered. */
	time_t		time_end;		/**< Timestamp of end of call. */
	t_direction	direction;
	string		from_display;
	t_url		from_uri;
	string		from_organization;
	string		to_display;
	t_url		to_uri;
	string		to_organization;
	string		reply_to_display;
	t_url		reply_to_uri;
	string		referred_by_display;
	t_url		referred_by_uri;
	string		subject;
	t_rel_cause	rel_cause;
	int		invite_resp_code;	/**< Response code sent/received on INVITE. */
	string		invite_resp_reason;	/**< Response reason sent/received on INVITE. */
	string		far_end_device;		/**< User-agent/Server description of device. */
	string		user_profile;
	
	/** Constructor. */
	t_call_record();

	/** Copy constructor */
	t_call_record(const t_call_record& that);

	/** Assignment operator */
	t_call_record& operator=(const t_call_record& that);
	
	/**
	 * Clear current settings and get a new record id.
	 * So this action creates a brand new call record.
	 */
	void renew();
	
	/**
	 * Record call start.
	 * @param invite [in] The INVITE request starting the call.
	 * @param dir [in] Call direction.
	 * @param _user_profile [in] The user profile.
	 */
	void start_call(const t_request *invite, t_direction dir, const string &_user_profile);
	
	/**
	 * Record call failure. This is also the end of the call.
	 * @param resp [in] The failure response.
	 */
	void fail_call(const t_response *resp);
	
	/**
	 * Record successful call answer.
	 * @param resp [in] The 2XX INVITE response.
	 */
	void answer_call(const t_response *resp);
	
	/**
	 * Record end of a successful call with an explicit cause.
	 * @param cause [in] The release cause.
	 */
	void end_call(t_rel_cause cause);
	
	/**
	 * Record end of a successful call.
	 * If far_end is true, then the far-end ended the call, otherwise
	 * the near-end ended the call. This indication together with the
	 * direction determines the correct cause of the call end.
	 * @param far_end [in] Indicates if the far end released the call.
	 */
	void end_call(bool far_end);
	
	/**
	 * Get user presentable release cause description.
	 * The release cause is returned in the language of the user.
	 * @return Release cause description.
	 */
	string get_rel_cause(void) const;
	
	/**
	 * Get release cause description for internal use.
	 * This description is written to file.
	 * @return Release cause description.
	 */
	string get_rel_cause_internal(void) const;
	
	/**
	 * Get user presentable direction description.
	 * The description is returned in the language of the user.
	 * @return Direction description.
	 */
	string get_direction(void) const;
	
	/**
	 * Get direction description for internal use.
	 * This description is written to file.
	 * @return Direction description.
	 */
	string get_direction_internal(void) const;
	
	/**
	 * Set the release cause from an internal description.
	 * @param cause [in] Internal release cause description.
	 * @return Indication if operation succeeded.
	 */
	bool set_rel_cause(const string &cause);
	
	/**
	 * Set the direction from an internal description.
	 * @param cause [in] Internal direction description.
	 * @return Indication if operation succeeded.
	 */
	bool set_direction(const string &dir);
	
	virtual bool create_file_record(vector<string> &v) const;
	virtual bool populate_from_file_record(const vector<string> &v);
	
	/**
	 * Check if this call record represents a valid call.
	 * @return Indication if call record is valid.
	 */
	bool is_valid(void) const;
	
	/** Get the record id. */
	unsigned short get_id(void) const;
private:
	// Guarded by a mutex, because contents of this class are updated from other threads.
	// The main thread always creates a copy (snapshot) of current state.
	mutable t_mutex mutex;
};

/** History of calls. */
class t_call_history : public utils::t_record_file<t_call_record> {
private:
	/** Number of missed calls since this counter was cleared. */
	int		num_missed_calls;
	
public:
	/** Constructor. */
	t_call_history();
	
	/**
	 * Add a call record to the history.
	 * @param call_record [in] The call record to be added.
	 * @param write [in] Indicates if history must be written to file after adding.
	 */
	void add_call_record(const t_call_record &call_record, bool write = true);
	
	/**
	 * Delete record with a given id.
	 * @param id [in] The record id that must be deleted.
	 * @param write [in] Indicates if history must be written to file after deleting.
	 */
	void delete_call_record(unsigned short id, bool write = true);
	
	/** 
	 * Get list of historic call records.
	 * @param history [out] List of historic call records.
	 */
	void get_history(list<t_call_record> &history);
	
	/** 
	 * Clear call history file.
	 * @param write [in] Indicates if history must be written to file after adding.
	 */
	void clear(bool write = true);
	
	/** Get number of missed calls. */
	int get_num_missed_calls(void) const;
	
	/** Clear number of missed calls. */
	void clear_num_missed_calls(void);
};

extern t_call_history *call_history;

#endif