Start the Big Split...
[siplcs.git] / src / sipe-dialog.c
blob42596ebcf2b019b8d294a3ef49bd17ecaa7eebb1
1 /**
2 * @file sipe-dialog.c
4 * pidgin-sipe
6 * Copyright (C) 2009 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 #include <string.h>
24 #include <glib.h>
26 #include "debug.h"
28 #include "sipe.h"
29 #include "sipe-dialog.h"
30 #include "sipmsg.h"
32 void free_dialog(struct sip_dialog *dialog)
34 GSList *entry;
36 if (!dialog) return;
38 g_free(dialog->with);
39 g_free(dialog->endpoint_GUID);
40 entry = dialog->routes;
41 while (entry) {
42 g_free(entry->data);
43 entry = g_slist_remove(entry, entry->data);
45 entry = dialog->supported;
46 while (entry) {
47 g_free(entry->data);
48 entry = g_slist_remove(entry, entry->data);
51 g_free(dialog->callid);
52 g_free(dialog->ourtag);
53 g_free(dialog->theirtag);
54 g_free(dialog->theirepid);
55 g_free(dialog->request);
57 g_free(dialog);
60 static void sipe_get_route_header(const struct sipmsg *msg,
61 struct sip_dialog *dialog,
62 gboolean outgoing)
64 GSList *hdr = msg->headers;
65 gchar *contact;
67 while (hdr) {
68 struct siphdrelement *elem = hdr->data;
69 if(!g_ascii_strcasecmp(elem->name, "Record-Route")) {
70 gchar **parts = g_strsplit(elem->value, ",", 0);
71 gchar **part = parts;
73 while (*part) {
74 gchar *route = sipmsg_find_part_of_header(*part, "<", ">", NULL);
75 purple_debug_info("sipe", "sipe_get_route_header: route %s \n", route);
76 dialog->routes = g_slist_append(dialog->routes, route);
77 part++;
80 g_strfreev(parts);
82 hdr = g_slist_next(hdr);
85 if (outgoing) {
86 dialog->routes = g_slist_reverse(dialog->routes);
89 if (dialog->routes) {
90 dialog->request = dialog->routes->data;
91 dialog->routes = g_slist_remove(dialog->routes, dialog->routes->data);
94 contact = sipmsg_find_part_of_header(sipmsg_find_header(msg, "Contact"), "<", ">", NULL);
95 dialog->routes = g_slist_append(dialog->routes, contact);
98 static void
99 sipe_get_supported_header(const struct sipmsg *msg,
100 struct sip_dialog *dialog,
101 gboolean outgoing)
103 GSList *hdr = msg->headers;
104 struct siphdrelement *elem;
105 while(hdr)
107 elem = hdr->data;
108 if(!g_ascii_strcasecmp(elem->name, "Supported")
109 && !g_slist_find_custom(dialog->supported, elem->value, (GCompareFunc)g_ascii_strcasecmp))
111 dialog->supported = g_slist_append(dialog->supported, g_strdup(elem->value));
114 hdr = g_slist_next(hdr);
118 static gchar *find_tag(const gchar *hdr)
120 gchar * tag = sipmsg_find_part_of_header (hdr, "tag=", ";", NULL);
121 if (!tag) {
122 // In case it's at the end and there's no trailing ;
123 tag = sipmsg_find_part_of_header (hdr, "tag=", NULL, NULL);
125 return tag;
128 void sipe_parse_dialog(const struct sipmsg *msg,
129 struct sip_dialog *dialog,
130 gboolean outgoing)
132 gchar *us = outgoing ? "From" : "To";
133 gchar *them = outgoing ? "To" : "From";
135 g_free(dialog->ourtag);
136 g_free(dialog->theirtag);
138 dialog->ourtag = find_tag(sipmsg_find_header(msg, us));
139 dialog->theirtag = find_tag(sipmsg_find_header(msg, them));
140 if (!dialog->theirepid) {
141 dialog->theirepid = sipmsg_find_part_of_header(sipmsg_find_header(msg, them), "epid=", ";", NULL);
142 if (!dialog->theirepid) {
143 dialog->theirepid = sipmsg_find_part_of_header(sipmsg_find_header(msg, them), "epid=", NULL, NULL);
147 // Catch a tag on the end of the To Header and get rid of it.
148 if (dialog->theirepid && strstr(dialog->theirepid, "tag=")) {
149 dialog->theirepid = strtok(dialog->theirepid, ";");
152 sipe_get_route_header(msg, dialog, outgoing);
153 sipe_get_supported_header(msg, dialog, outgoing);
157 Local Variables:
158 mode: c
159 c-file-style: "bsd"
160 indent-tabs-mode: t
161 tab-width: 8
162 End: