6 * Copyright (C) 2009-2016 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-core.h"
36 #include "sipe-chat.h"
37 #include "sipe-conf.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
);
96 sipe_session_find_chat(struct sipe_core_private
*sipe_private
,
97 struct sipe_chat_session
*chat_session
)
99 if (sipe_private
== NULL
|| chat_session
== NULL
) {
103 SIPE_SESSION_FOREACH
{
104 if (session
->chat_session
== chat_session
) {
107 } SIPE_SESSION_FOREACH_END
;
113 sipe_session_find_chat_by_callid(struct sipe_core_private
*sipe_private
,
116 if (sipe_private
== NULL
|| callid
== NULL
) {
120 SIPE_SESSION_FOREACH
{
121 if (session
->callid
&&
122 sipe_strcase_equal(callid
, session
->callid
)) {
125 } SIPE_SESSION_FOREACH_END
;
130 sipe_session_find_conference(struct sipe_core_private
*sipe_private
,
131 const gchar
*focus_uri
)
133 if (sipe_private
== NULL
|| focus_uri
== NULL
) {
137 SIPE_SESSION_FOREACH
{
138 if (session
->chat_session
&&
139 (session
->chat_session
->type
== SIPE_CHAT_TYPE_CONFERENCE
) &&
140 sipe_strcase_equal(focus_uri
, session
->chat_session
->id
)) {
143 } SIPE_SESSION_FOREACH_END
;
148 sipe_session_find_im(struct sipe_core_private
*sipe_private
,
151 if (sipe_private
== NULL
|| who
== NULL
) {
155 SIPE_SESSION_FOREACH
{
156 if (!session
->is_call
&&
157 session
->with
&& sipe_strcase_equal(who
, session
->with
)) {
160 } SIPE_SESSION_FOREACH_END
;
165 sipe_session_find_or_add_im(struct sipe_core_private
*sipe_private
,
168 struct sip_session
*session
= sipe_session_find_im(sipe_private
, who
);
170 SIPE_DEBUG_INFO("sipe_session_find_or_add_im: new session for %s", who
);
171 session
= g_new0(struct sip_session
, 1);
172 session
->with
= g_strdup(who
);
173 session
->unconfirmed_messages
= g_hash_table_new_full(
174 g_str_hash
, g_str_equal
, g_free
, (GDestroyNotify
)sipe_free_queued_message
);
175 sipe_private
->sessions
= g_slist_append(sipe_private
->sessions
, session
);
181 sipe_session_find_chat_or_im(struct sipe_core_private
*sipe_private
,
185 struct sip_session
*session
= sipe_session_find_chat_by_callid(sipe_private
,
188 session
= sipe_session_find_im(sipe_private
, who
);
194 sipe_session_remove(struct sipe_core_private
*sipe_private
,
195 struct sip_session
*session
)
197 sipe_private
->sessions
= g_slist_remove(sipe_private
->sessions
, session
);
199 sipe_dialog_remove_all(session
);
200 sipe_dialog_free(session
->focus_dialog
);
202 while (sipe_session_dequeue_message(session
));
204 sipe_utils_slist_free_full(session
->pending_invite_queue
, g_free
);
206 g_hash_table_destroy(session
->unconfirmed_messages
);
207 if (session
->conf_unconfirmed_messages
)
208 g_hash_table_destroy(session
->conf_unconfirmed_messages
);
210 if (session
->chat_session
) {
211 sipe_chat_remove_session(session
->chat_session
);
214 g_free(session
->with
);
215 g_free(session
->callid
);
216 g_free(session
->im_mcu_uri
);
217 g_free(session
->subject
);
218 g_free(session
->audio_video_entity
);
223 sipe_session_close(struct sipe_core_private
*sipe_private
,
224 struct sip_session
*session
)
227 if (session
->chat_session
&&
228 (session
->chat_session
->type
== SIPE_CHAT_TYPE_CONFERENCE
)) {
229 sipe_conf_immcu_closed(sipe_private
, session
);
230 conf_session_close(sipe_private
, session
);
233 SIPE_DIALOG_FOREACH
{
234 /* @TODO slow down BYE message sending rate */
235 /* @see single subscription code */
236 sip_transport_bye(sipe_private
, dialog
);
237 } SIPE_DIALOG_FOREACH_END
;
239 sipe_session_remove(sipe_private
, session
);
244 sipe_session_enqueue_message(struct sip_session
*session
,
245 const gchar
*body
, const gchar
*content_type
)
247 struct queued_message
*msg
= g_new0(struct queued_message
,1);
248 msg
->body
= g_strdup(body
);
249 if (content_type
!= NULL
)
250 msg
->content_type
= g_strdup(content_type
);
252 session
->outgoing_message_queue
= g_slist_append(session
->outgoing_message_queue
, msg
);
256 sipe_session_dequeue_message(struct sip_session
*session
)
258 struct queued_message
*msg
;
260 if (session
->outgoing_message_queue
== NULL
)
263 msg
= session
->outgoing_message_queue
->data
;
264 session
->outgoing_message_queue
= g_slist_remove(session
->outgoing_message_queue
, msg
);
266 g_free(msg
->content_type
);
269 return session
->outgoing_message_queue
;