6 * Copyright (C) 2009-2013 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "sip-transport.h"
34 #include "sipe-backend.h"
35 #include "sipe-chat.h"
36 #include "sipe-conf.h"
37 #include "sipe-core.h"
38 #include "sipe-core-private.h"
39 #include "sipe-dialog.h"
40 #include "sipe-session.h"
41 #include "sipe-utils.h"
44 sipe_free_queued_message(struct queued_message
*message
)
46 g_free(message
->body
);
47 g_free(message
->content_type
);
52 sipe_session_add_chat(struct sipe_core_private
*sipe_private
,
53 struct sipe_chat_session
*chat_session
,
57 struct sip_session
*session
= g_new0(struct sip_session
, 1);
58 session
->callid
= gencallid();
60 session
->chat_session
= chat_session
;
62 gchar
*chat_title
= sipe_chat_get_name();
63 session
->chat_session
= sipe_chat_create_session(multiparty
?
64 SIPE_CHAT_TYPE_MULTIPARTY
:
65 SIPE_CHAT_TYPE_CONFERENCE
,
70 session
->unconfirmed_messages
= g_hash_table_new_full(
71 g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
)sipe_free_queued_message
);
72 session
->conf_unconfirmed_messages
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, g_free
);
73 sipe_private
->sessions
= g_slist_append(sipe_private
->sessions
, session
);
80 sipe_session_add_call(struct sipe_core_private
*sipe_private
,
83 struct sip_session
*session
= g_new0(struct sip_session
, 1);
84 SIPE_DEBUG_INFO("sipe_session_add_call: new session for %s", who
);
85 session
->with
= g_strdup(who
);
86 session
->unconfirmed_messages
= g_hash_table_new_full(
87 g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
)sipe_free_queued_message
);
88 session
->is_call
= TRUE
;
89 sipe_private
->sessions
= g_slist_append(sipe_private
->sessions
, session
);
94 sipe_session_find_call(struct sipe_core_private
*sipe_private
,
97 if (sipe_private
== NULL
|| who
== NULL
) {
101 SIPE_SESSION_FOREACH
{
102 if (session
->is_call
&&
103 sipe_strcase_equal(who
, session
->with
)) {
106 } SIPE_SESSION_FOREACH_END
;
113 sipe_session_find_chat(struct sipe_core_private
*sipe_private
,
114 struct sipe_chat_session
*chat_session
)
116 if (sipe_private
== NULL
|| chat_session
== NULL
) {
120 SIPE_SESSION_FOREACH
{
121 if (session
->chat_session
== chat_session
) {
124 } SIPE_SESSION_FOREACH_END
;
130 sipe_session_find_chat_by_callid(struct sipe_core_private
*sipe_private
,
133 if (sipe_private
== NULL
|| callid
== NULL
) {
137 SIPE_SESSION_FOREACH
{
138 if (session
->callid
&&
139 sipe_strcase_equal(callid
, session
->callid
)) {
142 } SIPE_SESSION_FOREACH_END
;
147 sipe_session_find_conference(struct sipe_core_private
*sipe_private
,
148 const gchar
*focus_uri
)
150 if (sipe_private
== NULL
|| focus_uri
== NULL
) {
154 SIPE_SESSION_FOREACH
{
155 if (session
->chat_session
&&
156 (session
->chat_session
->type
== SIPE_CHAT_TYPE_CONFERENCE
) &&
157 sipe_strcase_equal(focus_uri
, session
->chat_session
->id
)) {
160 } SIPE_SESSION_FOREACH_END
;
165 sipe_session_find_im(struct sipe_core_private
*sipe_private
,
168 if (sipe_private
== NULL
|| who
== NULL
) {
172 SIPE_SESSION_FOREACH
{
173 if (!session
->is_call
&&
174 session
->with
&& sipe_strcase_equal(who
, session
->with
)) {
177 } SIPE_SESSION_FOREACH_END
;
182 sipe_session_find_or_add_im(struct sipe_core_private
*sipe_private
,
185 struct sip_session
*session
= sipe_session_find_im(sipe_private
, who
);
187 SIPE_DEBUG_INFO("sipe_session_find_or_add_im: new session for %s", who
);
188 session
= g_new0(struct sip_session
, 1);
189 session
->with
= g_strdup(who
);
190 session
->unconfirmed_messages
= g_hash_table_new_full(
191 g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
)sipe_free_queued_message
);
192 sipe_private
->sessions
= g_slist_append(sipe_private
->sessions
, session
);
198 sipe_session_find_chat_or_im(struct sipe_core_private
*sipe_private
,
202 struct sip_session
*session
= sipe_session_find_chat_by_callid(sipe_private
,
205 session
= sipe_session_find_im(sipe_private
, who
);
211 sipe_session_remove(struct sipe_core_private
*sipe_private
,
212 struct sip_session
*session
)
214 sipe_private
->sessions
= g_slist_remove(sipe_private
->sessions
, session
);
216 sipe_dialog_remove_all(session
);
217 sipe_dialog_free(session
->focus_dialog
);
219 while (sipe_session_dequeue_message(session
));
221 sipe_utils_slist_free_full(session
->pending_invite_queue
, g_free
);
223 g_hash_table_destroy(session
->unconfirmed_messages
);
224 if (session
->conf_unconfirmed_messages
)
225 g_hash_table_destroy(session
->conf_unconfirmed_messages
);
227 g_free(session
->with
);
228 g_free(session
->callid
);
229 g_free(session
->im_mcu_uri
);
230 g_free(session
->subject
);
235 sipe_session_close(struct sipe_core_private
*sipe_private
,
236 struct sip_session
*session
)
239 if (session
->chat_session
&&
240 (session
->chat_session
->type
== SIPE_CHAT_TYPE_CONFERENCE
)) {
241 sipe_conf_immcu_closed(sipe_private
, session
);
242 conf_session_close(sipe_private
, session
);
245 SIPE_DIALOG_FOREACH
{
246 /* @TODO slow down BYE message sending rate */
247 /* @see single subscription code */
248 sip_transport_bye(sipe_private
, dialog
);
249 } SIPE_DIALOG_FOREACH_END
;
251 sipe_session_remove(sipe_private
, session
);
256 sipe_session_enqueue_message(struct sip_session
*session
,
257 const gchar
*body
, const gchar
*content_type
)
259 struct queued_message
*msg
= g_new0(struct queued_message
,1);
260 msg
->body
= g_strdup(body
);
261 if (content_type
!= NULL
)
262 msg
->content_type
= g_strdup(content_type
);
264 session
->outgoing_message_queue
= g_slist_append(session
->outgoing_message_queue
, msg
);
268 sipe_session_dequeue_message(struct sip_session
*session
)
270 struct queued_message
*msg
;
272 if (session
->outgoing_message_queue
== NULL
)
275 msg
= session
->outgoing_message_queue
->data
;
276 session
->outgoing_message_queue
= g_slist_remove(session
->outgoing_message_queue
, msg
);
278 g_free(msg
->content_type
);
281 return session
->outgoing_message_queue
;