6 * Copyright (C) 2009-11 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
)
216 sipe_private
->sessions
= g_slist_remove(sipe_private
->sessions
, session
);
218 sipe_dialog_remove_all(session
);
219 sipe_dialog_free(session
->focus_dialog
);
221 while (sipe_session_dequeue_message(session
));
223 entry
= session
->pending_invite_queue
;
228 g_slist_free(session
->pending_invite_queue
);
230 g_hash_table_destroy(session
->unconfirmed_messages
);
231 if (session
->conf_unconfirmed_messages
)
232 g_hash_table_destroy(session
->conf_unconfirmed_messages
);
234 g_free(session
->with
);
235 g_free(session
->callid
);
236 g_free(session
->im_mcu_uri
);
237 g_free(session
->subject
);
242 sipe_session_close(struct sipe_core_private
*sipe_private
,
243 struct sip_session
*session
)
246 if (session
->chat_session
&&
247 (session
->chat_session
->type
== SIPE_CHAT_TYPE_CONFERENCE
)) {
248 sipe_conf_immcu_closed(sipe_private
, session
);
249 conf_session_close(sipe_private
, session
);
252 SIPE_DIALOG_FOREACH
{
253 /* @TODO slow down BYE message sending rate */
254 /* @see single subscription code */
255 sip_transport_bye(sipe_private
, dialog
);
256 } SIPE_DIALOG_FOREACH_END
;
258 sipe_session_remove(sipe_private
, session
);
263 sipe_session_enqueue_message(struct sip_session
*session
,
264 const gchar
*body
, const gchar
*content_type
)
266 struct queued_message
*msg
= g_new0(struct queued_message
,1);
267 msg
->body
= g_strdup(body
);
268 if (content_type
!= NULL
)
269 msg
->content_type
= g_strdup(content_type
);
271 session
->outgoing_message_queue
= g_slist_append(session
->outgoing_message_queue
, msg
);
275 sipe_session_dequeue_message(struct sip_session
*session
)
277 struct queued_message
*msg
;
279 if (session
->outgoing_message_queue
== NULL
)
282 msg
= session
->outgoing_message_queue
->data
;
283 session
->outgoing_message_queue
= g_slist_remove(session
->outgoing_message_queue
, msg
);
285 g_free(msg
->content_type
);
288 return session
->outgoing_message_queue
;