media: fix relay-info with Farstream 0.2
[siplcs.git] / src / core / sipe-session.c
blob334b1fa42f4f4a0b55c8780666c205829bc8bdbb
1 /**
2 * @file sipe-session.c
4 * pidgin-sipe
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
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
31 #include <glib.h>
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"
43 static void
44 sipe_free_queued_message(struct queued_message *message)
46 g_free(message->body);
47 g_free(message->content_type);
48 g_free(message);
51 struct sip_session *
52 sipe_session_add_chat(struct sipe_core_private *sipe_private,
53 struct sipe_chat_session *chat_session,
54 gboolean multiparty,
55 const gchar *id)
57 struct sip_session *session = g_new0(struct sip_session, 1);
58 session->callid = gencallid();
59 if (chat_session) {
60 session->chat_session = chat_session;
61 } else {
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,
66 id,
67 chat_title);
68 g_free(chat_title);
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);
74 return session;
77 #ifdef HAVE_VV
79 struct sip_session *
80 sipe_session_add_call(struct sipe_core_private *sipe_private,
81 const gchar *who)
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);
90 return session;
93 struct sip_session *
94 sipe_session_find_call(struct sipe_core_private *sipe_private,
95 const gchar *who)
97 if (sipe_private == NULL || who == NULL) {
98 return NULL;
101 SIPE_SESSION_FOREACH {
102 if (session->is_call &&
103 sipe_strcase_equal(who, session->with)) {
104 return session;
106 } SIPE_SESSION_FOREACH_END;
107 return NULL;
110 #endif
112 struct sip_session *
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) {
117 return NULL;
120 SIPE_SESSION_FOREACH {
121 if (session->chat_session == chat_session) {
122 return session;
124 } SIPE_SESSION_FOREACH_END;
125 return NULL;
129 struct sip_session *
130 sipe_session_find_chat_by_callid(struct sipe_core_private *sipe_private,
131 const gchar *callid)
133 if (sipe_private == NULL || callid == NULL) {
134 return NULL;
137 SIPE_SESSION_FOREACH {
138 if (session->callid &&
139 sipe_strcase_equal(callid, session->callid)) {
140 return session;
142 } SIPE_SESSION_FOREACH_END;
143 return NULL;
146 struct sip_session *
147 sipe_session_find_conference(struct sipe_core_private *sipe_private,
148 const gchar *focus_uri)
150 if (sipe_private == NULL || focus_uri == NULL) {
151 return 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)) {
158 return session;
160 } SIPE_SESSION_FOREACH_END;
161 return NULL;
164 struct sip_session *
165 sipe_session_find_im(struct sipe_core_private *sipe_private,
166 const gchar *who)
168 if (sipe_private == NULL || who == NULL) {
169 return NULL;
172 SIPE_SESSION_FOREACH {
173 if (!session->is_call &&
174 session->with && sipe_strcase_equal(who, session->with)) {
175 return session;
177 } SIPE_SESSION_FOREACH_END;
178 return NULL;
181 struct sip_session *
182 sipe_session_find_or_add_im(struct sipe_core_private *sipe_private,
183 const gchar *who)
185 struct sip_session *session = sipe_session_find_im(sipe_private, who);
186 if (!session) {
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);
194 return session;
197 struct sip_session *
198 sipe_session_find_chat_or_im(struct sipe_core_private *sipe_private,
199 const gchar *callid,
200 const gchar *who)
202 struct sip_session *session = sipe_session_find_chat_by_callid(sipe_private,
203 callid);
204 if (!session) {
205 session = sipe_session_find_im(sipe_private, who);
207 return session;
210 void
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);
231 g_free(session);
234 void
235 sipe_session_close(struct sipe_core_private *sipe_private,
236 struct sip_session *session)
238 if (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);
255 void
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);
267 GSList *
268 sipe_session_dequeue_message(struct sip_session *session)
270 struct queued_message *msg;
272 if (session->outgoing_message_queue == NULL)
273 return NULL;
275 msg = session->outgoing_message_queue->data;
276 session->outgoing_message_queue = g_slist_remove(session->outgoing_message_queue, msg);
277 g_free(msg->body);
278 g_free(msg->content_type);
279 g_free(msg);
281 return session->outgoing_message_queue;
285 Local Variables:
286 mode: c
287 c-file-style: "bsd"
288 indent-tabs-mode: t
289 tab-width: 8
290 End: