appshare: process incoming invite
[siplcs.git] / src / core / sipe-session.c
blobbdd734020e553e9dad15177a616bb77fc8c980ca
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 #endif
95 struct sip_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) {
100 return NULL;
103 SIPE_SESSION_FOREACH {
104 if (session->chat_session == chat_session) {
105 return session;
107 } SIPE_SESSION_FOREACH_END;
108 return NULL;
112 struct sip_session *
113 sipe_session_find_chat_by_callid(struct sipe_core_private *sipe_private,
114 const gchar *callid)
116 if (sipe_private == NULL || callid == NULL) {
117 return NULL;
120 SIPE_SESSION_FOREACH {
121 if (session->callid &&
122 sipe_strcase_equal(callid, session->callid)) {
123 return session;
125 } SIPE_SESSION_FOREACH_END;
126 return NULL;
129 struct sip_session *
130 sipe_session_find_conference(struct sipe_core_private *sipe_private,
131 const gchar *focus_uri)
133 if (sipe_private == NULL || focus_uri == NULL) {
134 return 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)) {
141 return session;
143 } SIPE_SESSION_FOREACH_END;
144 return NULL;
147 struct sip_session *
148 sipe_session_find_im(struct sipe_core_private *sipe_private,
149 const gchar *who)
151 if (sipe_private == NULL || who == NULL) {
152 return NULL;
155 SIPE_SESSION_FOREACH {
156 if (!session->is_call &&
157 session->with && sipe_strcase_equal(who, session->with)) {
158 return session;
160 } SIPE_SESSION_FOREACH_END;
161 return NULL;
164 struct sip_session *
165 sipe_session_find_or_add_im(struct sipe_core_private *sipe_private,
166 const gchar *who)
168 struct sip_session *session = sipe_session_find_im(sipe_private, who);
169 if (!session) {
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);
177 return session;
180 struct sip_session *
181 sipe_session_find_chat_or_im(struct sipe_core_private *sipe_private,
182 const gchar *callid,
183 const gchar *who)
185 struct sip_session *session = sipe_session_find_chat_by_callid(sipe_private,
186 callid);
187 if (!session) {
188 session = sipe_session_find_im(sipe_private, who);
190 return session;
193 void
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 g_free(session->with);
211 g_free(session->callid);
212 g_free(session->im_mcu_uri);
213 g_free(session->subject);
214 g_free(session->audio_video_entity);
215 g_free(session);
218 void
219 sipe_session_close(struct sipe_core_private *sipe_private,
220 struct sip_session *session)
222 if (session) {
223 if (session->chat_session &&
224 (session->chat_session->type == SIPE_CHAT_TYPE_CONFERENCE)) {
225 sipe_conf_immcu_closed(sipe_private, session);
226 conf_session_close(sipe_private, session);
229 SIPE_DIALOG_FOREACH {
230 /* @TODO slow down BYE message sending rate */
231 /* @see single subscription code */
232 sip_transport_bye(sipe_private, dialog);
233 } SIPE_DIALOG_FOREACH_END;
235 sipe_session_remove(sipe_private, session);
239 void
240 sipe_session_enqueue_message(struct sip_session *session,
241 const gchar *body, const gchar *content_type)
243 struct queued_message *msg = g_new0(struct queued_message,1);
244 msg->body = g_strdup(body);
245 if (content_type != NULL)
246 msg->content_type = g_strdup(content_type);
248 session->outgoing_message_queue = g_slist_append(session->outgoing_message_queue, msg);
251 GSList *
252 sipe_session_dequeue_message(struct sip_session *session)
254 struct queued_message *msg;
256 if (session->outgoing_message_queue == NULL)
257 return NULL;
259 msg = session->outgoing_message_queue->data;
260 session->outgoing_message_queue = g_slist_remove(session->outgoing_message_queue, msg);
261 g_free(msg->body);
262 g_free(msg->content_type);
263 g_free(msg);
265 return session->outgoing_message_queue;
269 Local Variables:
270 mode: c
271 c-file-style: "bsd"
272 indent-tabs-mode: t
273 tab-width: 8
274 End: