digest: add support for OpenSSL 1.1.0
[siplcs.git] / src / core / sipe-session.c
blobda1c05d0ed534a799e0f7d59ddd79fdd70ffadf9
1 /**
2 * @file sipe-session.c
4 * pidgin-sipe
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
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 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);
219 g_free(session);
222 void
223 sipe_session_close(struct sipe_core_private *sipe_private,
224 struct sip_session *session)
226 if (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);
243 void
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);
255 GSList *
256 sipe_session_dequeue_message(struct sip_session *session)
258 struct queued_message *msg;
260 if (session->outgoing_message_queue == NULL)
261 return NULL;
263 msg = session->outgoing_message_queue->data;
264 session->outgoing_message_queue = g_slist_remove(session->outgoing_message_queue, msg);
265 g_free(msg->body);
266 g_free(msg->content_type);
267 g_free(msg);
269 return session->outgoing_message_queue;
273 Local Variables:
274 mode: c
275 c-file-style: "bsd"
276 indent-tabs-mode: t
277 tab-width: 8
278 End: