From 13520da938628e250573dd9ace9cbb07c0b7094b Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Tue, 14 Jul 2009 18:27:33 +0300 Subject: [PATCH] Start the Big Split... sipe.c has clearly become too big to be managable. Start to split off functionality into self-contained modules with documented(!) interfaces. Possible candidates: session, plugin, account, send, receive, presence, buddy, ... Upgrade sipe-conf.c from hidden sipe.c #include to own module. Preliminary memory leak review for sipe-conf.c. --- src/Makefile.am | 6 ++ src/sipe-conf.c | 59 +++++++++++---- src/sipe-conf.h | 25 +------ src/sipe-dialog.c | 163 +++++++++++++++++++++++++++++++++++++++++ src/sipe-dialog.h | 61 ++++++++++++++++ src/sipe-utils.c | 90 +++++++++++++++++++++++ src/sipe-utils.h | 53 ++++++++++++++ src/sipe.c | 211 +++++------------------------------------------------- src/sipe.h | 47 ++++++------ src/sipmsg.c | 4 +- src/sipmsg.h | 4 +- 11 files changed, 463 insertions(+), 260 deletions(-) create mode 100644 src/sipe-dialog.c create mode 100644 src/sipe-dialog.h create mode 100644 src/sipe-utils.c create mode 100644 src/sipe-utils.h diff --git a/src/Makefile.am b/src/Makefile.am index 61c5459f..3b1313ea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,6 +12,12 @@ libsipe_la_SOURCES = \ sipmsg.h \ sipe.h \ sipe.c \ + sipe-conf.h \ + sipe-conf.c \ + sipe-dialog.h \ + sipe-dialog.c \ + sipe-utils.h \ + sipe-utils.c \ sip-sec.h \ sip-sec.c \ sip-sec-mech.h \ diff --git a/src/sipe-conf.c b/src/sipe-conf.c index e86304e8..8eccd6c0 100755 --- a/src/sipe-conf.c +++ b/src/sipe-conf.c @@ -21,6 +21,38 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include +#include + +#include "debug.h" + +#include "sipe.h" +#include "sipe-conf.h" +#include "sipe-dialog.h" +#include "sipe-utils.h" + +/** + * AddUser request to Focus. + * Params: + * focus_URI, from, request_id, focus_URI, from, endpoint_GUID + */ +#define SIPE_SEND_CONF_ADD_USER \ +""\ +""\ + ""\ + ""\ + ""\ + ""\ + "attendee"\ + ""\ + ""\ + ""\ + ""\ +"" static struct sip_im_session * find_conf_session(struct sipe_account_data *sip, @@ -129,15 +161,15 @@ process_invite_conf_focus_response(struct sipe_account_data *sip, return FALSE; } else if (msg->response == 200) { xmlnode *xn_response = xmlnode_from_str(msg->body, msg->bodylen); - gchar *code = g_strdup(xmlnode_get_attrib(xn_response, "code")); - xmlnode_free(xn_response); + const gchar *code = xmlnode_get_attrib(xn_response, "code"); if (!strcmp(code, "success")) { /* subscribe to focus */ sipe_subscribe_conference(sip, session); } - g_free(code); + xmlnode_free(xn_response); } + g_free(focus_uri); return TRUE; } @@ -149,7 +181,7 @@ sipe_invite_conf_focus(struct sipe_account_data *sip, gchar *hdr; gchar *contact; gchar *body; - gchar *self = g_strdup_printf("sip:%s", sip->username); + gchar *self; if (session->focus_dialog && session->focus_dialog->is_established) { purple_debug_info("sipe", "session with %s already has a dialog open\n", session->focus_uri); @@ -176,6 +208,7 @@ sipe_invite_conf_focus(struct sipe_account_data *sip, /* @TODO put request_id to queue to further compare with incoming one */ /* focus_URI, from, request_id, focus_URI, from, endpoint_GUID */ + self = g_strdup_printf("sip:%s", sip->username); body = g_strdup_printf( SIPE_SEND_CONF_ADD_USER, session->focus_dialog->with, @@ -184,6 +217,7 @@ sipe_invite_conf_focus(struct sipe_account_data *sip, session->focus_dialog->with, self, session->focus_dialog->endpoint_GUID); + g_free(self); session->focus_dialog->outgoing_invite = send_sip_request(sip->gc, "INVITE", @@ -193,14 +227,12 @@ sipe_invite_conf_focus(struct sipe_account_data *sip, body, session->focus_dialog, process_invite_conf_focus_response); - g_free(self); g_free(body); g_free(hdr); } -static void -process_incoming_invite_conf(struct sipe_account_data *sip, - struct sipmsg *msg) +void process_incoming_invite_conf(struct sipe_account_data *sip, + struct sipmsg *msg) { struct sip_im_session *session = NULL; struct sip_dialog *dialog = NULL; @@ -209,7 +241,7 @@ process_incoming_invite_conf(struct sipe_account_data *sip, xmlnode *xn_conferencing = xmlnode_from_str(msg->body, msg->bodylen); xmlnode *xn_focus_uri = xmlnode_get_child(xn_conferencing, "focus-uri"); char *focus_uri = xmlnode_get_data(xn_focus_uri); - + xmlnode_free(xn_conferencing); /* send OK */ @@ -217,12 +249,12 @@ process_incoming_invite_conf(struct sipe_account_data *sip, send_sip_response(sip->gc, msg, 200, "OK", NULL); session = create_chat_session(sip); - session->focus_uri = g_strdup(focus_uri); + session->focus_uri = focus_uri; /* temporaty dialog with invitor */ dialog = g_new0(struct sip_dialog, 1); dialog->callid = g_strdup(callid); - dialog->with = g_strdup(from); + dialog->with = from; sipe_parse_dialog(msg, dialog, FALSE); /* send BYE to invitor */ @@ -230,10 +262,7 @@ process_incoming_invite_conf(struct sipe_account_data *sip, free_dialog(dialog); //add self to conf - sipe_invite_conf_focus(sip, session); - - g_free(from); - g_free(focus_uri); + sipe_invite_conf_focus(sip, session); } /* diff --git a/src/sipe-conf.h b/src/sipe-conf.h index eabda4ab..41dc828e 100755 --- a/src/sipe-conf.h +++ b/src/sipe-conf.h @@ -27,29 +27,6 @@ * * Server 2007+ functionality. */ -static void +void process_incoming_invite_conf(struct sipe_account_data *sip, struct sipmsg *msg); - -/** - * AddUser request to Focus. - * Params: - * focus_URI, from, request_id, focus_URI, from, endpoint_GUID - */ -#define SIPE_SEND_CONF_ADD_USER \ -""\ -""\ - ""\ - ""\ - ""\ - ""\ - "attendee"\ - ""\ - ""\ - ""\ - ""\ -"" diff --git a/src/sipe-dialog.c b/src/sipe-dialog.c new file mode 100644 index 00000000..42596ebc --- /dev/null +++ b/src/sipe-dialog.c @@ -0,0 +1,163 @@ +/** + * @file sipe-dialog.c + * + * pidgin-sipe + * + * Copyright (C) 2009 SIPE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "debug.h" + +#include "sipe.h" +#include "sipe-dialog.h" +#include "sipmsg.h" + +void free_dialog(struct sip_dialog *dialog) +{ + GSList *entry; + + if (!dialog) return; + + g_free(dialog->with); + g_free(dialog->endpoint_GUID); + entry = dialog->routes; + while (entry) { + g_free(entry->data); + entry = g_slist_remove(entry, entry->data); + } + entry = dialog->supported; + while (entry) { + g_free(entry->data); + entry = g_slist_remove(entry, entry->data); + } + + g_free(dialog->callid); + g_free(dialog->ourtag); + g_free(dialog->theirtag); + g_free(dialog->theirepid); + g_free(dialog->request); + + g_free(dialog); +} + +static void sipe_get_route_header(const struct sipmsg *msg, + struct sip_dialog *dialog, + gboolean outgoing) +{ + GSList *hdr = msg->headers; + gchar *contact; + + while (hdr) { + struct siphdrelement *elem = hdr->data; + if(!g_ascii_strcasecmp(elem->name, "Record-Route")) { + gchar **parts = g_strsplit(elem->value, ",", 0); + gchar **part = parts; + + while (*part) { + gchar *route = sipmsg_find_part_of_header(*part, "<", ">", NULL); + purple_debug_info("sipe", "sipe_get_route_header: route %s \n", route); + dialog->routes = g_slist_append(dialog->routes, route); + part++; + } + + g_strfreev(parts); + } + hdr = g_slist_next(hdr); + } + + if (outgoing) { + dialog->routes = g_slist_reverse(dialog->routes); + } + + if (dialog->routes) { + dialog->request = dialog->routes->data; + dialog->routes = g_slist_remove(dialog->routes, dialog->routes->data); + } + + contact = sipmsg_find_part_of_header(sipmsg_find_header(msg, "Contact"), "<", ">", NULL); + dialog->routes = g_slist_append(dialog->routes, contact); +} + +static void +sipe_get_supported_header(const struct sipmsg *msg, + struct sip_dialog *dialog, + gboolean outgoing) +{ + GSList *hdr = msg->headers; + struct siphdrelement *elem; + while(hdr) + { + elem = hdr->data; + if(!g_ascii_strcasecmp(elem->name, "Supported") + && !g_slist_find_custom(dialog->supported, elem->value, (GCompareFunc)g_ascii_strcasecmp)) + { + dialog->supported = g_slist_append(dialog->supported, g_strdup(elem->value)); + + } + hdr = g_slist_next(hdr); + } +} + +static gchar *find_tag(const gchar *hdr) +{ + gchar * tag = sipmsg_find_part_of_header (hdr, "tag=", ";", NULL); + if (!tag) { + // In case it's at the end and there's no trailing ; + tag = sipmsg_find_part_of_header (hdr, "tag=", NULL, NULL); + } + return tag; +} + +void sipe_parse_dialog(const struct sipmsg *msg, + struct sip_dialog *dialog, + gboolean outgoing) +{ + gchar *us = outgoing ? "From" : "To"; + gchar *them = outgoing ? "To" : "From"; + + g_free(dialog->ourtag); + g_free(dialog->theirtag); + + dialog->ourtag = find_tag(sipmsg_find_header(msg, us)); + dialog->theirtag = find_tag(sipmsg_find_header(msg, them)); + if (!dialog->theirepid) { + dialog->theirepid = sipmsg_find_part_of_header(sipmsg_find_header(msg, them), "epid=", ";", NULL); + if (!dialog->theirepid) { + dialog->theirepid = sipmsg_find_part_of_header(sipmsg_find_header(msg, them), "epid=", NULL, NULL); + } + } + + // Catch a tag on the end of the To Header and get rid of it. + if (dialog->theirepid && strstr(dialog->theirepid, "tag=")) { + dialog->theirepid = strtok(dialog->theirepid, ";"); + } + + sipe_get_route_header(msg, dialog, outgoing); + sipe_get_supported_header(msg, dialog, outgoing); +} + +/* + Local Variables: + mode: c + c-file-style: "bsd" + indent-tabs-mode: t + tab-width: 8 + End: +*/ diff --git a/src/sipe-dialog.h b/src/sipe-dialog.h new file mode 100644 index 00000000..085ea6de --- /dev/null +++ b/src/sipe-dialog.h @@ -0,0 +1,61 @@ +/** + * @file sipe-dialog.h + * + * pidgin-sipe + * + * Copyright (C) 2009 SIPE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* dialog is the new term for call-leg */ +struct sip_dialog { + gchar *with; /* URI */ + gchar *endpoint_GUID; + /** + * >0 - pro + * <0 - contra + * 0 - didn't participate + */ + int election_vote; + gchar *ourtag; + gchar *theirtag; + gchar *theirepid; + gchar *callid; + GSList *routes; + gchar *request; + GSList *supported; /* counterparty capabilities */ + int cseq; + gboolean is_established; + struct transaction *outgoing_invite; +}; + +/** + * Free dialog structure + * + * @param dialog (in) Dialog to be freed. May be NULL. + */ +void free_dialog(struct sip_dialog *dialog); + +/** + * Fill dialog structure from SIP message + * + * @param msg (in) mesage + * @param dialog (in,out) dialog to fill + * @param outgoing (in) outgoing or incoming message + */ +void sipe_parse_dialog(const struct sipmsg *msg, + struct sip_dialog *dialog, + gboolean outgoing); diff --git a/src/sipe-utils.c b/src/sipe-utils.c new file mode 100644 index 00000000..af5f6b9a --- /dev/null +++ b/src/sipe-utils.c @@ -0,0 +1,90 @@ +/** + * @file sipe-utils.c + * + * pidgin-sipe + * + * Copyright (C) 2009 SIPE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "debug.h" + +#include "sipe.h" +#include "sipe-utils.h" + +/* Generate 32 random bits */ +#define RANDOM32BITS (rand() & 0xFFFF) + +gchar *gencallid(void) +{ + return g_strdup_printf("%04Xg%04Xa%04Xi%04Xm%04Xt%04Xb%04Xx%04Xx", + RANDOM32BITS, RANDOM32BITS, RANDOM32BITS, + RANDOM32BITS, RANDOM32BITS, RANDOM32BITS, + RANDOM32BITS, RANDOM32BITS); +} + +gchar *gentag() +{ + return g_strdup_printf("%04d%04d", RANDOM32BITS, RANDOM32BITS); +} + +gchar *get_contact(const struct sipe_account_data *sip) +{ + return g_strdup(sip->contact); +} + +gchar *parse_from(const gchar *hdr) +{ + gchar *from; + const gchar *tmp, *tmp2 = hdr; + + if (!hdr) return NULL; + purple_debug_info("sipe", "parsing address out of %s\n", hdr); + tmp = strchr(hdr, '<'); + + /* i hate the different SIP UA behaviours... */ + if (tmp) { /* sip address in <...> */ + tmp2 = tmp + 1; + tmp = strchr(tmp2, '>'); + if (tmp) { + from = g_strndup(tmp2, tmp - tmp2); + } else { + purple_debug_info("sipe", "found < without > in From\n"); + return NULL; + } + } else { + tmp = strchr(tmp2, ';'); + if (tmp) { + from = g_strndup(tmp2, tmp - tmp2); + } else { + from = g_strdup(tmp2); + } + } + purple_debug_info("sipe", "got %s\n", from); + return from; +} + +/* + Local Variables: + mode: c + c-file-style: "bsd" + indent-tabs-mode: t + tab-width: 8 + End: +*/ diff --git a/src/sipe-utils.h b/src/sipe-utils.h new file mode 100644 index 00000000..65f3a0ef --- /dev/null +++ b/src/sipe-utils.h @@ -0,0 +1,53 @@ +/** + * @file sipe-utils.h + * + * pidgin-sipe + * + * Copyright (C) 2009 SIPE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * Generate Call ID + * + * @return Call ID. Must be g_free()'d. + */ +gchar *gencallid(void); + +/** + * Generate Tag + * + * @return Tag. Must be g_free()'d. + */ +gchar *gentag(void); + +/** + * Get contact information from SIPE account + * + * @param sip (in) SIPE account + * + * @return Contact. Must be g_free()'d. + */ +gchar *get_contact(const struct sipe_account_data *sip); + +/** + * Parses URI from SIP header + * + * @param hdr (in) To/From header + * + * @return URI with sip: prefix. Must be g_free()'d. + */ +gchar *parse_from(const gchar *hdr); diff --git a/src/sipe.c b/src/sipe.c index d7d73871..f6f0367b 100755 --- a/src/sipe.c +++ b/src/sipe.c @@ -76,6 +76,8 @@ #include "sipe.h" #include "sipe-conf.h" +#include "sipe-dialog.h" +#include "sipe-utils.h" #include "sipmsg.h" #include "sipe-sign.h" #include "dnssrv.h" @@ -105,11 +107,6 @@ static const char *transport_descriptor[] = { "tls", "tcp", "udp" }; /* Action name templates */ #define ACTION_NAME_PRESENCE "<%s>" -static char *gentag() -{ - return g_strdup_printf("%04d%04d", rand() & 0xFFFF, rand() & 0xFFFF); -} - static gchar *get_epid(struct sipe_account_data *sip) { if (!sip->epid) { @@ -125,25 +122,6 @@ static char *genbranch() rand() & 0xFFFF, rand() & 0xFFFF); } -static char *gencallid() -{ - return g_strdup_printf("%04Xg%04Xa%04Xi%04Xm%04Xt%04Xb%04Xx%04Xx", - rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF, - rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF, - rand() & 0xFFFF, rand() & 0xFFFF); -} - -static gchar *find_tag(const gchar *hdr) -{ - gchar * tag = sipmsg_find_part_of_header (hdr, "tag=", ";", NULL); - if (!tag) { - // In case it's at the end and there's no trailing ; - tag = sipmsg_find_part_of_header (hdr, "tag=", NULL, NULL); - } - return tag; -} - - static const char *sipe_list_icon(PurpleAccount *a, PurpleBuddy *b) { return "sipe"; @@ -170,7 +148,7 @@ static void sipe_keep_alive(PurpleConnection *gc) /* in case of UDP send a packet only with a 0 byte to remain in the NAT table */ gchar buf[2] = {0, 0}; purple_debug_info("sipe", "sending keep alive\n"); - sendto(sip->fd, buf, 1, 0, (struct sockaddr*)&sip->serveraddr, sizeof(struct sockaddr_in)); + sendto(sip->fd, buf, 1, 0, sip->serveraddr, sizeof(struct sockaddr_in)); } else { time_t now = time(NULL); if ((sip->keepalive_timeout > 0) && @@ -565,7 +543,7 @@ static void sendout_pkt(PurpleConnection *gc, const char *buf) purple_debug(PURPLE_DEBUG_MISC, "sipe", "\n\nsending - %s\n######\n%s\n######\n\n", ctime(&currtime), buf); if (sip->transport == SIPE_TRANSPORT_UDP) { - if (sendto(sip->fd, buf, writelen, 0, (struct sockaddr*)&sip->serveraddr, sizeof(struct sockaddr_in)) < writelen) { + if (sendto(sip->fd, buf, writelen, 0, sip->serveraddr, sizeof(struct sockaddr_in)) < writelen) { purple_debug_info("sipe", "could not send packet\n"); } } else { @@ -687,11 +665,6 @@ static void sign_outgoing_message (struct sipmsg * msg, struct sipe_account_data } } -static char *get_contact(struct sipe_account_data *sip) -{ - return g_strdup(sip->contact); -} - /* * unused. Needed? static char *get_contact_service(struct sipe_account_data *sip) @@ -701,8 +674,8 @@ static char *get_contact_service(struct sipe_account_data *sip) } */ -static void send_sip_response(PurpleConnection *gc, struct sipmsg *msg, int code, - const char *text, const char *body) +void send_sip_response(PurpleConnection *gc, struct sipmsg *msg, int code, + const char *text, const char *body) { gchar *name; gchar *value; @@ -780,7 +753,7 @@ static struct transaction *transactions_find(struct sipe_account_data *sip, stru return NULL; } -static struct transaction * +struct transaction * send_sip_request(PurpleConnection *gc, const gchar *method, const gchar *url, const gchar *to, const gchar *addheaders, const gchar *body, struct sip_dialog *dialog, TransCallback tc) @@ -957,44 +930,6 @@ static void do_register(struct sipe_account_data *sip) do_register_exp(sip, -1); } -/** - * Returns URI from provided To or From header. - * - * Needs to g_free() after use. - * - * @return URI with sip: prefix - */ -static gchar *parse_from(const gchar *hdr) -{ - gchar *from; - const gchar *tmp, *tmp2 = hdr; - - if (!hdr) return NULL; - purple_debug_info("sipe", "parsing address out of %s\n", hdr); - tmp = strchr(hdr, '<'); - - /* i hate the different SIP UA behaviours... */ - if (tmp) { /* sip address in <...> */ - tmp2 = tmp + 1; - tmp = strchr(tmp2, '>'); - if (tmp) { - from = g_strndup(tmp2, tmp - tmp2); - } else { - purple_debug_info("sipe", "found < without > in From\n"); - return NULL; - } - } else { - tmp = strchr(tmp2, ';'); - if (tmp) { - from = g_strndup(tmp2, tmp - tmp2); - } else { - from = g_strdup(tmp2); - } - } - purple_debug_info("sipe", "got %s\n", from); - return from; -} - static xmlnode * xmlnode_get_descendant(xmlnode * parent, ...) { va_list args; @@ -1442,7 +1377,7 @@ sipe_schedule_action_msec(const gchar *name, static void process_incoming_notify(struct sipe_account_data *sip, struct sipmsg *msg, gboolean request, gboolean benotify); -static gboolean process_subscribe_response(struct sipe_account_data *sip, struct sipmsg *msg, struct transaction *tc) +gboolean process_subscribe_response(struct sipe_account_data *sip, struct sipmsg *msg, struct transaction *tc) { if (sipmsg_find_header(msg, "ms-piggyback-cseq")) { @@ -2690,7 +2625,7 @@ static struct sip_im_session * find_im_session (struct sipe_account_data *sip, c return NULL; } -static struct sip_im_session * +struct sip_im_session * create_chat_session (struct sipe_account_data *sip) { struct sip_im_session *session = g_new0(struct sip_im_session, 1); @@ -2725,36 +2660,7 @@ static struct sip_im_session * find_or_create_im_session (struct sipe_account_da return session; } -static void -free_dialog(struct sip_dialog *dialog) -{ - GSList *entry; - - if (!dialog) return; - - g_free(dialog->with); - g_free(dialog->endpoint_GUID); - entry = dialog->routes; - while (entry) { - g_free(entry->data); - entry = g_slist_remove(entry, entry->data); - } - entry = dialog->supported; - while (entry) { - g_free(entry->data); - entry = g_slist_remove(entry, entry->data); - } - - g_free(dialog->callid); - g_free(dialog->ourtag); - g_free(dialog->theirtag); - g_free(dialog->theirepid); - g_free(dialog->request); - - g_free(dialog); -} - -static void im_session_destroy(struct sipe_account_data *sip, struct sip_im_session * session) +void im_session_destroy(struct sipe_account_data *sip, struct sip_im_session * session) { GSList *entry; @@ -3019,90 +2925,6 @@ sipe_im_process_queue (struct sipe_account_data * sip, struct sip_im_session * s } static void -sipe_get_route_header(struct sipmsg *msg, struct sip_dialog * dialog, gboolean outgoing) -{ - GSList *hdr = msg->headers; - gchar *contact; - - while(hdr) { - struct siphdrelement *elem = hdr->data; - if(!g_ascii_strcasecmp(elem->name, "Record-Route")) { - gchar **parts = g_strsplit(elem->value, ",", 0); - gchar **part = parts; - - while (*part) { - gchar *route = sipmsg_find_part_of_header(*part, "<", ">", NULL); - purple_debug_info("sipe", "sipe_get_route_header: route %s \n", route); - dialog->routes = g_slist_append(dialog->routes, route); - part++; - } - - g_strfreev(parts); - } - hdr = g_slist_next(hdr); - } - - if (outgoing) - { - dialog->routes = g_slist_reverse(dialog->routes); - } - - if (dialog->routes) - { - dialog->request = dialog->routes->data; - dialog->routes = g_slist_remove(dialog->routes, dialog->routes->data); - } - - contact = sipmsg_find_part_of_header(sipmsg_find_header(msg, "Contact"), "<", ">", NULL); - dialog->routes = g_slist_append(dialog->routes, contact); -} - -static void -sipe_get_supported_header(struct sipmsg *msg, struct sip_dialog * dialog, gboolean outgoing) -{ - GSList *hdr = msg->headers; - struct siphdrelement *elem; - while(hdr) - { - elem = hdr->data; - if(!g_ascii_strcasecmp(elem->name, "Supported") - && !g_slist_find_custom(dialog->supported, elem->value, (GCompareFunc)g_ascii_strcasecmp)) - { - dialog->supported = g_slist_append(dialog->supported, g_strdup(elem->value)); - - } - hdr = g_slist_next(hdr); - } -} - -static void -sipe_parse_dialog(struct sipmsg * msg, struct sip_dialog * dialog, gboolean outgoing) -{ - gchar *us = outgoing ? "From" : "To"; - gchar *them = outgoing ? "To" : "From"; - - g_free(dialog->ourtag); - g_free(dialog->theirtag); - - dialog->ourtag = find_tag(sipmsg_find_header(msg, us)); - dialog->theirtag = find_tag(sipmsg_find_header(msg, them)); - if (!dialog->theirepid) { - dialog->theirepid = sipmsg_find_part_of_header(sipmsg_find_header(msg, them), "epid=", ";", NULL); - if (!dialog->theirepid) { - dialog->theirepid = sipmsg_find_part_of_header(sipmsg_find_header(msg, them), "epid=", NULL, NULL); - } - } - - // Catch a tag on the end of the To Header and get rid of it. - if (dialog->theirepid && strstr(dialog->theirepid, "tag=")) { - dialog->theirepid = strtok(dialog->theirepid, ";"); - } - - sipe_get_route_header(msg, dialog, outgoing); - sipe_get_supported_header(msg, dialog, outgoing); -} - -static void sipe_refer_notify(struct sipe_account_data *sip, struct sip_im_session *session, const gchar *who, @@ -5547,7 +5369,6 @@ static void sipe_udp_host_resolved_listen_cb(int listenfd, gpointer data) static void sipe_udp_host_resolved(GSList *hosts, gpointer data, const char *error_message) { struct sipe_account_data *sip = (struct sipe_account_data*) data; - int addr_size; sip->query_data = NULL; @@ -5556,10 +5377,9 @@ static void sipe_udp_host_resolved(GSList *hosts, gpointer data, const char *err return; } - addr_size = GPOINTER_TO_INT(hosts->data); hosts = g_slist_remove(hosts, hosts->data); - memcpy(&(sip->serveraddr), hosts->data, addr_size); - g_free(hosts->data); + g_free(sip->serveraddr); + sip->serveraddr = hosts->data; hosts = g_slist_remove(hosts, hosts->data); while (hosts) { hosts = g_slist_remove(hosts, hosts->data); @@ -5934,6 +5754,10 @@ static void sipe_connection_cleanup(struct sipe_account_data *sip) g_free(sip->regcallid); sip->regcallid = NULL; + if (sip->serveraddr) + g_free(sip->serveraddr); + sip->serveraddr = NULL; + sip->fd = -1; sip->processing_input = FALSE; } @@ -6894,9 +6718,6 @@ gboolean purple_init_plugin(PurplePlugin *plugin){ return purple_plugin_register(plugin); } -/* A continuation of sipe.c related to 2007 conferencing, placed in separate text file */ -#include "sipe-conf.c" - /* Local Variables: mode: c diff --git a/src/sipe.h b/src/sipe.h index d52e83a7..401129db 100644 --- a/src/sipe.h +++ b/src/sipe.h @@ -79,27 +79,6 @@ struct sip_im_session { }; // dialog is the new term for call-leg -struct sip_dialog { - gchar *with; /* URI */ - gchar *endpoint_GUID; - /** - * >0 - pro - * <0 - contra - * 0 - didn't participate - */ - int election_vote; - gchar *ourtag; - gchar *theirtag; - gchar *theirepid; - gchar *callid; - GSList *routes; - gchar *request; - GSList *supported; // counterparty capabilities - int cseq; - gboolean is_established; - struct transaction *outgoing_invite; -}; - struct sipe_buddy { gchar *name; gchar *annotation; @@ -200,7 +179,7 @@ struct sipe_account_data { sipe_transport_type transport; gboolean auto_transport; PurpleSslConnection *gsc; - struct sockaddr_in serveraddr; + struct sockaddr *serveraddr; gchar *realhostname; int realport; /* port and hostname from SRV record */ gboolean processing_input; @@ -251,6 +230,30 @@ GList *sipe_actions(PurplePlugin *plugin, gpointer context); gboolean purple_init_plugin(PurplePlugin *plugin); +/** + * THE BIG SPLIT - temporary interfaces + * + * Previously private functions in sipe.c that are + * - waiting to be factored out to an appropriate module + * - are needed by the already created new modules + */ +struct transaction * +send_sip_request(PurpleConnection *gc, const gchar *method, + const gchar *url, const gchar *to, const gchar *addheaders, + const gchar *body, struct sip_dialog *dialog, TransCallback tc); +void +send_sip_response(PurpleConnection *gc, struct sipmsg *msg, int code, + const char *text, const char *body); +gboolean process_subscribe_response(struct sipe_account_data *sip, + struct sipmsg *msg, + struct transaction *tc); +void +im_session_destroy(struct sipe_account_data *sip, + struct sip_im_session *session); +struct sip_im_session * +create_chat_session (struct sipe_account_data *sip); +/*** THE BIG SPLIT END ***/ + #define SIPE_INVITE_TEXT "ms-text-format: text/plain; charset=UTF-8%s;ms-body=%s\r\n" #define SIPE_SEND_TYPING \ diff --git a/src/sipmsg.c b/src/sipmsg.c index 592c6a3e..620226ba 100644 --- a/src/sipmsg.c +++ b/src/sipmsg.c @@ -302,11 +302,11 @@ void sipmsg_remove_header_now(struct sipmsg *msg, const gchar *name) { return; } -gchar *sipmsg_find_header(struct sipmsg *msg, const gchar *name) { +gchar *sipmsg_find_header(const struct sipmsg *msg, const gchar *name) { return sipmsg_find_header_instance (msg, name, 0); } -gchar *sipmsg_find_header_instance(struct sipmsg *msg, const gchar *name, int which) { +gchar *sipmsg_find_header_instance(const struct sipmsg *msg, const gchar *name, int which) { GSList *tmp; struct siphdrelement *elem; int i = 0; diff --git a/src/sipmsg.h b/src/sipmsg.h index a8e0fb7e..9769562a 100644 --- a/src/sipmsg.h +++ b/src/sipmsg.h @@ -60,8 +60,8 @@ void sipmsg_strip_headers(struct sipmsg *msg, const gchar *keepers[]); void sipmsg_merge_new_headers(struct sipmsg *msg); void sipmsg_free(struct sipmsg *msg); GSList *sipmsg_parse_endpoints_header(const gchar *header); -gchar *sipmsg_find_header(struct sipmsg *msg, const gchar *name); -gchar *sipmsg_find_header_instance(struct sipmsg *msg, const gchar *name, int which); +gchar *sipmsg_find_header(const struct sipmsg *msg, const gchar *name); +gchar *sipmsg_find_header_instance(const struct sipmsg *msg, const gchar *name, int which); gchar *sipmsg_find_part_of_header(const char *hdr, const char * before, const char * after, const char * def); gchar *sipmsg_find_auth_header(struct sipmsg *msg, const gchar *name); void sipmsg_remove_header_now(struct sipmsg *msg, const gchar *name); -- 2.11.4.GIT