From c4f5aee10a16df722487e354b8028724900a4f30 Mon Sep 17 00:00:00 2001 From: Brian West Date: Fri, 19 Jun 2009 15:35:26 +0000 Subject: [PATCH] refactor fs_path path from Math. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13864 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/endpoints/mod_sofia/mod_sofia.h | 8 ++ src/mod/endpoints/mod_sofia/sofia_glue.c | 132 +++++++++++++++---- src/mod/endpoints/mod_sofia/sofia_presence.c | 103 +++------------ 3 files changed, 133 insertions(+), 110 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index a27b26f5ee..c5a2e47123 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -643,6 +643,12 @@ typedef enum { AUTH_STALE, } auth_res_t; +typedef struct { + char *to; + char *contact; + char *route; + char *route_uri; +} sofia_destination_t; #define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0) #define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1 @@ -891,3 +897,5 @@ sofia_cid_type_t sofia_cid_name2type(const char *name); void sofia_glue_tech_set_local_sdp(private_object_t *tech_pvt, const char *sdp_str, switch_bool_t dup); void sofia_glue_set_rtp_stats(private_object_t *tech_pvt); void sofia_glue_get_addr(msg_t *msg, char *buf, size_t buflen, int *port); +sofia_destination_t* sofia_glue_get_destination(char *data); +void sofia_glue_free_destination(sofia_destination_t *dst); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index c53437f4fa..69460d4f95 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1319,6 +1319,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) char *route = NULL; char *route_uri = NULL; char *sendto = NULL; + sofia_destination_t *dst = NULL; sofia_cid_type_t cid_type = tech_pvt->profile->cid_type; rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER); @@ -1666,32 +1667,14 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) sofia_glue_tech_patch_sdp(tech_pvt); } - if (tech_pvt->dest && (route = strstr(tech_pvt->dest, ";fs_path=")) && (*(route + 9))) { - char *p; + dst = sofia_glue_get_destination(tech_pvt->dest); - route = switch_core_session_strdup(tech_pvt->session, route + 9); - switch_assert(route); - - for (p = route; p && *p ; p++) { - if (*p == '>' || *p == ';') { - *p = '\0'; - break; - } - } - switch_url_decode(route); - route_uri = switch_core_session_strdup(tech_pvt->session, route); - if ((p = strchr(route_uri, ','))) { - while (*(p-1) == ' ') { - p--; - } - if (*p) { - *p = '\0'; - } - } - - route_uri = sofia_overcome_sip_uri_weakness(tech_pvt->session, route_uri, 0, SWITCH_TRUE, NULL); - } else { - route = NULL; + if (dst->route_uri) { + route_uri = sofia_overcome_sip_uri_weakness(tech_pvt->session, dst->route_uri, 0, SWITCH_TRUE, NULL); + } + + if (dst->route) { + route = dst->route; } if ((val = switch_channel_get_variable(channel, "sip_route_uri"))) { @@ -1720,9 +1703,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) TAG_IF(!switch_strlen_zero(alert_info), SIPTAG_HEADER_STR(alert_info)), TAG_IF(!switch_strlen_zero(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(!switch_strlen_zero(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)), - TAG_IF(tech_pvt->route_uri, NUTAG_PROXY(tech_pvt->route_uri)), + TAG_IF(!switch_strlen_zero(route_uri), NUTAG_PROXY(route_uri)), TAG_IF(!switch_strlen_zero(route), SIPTAG_ROUTE_STR(route)), - TAG_IF(!switch_strlen_zero(sendto), NUTAG_PROXY(sendto)), SOATAG_ADDRESS(tech_pvt->adv_sdp_audio_ip), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), SOATAG_REUSE_REJECTED(1), @@ -1731,6 +1713,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), SOATAG_HOLD(holdstr), TAG_END()); switch_safe_free(stream.data); + sofia_glue_free_destination(dst); tech_pvt->redirected = NULL; return SWITCH_STATUS_SUCCESS; @@ -4159,6 +4142,101 @@ sofia_cid_type_t sofia_cid_name2type(const char *name) } +/* all the values of the structure are initialized to NULL */ +/* in case of failure the function returns NULL */ +/* sofia_destination->route can be NULL */ +sofia_destination_t* sofia_glue_get_destination(char *data) +{ + sofia_destination_t *dst = NULL; + char *to = NULL; + char *contact = NULL; + char *route = NULL; + char *route_uri = NULL; + char *eoc = NULL; + char *p = NULL; + + if (switch_strlen_zero(data)) { + return NULL; + } + + if (!(dst = (sofia_destination_t *)malloc(sizeof(sofia_destination_t)))) { + return NULL; + } + + /* return a copy of what is in the buffer between the first < and > */ + if (!(contact = sofia_glue_get_url_from_contact(data, 1))) { + goto mem_fail; + } + + if((eoc = strstr(contact, ";fs_path="))) { + *eoc = '\0'; + + if(!(route = strdup(eoc + 9))) { + goto mem_fail; + } + + for (p = route; p && *p ; p++) { + if (*p == '>' || *p == ';') { + *p = '\0'; + break; + } + } + + switch_url_decode(route); + + if (!(route_uri = strdup(route))) { + goto mem_fail; + } + if ((p = strchr(route_uri, ','))) { + do { + *p = '\0'; + } while ((--p > route_uri) && *p == ' '); + } + } + else { + if(!(route_uri = strdup(contact))) { + goto mem_fail; + } + } + + if (!(to = strdup(data))) { + goto mem_fail; + } + + if((eoc = strstr(to, ";fs_path="))) { + *eoc++ = '>'; + *eoc = '\0'; + } + + if ((p = strstr(contact, ";fs_"))) { + *p = '\0'; + } + + dst->contact = contact; + dst->to = to; + dst->route = route; + dst->route_uri = route_uri; + return dst; + +mem_fail: + switch_safe_free(contact); + switch_safe_free(to); + switch_safe_free(route); + switch_safe_free(route_uri); + switch_safe_free(dst); + return NULL; +} + +void sofia_glue_free_destination(sofia_destination_t *dst) +{ + if (dst) { + switch_safe_free(dst->contact); + switch_safe_free(dst->route); + switch_safe_free(dst->route_uri); + switch_safe_free(dst->to); + switch_safe_free(dst); + } +} /* For Emacs: * Local Variables: diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 4ef53a0660..8147cbde73 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -61,10 +61,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co char *dup = NULL; switch_status_t status = SWITCH_STATUS_FALSE; const char *ct = "text/html"; - char *clean_to = NULL; - char *route = NULL; - char *route_uri = NULL; - char *ptr = NULL; + sofia_destination_t *dst = NULL; if (!to) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n"); @@ -138,57 +135,29 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co from = ffrom; switch_safe_free(fp); } - - contact = sofia_glue_get_url_from_contact(buf, 1); - - if (contact && (ptr = strstr(contact, ";fs_path=")) && (route = strdup(ptr + 9))) { - char *p; - for (p = route; p && *p ; p++) { - if (*p == '>' || *p == ';') { - *p = '\0'; - break; - } - } - switch_url_decode(route); - route_uri = strdup(route); - if ((p = strchr(route_uri, ','))) { - while ((p > route_uri) && *(p-1) == ' ') { - p--; - } - if (*p) { - *p = '\0'; - } - } - *ptr++ = '>'; - *ptr++ = '\0'; - } - - clean_to = strdup(buf); - if ((ptr = strstr(clean_to, ";fs_path="))) { - *ptr++ = '>'; - *ptr++ = '\0'; + + if (!(dst = sofia_glue_get_destination(buf))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); + goto end; } /* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */ status = SWITCH_STATUS_SUCCESS; /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */ - msg_nh = nua_handle(profile->nua, NULL, TAG_IF(route, NUTAG_PROXY(route_uri)), TAG_IF(route, SIPTAG_ROUTE_STR(route)), + msg_nh = nua_handle(profile->nua, NULL, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), SIPTAG_FROM_STR(from), NUTAG_URL(contact), - SIPTAG_TO_STR(clean_to), SIPTAG_CONTACT_STR(profile->url), + SIPTAG_TO_STR(dst->to), SIPTAG_CONTACT_STR(profile->url), TAG_END()); nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private); nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), TAG_END()); - + + end: - + sofia_glue_free_destination(dst); switch_safe_free(contact); - switch_safe_free(route); - switch_safe_free(route_uri); switch_safe_free(ffrom); switch_safe_free(dup); - switch_safe_free(clean_to); - if (profile) { switch_thread_rwlock_unlock(profile->rwlock); } @@ -1399,7 +1368,7 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char char *sub_to_user = argv[0]; char *sub_to_host = argv[1]; char *event = "message-summary"; - char *contact, *o_contact = argv[2]; + char *o_contact = argv[2]; char *profile_name = argv[3]; char *network_ip = argv[4]; char *body = argv[5]; @@ -1407,8 +1376,8 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char nua_handle_t *nh; struct mwi_helper *h = (struct mwi_helper *) pArg; sofia_profile_t *ext_profile = NULL, *profile = h->profile; - char *route = NULL, *route_uri = NULL, *user_via = NULL; - char *p, *contact_str; + sofia_destination_t *dst = NULL; + char *contact_str, *contact, *user_via = NULL; if (profile_name && strcasecmp(profile_name, h->profile->name)) { if ((ext_profile = sofia_glue_find_profile(profile_name))) { @@ -1421,7 +1390,9 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char char *ptr = NULL; const char *transport_str = NULL; + id = switch_mprintf("sip:%s@%s", sub_to_user, profile->extsipip); + switch_assert(id); if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) { sofia_transport_t transport = sofia_glue_str2transport(ptr); @@ -1449,43 +1420,9 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host); } - if ((route = strstr(contact, ";fs_path=")) && (route = strdup(route + 9))) { - - for (p = route; p && *p ; p++) { - if (*p == '>' || *p == ';') { - *p = '\0'; - break; - } - } - switch_url_decode(route); - route_uri = route; - if ((p = strchr(route_uri, ','))) { - while (*(p-1) == ' ') { - p--; - } - if (*p) { - *p = '\0'; - } - } - } + dst = sofia_glue_get_destination(o_contact); + switch_assert(dst); - if (!route_uri && strstr(contact, ";fs_nat")) { - route_uri = contact; - } - - if ((p = strstr(contact, ";fs_"))) { - *p = '\0'; - } - - if (route_uri) { - while (route_uri && *route_uri && (*route_uri == '<' || *route_uri == ' ')) { - route_uri++; - } - if ((p = strchr(route_uri, '>'))) { - *p++ = '\0'; - } - } - nh = nua_handle(profile->nua, NULL, NUTAG_URL(contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(contact_str), TAG_END()); @@ -1493,15 +1430,15 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char nua_notify(nh, NUTAG_NEWSUB(1), - TAG_IF(route_uri, NUTAG_PROXY(route_uri)), + TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_IF(user_via, SIPTAG_VIA_STR(user_via)), SIPTAG_EVENT_STR(event), SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), SIPTAG_PAYLOAD_STR(body), TAG_END()); - + switch_safe_free(contact); switch_safe_free(id); - switch_safe_free(route); + sofia_glue_free_destination(dst); switch_safe_free(user_via); if (ext_profile) {