Bug Summary

File:mod/endpoints/mod_sofia/sofia_glue.c
Warning:line 1394, column 11
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sofia_glue.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fno-trapping-math -ffp-contract=fast -ffast-math -ffinite-math-only -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -resource-dir /usr/lib/llvm-7/lib/clang/7.0.1 -D HAVE_CONFIG_H -I . -I ../../../../src/include -I ../../../../libs/esl/src/include -I ../../../../libs/xmlrpc-c -I /drone/src/src/include -I /drone/src/src/include -I /drone/src/libs/libteletone/src -D SWITCH_API_VISIBILITY=1 -D CJSON_API_VISIBILITY=1 -D HAVE_VISIBILITY=1 -I /usr/include/uuid -I /drone/src/src/include -I /drone/src/src/include -I /drone/src/libs/libteletone/src -D SWITCH_API_VISIBILITY=1 -D CJSON_API_VISIBILITY=1 -D HAVE_VISIBILITY=1 -D HAVE_OPENSSL -I . -I /usr/include/sofia-sip-1.13 -D HAVE_STIRSHAKEN -D PIC -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-result -Wno-misleading-indentation -std=c99 -fdebug-compilation-dir /drone/src/src/mod/endpoints/mod_sofia -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -o /drone/src/scan-build/2021-10-18-184555-401-1 -x c sofia_glue.c -faddrsig
1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Ken Rice <krice@freeswitch.org>
28 * Paul D. Tinsley <pdt at jackhammer.org>
29 * Bret McDanel <trixter AT 0xdecafbad.com>
30 * Eliot Gable <egable AT.AT broadvox.com>
31 *
32 *
33 * sofia_glue.c -- SOFIA SIP Endpoint (code to tie sofia to freeswitch)
34 *
35 */
36#include "mod_sofia.h"
37#include <switch_stun.h>
38
39switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line);
40#define sofia_glue_get_db_handle(_p)_sofia_glue_get_db_handle(_p, "sofia_glue.c", (const char *)__func__
, 40)
_sofia_glue_get_db_handle(_p, __FILE__"sofia_glue.c", __SWITCH_FUNC__(const char *)__func__, __LINE__40)
41
42
43int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip)
44{
45 switch_assert(network_ip)((network_ip) ? (void) (0) : __assert_fail ("network_ip", "sofia_glue.c"
, 45, __extension__ __PRETTY_FUNCTION__))
;
46
47 return (profile->extsipip &&
48 !switch_check_network_list_ip(network_ip, "loopback.auto")switch_check_network_list_ip_token(network_ip, "loopback.auto"
, ((void*)0))
&&
49 !switch_check_network_list_ip(network_ip, profile->local_network)switch_check_network_list_ip_token(network_ip, profile->local_network
, ((void*)0))
);
50}
51
52private_object_t *sofia_glue_new_pvt(switch_core_session_t *session)
53{
54 private_object_t *tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t))switch_core_perform_session_alloc(session, sizeof(private_object_t
), "sofia_glue.c", (const char *)__func__, 54)
;
55 switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session));
56 switch_mutex_init(&tech_pvt->sofia_mutex, SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session));
57 return tech_pvt;
58}
59
60void sofia_glue_set_name(private_object_t *tech_pvt, const char *channame)
61{
62 char name[256];
63 char *p;
64
65 switch_snprintf(name, sizeof(name), "sofia/%s/%s", tech_pvt->profile->name, channame);
66 if ((p = strchr(name, ';'))) {
67 *p = '\0';
68 }
69 switch_channel_set_name(tech_pvt->channel, name);
70}
71
72void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *profile, private_object_t *tech_pvt, const char *channame)
73{
74
75 unsigned int x, i;
76
77 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "sofia_glue.c", 77, __extension__ __PRETTY_FUNCTION__))
;
78 switch_assert(profile != NULL)((profile != ((void*)0)) ? (void) (0) : __assert_fail ("profile != ((void*)0)"
, "sofia_glue.c", 78, __extension__ __PRETTY_FUNCTION__))
;
79 switch_assert(tech_pvt != NULL)((tech_pvt != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt != ((void*)0)"
, "sofia_glue.c", 79, __extension__ __PRETTY_FUNCTION__))
;
80
81 switch_core_session_add_stream(session, NULL((void*)0));
82
83 switch_mutex_lock(tech_pvt->flag_mutex);
84 switch_mutex_lock(profile->flag_mutex);
85
86 /* copy flags from profile to the sofia private */
87 for (x = 0; x < TFLAG_MAX; x++) {
88 tech_pvt->flags[x] = profile->flags[x];
89 }
90
91 tech_pvt->x_freeswitch_support_local = FREESWITCH_SUPPORT"update_display,send_info";
92
93 tech_pvt->profile = profile;
94
95 if (!zstr(profile->rtpip[profile->rtpip_next])_zstr(profile->rtpip[profile->rtpip_next])) {
96 tech_pvt->mparams.rtpip4 = switch_core_session_strdup(session, profile->rtpip[profile->rtpip_next++])switch_core_perform_session_strdup(session, profile->rtpip
[profile->rtpip_next++], "sofia_glue.c", (const char *)__func__
, 96)
;
97 tech_pvt->mparams.rtpip = tech_pvt->mparams.rtpip4;
98
99 if (profile->rtpip_next >= profile->rtpip_index) {
100 profile->rtpip_next = 0;
101 }
102 }
103
104 if (!zstr(profile->rtpip6[profile->rtpip_next6])_zstr(profile->rtpip6[profile->rtpip_next6])) {
105 tech_pvt->mparams.rtpip6 = switch_core_session_strdup(session, profile->rtpip6[profile->rtpip_next6++])switch_core_perform_session_strdup(session, profile->rtpip6
[profile->rtpip_next6++], "sofia_glue.c", (const char *)__func__
, 105)
;
106
107 if (zstr(tech_pvt->mparams.rtpip)_zstr(tech_pvt->mparams.rtpip)) {
108 tech_pvt->mparams.rtpip = tech_pvt->mparams.rtpip6;
109 }
110
111 if (profile->rtpip_next6 >= profile->rtpip_index6) {
112 profile->rtpip_next6 = 0;
113 }
114 }
115
116 profile->inuse++;
117 switch_mutex_unlock(profile->flag_mutex);
118 switch_mutex_unlock(tech_pvt->flag_mutex);
119
120 if (tech_pvt->bte) {
121 tech_pvt->recv_te = tech_pvt->te = tech_pvt->bte;
122 } else if (!tech_pvt->te) {
123 tech_pvt->mparams.recv_te = tech_pvt->mparams.te = profile->te;
124 }
125
126 tech_pvt->mparams.dtmf_type = tech_pvt->profile->dtmf_type;
127
128 if (!sofia_test_media_flag(tech_pvt->profile, SCMF_SUPPRESS_CNG)((tech_pvt->profile)->media_flags[SCMF_SUPPRESS_CNG] ? 1
: 0)
) {
129 if (tech_pvt->bcng_pt) {
130 tech_pvt->cng_pt = tech_pvt->bcng_pt;
131 } else if (!tech_pvt->cng_pt) {
132 tech_pvt->cng_pt = profile->cng_pt;
133 }
134 }
135
136 tech_pvt->session = session;
137 tech_pvt->channel = switch_core_session_get_channel(session);
138
139 if (sofia_test_pflag(profile, PFLAG_TRACK_CALLS)((profile)->pflags[PFLAG_TRACK_CALLS] ? 1 : 0)) {
140 switch_channel_set_flag(tech_pvt->channel, CF_TRACKABLE)switch_channel_set_flag_value(tech_pvt->channel, CF_TRACKABLE
, 1)
;
141 }
142
143
144 if (profile->flags[PFLAG_PASS_RFC2833]) {
145 switch_channel_set_flag(tech_pvt->channel, CF_PASS_RFC2833)switch_channel_set_flag_value(tech_pvt->channel, CF_PASS_RFC2833
, 1)
;
146 }
147
148 if (sofia_test_pflag(tech_pvt->profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)((tech_pvt->profile)->pflags[PFLAG_RTP_NOTIMER_DURING_BRIDGE
] ? 1 : 0)
) {
149 switch_channel_set_flag(tech_pvt->channel, CF_RTP_NOTIMER_DURING_BRIDGE)switch_channel_set_flag_value(tech_pvt->channel, CF_RTP_NOTIMER_DURING_BRIDGE
, 1)
;
150 }
151
152 if (sofia_test_pflag(tech_pvt->profile, PFLAG_T38_PASSTHRU)((tech_pvt->profile)->pflags[PFLAG_T38_PASSTHRU] ? 1 : 0
)
) {
153 switch_channel_set_flag(tech_pvt->channel, CF_T38_PASSTHRU)switch_channel_set_flag_value(tech_pvt->channel, CF_T38_PASSTHRU
, 1)
;
154 }
155
156 switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK)switch_channel_set_cap_value(tech_pvt->channel, CC_MEDIA_ACK
, 1)
;
157 switch_channel_set_cap(tech_pvt->channel, CC_BYPASS_MEDIA)switch_channel_set_cap_value(tech_pvt->channel, CC_BYPASS_MEDIA
, 1)
;
158 switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA)switch_channel_set_cap_value(tech_pvt->channel, CC_PROXY_MEDIA
, 1)
;
159 switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER)switch_channel_set_cap_value(tech_pvt->channel, CC_JITTERBUFFER
, 1)
;
160 switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP)switch_channel_set_cap_value(tech_pvt->channel, CC_FS_RTP,
1)
;
161 switch_channel_set_cap(tech_pvt->channel, CC_RTP_RTT)switch_channel_set_cap_value(tech_pvt->channel, CC_RTP_RTT
, 1)
;
162 switch_channel_set_cap(tech_pvt->channel, CC_MSRP)switch_channel_set_cap_value(tech_pvt->channel, CC_MSRP, 1
)
;
163 switch_channel_set_cap(tech_pvt->channel, CC_QUEUEABLE_DTMF_DELAY)switch_channel_set_cap_value(tech_pvt->channel, CC_QUEUEABLE_DTMF_DELAY
, 1)
;
164
165
166
167 tech_pvt->mparams.ndlb = tech_pvt->profile->mndlb;
168 tech_pvt->mparams.inbound_codec_string = profile->inbound_codec_string;
169 tech_pvt->mparams.outbound_codec_string = profile->outbound_codec_string;
170 tech_pvt->mparams.auto_rtp_bugs = profile->auto_rtp_bugs;
171 tech_pvt->mparams.timer_name = profile->timer_name;
172 tech_pvt->mparams.vflags = profile->vflags;
173 tech_pvt->mparams.manual_rtp_bugs = profile->manual_rtp_bugs;
174 tech_pvt->mparams.manual_video_rtp_bugs = profile->manual_video_rtp_bugs;
175 tech_pvt->mparams.extsipip = profile->extsipip;
176 tech_pvt->mparams.extrtpip = profile->extrtpip;
177 tech_pvt->mparams.local_network = profile->local_network;
178 tech_pvt->mparams.sipip = profile->sipip;
179 tech_pvt->mparams.jb_msec = profile->jb_msec;
180 tech_pvt->mparams.rtcp_audio_interval_msec = profile->rtcp_audio_interval_msec;
181 tech_pvt->mparams.rtcp_video_interval_msec = profile->rtcp_video_interval_msec;
182 tech_pvt->mparams.sdp_username = profile->sdp_username;
183 tech_pvt->mparams.cng_pt = tech_pvt->cng_pt;
184 tech_pvt->mparams.rtp_timeout_sec = profile->rtp_timeout_sec;
185 tech_pvt->mparams.rtp_hold_timeout_sec = profile->rtp_hold_timeout_sec;
186
187 if (profile->rtp_digit_delay) {
188 tech_pvt->mparams.dtmf_delay = profile->rtp_digit_delay;
189 }
190
191 switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams);
192 switch_media_handle_set_media_flags(tech_pvt->media_handle, tech_pvt->profile->media_flags);
193
194 switch_core_media_check_dtmf_type(session);
195
196 for(i = 0; i < profile->cand_acl_count; i++) {
197 switch_core_media_add_ice_acl(session, SWITCH_MEDIA_TYPE_AUDIO, profile->cand_acl[i]);
198 switch_core_media_add_ice_acl(session, SWITCH_MEDIA_TYPE_VIDEO, profile->cand_acl[i]);
199 }
200
201
202 switch_core_session_set_private(session, tech_pvt)switch_core_session_set_private_class(session, tech_pvt, SWITCH_PVT_PRIMARY
)
;
203
204 if (channame) {
205 sofia_glue_set_name(tech_pvt, channame);
206 }
207
208}
209
210
211
212
213switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **ip, switch_port_t *port,
214 const char *sourceip, switch_memory_pool_t *pool)
215{
216 char *error = "";
217 switch_status_t status = SWITCH_STATUS_FALSE;
218 int x;
219 switch_port_t stun_port = SWITCH_STUN_DEFAULT_PORT3478;
220 char *stun_ip = NULL((void*)0);
221
222 if (!sourceip) {
223 return status;
224 }
225
226 if (!strncasecmp(sourceip, "host:", 5)) {
227 status = (*ip = switch_stun_host_lookup(sourceip + 5, pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
228 } else if (!strncasecmp(sourceip, "stun:", 5)) {
229 char *p;
230
231 stun_ip = strdup(sourceip + 5);
232
233 switch_assert(stun_ip)((stun_ip) ? (void) (0) : __assert_fail ("stun_ip", "sofia_glue.c"
, 233, __extension__ __PRETTY_FUNCTION__))
;
234
235 if ((p = strchr(stun_ip, ':'))) {
236 int iport;
237 *p++ = '\0';
238 iport = atoi(p);
239 if (iport > 0 && iport < 0xFFFF) {
240 stun_port = (switch_port_t) iport;
241 }
242 }
243
244 if (zstr(stun_ip)_zstr(stun_ip)) {
245 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 245, ((void*)0)
, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n");
246 goto out;
247 }
248
249
250 for (x = 0; x < 5; x++) {
251 if ((status = switch_stun_lookup(ip, port, stun_ip, stun_port, &error, pool)) != SWITCH_STATUS_SUCCESS) {
252 switch_yield(100000)switch_sleep(100000);;
253 } else {
254 break;
255 }
256 }
257
258 if (!*ip) {
259 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 259, ((void*)0)
, SWITCH_LOG_ERROR, "STUN Failed! No IP returned\n");
260 goto out;
261 }
262 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 262, ((void*)0)
, SWITCH_LOG_DEBUG, "STUN Success [%s]:[%d]\n", *ip, *port);
263 status = SWITCH_STATUS_SUCCESS;
264 } else {
265 *ip = (char *) sourceip;
266 status = SWITCH_STATUS_SUCCESS;
267 }
268
269 out:
270
271 switch_safe_free(stun_ip)if (stun_ip) {free(stun_ip);stun_ip=((void*)0);};
272
273 return status;
274}
275
276
277const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name)
278{
279 sip_unknown_t *un;
280 for (un = sip->sip_unknown; un; un = un->un_next) {
281 if (!strcasecmp(un->un_name, name)) {
282 if (!zstr(un->un_value)_zstr(un->un_value)) {
283 return un->un_value;
284 }
285 }
286 }
287 return NULL((void*)0);
288}
289
290sofia_transport_t sofia_glue_str2transport(const char *str)
291{
292 if (!strncasecmp(str, "udp", 3)) {
293 return SOFIA_TRANSPORT_UDP;
294 } else if (!strncasecmp(str, "tcp", 3)) {
295 return SOFIA_TRANSPORT_TCP;
296 } else if (!strncasecmp(str, "sctp", 4)) {
297 return SOFIA_TRANSPORT_SCTP;
298 } else if (!strncasecmp(str, "tls", 3)) {
299 return SOFIA_TRANSPORT_TCP_TLS;
300 }
301
302 return SOFIA_TRANSPORT_UNKNOWN;
303}
304
305enum tport_tls_verify_policy sofia_glue_str2tls_verify_policy(const char * str){
306 char *ptr_next;
307 int len;
308 enum tport_tls_verify_policy ret;
309 char *ptr_cur = (char *) str;
310 ret = TPTLS_VERIFY_NONE;
311
312 while (ptr_cur) {
313 if ((ptr_next = strchr(ptr_cur, '|'))) {
314 len = (int)(ptr_next++ - ptr_cur);
315 } else {
316 len = (int)strlen(ptr_cur);
317 }
318 if (!strncasecmp(ptr_cur, "in",len)) {
319 ret |= TPTLS_VERIFY_IN;
320 } else if (!strncasecmp(ptr_cur, "none",len)) {
321 ret = TPTLS_VERIFY_NONE;
322 break;
323 } else if (!strncasecmp(ptr_cur, "out",len)) {
324 ret |= TPTLS_VERIFY_OUT;
325 } else if (!strncasecmp(ptr_cur, "all",len)) {
326 ret |= TPTLS_VERIFY_ALL;
327 } else if (!strncasecmp(ptr_cur, "subjects_in",len)) {
328 ret |= TPTLS_VERIFY_SUBJECTS_IN;
329 } else if (!strncasecmp(ptr_cur, "subjects_out",len)) {
330 ret |= TPTLS_VERIFY_SUBJECTS_OUT;
331 } else if (!strncasecmp(ptr_cur, "subjects_all",len)) {
332 ret |= TPTLS_VERIFY_SUBJECTS_ALL;
333 } else {
334 char el[32] = {0};
335 strncpy(el, ptr_cur, len < sizeof(el) ? len : sizeof(el) - 1);
336 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 336, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid tls-verify-policy value: %s\n", el);
337 }
338 ptr_cur = ptr_next;
339 }
340 return ret;
341}
342
343/* create "local-uuid" */
344int sofia_glue_is_valid_session_uuid(const char *session_uuid)
345{
346 int i;
347 if (zstr(session_uuid)_zstr(session_uuid) || strlen(session_uuid) != RFC7989_SESSION_UUID_LEN32) {
348 return 0;
349 }
350 for (i = 0; i < RFC7989_SESSION_UUID_LEN32; i++) {
351 char c = session_uuid[i];
352 if ((c < '0' || c > '9') && (c < 'a' || c > 'f')) {
353 return 0;
354 }
355 }
356 return 1;
357}
358
359/* NIL session-uuid: 00000000000000000000000000000000 */
360int sofia_glue_is_nil_session_uuid(const char *session_uuid)
361{
362 if (zstr(session_uuid)_zstr(session_uuid)) {
363 return 0;
364 }
365 if (!memcmp(session_uuid, RFC7989_SESSION_UUID_NULL"00000000000000000000000000000000", RFC7989_SESSION_UUID_LEN32)) {
366 return 1;
367 }
368 return 0;
369}
370
371const char *sofia_glue_uuid_to_session_uuid(switch_memory_pool_t *pool, const char *uuid)
372{
373 char *session_uuid = NULL((void*)0); /*"local-uuid", per rfc7989*/
374 if (zstr(uuid)_zstr(uuid) || strlen(uuid) != 36) return NULL((void*)0);
375
376 session_uuid = switch_core_alloc(pool, RFC7989_SESSION_UUID_LEN + 1)switch_core_perform_alloc(pool, 32 + 1, "sofia_glue.c", (const
char *)__func__, 376)
;
377 memcpy(session_uuid, uuid, 8);
378 memcpy(session_uuid + 8, uuid + 9, 4);
379 memcpy(session_uuid + 12, uuid + 14, 4);
380 memcpy(session_uuid + 16, uuid + 19, 4);
381 memcpy(session_uuid + 20, uuid + 24, 12);
382
383 if (!sofia_glue_is_valid_session_uuid(session_uuid)) return NULL((void*)0);
384
385 return session_uuid;
386}
387
388/* rfc7989 generic params, return 0 if param is disabled from config or invalid. ALL params allowed by default. */
389/* save updated generic params list in chan var. */
390int sofia_glue_check_filter_generic_params(switch_core_session_t *session, sofia_profile_t *profile, char *param)
391{
392
393 char *tmp = NULL((void*)0);
394 switch_channel_t *channel = switch_core_session_get_channel(session);
395
396 if (zstr(param)_zstr(param)) {
397 return 0;
398 }
399 if (profile->rfc7989_filter) {
400 char *found = NULL((void*)0); char *end = NULL((void*)0);
401 char *token_array[100] = { 0 };
402 int tokens = switch_separate_string(profile->rfc7989_filter, ',', token_array, (sizeof(token_array) / sizeof(token_array[0])));
403 tmp = switch_core_session_strdup(session, param)switch_core_perform_session_strdup(session, param, "sofia_glue.c"
, (const char *)__func__, 403)
;
404 if (tokens) {
405 int i;
406 for (i = 0; i < tokens && token_array[i]; i++) {
407 while ((found = strstr(tmp, token_array[i]))) {
408 end = strchr(found, ';');
409 if (!end) end = strchr(found, '\0');
410 *found = '\0';
411 strcat(tmp, found + (end - found));
412 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 412, (const char*)(session)
, SWITCH_LOG_WARNING,
413 "Session-ID: Dropped generic param: %s\n", token_array[i]);
414 }
415 }
416 }
417 }
418
419 if (tmp) {
420 switch_channel_set_variable(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE, tmp)switch_channel_set_variable_var_check(channel, "generic_param_session_uuid"
, tmp, SWITCH_TRUE)
;
421 } else {
422 switch_channel_set_variable(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE, param)switch_channel_set_variable_var_check(channel, "generic_param_session_uuid"
, param, SWITCH_TRUE)
;
423 }
424
425 return 1;
426}
427/* check and store Session-ID header. */
428/* retrieve "local-uuid" and "remote-uuid" of the remote party. */
429void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t is_reply)
430{
431 char *a_id, *b_id, *duped, *p, *remote_param;
432 const char *header = sofia_glue_get_unknown_header(sip, "Session-ID");
433 switch_channel_t *channel = switch_core_session_get_channel(session);
434
435 if (!sofia_test_pflag(profile, PFLAG_RFC7989_SESSION_ID)((profile)->pflags[PFLAG_RFC7989_SESSION_ID] ? 1 : 0)) return;
436
437 if (!header) {
438 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 438, (const char*)(session)
, SWITCH_LOG_WARNING, "Session-ID: missing header.");
439 return;
440 }
441
442 duped = switch_core_session_strdup(session, header)switch_core_perform_session_strdup(session, header, "sofia_glue.c"
, (const char *)__func__, 442)
;
443
444 if (zstr(duped)_zstr(duped)) return;
445
446 a_id = switch_strip_whitespace(duped);
447
448 if (zstr(a_id)_zstr(a_id)) return;
449
450 p = strchr(a_id, ';');
451 if (p) *p = '\0';
452
453 if (!sofia_glue_is_valid_session_uuid(a_id)) {
454 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 454, (const char*)(session)
, SWITCH_LOG_WARNING, "Session-ID: Ignoring \"%s\" parsed as \"%s\"\n", header, a_id);
455 return;
456 }
457
458 /* RFC7329 compatibility */
459 if (is_reply) {
460 const char *temp_id = switch_channel_get_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE)switch_channel_get_variable_dup(channel, "app_session_uuid", SWITCH_TRUE
, -1)
;
461 if (!zstr(temp_id)_zstr(temp_id) && !memcmp(a_id, temp_id, RFC7989_SESSION_UUID_LEN32) ) {
462 /* 'If a SIP response only contains the "local-uuid" that was sent
463 * originally, this comes from a pre-standard implementation and MUST
464 * NOT be discarded for removing the nil "remote-uuid". In this
465 * case, all future transactions within this dialog MUST contain only
466 * the UUID received in the first SIP response" */
467 switch_channel_set_flag(channel, CF_RFC7329_COMPAT)switch_channel_set_flag_value(channel, CF_RFC7329_COMPAT, 1);
468 switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
469 }
470 }
471
472 /* "local-uuid" field retrieved from remote party will become
473 * SWITCH_RFC7989_APP_SESSION_ID_VARIABLE in a b2bua role. */
474 if (!zstr(a_id)_zstr(a_id)) {
475 struct private_object *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
476 switch_channel_set_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE, a_id)switch_channel_set_variable_var_check(channel, "session_uuid"
, a_id, SWITCH_TRUE)
;
477 if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
478 tech_pvt->sofia_private->rfc7989_uuid = su_strdup(nua_handle_get_home(tech_pvt->nh), a_id);
479 }
480 }
481
482 if (!p) {
483 switch_channel_set_flag(channel, CF_RFC7329_COMPAT)switch_channel_set_flag_value(channel, CF_RFC7329_COMPAT, 1);
484 switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
485 return;
486 }
487 p++;
488 remote_param = strstr(p, "remote=");
489 if (!remote_param) {
490 switch_channel_set_flag(channel, CF_RFC7329_COMPAT)switch_channel_set_flag_value(channel, CF_RFC7329_COMPAT, 1);
491 switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
492 sofia_glue_check_filter_generic_params(session, profile, p);
493 return;
494 }
495 b_id = remote_param + 7;
496 if (!zstr(b_id)_zstr(b_id) && strlen(b_id) == RFC7989_SESSION_UUID_LEN32 /*32*/) {
497 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 497, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session-ID: Set remote-uuid: %s\n", b_id);
498 /*using chan var as placeholder only when UAS or when answer() was called in the dialplan */
499 switch_channel_set_variable(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE, b_id)switch_channel_set_variable_var_check(channel, "remote_session_uuid"
, b_id, SWITCH_TRUE)
;
500 switch_channel_set_variable_partner(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE, b_id)switch_channel_set_variable_partner_var_check(channel, "remote_session_uuid"
, b_id, SWITCH_TRUE)
;
501
502 } else {
503 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 503, (const char*)(session)
, SWITCH_LOG_WARNING, "Session-ID: invalid uuid, ignored.\n");
504 }
505}
506
507/* add "Session-ID:" header */
508char *sofia_glue_session_id_header(switch_core_session_t *session, sofia_profile_t *profile)
509{
510 switch_channel_t *channel;
511 const char *b_id = NULL((void*)0);
512 const char *a_id = NULL((void*)0);
513 const char *temp_id = NULL((void*)0);
514 const char *generic = NULL((void*)0);
515
516 if (!session) return NULL((void*)0);
517
518 if (!profile) return NULL((void*)0);
519
520 if (!sofia_test_pflag(profile, PFLAG_RFC7989_SESSION_ID)((profile)->pflags[PFLAG_RFC7989_SESSION_ID] ? 1 : 0)) return NULL((void*)0);
521
522 channel = switch_core_session_get_channel(session);
523
524 a_id = switch_channel_get_variable_partner(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE"session_uuid");
525
526 if (zstr(a_id)_zstr(a_id)) {
527 a_id = switch_channel_get_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE)switch_channel_get_variable_dup(channel, "app_session_uuid", SWITCH_TRUE
, -1)
;
528 if (!zstr(a_id)_zstr(a_id) && strlen(a_id) == 36) {
529 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 529, (const char*)(session)
, SWITCH_LOG_INFO, "Reformatting app Session-ID: %s\n", a_id);
530 a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), a_id);
531 if (!zstr(a_id)_zstr(a_id)) {
532 struct private_object *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
533 switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id)switch_channel_set_variable_var_check(channel, "app_session_uuid"
, a_id, SWITCH_TRUE)
;
534 if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
535 tech_pvt->sofia_private->rfc7989_uuid = su_strdup(nua_handle_get_home(tech_pvt->nh), a_id);
536 }
537 }
538 }
539 }
540
541 if (zstr(a_id)_zstr(a_id)) {
542 const char *partner_uuid = switch_channel_get_partner_uuid(channel);
543 if (!zstr(partner_uuid)_zstr(partner_uuid)) {
544 const char *partner_session_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), partner_uuid);
545 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 545, (const char*)(session)
, SWITCH_LOG_INFO, "Setting \"Session-ID: %s\" from partner leg\n", partner_session_id);
546 switch_channel_set_variable_partner(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE, partner_session_id)switch_channel_set_variable_partner_var_check(channel, "session_uuid"
, partner_session_id, SWITCH_TRUE)
;
547 a_id = partner_session_id;
548 }
549 }
550
551 if (((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) && zstr(a_id)_zstr(a_id) &&
552 switch_channel_get_state(channel) == CS_INIT) && switch_channel_test_flag(channel, CF_ORIGINATING)) {
553 /*outbound initial request*/
554 char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256 + 1];
555
556 switch_uuid_str(uuid_str, sizeof(uuid_str));
557 a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), uuid_str);
558 if (!zstr(a_id)_zstr(a_id)) {
559 struct private_object *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
560 switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id)switch_channel_set_variable_var_check(channel, "app_session_uuid"
, a_id, SWITCH_TRUE)
;
561 if (tech_pvt && tech_pvt->sofia_private && !tech_pvt->sofia_private->rfc7989_uuid) {
562 tech_pvt->sofia_private->rfc7989_uuid = su_strdup(nua_handle_get_home(tech_pvt->nh), a_id);
563 }
564 }
565 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 565, (const char*)(session)
, SWITCH_LOG_DEBUG,
566 "Session-ID: Outbound initial request. local-uuid: %s", a_id);
567 if (sofia_test_pflag(profile, PFLAG_RFC7989_FORCE_OLD)((profile)->pflags[PFLAG_RFC7989_FORCE_OLD] ? 1 : 0)) {
568 /*for old (and obsolete) Session-ID RFC7329 */
569 return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
570 }
571
572 b_id = RFC7989_SESSION_UUID_NULL"00000000000000000000000000000000";
573 return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
574 }
575
576 temp_id = switch_channel_get_variable(channel, SWITCH_RFC7989_REMOTE_SESSION_ID_VARIABLE)switch_channel_get_variable_dup(channel, "remote_session_uuid"
, SWITCH_TRUE, -1)
;
577 if ((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) &&
578 ((switch_channel_get_state(channel) == CS_INIT) || (switch_channel_get_state(channel) == CS_EXECUTE)) &&
579 zstr(temp_id)_zstr(temp_id)) {
580 /* fallback to RFC7329 - "old". */
581 /* inbound initial request, no "remote" param. section 11 of RFC7989. */
582 a_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE)switch_channel_get_variable_dup(channel, "session_uuid", SWITCH_TRUE
, -1)
;
583 if (zstr(a_id)_zstr(a_id)) {
584 a_id = RFC7989_SESSION_UUID_NULL"00000000000000000000000000000000";
585 } else {
586 switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id)switch_channel_set_variable_var_check(channel, "app_session_uuid"
, a_id, SWITCH_TRUE)
;
587 }
588 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 588, (const char*)(session)
, SWITCH_LOG_WARNING, "Session-ID: Fallback to RFC7329");
589 switch_channel_set_flag(channel, CF_RFC7329_COMPAT)switch_channel_set_flag_value(channel, CF_RFC7329_COMPAT, 1);
590 return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
591 }
592 if ((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) &&
593 ((switch_channel_get_state(channel) == CS_INIT) || (switch_channel_get_state(channel) == CS_EXECUTE)) &&
594 sofia_glue_is_nil_session_uuid(temp_id)) {
595 /*inbound initial request*/
596 char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256 + 1];
597
598 switch_uuid_str(uuid_str, sizeof(uuid_str));
599 a_id = sofia_glue_uuid_to_session_uuid(switch_core_session_get_pool(session), uuid_str);
600 if (!zstr(a_id)_zstr(a_id)) {
601 struct private_object *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
602 switch_channel_set_variable(channel, SWITCH_RFC7989_APP_SESSION_ID_VARIABLE, a_id)switch_channel_set_variable_var_check(channel, "app_session_uuid"
, a_id, SWITCH_TRUE)
;
603 if (tech_pvt && tech_pvt->sofia_private) {
604 tech_pvt->sofia_private->rfc7989_uuid = su_strdup(nua_handle_get_home(tech_pvt->nh), a_id);
605 }
606 }
607 b_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE)switch_channel_get_variable_dup(channel, "session_uuid", SWITCH_TRUE
, -1)
;
608 if (zstr(b_id)_zstr(b_id)) {
609 b_id = RFC7989_SESSION_UUID_NULL"00000000000000000000000000000000";
610 }
611 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 611, (const char*)(session)
, SWITCH_LOG_DEBUG,
612 "Session-ID: Inbound initial request. local-uuid: %s", a_id);
613 return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
614 }
615
616 if (zstr(a_id)_zstr(a_id)) {
617 struct private_object *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
618 /* setting NIL local-uuid should never happen,
619 * but in case we don't get to set it properly by here, just set it to NIL */
620 if (tech_pvt && tech_pvt->sofia_private && tech_pvt->sofia_private->rfc7989_uuid) {
621 /* handle BYE after REFER or other cases where the channel is destroyed already and we can't get the chan var */
622 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 622, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session-ID: retrieved local-uuid ");
623 a_id = tech_pvt->sofia_private->rfc7989_uuid;
624 } else {
625 a_id = RFC7989_SESSION_UUID_NULL"00000000000000000000000000000000";
626 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 626, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session-ID: NIL local-uuid ");
627 }
628 }
629
630 b_id = switch_channel_get_variable(channel, SWITCH_RFC7989_SESSION_ID_VARIABLE)switch_channel_get_variable_dup(channel, "session_uuid", SWITCH_TRUE
, -1)
;
631
632 if (zstr(b_id)_zstr(b_id) && switch_channel_test_flag(channel, CF_RFC7329_COMPAT)) {
633 /* fallback to RFC7329 , only one uuid*/
634 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 634, (const char*)(session)
, SWITCH_LOG_WARNING ,"Session-ID: Fallback to RFC7329, use one uuid");
635 return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
636 } else if (zstr(b_id)_zstr(b_id)) {
637 b_id = RFC7989_SESSION_UUID_NULL"00000000000000000000000000000000";
638 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 638, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session-ID: set NIL remote-uuid");
639 }
640
641 /* B2B: handle generic params*/
642 generic = switch_channel_get_variable_partner(channel, SWITCH_RFC7989_GENERIC_PARAM_VARIABLE"generic_param_session_uuid");
643 if (!zstr(generic)_zstr(generic)) {
644 /* copy generic param (name and val) */
645 return switch_core_session_sprintf(session, "Session-ID: %s;%s", a_id, generic);
646 }
647 if (switch_channel_test_flag(channel, CF_RFC7329_COMPAT)) {
648 return switch_core_session_sprintf(session, "Session-ID: %s", a_id);
649 }
650 return switch_core_session_sprintf(session, "Session-ID: %s;remote=%s", a_id, b_id);
651}
652
653char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char *str, const char *param)
654{
655 const char *param_ptr;
656 char *param_value;
657 char *tmp;
658 switch_size_t param_len;
659
660 if (zstr(str)_zstr(str) || zstr(param)_zstr(param) || !session) return NULL((void*)0);
661
662 if (end_of(param)*(*param == '\0' ? param : param + strlen(param) - 1) != '=') {
663 param = switch_core_session_sprintf(session, "%s=", param);
664 if (zstr(param)_zstr(param)) return NULL((void*)0);
665 }
666
667 param_len = strlen(param);
668 param_ptr = sofia_glue_find_parameter(str, param);
669
670 if (zstr(param_ptr)_zstr(param_ptr)) return NULL((void*)0);
671
672 param_value = switch_core_session_strdup(session, param_ptr + param_len)switch_core_perform_session_strdup(session, param_ptr + param_len
, "sofia_glue.c", (const char *)__func__, 672)
;
673
674 if (zstr(param_value)_zstr(param_value)) return NULL((void*)0);
675
676 if ((tmp = strchr(param_value, ';'))) *tmp = '\0';
677
678 return param_value;
679}
680
681char *sofia_glue_find_parameter(const char *str, const char *param)
682{
683 char *ptr = NULL((void*)0);
684
685 ptr = (char *) str;
686 while (ptr) {
687 if (!strncasecmp(ptr, param, strlen(param)))
688 return ptr;
689
690 if ((ptr = strchr(ptr, ';')))
691 ptr++;
692 }
693
694 return NULL((void*)0);
695}
696
697sofia_transport_t sofia_glue_url2transport(const url_t *url)
698{
699 char *ptr = NULL((void*)0);
700 int tls = 0;
701
702 if (!url)
703 return SOFIA_TRANSPORT_UNKNOWN;
704
705 if (url->url_scheme && !strcasecmp(url->url_scheme, "sips")) {
706 tls++;
707 }
708
709 if ((ptr = sofia_glue_find_parameter(url->url_params, "transport="))) {
710 return sofia_glue_str2transport(ptr + 10);
711 }
712
713 return (tls) ? SOFIA_TRANSPORT_TCP_TLS : SOFIA_TRANSPORT_UDP;
714}
715
716sofia_transport_t sofia_glue_via2transport(const sip_via_t * via)
717{
718 char *ptr = NULL((void*)0);
719
720 if (!via || !via->v_protocol)
721 return SOFIA_TRANSPORT_UNKNOWN;
722
723 if ((ptr = strrchr(via->v_protocol, '/'))) {
724 ptr++;
725
726 if (!strncasecmp(ptr, "udp", 3)) {
727 return SOFIA_TRANSPORT_UDP;
728 } else if (!strncasecmp(ptr, "tcp", 3)) {
729 return SOFIA_TRANSPORT_TCP;
730 } else if (!strncasecmp(ptr, "tls", 3)) {
731 return SOFIA_TRANSPORT_TCP_TLS;
732 } else if (!strncasecmp(ptr, "sctp", 4)) {
733 return SOFIA_TRANSPORT_SCTP;
734 } else if (!strncasecmp(ptr, "wss", 3)) {
735 return SOFIA_TRANSPORT_WSS;
736 } else if (!strncasecmp(ptr, "ws", 2)) {
737 return SOFIA_TRANSPORT_WS;
738 }
739 }
740
741 return SOFIA_TRANSPORT_UNKNOWN;
742}
743
744const char *sofia_glue_transport2str(const sofia_transport_t tp)
745{
746 switch (tp) {
747 case SOFIA_TRANSPORT_TCP:
748 return "tcp";
749
750 case SOFIA_TRANSPORT_TCP_TLS:
751 return "tls";
752
753 case SOFIA_TRANSPORT_SCTP:
754 return "sctp";
755
756 case SOFIA_TRANSPORT_WS:
757 return "ws";
758
759 case SOFIA_TRANSPORT_WSS:
760 return "wss";
761
762 default:
763 return "udp";
764 }
765}
766
767char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport)
768{
769 return sofia_glue_create_via(session, profile->extsipip, (sofia_glue_transport_has_tls(transport))
770 ? profile->tls_sip_port : profile->extsipport, transport);
771}
772
773char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport)
774{
775 char *ipv6 = strchr(ip, ':');
776 if (port && port != 5060) {
777 if (session) {
778 return switch_core_session_sprintf(session, "SIP/2.0/%s %s%s%s:%d;rport", sofia_glue_transport2str(transport), ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
779 } else {
780 return switch_mprintf("SIP/2.0/%s %s%s%s:%d;rport", sofia_glue_transport2str(transport), ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
781 }
782 } else {
783 if (session) {
784 return switch_core_session_sprintf(session, "SIP/2.0/%s %s%s%s;rport", sofia_glue_transport2str(transport), ipv6 ? "[" : "", ip, ipv6 ? "]" : "");
785 } else {
786 return switch_mprintf("SIP/2.0/%s %s%s%s;rport", sofia_glue_transport2str(transport), ipv6 ? "[" : "", ip, ipv6 ? "]" : "");
787 }
788 }
789}
790
791char *sofia_glue_strip_uri(const char *str)
792{
793 char *p;
794 char *r;
795
796 if ((p = strchr(str, '<'))) {
797 p++;
798 r = strdup(p);
799 switch_assert(r)((r) ? (void) (0) : __assert_fail ("r", "sofia_glue.c", 799, __extension__
__PRETTY_FUNCTION__))
;
800 if ((p = strchr(r, '>'))) {
801 *p = '\0';
802 }
803 } else {
804 r = strdup(str);
805 switch_assert(r)((r) ? (void) (0) : __assert_fail ("r", "sofia_glue.c", 805, __extension__
__PRETTY_FUNCTION__))
;
806 }
807
808 return r;
809}
810
811
812
813int sofia_glue_transport_has_tls(const sofia_transport_t tp)
814{
815 switch (tp) {
816 case SOFIA_TRANSPORT_TCP_TLS:
817 return 1;
818
819 default:
820 return 0;
821 }
822}
823
824void sofia_glue_get_addr(msg_t *msg, char *buf, size_t buflen, int *port)
825{
826 su_addrinfo_t *addrinfo = msg_addrinfo(msg);
827 if (!addrinfo) {
828 return;
829 }
830
831 if (buf) {
832 get_addr(buf, buflen, addrinfo->ai_addr, (socklen_t)addrinfo->ai_addrlen);
833 }
834
835 if (port) {
836 *port = get_port(addrinfo->ai_addr);
837 }
838}
839
840char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char *uri, const sofia_transport_t transport, switch_bool_t uri_only,
841 const char *params, const char *invite_tel_params)
842{
843 char *stripped = switch_core_session_strdup(session, uri)switch_core_perform_session_strdup(session, uri, "sofia_glue.c"
, (const char *)__func__, 843)
;
844 char *new_uri = NULL((void*)0);
845 char *p;
846 const char *url_params = NULL((void*)0);
847
848 if (!zstr(params)_zstr(params) && *params == '~') {
849 url_params = params + 1;
850 params = NULL((void*)0);
851 }
852
853 stripped = sofia_glue_get_url_from_contact(stripped, 0);
854
855 /* remove our params so we don't make any whiny moronic device piss its pants and forget who it is for a half-hour */
856 if ((p = (char *) switch_stristr(";fs_", stripped))) {
857 *p = '\0';
858 }
859
860 if (transport && transport != SOFIA_TRANSPORT_UDP) {
861
862 if (switch_stristr("port=", stripped)) {
863 new_uri = switch_core_session_sprintf(session, "%s%s%s", uri_only ? "" : "<", stripped, uri_only ? "" : ">");
864 } else {
865 if (params) {
866 new_uri = switch_core_session_sprintf(session, "%s%s;transport=%s;%s%s",
867 uri_only ? "" : "<", stripped, sofia_glue_transport2str(transport), params, uri_only ? "" : ">");
868 } else {
869 new_uri = switch_core_session_sprintf(session, "%s%s;transport=%s%s",
870 uri_only ? "" : "<", stripped, sofia_glue_transport2str(transport), uri_only ? "" : ">");
871 }
872 }
873 } else {
874 if (params) {
875 new_uri = switch_core_session_sprintf(session, "%s%s;%s%s", uri_only ? "" : "<", stripped, params, uri_only ? "" : ">");
876 } else {
877 if (uri_only) {
878 new_uri = stripped;
879 } else {
880 new_uri = switch_core_session_sprintf(session, "<%s>", stripped);
881 }
882 }
883 }
884
885 if (url_params && !uri_only) {
886 new_uri = switch_core_session_sprintf(session, "%s;%s", new_uri, url_params);
887 }
888
889 if (!zstr(invite_tel_params)_zstr(invite_tel_params)) {
890 char *lhs, *rhs = strchr(new_uri, '@');
891
892 if (!zstr(rhs)_zstr(rhs)) {
893 *rhs++ = '\0';
894 lhs = new_uri;
895 new_uri = switch_core_session_sprintf(session, "%s;%s@%s", lhs, invite_tel_params, rhs);
896 }
897 }
898
899 return new_uri;
900}
901
902char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix)
903{
904 char *extra_headers = NULL((void*)0);
905 switch_stream_handle_t stream = { 0 };
906 switch_event_header_t *hi = NULL((void*)0);
907 const char *exclude_regex = NULL((void*)0);
908 switch_regex_t *re = NULL((void*)0);
909 int ovector[30] = {0};
910 int proceed;
911
912 exclude_regex = switch_channel_get_variable(channel, "exclude_outgoing_extra_header")switch_channel_get_variable_dup(channel, "exclude_outgoing_extra_header"
, SWITCH_TRUE, -1)
;
913 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia_glue.c", 913, __extension__ __PRETTY_FUNCTION__)); memset
(stream.data, 0, 1024); stream.end = stream.data; stream.data_size
= 1024; stream.write_function = switch_console_stream_write;
stream.raw_write_function = switch_console_stream_raw_write;
stream.alloc_len = 1024; stream.alloc_chunk = 1024
;
914 if ((hi = switch_channel_variable_first(channel))) {
915 for (; hi; hi = hi->next) {
916 const char *name = (char *) hi->name;
917 char *value = (char *) hi->value;
918
919 if (!strcasecmp(name, "sip_geolocation")) {
920 stream.write_function(&stream, "Geolocation: %s\r\n", value);
921 }
922
923 if (!strncasecmp(name, prefix, strlen(prefix))) {
924 if ( !exclude_regex || !(proceed = switch_regex_perform(name, exclude_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
925 const char *hname = name + strlen(prefix);
926 stream.write_function(&stream, "%s: %s\r\n", hname, value);
927 switch_regex_safe_free(re)if (re) { switch_regex_free(re); re = ((void*)0); };
928 } else {
929 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 929, ((void*)0)
, SWITCH_LOG_DEBUG, "Ignoring Extra Header [%s] , matches exclude_outgoing_extra_header [%s]\n", name, exclude_regex);
930 }
931 }
932 }
933 switch_channel_variable_last(channel);
934 }
935
936 if (!zstr((char *) stream.data)_zstr((char *) stream.data)) {
937 extra_headers = stream.data;
938 } else {
939 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
940 }
941
942 return extra_headers;
943}
944
945void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *sip, const char *prefix)
946{
947 sip_unknown_t *un;
948 char name[512] = "";
949 switch_channel_t *channel = switch_core_session_get_channel(session);
950 char pstr[32];
951
952
953 if (!sip || !channel) {
954 return;
955 }
956
957 for (un = sip->sip_unknown; un; un = un->un_next) {
958 if (sofia_test_extra_headers(un->un_name)(((!strncasecmp(un->un_name, "X-", 2) && strncasecmp
(un->un_name, "X-FS-", 5)) || !strncasecmp(un->un_name,
"P-", 2) || !strncasecmp(un->un_name, "On", 2)) ? 1 : 0)
) {
959 if (!zstr(un->un_value)_zstr(un->un_value)) {
960 switch_snprintf(name, sizeof(name), "%s%s", prefix, un->un_name);
961 switch_channel_set_variable(channel, name, un->un_value)switch_channel_set_variable_var_check(channel, name, un->un_value
, SWITCH_TRUE)
;
962 }
963 }
964 }
965
966 switch_snprintf(pstr, sizeof(pstr), "execute_on_%sprefix", prefix);
967 switch_channel_execute_on(channel, pstr);
968 switch_channel_api_on(channel, pstr);
969
970 switch_channel_execute_on(channel, "execute_on_sip_extra_headers");
971 switch_channel_api_on(channel, "api_on_sip_extra_headers");
972}
973
974char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char *prefix)
975{
976 char *extra_headers = NULL((void*)0);
977 switch_stream_handle_t stream = { 0 };
978 switch_event_header_t *hp;
979
980 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia_glue.c", 980, __extension__ __PRETTY_FUNCTION__)); memset
(stream.data, 0, 1024); stream.end = stream.data; stream.data_size
= 1024; stream.write_function = switch_console_stream_write;
stream.raw_write_function = switch_console_stream_raw_write;
stream.alloc_len = 1024; stream.alloc_chunk = 1024
;
981 for (hp = event->headers; hp; hp = hp->next) {
982 if (!zstr(hp->name)_zstr(hp->name) && !zstr(hp->value)_zstr(hp->value) && !strncasecmp(hp->name, prefix, strlen(prefix))) {
983 char *name = strdup(hp->name);
984 const char *hname;
985 switch_assert(name)((name) ? (void) (0) : __assert_fail ("name", "sofia_glue.c",
985, __extension__ __PRETTY_FUNCTION__))
;
986 hname = name + strlen(prefix);
987 stream.write_function(&stream, "%s: %s\r\n", hname, (char *)hp->value);
988 free(name);
989 }
990 }
991
992 if (!zstr((char *) stream.data)_zstr((char *) stream.data)) {
993 extra_headers = stream.data;
994 } else {
995 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
996 }
997
998 return extra_headers;
999}
1000
1001char *sofia_glue_get_non_extra_unknown_headers(sip_t const *sip)
1002{
1003 char *unknown = NULL((void*)0);
1004 switch_stream_handle_t stream = { 0 };
1005 sip_unknown_t *un;
1006
1007 if (!sip) {
1008 return NULL((void*)0);
1009 }
1010
1011 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia_glue.c", 1011, __extension__ __PRETTY_FUNCTION__)); memset
(stream.data, 0, 1024); stream.end = stream.data; stream.data_size
= 1024; stream.write_function = switch_console_stream_write;
stream.raw_write_function = switch_console_stream_raw_write;
stream.alloc_len = 1024; stream.alloc_chunk = 1024
;
1012 for (un = sip->sip_unknown; un; un = un->un_next) {
1013 if (!sofia_test_extra_headers(un->un_name)(((!strncasecmp(un->un_name, "X-", 2) && strncasecmp
(un->un_name, "X-FS-", 5)) || !strncasecmp(un->un_name,
"P-", 2) || !strncasecmp(un->un_name, "On", 2)) ? 1 : 0)
) {
1014 if (!zstr(un->un_value)_zstr(un->un_value)) {
1015 stream.write_function(&stream, "%s: %s\r\n",un->un_name,un->un_value);
1016 }
1017 }
1018 }
1019 if (!zstr((char *) stream.data)_zstr((char *) stream.data)) {
1020 unknown = stream.data;
1021 } else {
1022 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
1023 }
1024
1025 return unknown;
1026}
1027
1028switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
1029{
1030 char *alert_info = NULL((void*)0);
1031 const char *max_forwards = NULL((void*)0);
1032 const char *alertbuf;
1033 const char *identity = NULL((void*)0);
1034 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
1035 switch_channel_t *channel = switch_core_session_get_channel(session);
1036 switch_caller_profile_t *caller_profile;
1037 const char *cid_name, *cid_num;
1038 char *e_dest = NULL((void*)0);
1039 const char *holdstr = "";
1040 char *extra_headers = NULL((void*)0);
1041 switch_status_t status = SWITCH_STATUS_FALSE;
1042 uint32_t session_timeout = tech_pvt->profile->session_timeout;
1043 const char *val;
1044 const char *rep;
1045 const char *call_id = NULL((void*)0);
1046 char *route = NULL((void*)0);
1047 char *route_uri = NULL((void*)0);
1048 sofia_destination_t *dst = NULL((void*)0);
1049 sofia_cid_type_t cid_type = tech_pvt->profile->cid_type;
1050 sip_cseq_t *cseq = NULL((void*)0);
1051 const char *invite_record_route = switch_channel_get_variable(tech_pvt->channel, "sip_invite_record_route")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_record_route"
, SWITCH_TRUE, -1)
;
1052 const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_route_uri"
, SWITCH_TRUE, -1)
;
1053 const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_full_from"
, SWITCH_TRUE, -1)
;
1054 const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_full_to"
, SWITCH_TRUE, -1)
;
1055 const char *handle_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_handle_full_from")switch_channel_get_variable_dup(tech_pvt->channel, "sip_handle_full_from"
, SWITCH_TRUE, -1)
;
1056 const char *handle_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_handle_full_to")switch_channel_get_variable_dup(tech_pvt->channel, "sip_handle_full_to"
, SWITCH_TRUE, -1)
;
1057 const char *force_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_force_full_from")switch_channel_get_variable_dup(tech_pvt->channel, "sip_force_full_from"
, SWITCH_TRUE, -1)
;
1058 const char *force_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_force_full_to")switch_channel_get_variable_dup(tech_pvt->channel, "sip_force_full_to"
, SWITCH_TRUE, -1)
;
1059 const char *content_encoding = switch_channel_get_variable(tech_pvt->channel, "sip_content_encoding")switch_channel_get_variable_dup(tech_pvt->channel, "sip_content_encoding"
, SWITCH_TRUE, -1)
;
1060 char *mp = NULL((void*)0), *mp_type = NULL((void*)0);
1061 char *record_route = NULL((void*)0);
1062 const char *recover_via = NULL((void*)0);
1063 int require_timer = 1;
1064 uint8_t is_t38 = 0;
1065 const char *hold_char = "*";
1066 const char *session_id_header = sofia_glue_session_id_header(session, tech_pvt->profile);
1067 const char *stir_shaken_attest = NULL((void*)0);
1068 char *identity_to_free = NULL((void*)0);
1069 const char *date = NULL((void*)0);
1070
1071
1072 if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD_INACTIVE)((tech_pvt)->flags[TFLAG_SIP_HOLD_INACTIVE] ? 1 : 0) ||
1
Taking false branch
1073 switch_true(switch_channel_get_variable_dup(tech_pvt->channel, "sofia_hold_inactive", SWITCH_FALSE, -1))) {
1074 hold_char = "#";
1075 }
1076
1077 if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING)) {
2
Assuming the condition is false
3
Taking false branch
1078 const char *recover_contact = switch_channel_get_variable(tech_pvt->channel, "sip_recover_contact")switch_channel_get_variable_dup(tech_pvt->channel, "sip_recover_contact"
, SWITCH_TRUE, -1)
;
1079 recover_via = switch_channel_get_variable(tech_pvt->channel, "sip_recover_via")switch_channel_get_variable_dup(tech_pvt->channel, "sip_recover_via"
, SWITCH_TRUE, -1)
;
1080
1081 if (!zstr(invite_record_route)_zstr(invite_record_route)) {
1082 record_route = switch_core_session_sprintf(session, "Record-Route: %s", invite_record_route);
1083 }
1084
1085 if (recover_contact) {
1086 char *tmp = switch_core_session_strdup(session, recover_contact)switch_core_perform_session_strdup(session, recover_contact, "sofia_glue.c"
, (const char *)__func__, 1086)
;
1087 tech_pvt->redirected = sofia_glue_get_url_from_contact(tmp, 0);
1088 }
1089 }
1090
1091
1092 if ((rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER)switch_channel_get_variable_dup(channel, "_sofia_replaces_", SWITCH_TRUE
, -1)
)) {
4
Assuming 'rep' is null
5
Taking false branch
1093 switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, NULL)switch_channel_set_variable_var_check(channel, "_sofia_replaces_"
, ((void*)0), SWITCH_TRUE)
;
1094 }
1095
1096 switch_assert(tech_pvt != NULL)((tech_pvt != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt != ((void*)0)"
, "sofia_glue.c", 1096, __extension__ __PRETTY_FUNCTION__))
;
1097
1098 sofia_clear_flag_locked(tech_pvt, TFLAG_SDP)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_SDP] = 0; switch_mutex_unlock(tech_pvt->flag_mutex)
;
;
1099
1100 caller_profile = switch_channel_get_caller_profile(channel);
1101
1102 if (!caller_profile) {
6
Assuming 'caller_profile' is non-null
7
Taking false branch
1103 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia_glue.c", (const
char *)__func__, 1103, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
1104 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1105 }
1106
1107
1108 if ((val = switch_channel_get_variable_dup(channel, "sip_require_timer", SWITCH_FALSE, -1)) && switch_false(val)) {
8
Assuming 'val' is null
1109 require_timer = 0;
1110 }
1111
1112
1113 cid_name = caller_profile->caller_id_name;
1114 cid_num = caller_profile->caller_id_number;
1115
1116 if (!tech_pvt->sent_invites && !switch_channel_test_flag(channel, CF_ANSWERED)) {
9
Assuming the condition is false
1117 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
1118 switch_core_media_check_video_codecs(tech_pvt->session);
1119 }
1120
1121 check_decode(cid_name, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia_glue.c"
, 1121, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(cid_name
)) { int d = 0; char *p; if (strchr(cid_name, '%')) { char *tmp
= switch_core_perform_session_strdup(session, cid_name, "sofia_glue.c"
, (const char *)__func__, 1121); switch_url_decode(tmp); cid_name
= tmp; d++; } if ((p = strchr(cid_name, '"'))) { if (!d) { char
*tmp = switch_core_perform_session_strdup(session, cid_name,
"sofia_glue.c", (const char *)__func__, 1121); cid_name = tmp
; } if ((p = strchr(cid_name, '"'))) { cid_name = p+1; } if (
(p = strrchr(cid_name, '"'))) { *p = '\0'; } } } break; } while
(0)
;
1122 check_decode(cid_num, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia_glue.c"
, 1122, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(cid_num
)) { int d = 0; char *p; if (strchr(cid_num, '%')) { char *tmp
= switch_core_perform_session_strdup(session, cid_num, "sofia_glue.c"
, (const char *)__func__, 1122); switch_url_decode(tmp); cid_num
= tmp; d++; } if ((p = strchr(cid_num, '"'))) { if (!d) { char
*tmp = switch_core_perform_session_strdup(session, cid_num, "sofia_glue.c"
, (const char *)__func__, 1122); cid_num = tmp; } if ((p = strchr
(cid_num, '"'))) { cid_num = p+1; } if ((p = strrchr(cid_num,
'"'))) { *p = '\0'; } } } break; } while (0)
;
1123
1124
1125 if ((alertbuf = switch_channel_get_variable(channel, "alert_info")switch_channel_get_variable_dup(channel, "alert_info", SWITCH_TRUE
, -1)
)) {
10
Assuming 'alertbuf' is null
11
Taking false branch
1126 alert_info = switch_core_session_sprintf(tech_pvt->session, "Alert-Info: %s", alertbuf);
1127 }
1128
1129 if ((stir_shaken_attest = switch_channel_get_variable(tech_pvt->channel, "sip_stir_shaken_attest")switch_channel_get_variable_dup(tech_pvt->channel, "sip_stir_shaken_attest"
, SWITCH_TRUE, -1)
)) {
12
Assuming 'stir_shaken_attest' is null
13
Taking false branch
1130 char date_buf[80] = "";
1131 char *dest = caller_profile->destination_number;
1132 check_decode(dest, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia_glue.c"
, 1132, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(dest)
) { int d = 0; char *p; if (strchr(dest, '%')) { char *tmp = switch_core_perform_session_strdup
(session, dest, "sofia_glue.c", (const char *)__func__, 1132)
; switch_url_decode(tmp); dest = tmp; d++; } if ((p = strchr(
dest, '"'))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, dest, "sofia_glue.c", (const char *)__func__, 1132)
; dest = tmp; } if ((p = strchr(dest, '"'))) { dest = p+1; } if
((p = strrchr(dest, '"'))) { *p = '\0'; } } } break; } while
(0)
;
1133 switch_rfc822_date(date_buf, switch_micro_time_now());
1134 date = switch_core_session_strdup(tech_pvt->session, date_buf)switch_core_perform_session_strdup(tech_pvt->session, date_buf
, "sofia_glue.c", (const char *)__func__, 1134)
;
1135 identity = identity_to_free = sofia_stir_shaken_as_create_identity_header(tech_pvt->session, stir_shaken_attest, cid_num, dest);
1136 }
1137 if (!identity) {
14
Taking true branch
1138 identity = switch_channel_get_variable(channel, "sip_h_identity")switch_channel_get_variable_dup(channel, "sip_h_identity", SWITCH_TRUE
, -1)
;
1139 }
1140 if (!date) {
15
Taking true branch
1141 date = switch_channel_get_variable(channel, "sip_h_date")switch_channel_get_variable_dup(channel, "sip_h_date", SWITCH_TRUE
, -1)
;
1142 }
1143
1144 max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE)switch_channel_get_variable_dup(channel, "max_forwards", SWITCH_TRUE
, -1)
;
1145
1146 if ((status = switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0)) != SWITCH_STATUS_SUCCESS) {
16
Assuming the condition is false
17
Taking false branch
1147 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1147, (const char*)(tech_pvt->session)
, SWITCH_LOG_ERROR, "Port Error!\n");
1148 goto end;
1149 }
1150
1151 if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams.local_sdp_str)_zstr(tech_pvt->mparams.local_sdp_str)) {
18
Assuming the condition is false
19
Taking false branch
1152 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL((void*)0), 0, NULL((void*)0), 0);
1153 }
1154
1155 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia_glue.c", 1155, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
1156
1157 if (!tech_pvt->nh) {
20
Assuming the condition is true
21
Taking true branch
1158 char *d_url = NULL((void*)0), *url = NULL((void*)0), *url_str = NULL((void*)0);
1159 sofia_private_t *sofia_private;
1160 char *invite_contact = NULL((void*)0), *to_str, *use_from_str, *from_str;
1161 const char *t_var;
1162 char *rpid_domain = NULL((void*)0), *p;
1163 const char *priv = "off";
1164 const char *screen = "no";
1165 const char *invite_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_params")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_params"
, SWITCH_TRUE, -1)
;
1166 const char *invite_to_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_to_params")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_to_params"
, SWITCH_TRUE, -1)
;
1167 const char *invite_tel_params = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_invite_tel_params")switch_channel_get_variable_dup(switch_core_session_get_channel
(session), "sip_invite_tel_params", SWITCH_TRUE, -1)
;
1168 const char *invite_to_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_to_uri")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_to_uri"
, SWITCH_TRUE, -1)
;
1169 const char *invite_from_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_from_uri")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_from_uri"
, SWITCH_TRUE, -1)
;
1170 const char *invite_contact_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_contact_params")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_contact_params"
, SWITCH_TRUE, -1)
;
1171 const char *invite_from_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_from_params")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_from_params"
, SWITCH_TRUE, -1)
;
1172 const char *invite_pid_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_pid_params")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_pid_params"
, SWITCH_TRUE, -1)
;
1173 const char *from_var = switch_channel_get_variable(tech_pvt->channel, "sip_from_uri")switch_channel_get_variable_dup(tech_pvt->channel, "sip_from_uri"
, SWITCH_TRUE, -1)
;
1174 const char *from_display = switch_channel_get_variable(tech_pvt->channel, "sip_from_display")switch_channel_get_variable_dup(tech_pvt->channel, "sip_from_display"
, SWITCH_TRUE, -1)
;
1175 const char *invite_req_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_req_uri")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_req_uri"
, SWITCH_TRUE, -1)
;
1176 const char *invite_domain = switch_channel_get_variable(tech_pvt->channel, "sip_invite_domain")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_domain"
, SWITCH_TRUE, -1)
;
1177
1178 const char *use_name, *use_number;
1179
1180 if (zstr(tech_pvt->dest)_zstr(tech_pvt->dest)) {
22
Taking false branch
1181 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1181, (const char*)(tech_pvt->session)
, SWITCH_LOG_ERROR, "URL Error!\n");
1182 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1183 }
1184
1185 if ((d_url = sofia_glue_get_url_from_contact(tech_pvt->dest, 1))) {
23
Assuming 'd_url' is null
24
Taking false branch
1186 url = d_url;
1187 } else {
1188 url = tech_pvt->dest;
1189 }
1190
1191 if (!tech_pvt->from_str) {
25
Assuming the condition is false
26
Taking false branch
1192 const char *sipip;
1193 const char *format;
1194 char *use_cid_num = switch_core_session_url_encode(tech_pvt->session, cid_num);
1195
1196 sipip = tech_pvt->profile->sipip;
1197
1198 if (!zstr(tech_pvt->mparams.remote_ip)_zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
1199 sipip = tech_pvt->profile->extsipip;
1200 }
1201
1202 if (!zstr(invite_domain)_zstr(invite_domain)) {
1203 sipip = invite_domain;
1204 }
1205
1206 format = strchr(sipip, ':') ? "\"%s\" <sip:%s%s[%s]>" : "\"%s\" <sip:%s%s%s>";
1207
1208 tech_pvt->from_str = switch_core_session_sprintf(tech_pvt->session, format, cid_name, use_cid_num, !zstr(cid_num)_zstr(cid_num) ? "@" : "", sipip);
1209 }
1210
1211 if (from_var) {
27
Assuming 'from_var' is null
28
Taking false branch
1212 if (strncasecmp(from_var, "sip:", 4) || strncasecmp(from_var, "sips:", 5)) {
1213 use_from_str = switch_core_session_strdup(tech_pvt->session, from_var)switch_core_perform_session_strdup(tech_pvt->session, from_var
, "sofia_glue.c", (const char *)__func__, 1213)
;
1214 } else {
1215 use_from_str = switch_core_session_sprintf(tech_pvt->session, "sip:%s", from_var);
1216 }
1217 } else if (!zstr(tech_pvt->gateway_from_str)_zstr(tech_pvt->gateway_from_str)) {
29
Taking true branch
1218 use_from_str = tech_pvt->gateway_from_str;
1219 } else {
1220 use_from_str = tech_pvt->from_str;
1221 }
1222
1223 if (!zstr(tech_pvt->gateway_from_str)_zstr(tech_pvt->gateway_from_str)) {
30
Taking true branch
1224 rpid_domain = switch_core_session_strdup(session, tech_pvt->gateway_from_str)switch_core_perform_session_strdup(session, tech_pvt->gateway_from_str
, "sofia_glue.c", (const char *)__func__, 1224)
;
1225 } else if (!zstr(tech_pvt->from_str)_zstr(tech_pvt->from_str)) {
1226 rpid_domain = switch_core_session_strdup(session, use_from_str)switch_core_perform_session_strdup(session, use_from_str, "sofia_glue.c"
, (const char *)__func__, 1226)
;
1227 }
1228
1229 sofia_glue_get_url_from_contact(rpid_domain, 0);
1230 if (rpid_domain && (rpid_domain = strrchr(rpid_domain, '@'))) {
31
Assuming 'rpid_domain' is null
1231 rpid_domain++;
1232 if ((p = strchr(rpid_domain, ';'))) {
1233 *p = '\0';
1234 }
1235 }
1236
1237 if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT)((tech_pvt->profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
32
Taking false branch
1238 if (!zstr(tech_pvt->mparams.remote_ip)_zstr(tech_pvt->mparams.remote_ip) && !zstr(tech_pvt->profile->extsipip)_zstr(tech_pvt->profile->extsipip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
1239 rpid_domain = tech_pvt->profile->extsipip;
1240 } else {
1241 rpid_domain = tech_pvt->profile->sipip;
1242 }
1243 }
1244
1245 if (!zstr(invite_domain)_zstr(invite_domain)) {
33
Taking true branch
1246 rpid_domain = (char *)invite_domain;
1247 }
1248
1249 if (zstr(rpid_domain)_zstr(rpid_domain)) {
34
Taking false branch
1250 rpid_domain = "cluecon.com";
1251 }
1252
1253 if (!zstr(tech_pvt->dest)_zstr(tech_pvt->dest)) {
35
Taking true branch
1254 dst = sofia_glue_get_destination(tech_pvt->dest);
1255 }
1256
1257 /*
1258 * Ignore transport chanvar and uri parameter for gateway connections
1259 * since all of them have been already taken care of in mod_sofia.c:sofia_outgoing_channel()
1260 */
1261 if (tech_pvt->transport == SOFIA_TRANSPORT_UNKNOWN && zstr(tech_pvt->gateway_name)_zstr(tech_pvt->gateway_name)) {
36
Assuming the condition is false
1262 if (dst && dst->route_uri) {
1263 p = dst->route_uri;
1264 } else {
1265 p = url;
1266 }
1267 if ((p = (char *) switch_stristr("port=", p))) {
1268 p += 5;
1269 tech_pvt->transport = sofia_glue_str2transport(p);
1270 } else {
1271 if ((t_var = switch_channel_get_variable(channel, "sip_transport")switch_channel_get_variable_dup(channel, "sip_transport", SWITCH_TRUE
, -1)
)) {
1272 tech_pvt->transport = sofia_glue_str2transport(t_var);
1273 }
1274 }
1275
1276 if (tech_pvt->transport == SOFIA_TRANSPORT_UNKNOWN) {
1277 tech_pvt->transport = SOFIA_TRANSPORT_UDP;
1278 }
1279 }
1280
1281 if (!zstr(tech_pvt->mparams.remote_ip)_zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
37
Taking false branch
1282 tech_pvt->user_via = sofia_glue_create_external_via(session, tech_pvt->profile, tech_pvt->transport);
1283 }
1284
1285 if (!sofia_test_pflag(tech_pvt->profile, PFLAG_TLS)((tech_pvt->profile)->pflags[PFLAG_TLS] ? 1 : 0) && sofia_glue_transport_has_tls(tech_pvt->transport)) {
38
Taking false branch
1286 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1286, (const char*)(tech_pvt->session)
, SWITCH_LOG_ERROR, "TLS not supported by profile\n");
1287 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1288 }
1289
1290 if (zstr(tech_pvt->invite_contact)_zstr(tech_pvt->invite_contact)) {
39
Taking false branch
1291 const char *contact;
1292 if ((contact = switch_channel_get_variable(channel, "sip_contact_user")switch_channel_get_variable_dup(channel, "sip_contact_user", SWITCH_TRUE
, -1)
)) {
1293 char *ip_addr = tech_pvt->profile->sipip;
1294 char *ipv6;
1295
1296 if ( !zstr(tech_pvt->mparams.remote_ip)_zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip ) ) {
1297 ip_addr = tech_pvt->profile->extsipip;
1298 }
1299
1300 ipv6 = strchr(ip_addr, ':');
1301
1302 if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
1303 tech_pvt->invite_contact = switch_core_session_sprintf(session, "sip:%s@%s%s%s:%d", contact,
1304 ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->tls_sip_port);
1305 } else {
1306 tech_pvt->invite_contact = switch_core_session_sprintf(session, "sip:%s@%s%s%s:%d", contact,
1307 ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->extsipport);
1308 }
1309 } else {
1310 tech_pvt->invite_contact = sofia_glue_get_profile_url(tech_pvt->profile, tech_pvt->mparams.remote_ip, tech_pvt->transport);
1311 }
1312 }
1313
1314 url_str = sofia_overcome_sip_uri_weakness(session, url, tech_pvt->transport, SWITCH_TRUE, invite_params, invite_tel_params);
1315 invite_contact = sofia_overcome_sip_uri_weakness(session, tech_pvt->invite_contact, tech_pvt->transport, SWITCH_FALSE, invite_contact_params, NULL((void*)0));
1316 from_str = sofia_overcome_sip_uri_weakness(session, invite_from_uri ? invite_from_uri : use_from_str, 0, SWITCH_TRUE, invite_from_params, NULL((void*)0));
40
Assuming 'invite_from_uri' is null
41
'?' condition is false
1317 to_str = sofia_overcome_sip_uri_weakness(session, invite_to_uri ? invite_to_uri : tech_pvt->dest_to, 0, SWITCH_FALSE, invite_to_params, NULL((void*)0));
42
Assuming 'invite_to_uri' is non-null
43
'?' condition is true
1318
1319 switch_channel_set_variable(channel, "sip_outgoing_contact_uri", invite_contact)switch_channel_set_variable_var_check(channel, "sip_outgoing_contact_uri"
, invite_contact, SWITCH_TRUE)
;
1320
1321 /*
1322 Does the "genius" who wanted SIP to be "text-based" so it was "easier to read" even use it now,
1323 or did he just suggest it to make our lives miserable?
1324 */
1325 use_from_str = from_str;
1326
1327 if (!switch_stristr("sip:", use_from_str)) {
44
Assuming the condition is false
45
Taking false branch
1328 use_from_str = switch_core_session_sprintf(session, "sip:%s", use_from_str);
1329 }
1330
1331 if (!from_display && (!strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_") || zstr(tech_pvt->caller_profile->caller_id_name)_zstr(tech_pvt->caller_profile->caller_id_name))) {
46
Assuming 'from_display' is non-null
1332 from_str = switch_core_session_sprintf(session, "<%s>", use_from_str);
1333 } else {
1334 char *name = switch_core_session_strdup(session, from_display ? from_display : tech_pvt->caller_profile->caller_id_name)switch_core_perform_session_strdup(session, from_display ? from_display
: tech_pvt->caller_profile->caller_id_name, "sofia_glue.c"
, (const char *)__func__, 1334)
;
1335 check_decode(name, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia_glue.c"
, 1335, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(name)
) { int d = 0; char *p; if (strchr(name, '%')) { char *tmp = switch_core_perform_session_strdup
(session, name, "sofia_glue.c", (const char *)__func__, 1335)
; switch_url_decode(tmp); name = tmp; d++; } if ((p = strchr(
name, '"'))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, name, "sofia_glue.c", (const char *)__func__, 1335)
; name = tmp; } if ((p = strchr(name, '"'))) { name = p+1; } if
((p = strrchr(name, '"'))) { *p = '\0'; } } } break; } while
(0)
;
1336 from_str = switch_core_session_sprintf(session, "\"%s\" <%s>", name, use_from_str);
1337 }
1338
1339 if (!(call_id = switch_channel_get_variable(channel, "sip_invite_call_id")switch_channel_get_variable_dup(channel, "sip_invite_call_id"
, SWITCH_TRUE, -1)
)) {
47
Assuming 'call_id' is not null
48
Taking false branch
1340 if (sofia_test_pflag(tech_pvt->profile, PFLAG_UUID_AS_CALLID)((tech_pvt->profile)->pflags[PFLAG_UUID_AS_CALLID] ? 1 :
0)
) {
1341 call_id = switch_core_session_get_uuid(session);
1342 }
1343 }
1344
1345 if (handle_full_from) {
49
Assuming 'handle_full_from' is null
50
Taking false branch
1346 from_str = (char *) handle_full_from;
1347 }
1348
1349 if (handle_full_to) {
51
Assuming 'handle_full_to' is null
52
Taking false branch
1350 to_str = (char *) handle_full_to;
1351 }
1352
1353
1354 if (force_full_from) {
53
Assuming 'force_full_from' is null
54
Taking false branch
1355 from_str = (char *) force_full_from;
1356 }
1357
1358 if (force_full_to) {
55
Assuming 'force_full_to' is null
56
Taking false branch
1359 to_str = (char *) force_full_to;
1360 }
1361
1362
1363 if (invite_req_uri) {
57
Assuming 'invite_req_uri' is null
58
Taking false branch
1364 url_str = (char *) invite_req_uri;
1365 }
1366
1367 if (url_str) {
59
Assuming 'url_str' is null
60
Taking false branch
1368 char *s = NULL((void*)0);
1369 if (!strncasecmp(url_str, "sip:", 4)) {
1370 s = url_str + 4;
1371 }
1372 if (!strncasecmp(url_str, "sips:", 5)) {
1373 s = url_str + 5;
1374 }
1375
1376 /* tel: patch from jaybinks, added by MC
1377 It compiles but I don't have a way to test it
1378 */
1379 if (!strncasecmp(url_str, "tel:", 4)) {
1380 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1380, (const char*)(tech_pvt->session)
,
1381 SWITCH_LOG_ERROR, "URL Error! tel: uri's not supported at this time\n");
1382 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1383 }
1384 if (!s) {
1385 s = url_str;
1386 }
1387 switch_channel_set_variable(channel, "sip_req_uri", s)switch_channel_set_variable_var_check(channel, "sip_req_uri",
s, SWITCH_TRUE)
;
1388 }
1389
1390 switch_channel_set_variable(channel, "sip_to_host", sofia_glue_get_host(to_str, switch_core_session_get_pool(session)))switch_channel_set_variable_var_check(channel, "sip_to_host",
sofia_glue_get_host(to_str, switch_core_session_get_pool(session
)), SWITCH_TRUE)
;
1391 switch_channel_set_variable(channel, "sip_from_host", sofia_glue_get_host(from_str, switch_core_session_get_pool(session)))switch_channel_set_variable_var_check(channel, "sip_from_host"
, sofia_glue_get_host(from_str, switch_core_session_get_pool(
session)), SWITCH_TRUE)
;
61
Within the expansion of the macro 'switch_channel_set_variable':
a
Calling 'sofia_glue_get_host'
b
Returned allocated memory
1392
1393 if (!(tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL((void*)0),
1394 NUTAG_URL(url_str)nutag_url, urltag_url_v(url_str),
69
Within the expansion of the macro 'NUTAG_URL':
a
Potential memory leak
1395 TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id))!(call_id) ? tag_skip : siptag_call_id_str, tag_str_v(call_id
)
,
1396 TAG_IF(!zstr(record_route), SIPTAG_HEADER_STR(record_route))!(!_zstr(record_route)) ? tag_skip : siptag_header_str, tag_str_v
((record_route))
,
1397 SIPTAG_TO_STR(to_str)siptag_to_str, tag_str_v(to_str), SIPTAG_FROM_STR(from_str)siptag_from_str, tag_str_v(from_str), SIPTAG_CONTACT_STR(invite_contact)siptag_contact_str, tag_str_v(invite_contact), TAG_END()(tag_type_t)0, (tag_value_t)0))) {
1398
1399 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1399, (const char*)(session)
, SWITCH_LOG_CRIT,
1400 "Error creating HANDLE!\nurl_str=[%s]\ncall_id=[%s]\nto_str=[%s]\nfrom_str=[%s]\ninvite_contact=[%s]\n",
1401 url_str,
1402 call_id ? call_id : "N/A",
1403 to_str,
1404 from_str,
1405 invite_contact);
1406
1407 switch_safe_free(d_url)if (d_url) {free(d_url);d_url=((void*)0);};
1408 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1409 }
1410
1411 if (tech_pvt->dest && (strstr(tech_pvt->dest, ";fs_nat") || strstr(tech_pvt->dest, ";received")
1412 || ((val = switch_channel_get_variable(channel, "sip_sticky_contact")switch_channel_get_variable_dup(channel, "sip_sticky_contact"
, SWITCH_TRUE, -1)
) && switch_true(val)))) {
1413 sofia_set_flag(tech_pvt, TFLAG_NAT)(tech_pvt)->flags[TFLAG_NAT] = 1;
1414 tech_pvt->record_route = switch_core_session_strdup(tech_pvt->session, url_str)switch_core_perform_session_strdup(tech_pvt->session, url_str
, "sofia_glue.c", (const char *)__func__, 1414)
;
1415 if (!dst || !dst->route_uri) {
1416 route_uri = tech_pvt->record_route;
1417 }
1418 session_timeout = SOFIA_NAT_SESSION_TIMEOUT90;
1419 switch_channel_set_variable(channel, "sip_nat_detected", "true")switch_channel_set_variable_var_check(channel, "sip_nat_detected"
, "true", SWITCH_TRUE)
;
1420 }
1421
1422 if ((val = switch_channel_get_variable(channel, "sip_cid_type")switch_channel_get_variable_dup(channel, "sip_cid_type", SWITCH_TRUE
, -1)
)) {
1423 cid_type = sofia_cid_name2type(val);
1424 }
1425
1426 if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
1427 if (zstr((use_name = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_name")))_zstr((use_name = switch_channel_get_variable_dup(tech_pvt->
channel, "effective_callee_id_name", SWITCH_TRUE, -1)))
&&
1428 zstr((use_name = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_name")))_zstr((use_name = switch_channel_get_variable_dup(tech_pvt->
channel, "sip_callee_id_name", SWITCH_TRUE, -1)))
) {
1429 if (!(use_name = switch_channel_get_variable(tech_pvt->channel, "sip_to_display")switch_channel_get_variable_dup(tech_pvt->channel, "sip_to_display"
, SWITCH_TRUE, -1)
)) {
1430 use_name = switch_channel_get_variable(tech_pvt->channel, "sip_to_user")switch_channel_get_variable_dup(tech_pvt->channel, "sip_to_user"
, SWITCH_TRUE, -1)
;
1431 }
1432 }
1433
1434 if (zstr((use_number = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_number")))_zstr((use_number = switch_channel_get_variable_dup(tech_pvt->
channel, "effective_callee_id_number", SWITCH_TRUE, -1)))
&&
1435 zstr((use_number = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_number")))_zstr((use_number = switch_channel_get_variable_dup(tech_pvt->
channel, "sip_callee_id_number", SWITCH_TRUE, -1)))
) {
1436 use_number = switch_channel_get_variable(tech_pvt->channel, "sip_to_user")switch_channel_get_variable_dup(tech_pvt->channel, "sip_to_user"
, SWITCH_TRUE, -1)
;
1437 }
1438
1439 if (zstr(use_name)_zstr(use_name) && zstr(use_name = tech_pvt->caller_profile->callee_id_name)_zstr(use_name = tech_pvt->caller_profile->callee_id_name
)
) {
1440 use_name = tech_pvt->caller_profile->caller_id_name;
1441 }
1442
1443 if (zstr(use_number)_zstr(use_number) && zstr(use_number = tech_pvt->caller_profile->callee_id_number)_zstr(use_number = tech_pvt->caller_profile->callee_id_number
)
) {
1444 use_number = tech_pvt->caller_profile->caller_id_number;
1445 }
1446 } else {
1447 use_name = tech_pvt->caller_profile->caller_id_name;
1448 use_number = tech_pvt->caller_profile->caller_id_number;
1449 }
1450
1451 check_decode(use_name, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia_glue.c"
, 1451, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(use_name
)) { int d = 0; char *p; if (strchr(use_name, '%')) { char *tmp
= switch_core_perform_session_strdup(session, use_name, "sofia_glue.c"
, (const char *)__func__, 1451); switch_url_decode(tmp); use_name
= tmp; d++; } if ((p = strchr(use_name, '"'))) { if (!d) { char
*tmp = switch_core_perform_session_strdup(session, use_name,
"sofia_glue.c", (const char *)__func__, 1451); use_name = tmp
; } if ((p = strchr(use_name, '"'))) { use_name = p+1; } if (
(p = strrchr(use_name, '"'))) { *p = '\0'; } } } break; } while
(0)
;
1452
1453 switch (cid_type) {
1454 case CID_TYPE_PID:
1455 if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)((caller_profile)->flags & SWITCH_CPF_SCREEN)) {
1456 if (zstr(tech_pvt->caller_profile->caller_id_name)_zstr(tech_pvt->caller_profile->caller_id_name) || !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
1457 tech_pvt->asserted_id = switch_core_session_sprintf(tech_pvt->session, "<sip:%s@%s%s%s>",
1458 use_number, rpid_domain,
1459 invite_pid_params ? ";" : "",
1460 invite_pid_params ? invite_pid_params : "");
1461 } else {
1462 tech_pvt->asserted_id = switch_core_session_sprintf(tech_pvt->session, "\"%s\" <sip:%s@%s%s%s>",
1463 use_name, use_number, rpid_domain,
1464 invite_pid_params ? ";" : "",
1465 invite_pid_params ? invite_pid_params : "");
1466 }
1467 } else {
1468 if (zstr(tech_pvt->caller_profile->caller_id_name)_zstr(tech_pvt->caller_profile->caller_id_name) || !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
1469 tech_pvt->preferred_id = switch_core_session_sprintf(tech_pvt->session, "<sip:%s@%s%s%s>",
1470 tech_pvt->caller_profile->caller_id_number, rpid_domain,
1471 invite_pid_params ? ";" : "",
1472 invite_pid_params ? invite_pid_params : "");
1473 } else {
1474 tech_pvt->preferred_id = switch_core_session_sprintf(tech_pvt->session, "\"%s\" <sip:%s@%s%s%s>",
1475 tech_pvt->caller_profile->caller_id_name,
1476 tech_pvt->caller_profile->caller_id_number, rpid_domain,
1477 invite_pid_params ? ";" : "",
1478 invite_pid_params ? invite_pid_params : "");
1479 }
1480 }
1481
1482 if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)((caller_profile)->flags & SWITCH_CPF_HIDE_NUMBER)) {
1483 tech_pvt->privacy = "id";
1484 } else {
1485 if (!(val = switch_channel_get_variable(channel, "sip_cid_suppress_privacy_none")switch_channel_get_variable_dup(channel, "sip_cid_suppress_privacy_none"
, SWITCH_TRUE, -1)
) || !switch_true(val)) {
1486 tech_pvt->privacy = "none";
1487 }
1488 }
1489
1490 break;
1491 case CID_TYPE_RPID:
1492 {
1493 if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NAME)((caller_profile)->flags & SWITCH_CPF_HIDE_NAME)) {
1494 priv = "name";
1495 if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)((caller_profile)->flags & SWITCH_CPF_HIDE_NUMBER)) {
1496 priv = "full";
1497 }
1498 } else if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)((caller_profile)->flags & SWITCH_CPF_HIDE_NUMBER)) {
1499 priv = "full";
1500 }
1501
1502 if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)((caller_profile)->flags & SWITCH_CPF_SCREEN)) {
1503 screen = "yes";
1504 }
1505
1506 if (zstr(tech_pvt->caller_profile->caller_id_name)_zstr(tech_pvt->caller_profile->caller_id_name) || !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
1507 tech_pvt->rpid = switch_core_session_sprintf(tech_pvt->session, "<sip:%s@%s>;party=calling;screen=%s;privacy=%s",
1508 use_number, rpid_domain, screen, priv);
1509 } else {
1510 tech_pvt->rpid = switch_core_session_sprintf(tech_pvt->session, "\"%s\"<sip:%s@%s>;party=calling;screen=%s;privacy=%s",
1511 use_name, use_number, rpid_domain, screen, priv);
1512 }
1513 }
1514 break;
1515 default:
1516 break;
1517 }
1518
1519
1520 switch_safe_free(d_url)if (d_url) {free(d_url);d_url=((void*)0);};
1521
1522 if (!(sofia_private = su_alloc(nua_handle_get_home(tech_pvt->nh), sizeof(*sofia_private)))) {
1523 abort();
1524 }
1525
1526 memset(sofia_private, 0, sizeof(*sofia_private));
1527 sofia_private->is_call = 2;
1528 sofia_private->is_static++;
1529
1530 if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING)) {
1531 sofia_private->is_call++;
1532 }
1533
1534 tech_pvt->sofia_private = sofia_private;
1535 switch_copy_string(tech_pvt->sofia_private->uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid_str));
1536 tech_pvt->sofia_private->uuid = tech_pvt->sofia_private->uuid_str;
1537 nua_handle_bind(tech_pvt->nh, tech_pvt->sofia_private);
1538 }
1539
1540 if (tech_pvt->e_dest && sofia_test_pflag(tech_pvt->profile, PFLAG_IN_DIALOG_CHAT)((tech_pvt->profile)->pflags[PFLAG_IN_DIALOG_CHAT] ? 1 :
0)
) {
1541 char *user = NULL((void*)0), *host = NULL((void*)0);
1542 char hash_key[256] = "";
1543
1544 e_dest = strdup(tech_pvt->e_dest);
1545 switch_assert(e_dest != NULL)((e_dest != ((void*)0)) ? (void) (0) : __assert_fail ("e_dest != ((void*)0)"
, "sofia_glue.c", 1545, __extension__ __PRETTY_FUNCTION__))
;
1546 user = e_dest;
1547
1548 if ((host = strchr(user, '@'))) {
1549 *host++ = '\0';
1550 }
1551 switch_snprintf(hash_key, sizeof(hash_key), "%s%s%s", user, host, cid_num);
1552
1553 tech_pvt->chat_from = tech_pvt->from_str;
1554 tech_pvt->chat_to = tech_pvt->dest;
1555 if (tech_pvt->profile->pres_type) {
1556 tech_pvt->hash_key = switch_core_session_strdup(tech_pvt->session, hash_key)switch_core_perform_session_strdup(tech_pvt->session, hash_key
, "sofia_glue.c", (const char *)__func__, 1556)
;
1557 switch_mutex_lock(tech_pvt->profile->flag_mutex);
1558 switch_core_hash_insert(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt)switch_core_hash_insert_destructor(tech_pvt->profile->chat_hash
, tech_pvt->hash_key, tech_pvt, ((void*)0))
;
1559 switch_mutex_unlock(tech_pvt->profile->flag_mutex);
1560 }
1561 free(e_dest);
1562 }
1563
1564 holdstr = sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt)->flags[TFLAG_SIP_HOLD] ? 1 : 0) ? hold_char : "";
1565
1566 if (!switch_channel_get_variable(channel, "sofia_profile_name")switch_channel_get_variable_dup(channel, "sofia_profile_name"
, SWITCH_TRUE, -1)
) {
1567 switch_channel_set_variable(channel, "sofia_profile_name", tech_pvt->profile->name)switch_channel_set_variable_var_check(channel, "sofia_profile_name"
, tech_pvt->profile->name, SWITCH_TRUE)
;
1568 switch_channel_set_variable(channel, "recovery_profile_name", tech_pvt->profile->name)switch_channel_set_variable_var_check(channel, "recovery_profile_name"
, tech_pvt->profile->name, SWITCH_TRUE)
;
1569 switch_channel_set_variable(channel, "sofia_profile_url", tech_pvt->profile->url)switch_channel_set_variable_var_check(channel, "sofia_profile_url"
, tech_pvt->profile->url, SWITCH_TRUE)
;
1570 }
1571
1572 extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX"sip_h_");
1573
1574 if ((val = switch_channel_get_variable(channel, SOFIA_SESSION_TIMEOUT)switch_channel_get_variable_dup(channel, "sofia_session_timeout"
, SWITCH_TRUE, -1)
)) {
1575 int v_session_timeout = atoi(val);
1576 if (v_session_timeout >= 0) {
1577 session_timeout = v_session_timeout;
1578 }
1579 }
1580
1581 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
1582 switch_core_media_proxy_remote_addr(session, NULL((void*)0));
1583 switch_core_media_patch_sdp(tech_pvt->session);
1584 }
1585
1586 if (!zstr(tech_pvt->dest)_zstr(tech_pvt->dest)) {
1587 if (!dst) {
1588 dst = sofia_glue_get_destination(tech_pvt->dest);
1589 }
1590
1591 if (dst->route_uri) {
1592 route_uri = sofia_overcome_sip_uri_weakness(tech_pvt->session, dst->route_uri, tech_pvt->transport, SWITCH_TRUE, NULL((void*)0), NULL((void*)0));
1593 }
1594
1595 if (dst->route) {
1596 route = dst->route;
1597 }
1598 }
1599
1600 if ((val = switch_channel_get_variable(channel, "sip_route_uri")switch_channel_get_variable_dup(channel, "sip_route_uri", SWITCH_TRUE
, -1)
)) {
1601 route_uri = switch_core_session_strdup(session, val)switch_core_perform_session_strdup(session, val, "sofia_glue.c"
, (const char *)__func__, 1601)
;
1602 route = NULL((void*)0);
1603 }
1604
1605 if (route_uri) {
1606 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1606, (const char*)(tech_pvt->session)
, SWITCH_LOG_DEBUG, "%s Setting proxy route to %s\n", route_uri,
1607 switch_channel_get_name(channel));
1608 tech_pvt->route_uri = switch_core_session_strdup(tech_pvt->session, route_uri)switch_core_perform_session_strdup(tech_pvt->session, route_uri
, "sofia_glue.c", (const char *)__func__, 1608)
;
1609 }
1610
1611
1612 if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_invite_cseq")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_cseq"
, SWITCH_TRUE, -1)
)) {
1613 uint32_t callsequence = (uint32_t) strtoul(val, NULL((void*)0), 10);
1614 cseq = sip_cseq_create(nua_handle_get_home(tech_pvt->nh), callsequence, SIP_METHOD_INVITEsip_method_invite, "INVITE");
1615 }
1616
1617
1618 switch_channel_clear_flag(channel, CF_MEDIA_ACK);
1619
1620 if (handle_full_from) {
1621 nua_handle_set_has_invite(tech_pvt->nh, 1);
1622 }
1623
1624 if ((mp = sofia_media_get_multipart(session, "sip_multipart", tech_pvt->mparams.local_sdp_str, &mp_type))) {
1625 sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA)(tech_pvt)->flags[TFLAG_ENABLE_SOA] = 0;
1626 }
1627
1628 if ((tech_pvt->session_timeout = session_timeout)) {
1629 tech_pvt->session_refresher = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? nua_local_refresher : nua_remote_refresher;
1630 if (sofia_test_pflag(tech_pvt->profile, PFLAG_UPDATE_REFRESHER)((tech_pvt->profile)->pflags[PFLAG_UPDATE_REFRESHER] ? 1
: 0)
|| switch_channel_var_true(tech_pvt->channel, "sip_update_refresher")) {
1631 tech_pvt->update_refresher = 1;
1632 }
1633 } else {
1634 tech_pvt->session_refresher = nua_no_refresher;
1635 }
1636
1637 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1637, (const char*)(tech_pvt->session)
, SWITCH_LOG_INFO, "%s sending invite call-id: %s\n",
1638 switch_channel_get_name(tech_pvt->channel), call_id);
1639
1640 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1640, (const char*)(tech_pvt->session)
, SWITCH_LOG_DEBUG, "%s sending invite version: %s\nLocal SDP:\n%s\n",
1641 switch_channel_get_name(tech_pvt->channel), switch_version_full_human(),
1642 tech_pvt->mparams.local_sdp_str ? tech_pvt->mparams.local_sdp_str : "NO SDP PRESENT\n");
1643
1644
1645
1646 if ((switch_channel_get_private(tech_pvt->channel, "t38_options")) ||
1647 ((switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) ||
1648 switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) )
1649 && switch_stristr("m=image", tech_pvt->mparams.local_sdp_str))) {
1650 sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA)(tech_pvt)->flags[TFLAG_ENABLE_SOA] = 0;
1651 is_t38 = 1;
1652 }
1653
1654
1655 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
1656 nua_invite(tech_pvt->nh,
1657 NUTAG_AUTOANSWER(0)nutag_autoanswer, tag_bool_v(0),
1658 //TAG_IF(zstr(tech_pvt->mparams.local_sdp_str), NUTAG_AUTOACK(0)),
1659 //TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), NUTAG_AUTOACK(1)),
1660 // The code above is breaking things...... grrr WE need this because we handle our own acks and there are 3pcc cases in there too
1661 NUTAG_AUTOACK(0)nutag_autoack, tag_bool_v(0),
1662 NUTAG_SESSION_TIMER(tech_pvt->session_timeout)nutag_session_timer, tag_uint_v((tech_pvt->session_timeout
))
,
1663 NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher)nutag_session_refresher, tag_int_v((tech_pvt->session_refresher
))
,
1664 NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher)nutag_update_refresh, tag_bool_v((tech_pvt->update_refresher
))
,
1665 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header))!(!_zstr(session_id_header)) ? tag_skip : siptag_header_str, tag_str_v
((session_id_header))
,
1666 TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX))!(((tech_pvt)->flags[TFLAG_RECOVERED] ? 1 : 0)) ? tag_skip
: nutag_invite_timer, tag_uint_v(((2147483647 *2U +1U)))
,
1667 TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from))!(invite_full_from) ? tag_skip : siptag_from_str, tag_str_v(invite_full_from
)
,
1668 TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to))!(invite_full_to) ? tag_skip : siptag_to_str, tag_str_v(invite_full_to
)
,
1669 TAG_IF(tech_pvt->redirected, NUTAG_URL(tech_pvt->redirected))!(tech_pvt->redirected) ? tag_skip : nutag_url, urltag_url_v
(tech_pvt->redirected)
,
1670 TAG_IF(!zstr(recover_via), SIPTAG_VIA_STR(recover_via))!(!_zstr(recover_via)) ? tag_skip : siptag_via_str, tag_str_v
(recover_via)
,
1671 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via))!(!_zstr(tech_pvt->user_via)) ? tag_skip : siptag_via_str,
tag_str_v(tech_pvt->user_via)
,
1672 TAG_IF(!zstr(tech_pvt->rpid), SIPTAG_REMOTE_PARTY_ID_STR(tech_pvt->rpid))!(!_zstr(tech_pvt->rpid)) ? tag_skip : siptag_remote_party_id_str
, tag_str_v(tech_pvt->rpid)
,
1673 TAG_IF(!zstr(tech_pvt->preferred_id), SIPTAG_P_PREFERRED_IDENTITY_STR(tech_pvt->preferred_id))!(!_zstr(tech_pvt->preferred_id)) ? tag_skip : siptag_p_preferred_identity_str
, tag_str_v(tech_pvt->preferred_id)
,
1674 TAG_IF(!zstr(tech_pvt->asserted_id), SIPTAG_P_ASSERTED_IDENTITY_STR(tech_pvt->asserted_id))!(!_zstr(tech_pvt->asserted_id)) ? tag_skip : siptag_p_asserted_identity_str
, tag_str_v(tech_pvt->asserted_id)
,
1675 TAG_IF(!zstr(tech_pvt->privacy), SIPTAG_PRIVACY_STR(tech_pvt->privacy))!(!_zstr(tech_pvt->privacy)) ? tag_skip : siptag_privacy_str
, tag_str_v(tech_pvt->privacy)
,
1676 TAG_IF(!zstr(identity), SIPTAG_IDENTITY_STR(identity))!(!_zstr(identity)) ? tag_skip : siptag_identity_str, tag_str_v
(identity)
,
1677 TAG_IF(!zstr(date), SIPTAG_DATE_STR(date))!(!_zstr(date)) ? tag_skip : siptag_date_str, tag_str_v(date),
1678 TAG_IF(!zstr(alert_info), SIPTAG_HEADER_STR(alert_info))!(!_zstr(alert_info)) ? tag_skip : siptag_header_str, tag_str_v
((alert_info))
,
1679 TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers))!(!_zstr(extra_headers)) ? tag_skip : siptag_header_str, tag_str_v
((extra_headers))
,
1680 TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_PASS_CALLEE_ID), SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT))!(((tech_pvt->profile)->pflags[PFLAG_PASS_CALLEE_ID] ? 1
: 0)) ? tag_skip : siptag_header_str, tag_str_v(("X-FS-Support: "
"update_display,send_info"))
,
1681 TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards))!(!_zstr(max_forwards)) ? tag_skip : siptag_max_forwards_str,
tag_str_v(max_forwards)
,
1682 TAG_IF(!zstr(route_uri), NUTAG_PROXY(route_uri))!(!_zstr(route_uri)) ? tag_skip : ntatag_default_proxy, urltag_url_v
((route_uri))
,
1683 TAG_IF(!zstr(invite_route_uri), NUTAG_INITIAL_ROUTE_STR(invite_route_uri))!(!_zstr(invite_route_uri)) ? tag_skip : nutag_initial_route_str
, tag_str_v(invite_route_uri)
,
1684 TAG_IF(!zstr(route), SIPTAG_ROUTE_STR(route))!(!_zstr(route)) ? tag_skip : siptag_route_str, tag_str_v(route
)
,
1685 TAG_IF(tech_pvt->profile->minimum_session_expires, NUTAG_MIN_SE(tech_pvt->profile->minimum_session_expires))!(tech_pvt->profile->minimum_session_expires) ? tag_skip
: nutag_min_se, tag_uint_v((tech_pvt->profile->minimum_session_expires
))
,
1686 TAG_IF(cseq, SIPTAG_CSEQ(cseq))!(cseq) ? tag_skip : siptag_cseq, siptag_cseq_v(cseq),
1687 TAG_IF(content_encoding, SIPTAG_CONTENT_ENCODING_STR(content_encoding))!(content_encoding) ? tag_skip : siptag_content_encoding_str,
tag_str_v(content_encoding)
,
1688 TAG_IF(zstr(tech_pvt->mparams.local_sdp_str), SIPTAG_PAYLOAD_STR(""))!(_zstr(tech_pvt->mparams.local_sdp_str)) ? tag_skip : siptag_payload_str
, tag_str_v("")
,
1689 TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_ADDRESS(tech_pvt->mparams.adv_sdp_audio_ip))!(!_zstr(tech_pvt->mparams.local_sdp_str)) ? tag_skip : soatag_address
, tag_str_v(tech_pvt->mparams.adv_sdp_audio_ip)
,
1690 TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str))!(!_zstr(tech_pvt->mparams.local_sdp_str)) ? tag_skip : soatag_user_sdp_str
, tag_str_v(tech_pvt->mparams.local_sdp_str)
,
1691 TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_REUSE_REJECTED(1))!(!_zstr(tech_pvt->mparams.local_sdp_str)) ? tag_skip : soatag_reuse_rejected
, tag_bool_v(1)
,
1692 TAG_IF(is_t38, SOATAG_ORDERED_USER(1))!(is_t38) ? tag_skip : soatag_ordered_user, tag_bool_v(1),
1693 TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE))!(!_zstr(tech_pvt->mparams.local_sdp_str)) ? tag_skip : soatag_rtp_sort
, tag_int_v(SOA_RTP_SORT_REMOTE)
,
1694 TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL))!(!_zstr(tech_pvt->mparams.local_sdp_str)) ? tag_skip : soatag_rtp_select
, tag_int_v(SOA_RTP_SELECT_ALL)
,
1695 TAG_IF(rep, SIPTAG_REPLACES_STR(rep))!(rep) ? tag_skip : siptag_replaces_str, tag_str_v(rep),
1696 TAG_IF(!require_timer, NUTAG_TIMER_AUTOREQUIRE(0))!(!require_timer) ? tag_skip : nutag_timer_autorequire, tag_bool_v
(0)
,
1697 TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_HOLD(holdstr))!(!_zstr(tech_pvt->mparams.local_sdp_str)) ? tag_skip : soatag_hold
, tag_str_v(holdstr)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
1698 } else {
1699 nua_invite(tech_pvt->nh,
1700 NUTAG_AUTOANSWER(0)nutag_autoanswer, tag_bool_v(0),
1701 NUTAG_AUTOACK(0)nutag_autoack, tag_bool_v(0),
1702 NUTAG_SESSION_TIMER(tech_pvt->session_timeout)nutag_session_timer, tag_uint_v((tech_pvt->session_timeout
))
,
1703 NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher)nutag_session_refresher, tag_int_v((tech_pvt->session_refresher
))
,
1704 NUTAG_UPDATE_REFRESH(tech_pvt->update_refresher)nutag_update_refresh, tag_bool_v((tech_pvt->update_refresher
))
,
1705 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header))!(!_zstr(session_id_header)) ? tag_skip : siptag_header_str, tag_str_v
((session_id_header))
,
1706 TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX))!(((tech_pvt)->flags[TFLAG_RECOVERED] ? 1 : 0)) ? tag_skip
: nutag_invite_timer, tag_uint_v(((2147483647 *2U +1U)))
,
1707 TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from))!(invite_full_from) ? tag_skip : siptag_from_str, tag_str_v(invite_full_from
)
,
1708 TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to))!(invite_full_to) ? tag_skip : siptag_to_str, tag_str_v(invite_full_to
)
,
1709 TAG_IF(tech_pvt->redirected, NUTAG_URL(tech_pvt->redirected))!(tech_pvt->redirected) ? tag_skip : nutag_url, urltag_url_v
(tech_pvt->redirected)
,
1710 TAG_IF(!zstr(recover_via), SIPTAG_VIA_STR(recover_via))!(!_zstr(recover_via)) ? tag_skip : siptag_via_str, tag_str_v
(recover_via)
,
1711 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via))!(!_zstr(tech_pvt->user_via)) ? tag_skip : siptag_via_str,
tag_str_v(tech_pvt->user_via)
,
1712 TAG_IF(!zstr(tech_pvt->rpid), SIPTAG_REMOTE_PARTY_ID_STR(tech_pvt->rpid))!(!_zstr(tech_pvt->rpid)) ? tag_skip : siptag_remote_party_id_str
, tag_str_v(tech_pvt->rpid)
,
1713 TAG_IF(!zstr(tech_pvt->preferred_id), SIPTAG_P_PREFERRED_IDENTITY_STR(tech_pvt->preferred_id))!(!_zstr(tech_pvt->preferred_id)) ? tag_skip : siptag_p_preferred_identity_str
, tag_str_v(tech_pvt->preferred_id)
,
1714 TAG_IF(!zstr(tech_pvt->asserted_id), SIPTAG_P_ASSERTED_IDENTITY_STR(tech_pvt->asserted_id))!(!_zstr(tech_pvt->asserted_id)) ? tag_skip : siptag_p_asserted_identity_str
, tag_str_v(tech_pvt->asserted_id)
,
1715 TAG_IF(!zstr(tech_pvt->privacy), SIPTAG_PRIVACY_STR(tech_pvt->privacy))!(!_zstr(tech_pvt->privacy)) ? tag_skip : siptag_privacy_str
, tag_str_v(tech_pvt->privacy)
,
1716 TAG_IF(!zstr(alert_info), SIPTAG_HEADER_STR(alert_info))!(!_zstr(alert_info)) ? tag_skip : siptag_header_str, tag_str_v
((alert_info))
,
1717 TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers))!(!_zstr(extra_headers)) ? tag_skip : siptag_header_str, tag_str_v
((extra_headers))
,
1718 TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_PASS_CALLEE_ID), SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT))!(((tech_pvt->profile)->pflags[PFLAG_PASS_CALLEE_ID] ? 1
: 0)) ? tag_skip : siptag_header_str, tag_str_v(("X-FS-Support: "
"update_display,send_info"))
,
1719 TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards))!(!_zstr(max_forwards)) ? tag_skip : siptag_max_forwards_str,
tag_str_v(max_forwards)
,
1720 TAG_IF(!zstr(identity), SIPTAG_IDENTITY_STR(identity))!(!_zstr(identity)) ? tag_skip : siptag_identity_str, tag_str_v
(identity)
,
1721 TAG_IF(!zstr(route_uri), NUTAG_PROXY(route_uri))!(!_zstr(route_uri)) ? tag_skip : ntatag_default_proxy, urltag_url_v
((route_uri))
,
1722 TAG_IF(!zstr(route), SIPTAG_ROUTE_STR(route))!(!_zstr(route)) ? tag_skip : siptag_route_str, tag_str_v(route
)
,
1723 TAG_IF(!zstr(invite_route_uri), NUTAG_INITIAL_ROUTE_STR(invite_route_uri))!(!_zstr(invite_route_uri)) ? tag_skip : nutag_initial_route_str
, tag_str_v(invite_route_uri)
,
1724 TAG_IF(tech_pvt->profile->minimum_session_expires, NUTAG_MIN_SE(tech_pvt->profile->minimum_session_expires))!(tech_pvt->profile->minimum_session_expires) ? tag_skip
: nutag_min_se, tag_uint_v((tech_pvt->profile->minimum_session_expires
))
,
1725 TAG_IF(!require_timer, NUTAG_TIMER_AUTOREQUIRE(0))!(!require_timer) ? tag_skip : nutag_timer_autorequire, tag_bool_v
(0)
,
1726 TAG_IF(cseq, SIPTAG_CSEQ(cseq))!(cseq) ? tag_skip : siptag_cseq, siptag_cseq_v(cseq),
1727 TAG_IF(content_encoding, SIPTAG_CONTENT_ENCODING_STR(content_encoding))!(content_encoding) ? tag_skip : siptag_content_encoding_str,
tag_str_v(content_encoding)
,
1728 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
1729 SIPTAG_CONTENT_TYPE_STR(mp_type ? mp_type : "application/sdp")siptag_content_type_str, tag_str_v(mp_type ? mp_type : "application/sdp"
)
,
1730 SIPTAG_PAYLOAD_STR(mp ? mp : tech_pvt->mparams.local_sdp_str)siptag_payload_str, tag_str_v(mp ? mp : tech_pvt->mparams.
local_sdp_str)
, TAG_IF(rep, SIPTAG_REPLACES_STR(rep))!(rep) ? tag_skip : siptag_replaces_str, tag_str_v(rep), SOATAG_HOLD(holdstr)soatag_hold, tag_str_v(holdstr), TAG_END()(tag_type_t)0, (tag_value_t)0);
1731 }
1732
1733 switch_safe_free(extra_headers)if (extra_headers) {free(extra_headers);extra_headers=((void*
)0);}
;
1734 switch_safe_free(mp)if (mp) {free(mp);mp=((void*)0);};
1735 tech_pvt->redirected = NULL((void*)0);
1736
1737 status = SWITCH_STATUS_SUCCESS;
1738
1739end:
1740
1741 if (dst) {
1742 sofia_glue_free_destination(dst);
1743 }
1744
1745 switch_safe_free(identity_to_free)if (identity_to_free) {free(identity_to_free);identity_to_free
=((void*)0);}
;
1746
1747 return status;
1748}
1749
1750void sofia_glue_do_xfer_invite(switch_core_session_t *session)
1751{
1752 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
1753 switch_channel_t *channel = switch_core_session_get_channel(session);
1754 switch_caller_profile_t *caller_profile;
1755 const char *sipip, *format, *contact_url;
1756
1757 switch_assert(tech_pvt != NULL)((tech_pvt != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt != ((void*)0)"
, "sofia_glue.c", 1757, __extension__ __PRETTY_FUNCTION__))
;
1758 switch_mutex_lock(tech_pvt->sofia_mutex);
1759 caller_profile = switch_channel_get_caller_profile(channel);
1760
1761 if (!zstr(tech_pvt->mparams.remote_ip)_zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
1762 sipip = tech_pvt->profile->extsipip;
1763 contact_url = tech_pvt->profile->public_url;
1764 } else {
1765 sipip = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
1766 contact_url = tech_pvt->profile->url;
1767 }
1768
1769 format = strchr(sipip, ':') ? "\"%s\" <sip:%s@[%s]>" : "\"%s\" <sip:%s@%s>";
1770
1771 if ((tech_pvt->from_str = switch_core_session_sprintf(session, format, caller_profile->caller_id_name, caller_profile->caller_id_number, sipip))) {
1772
1773 const char *rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER)switch_channel_get_variable_dup(channel, "_sofia_replaces_", SWITCH_TRUE
, -1)
;
1774
1775 tech_pvt->nh2 = nua_handle(tech_pvt->profile->nua, NULL((void*)0),
1776 SIPTAG_TO_STR(tech_pvt->dest)siptag_to_str, tag_str_v(tech_pvt->dest), SIPTAG_FROM_STR(tech_pvt->from_str)siptag_from_str, tag_str_v(tech_pvt->from_str), SIPTAG_CONTACT_STR(contact_url)siptag_contact_str, tag_str_v(contact_url), TAG_END()(tag_type_t)0, (tag_value_t)0);
1777
1778 nua_handle_bind(tech_pvt->nh2, tech_pvt->sofia_private);
1779
1780 nua_invite(tech_pvt->nh2,
1781 SIPTAG_CONTACT_STR(contact_url)siptag_contact_str, tag_str_v(contact_url),
1782 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via))!(!_zstr(tech_pvt->user_via)) ? tag_skip : siptag_via_str,
tag_str_v(tech_pvt->user_via)
,
1783 SOATAG_ADDRESS(tech_pvt->mparams.adv_sdp_audio_ip)soatag_address, tag_str_v(tech_pvt->mparams.adv_sdp_audio_ip
)
,
1784 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
1785 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
1786 SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE)soatag_rtp_sort, tag_int_v(SOA_RTP_SORT_REMOTE), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL)soatag_rtp_select, tag_int_v(SOA_RTP_SELECT_ALL), TAG_IF(rep, SIPTAG_REPLACES_STR(rep))!(rep) ? tag_skip : siptag_replaces_str, tag_str_v(rep), TAG_END()(tag_type_t)0, (tag_value_t)0);
1787 } else {
1788 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 1788, (const char*)(tech_pvt->session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
1789 }
1790 switch_mutex_unlock(tech_pvt->sofia_mutex);
1791}
1792
1793
1794/* map sip responses to QSIG cause codes ala RFC4497 section 8.4.4 */
1795switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status)
1796{
1797 switch (status) {
1798 case 200:
1799 return SWITCH_CAUSE_NORMAL_CLEARING;
1800 case 401:
1801 case 402:
1802 case 403:
1803 case 407:
1804 case 603:
1805 case 607:
1806 return SWITCH_CAUSE_CALL_REJECTED;
1807 case 404:
1808 return SWITCH_CAUSE_UNALLOCATED_NUMBER;
1809 case 485:
1810 case 604:
1811 return SWITCH_CAUSE_NO_ROUTE_DESTINATION;
1812 case 408:
1813 case 504:
1814 return SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
1815 case 410:
1816 return SWITCH_CAUSE_NUMBER_CHANGED;
1817 case 413:
1818 case 414:
1819 case 416:
1820 case 420:
1821 case 421:
1822 case 423:
1823 case 505:
1824 case 513:
1825 return SWITCH_CAUSE_INTERWORKING;
1826 case 480:
1827 return SWITCH_CAUSE_NO_USER_RESPONSE;
1828 case 400:
1829 case 481:
1830 case 500:
1831 case 503:
1832 return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE;
1833 case 486:
1834 case 600:
1835 return SWITCH_CAUSE_USER_BUSY;
1836 case 484:
1837 return SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
1838 case 488:
1839 case 606:
1840 return SWITCH_CAUSE_INCOMPATIBLE_DESTINATION;
1841 case 502:
1842 return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
1843 case 405:
1844 return SWITCH_CAUSE_SERVICE_UNAVAILABLE;
1845 case 406:
1846 case 415:
1847 case 501:
1848 return SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED;
1849 case 482:
1850 case 483:
1851 return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR;
1852 case 487:
1853 return SWITCH_CAUSE_ORIGINATOR_CANCEL;
1854 case 428:
1855 return SWITCH_CAUSE_NO_IDENTITY;
1856 case 429:
1857 return SWITCH_CAUSE_BAD_IDENTITY_INFO;
1858 case 437:
1859 return SWITCH_CAUSE_UNSUPPORTED_CERTIFICATE;
1860 case 438:
1861 return SWITCH_CAUSE_INVALID_IDENTITY;
1862 default:
1863 return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
1864 }
1865}
1866
1867void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp)
1868{
1869 const char *val;
1870 switch_core_session_t *other_session;
1871 switch_channel_t *other_channel;
1872
1873 if ((val = switch_channel_get_partner_uuid(tech_pvt->channel))
1874 && (other_session = switch_core_session_locate(val)switch_core_session_perform_locate(val, "sofia_glue.c", (const
char *)__func__, 1874)
)) {
1875 other_channel = switch_core_session_get_channel(other_session);
1876 switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, sdp)switch_channel_set_variable_var_check(other_channel, "switch_m_sdp"
, sdp, SWITCH_TRUE)
;
1877
1878#if 0
1879 if (!sofia_test_flag(tech_pvt, TFLAG_CHANGE_MEDIA)((tech_pvt)->flags[TFLAG_CHANGE_MEDIA] ? 1 : 0) && !switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING) &&
1880 (switch_channel_direction(other_channel) == SWITCH_CALL_DIRECTION_OUTBOUND &&
1881 switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) {
1882 switch_ivr_nomedia(val, SMF_FORCE);
1883 sofia_set_flag_locked(tech_pvt, TFLAG_CHANGE_MEDIA)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia_glue.c", 1883, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_CHANGE_MEDIA] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
1884 }
1885#endif
1886
1887 switch_core_session_rwunlock(other_session);
1888 }
1889}
1890
1891char *sofia_glue_get_path_from_contact(char *buf)
1892{
1893 char *p, *e, *path = NULL((void*)0), *contact = NULL((void*)0);
1894
1895 if (!buf) return NULL((void*)0);
1896
1897 contact = sofia_glue_get_url_from_contact(buf, SWITCH_TRUE);
1898
1899 if (!contact) return NULL((void*)0);
1900
1901 if ((p = strstr(contact, "fs_path="))) {
1902 p += 8;
1903
1904 if (!zstr(p)_zstr(p)) {
1905 path = strdup(p);
1906 }
1907 }
1908
1909 if (!path) {
1910 free(contact);
1911 return NULL((void*)0);
1912 }
1913
1914 if ((e = strrchr(path, ';'))) {
1915 *e = '\0';
1916 }
1917
1918 switch_url_decode(path);
1919
1920 free(contact);
1921
1922 return path;
1923}
1924
1925char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup)
1926{
1927 char *url = NULL((void*)0), *e;
1928
1929 switch_assert(buf)((buf) ? (void) (0) : __assert_fail ("buf", "sofia_glue.c", 1929
, __extension__ __PRETTY_FUNCTION__))
;
1930
1931 while(*buf == ' ') {
1932 buf++;
1933 }
1934
1935 if (*buf == '"') {
1936 buf++;
1937 if((e = strchr(buf, '"'))) {
1938 buf = e+1;
1939 }
1940 }
1941
1942 while(*buf == ' ') {
1943 buf++;
1944 }
1945
1946 url = strchr(buf, '<');
1947
1948 if (url && (e = switch_find_end_paren(url, '<', '>'))) {
1949 url++;
1950 if (to_dup) {
1951 url = strdup(url);
1952 switch_assert(url)((url) ? (void) (0) : __assert_fail ("url", "sofia_glue.c", 1952
, __extension__ __PRETTY_FUNCTION__))
;
1953 e = strchr(url, '>');
1954 }
1955
1956 *e = '\0';
1957 } else {
1958 if (url) buf++;
1959
1960 if (to_dup) {
1961 url = strdup(buf);
1962 } else {
1963 url = buf;
1964 }
1965 }
1966 return url;
1967}
1968
1969switch_status_t sofia_glue_profile_rdlock__(const char *file, const char *func, int line, sofia_profile_t *profile)
1970{
1971 switch_status_t status = switch_thread_rwlock_tryrdlock(profile->rwlock);
1972 if (status != SWITCH_STATUS_SUCCESS) {
1973 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_ERROR, "Profile %s is locked\n", profile->name);
1974 return status;
1975 }
1976#ifdef SOFIA_DEBUG_RWLOCKS
1977 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_ERROR, "XXXXXXXXXXXXXX LOCK %s\n", profile->name);
1978#endif
1979 return status;
1980}
1981
1982switch_bool_t sofia_glue_profile_exists(const char *key)
1983{
1984 switch_bool_t tf = SWITCH_FALSE;
1985
1986 switch_mutex_lock(mod_sofia_globals.hash_mutex);
1987 if (switch_core_hash_find(mod_sofia_globals.profile_hash, key)) {
1988 tf = SWITCH_TRUE;
1989 }
1990 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
1991
1992 return tf;
1993}
1994
1995sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, const char *key)
1996{
1997 sofia_profile_t *profile;
1998
1999 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2000 if ((profile = (sofia_profile_t *) switch_core_hash_find(mod_sofia_globals.profile_hash, key))) {
2001 if (!sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0)) {
2002#ifdef SOFIA_DEBUG_RWLOCKS
2003 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_ERROR, "Profile %s is not running\n", profile->name);
2004#endif
2005 profile = NULL((void*)0);
2006 goto done;
2007 }
2008 if (sofia_glue_profile_rdlock__(file, func, line, profile) != SWITCH_STATUS_SUCCESS) {
2009 profile = NULL((void*)0);
2010 }
2011 } else {
2012#ifdef SOFIA_DEBUG_RWLOCKS
2013 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_ERROR, "Profile %s is not in the hash\n", key);
2014#endif
2015 }
2016
2017 done:
2018 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2019
2020 return profile;
2021}
2022
2023void sofia_glue_release_profile__(const char *file, const char *func, int line, sofia_profile_t *profile)
2024{
2025 if (profile) {
2026#ifdef SOFIA_DEBUG_RWLOCKS
2027 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL((void*)0), SWITCH_LOG_ERROR, "XXXXXXXXXXXXXX UNLOCK %s\n", profile->name);
2028#endif
2029 switch_thread_rwlock_unlock(profile->rwlock);
2030 }
2031}
2032
2033switch_status_t sofia_glue_add_profile(char *key, sofia_profile_t *profile)
2034{
2035 switch_status_t status = SWITCH_STATUS_FALSE;
2036
2037 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2038 if (!switch_core_hash_find(mod_sofia_globals.profile_hash, key)) {
2039 status = switch_core_hash_insert(mod_sofia_globals.profile_hash, key, profile)switch_core_hash_insert_destructor(mod_sofia_globals.profile_hash
, key, profile, ((void*)0))
;
2040 }
2041 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2042
2043 return status;
2044}
2045
2046
2047void sofia_glue_del_every_gateway(sofia_profile_t *profile)
2048{
2049 sofia_gateway_t *gp = NULL((void*)0);
2050
2051 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2052 for (gp = profile->gateways; gp; gp = gp->next) {
2053 sofia_glue_del_gateway(gp);
2054 }
2055 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2056}
2057
2058
2059void sofia_glue_gateway_list(sofia_profile_t *profile, switch_stream_handle_t *stream, int up)
2060{
2061 sofia_gateway_t *gp = NULL((void*)0);
2062
2063 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2064 for (gp = profile->gateways; gp; gp = gp->next) {
2065 int reged = (gp->status == SOFIA_GATEWAY_UP);
2066
2067 if (up ? reged : !reged) {
2068 stream->write_function(stream, "%s ", gp->name);
2069 }
2070 }
2071
2072 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2073}
2074
2075
2076void sofia_glue_del_gateway(sofia_gateway_t *gp)
2077{
2078 if (!gp->deleted) {
2079 if (gp->state != REG_STATE_NOREG) {
2080 gp->retry = 0;
2081 gp->state = REG_STATE_UNREGISTER;
2082 }
2083
2084 gp->deleted = 1;
2085 }
2086}
2087
2088void sofia_glue_restart_all_profiles(void)
2089{
2090 switch_hash_index_t *hi;
2091 const void *var;
2092 void *val;
2093 sofia_profile_t *pptr;
2094 switch_xml_t xml_root;
2095 const char *err;
2096
2097 if ((xml_root = switch_xml_open_root(1, &err))) {
2098 switch_xml_free(xml_root);
2099 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2099, ((void*)0)
, SWITCH_LOG_NOTICE, "Reload XML [%s]\n", err);
2100 }
2101
2102 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2103 if (mod_sofia_globals.profile_hash) {
2104 for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash)switch_core_hash_first_iter(mod_sofia_globals.profile_hash, (
(void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
2105 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
2106 if ((pptr = (sofia_profile_t *) val)) {
2107 int rsec = 10;
2108 int diff = (int) (switch_epoch_time_now(NULL((void*)0)) - pptr->started);
2109 int remain = rsec - diff;
2110 if (sofia_test_pflag(pptr, PFLAG_RESPAWN)((pptr)->pflags[PFLAG_RESPAWN] ? 1 : 0) || !sofia_test_pflag(pptr, PFLAG_RUNNING)((pptr)->pflags[PFLAG_RUNNING] ? 1 : 0)) {
2111 continue;
2112 }
2113
2114 if (diff < rsec) {
2115 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2115, ((void*)0)
, SWITCH_LOG_ERROR,
2116 "Profile %s must be up for at least %d seconds to stop/restart.\nPlease wait %d second%s\n",
2117 pptr->name, rsec, remain, remain == 1 ? "" : "s");
2118 continue;
2119 }
2120 sofia_set_pflag_locked(pptr, PFLAG_RESPAWN)((pptr->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("pptr->flag_mutex != NULL", "sofia_glue.c", 2120, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(pptr->flag_mutex)
;(pptr)->pflags[PFLAG_RESPAWN] = 1;switch_mutex_unlock(pptr
->flag_mutex);
;
2121 sofia_clear_pflag_locked(pptr, PFLAG_RUNNING)switch_mutex_lock(pptr->flag_mutex); (pptr)->pflags[PFLAG_RUNNING
] = 0; switch_mutex_unlock(pptr->flag_mutex);
;
2122 }
2123 }
2124 }
2125 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2126
2127}
2128
2129
2130void sofia_glue_global_siptrace(switch_bool_t on)
2131{
2132 switch_hash_index_t *hi;
2133 const void *var;
2134 void *val;
2135 sofia_profile_t *pptr;
2136
2137 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2138 if (mod_sofia_globals.profile_hash) {
2139 for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash)switch_core_hash_first_iter(mod_sofia_globals.profile_hash, (
(void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
2140 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
2141 if ((pptr = (sofia_profile_t *) val)) {
2142 nua_set_params(pptr->nua, TPTAG_LOG(on)tptag_log, tag_bool_v((on)), TAG_END()(tag_type_t)0, (tag_value_t)0);
2143 }
2144 }
2145 }
2146 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2147
2148}
2149
2150void sofia_glue_global_standby(switch_bool_t on)
2151{
2152 switch_hash_index_t *hi;
2153 const void *var;
2154 void *val;
2155 sofia_profile_t *pptr;
2156
2157 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2158 if (mod_sofia_globals.profile_hash) {
2159 for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash)switch_core_hash_first_iter(mod_sofia_globals.profile_hash, (
(void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
2160 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
2161 if ((pptr = (sofia_profile_t *) val)) {
2162 if (on) {
2163 sofia_set_pflag_locked(pptr, PFLAG_STANDBY)((pptr->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("pptr->flag_mutex != NULL", "sofia_glue.c", 2163, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(pptr->flag_mutex)
;(pptr)->pflags[PFLAG_STANDBY] = 1;switch_mutex_unlock(pptr
->flag_mutex);
;
2164 } else {
2165 sofia_clear_pflag_locked(pptr, PFLAG_STANDBY)switch_mutex_lock(pptr->flag_mutex); (pptr)->pflags[PFLAG_STANDBY
] = 0; switch_mutex_unlock(pptr->flag_mutex);
;
2166 }
2167 }
2168 }
2169 }
2170 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2171
2172}
2173
2174void sofia_glue_global_capture(switch_bool_t on)
2175{
2176 switch_hash_index_t *hi;
2177 const void *var;
2178 void *val;
2179 sofia_profile_t *pptr;
2180
2181 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2182 if (mod_sofia_globals.profile_hash) {
2183 for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash)switch_core_hash_first_iter(mod_sofia_globals.profile_hash, (
(void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
2184 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
2185 if ((pptr = (sofia_profile_t *) val)) {
2186 nua_set_params(pptr->nua, TPTAG_CAPT(on ? mod_sofia_globals.capture_server : NULL)tptag_capt, tag_str_v((on ? mod_sofia_globals.capture_server :
((void*)0)))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
2187 }
2188 }
2189 }
2190 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2191
2192}
2193
2194
2195void sofia_glue_global_watchdog(switch_bool_t on)
2196{
2197 switch_hash_index_t *hi;
2198 const void *var;
2199 void *val;
2200 sofia_profile_t *pptr;
2201
2202 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2203 if (mod_sofia_globals.profile_hash) {
2204 for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash)switch_core_hash_first_iter(mod_sofia_globals.profile_hash, (
(void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
2205 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
2206 if ((pptr = (sofia_profile_t *) val)) {
2207 pptr->watchdog_enabled = (on ? 1 : 0);
2208 }
2209 }
2210 }
2211 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2212
2213}
2214
2215void sofia_glue_del_profile(sofia_profile_t *profile)
2216{
2217 sofia_gateway_t *gp;
2218 char *aliases[512];
2219 int i = 0, j = 0;
2220 switch_hash_index_t *hi;
2221 const void *var;
2222 void *val;
2223 sofia_profile_t *pptr;
2224
2225 switch_mutex_lock(mod_sofia_globals.hash_mutex);
2226 if (mod_sofia_globals.profile_hash) {
2227 for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash)switch_core_hash_first_iter(mod_sofia_globals.profile_hash, (
(void*)0))
; hi; hi = switch_core_hash_next(&hi)) {
2228 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
2229 if ((pptr = (sofia_profile_t *) val) && pptr == profile) {
2230 aliases[i++] = strdup((char *) var);
2231 if (i == 512) {
2232 abort();
2233 }
2234 }
2235 }
2236
2237 for (j = 0; j < i && j < 512; j++) {
2238 switch_core_hash_delete(mod_sofia_globals.profile_hash, aliases[j]);
2239 free(aliases[j]);
2240 }
2241
2242 for (gp = profile->gateways; gp; gp = gp->next) {
2243 char *pkey = switch_mprintf("%s::%s", profile->name, gp->name);
2244
2245 switch_core_hash_delete(mod_sofia_globals.gateway_hash, gp->name);
2246 switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
2247 switch_safe_free(pkey)if (pkey) {free(pkey);pkey=((void*)0);};
2248 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2248, ((void*)0)
, SWITCH_LOG_NOTICE, "deleted gateway %s from profile %s\n", gp->name, profile->name);
2249 }
2250 profile->gateways = NULL((void*)0);
2251 }
2252 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
2253}
2254
2255int sofia_recover_callback(switch_core_session_t *session)
2256{
2257
2258 switch_channel_t *channel = switch_core_session_get_channel(session);
2259 private_object_t *tech_pvt = NULL((void*)0);
2260 sofia_profile_t *profile = NULL((void*)0);
2261 const char *tmp;
2262 const char *rr;
2263 int r = 0;
2264 const char *profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1);
2265 int swap = switch_channel_var_true(channel, "dlg_req_swap_direction");
2266
2267 if (zstr(profile_name)_zstr(profile_name)) {
2268 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 2268, (const char*)(session)
, SWITCH_LOG_CRIT, "Missing profile\n");
2269 return 0;
2270 }
2271
2272 if (!(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia_glue.c", (const char *)__func__
, 2272, profile_name)
)) {
2273 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 2273, (const char*)(session)
, SWITCH_LOG_CRIT, "Invalid profile %s\n", profile_name);
2274 return 0;
2275 }
2276
2277
2278 tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t))switch_core_perform_session_alloc(session, sizeof(private_object_t
), "sofia_glue.c", (const char *)__func__, 2278)
;
2279 tech_pvt->channel = channel;
2280
2281 switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session));
2282 switch_mutex_init(&tech_pvt->sofia_mutex, SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session));
2283
2284 tech_pvt->mparams.remote_ip = (char *) switch_channel_get_variable(channel, "sip_network_ip")switch_channel_get_variable_dup(channel, "sip_network_ip", SWITCH_TRUE
, -1)
;
2285 tech_pvt->mparams.remote_port = atoi(switch_str_nil(switch_channel_get_variable(channel, "sip_network_port"))(switch_channel_get_variable_dup(channel, "sip_network_port",
SWITCH_TRUE, -1) ? switch_channel_get_variable_dup(channel, "sip_network_port"
, SWITCH_TRUE, -1) : "")
);
2286 tech_pvt->caller_profile = switch_channel_get_caller_profile(channel);
2287
2288 if ((tmp = switch_channel_get_variable(tech_pvt->channel, "rtp_2833_send_payload")switch_channel_get_variable_dup(tech_pvt->channel, "rtp_2833_send_payload"
, SWITCH_TRUE, -1)
)) {
2289 int te = atoi(tmp);
2290 if (te > 64) {
2291 tech_pvt->te = (switch_payload_t)te;
2292 }
2293 }
2294
2295 if ((tmp = switch_channel_get_variable(tech_pvt->channel, "rtp_2833_recv_payload")switch_channel_get_variable_dup(tech_pvt->channel, "rtp_2833_recv_payload"
, SWITCH_TRUE, -1)
)) {
2296 int te = atoi(tmp);
2297 if (te > 64) {
2298 tech_pvt->recv_te = (switch_payload_t)te;
2299 }
2300 }
2301
2302 rr = switch_channel_get_variable(channel, "sip_invite_record_route")switch_channel_get_variable_dup(channel, "sip_invite_record_route"
, SWITCH_TRUE, -1)
;
2303
2304 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
2305 tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_req_uri")switch_channel_get_variable_dup(channel, "sip_req_uri", SWITCH_TRUE
, -1)
);
2306 switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, swap ? "sip_full_to" : "sip_full_from"))switch_channel_set_variable_var_check(channel, "sip_handle_full_from"
, switch_channel_get_variable_dup(channel, swap ? "sip_full_to"
: "sip_full_from", SWITCH_TRUE, -1), SWITCH_TRUE)
;
2307 switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, swap ? "sip_full_from" : "sip_full_to"))switch_channel_set_variable_var_check(channel, "sip_handle_full_to"
, switch_channel_get_variable_dup(channel, swap ? "sip_full_from"
: "sip_full_to", SWITCH_TRUE, -1), SWITCH_TRUE)
;
2308 } else {
2309 const char *contact_params = switch_channel_get_variable(channel, "sip_contact_params")switch_channel_get_variable_dup(channel, "sip_contact_params"
, SWITCH_TRUE, -1)
;
2310 const char *contact_uri = switch_channel_get_variable(channel, "sip_contact_uri")switch_channel_get_variable_dup(channel, "sip_contact_uri", SWITCH_TRUE
, -1)
;
2311 tech_pvt->redirected = switch_core_session_sprintf(session, "sip:%s%s%s", contact_uri, contact_params ? ";" : "", switch_str_nil(contact_params)(contact_params ? contact_params : ""));
2312
2313 if (zstr(rr)_zstr(rr)) {
2314 switch_channel_set_variable_printf(channel, "sip_invite_route_uri", "<sip:%s@%s:%s;transport=%s>",
2315 switch_channel_get_variable(channel, "sip_from_user")switch_channel_get_variable_dup(channel, "sip_from_user", SWITCH_TRUE
, -1)
,
2316 switch_channel_get_variable(channel, "sip_network_ip")switch_channel_get_variable_dup(channel, "sip_network_ip", SWITCH_TRUE
, -1)
,
2317 switch_channel_get_variable(channel, "sip_network_port")switch_channel_get_variable_dup(channel, "sip_network_port", SWITCH_TRUE
, -1)
,
2318 switch_channel_get_variable(channel,"sip_via_protocol")switch_channel_get_variable_dup(channel, "sip_via_protocol", SWITCH_TRUE
, -1)
2319 );
2320
2321 }
2322
2323 tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_from_uri")switch_channel_get_variable_dup(channel, "sip_from_uri", SWITCH_TRUE
, -1)
);
2324
2325 if (!switch_channel_get_variable_dup(channel, "sip_handle_full_from", SWITCH_FALSE, -1)) {
2326 switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, swap ? "sip_full_from" :"sip_full_to"))switch_channel_set_variable_var_check(channel, "sip_handle_full_from"
, switch_channel_get_variable_dup(channel, swap ? "sip_full_from"
:"sip_full_to", SWITCH_TRUE, -1), SWITCH_TRUE)
;
2327 }
2328
2329 if (!switch_channel_get_variable_dup(channel, "sip_handle_full_to", SWITCH_FALSE, -1)) {
2330 switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, swap ? "sip_full_to" : "sip_full_from"))switch_channel_set_variable_var_check(channel, "sip_handle_full_to"
, switch_channel_get_variable_dup(channel, swap ? "sip_full_to"
: "sip_full_from", SWITCH_TRUE, -1), SWITCH_TRUE)
;
2331 }
2332 }
2333
2334 if (rr && !switch_channel_get_variable(channel, "sip_invite_route_uri")switch_channel_get_variable_dup(channel, "sip_invite_route_uri"
, SWITCH_TRUE, -1)
) {
2335 switch_channel_set_variable(channel, "sip_invite_route_uri", rr)switch_channel_set_variable_var_check(channel, "sip_invite_route_uri"
, rr, SWITCH_TRUE)
;
2336 }
2337
2338 tech_pvt->dest_to = tech_pvt->dest;
2339
2340 sofia_glue_attach_private(session, profile, tech_pvt, NULL((void*)0));
2341 switch_channel_set_name(tech_pvt->channel, switch_channel_get_variable(channel, "channel_name")switch_channel_get_variable_dup(channel, "channel_name", SWITCH_TRUE
, -1)
);
2342
2343
2344 switch_channel_set_variable(channel, "sip_invite_call_id", switch_channel_get_variable(channel, "sip_call_id"))switch_channel_set_variable_var_check(channel, "sip_invite_call_id"
, switch_channel_get_variable_dup(channel, "sip_call_id", SWITCH_TRUE
, -1), SWITCH_TRUE)
;
2345
2346 if (switch_true(switch_channel_get_variable(channel, "sip_nat_detected")switch_channel_get_variable_dup(channel, "sip_nat_detected", SWITCH_TRUE
, -1)
)) {
2347 switch_channel_set_variable_printf(channel, "sip_route_uri", "sip:%s@%s:%s",
2348 switch_channel_get_variable(channel, "sip_req_user")switch_channel_get_variable_dup(channel, "sip_req_user", SWITCH_TRUE
, -1)
,
2349 switch_channel_get_variable(channel, "sip_network_ip")switch_channel_get_variable_dup(channel, "sip_network_ip", SWITCH_TRUE
, -1)
, switch_channel_get_variable(channel, "sip_network_port")switch_channel_get_variable_dup(channel, "sip_network_port", SWITCH_TRUE
, -1)
2350 );
2351 }
2352
2353 if (session) {
2354 const char *use_uuid;
2355
2356 if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid")switch_channel_get_variable_dup(channel, "origination_uuid", SWITCH_TRUE
, -1)
)) {
2357 if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
2358 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 2358, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
2359 use_uuid);
2360 } else {
2361 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia_glue.c", (const char *)__func__
, 2361, (const char*)(session)
, SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
2362 switch_channel_get_name(channel), use_uuid);
2363 }
2364 }
2365 }
2366
2367 r++;
2368
2369 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_glue.c", (const char *)__func__
, 2369, profile)
;
2370
2371
2372 return r;
2373
2374}
2375
2376
2377
2378int sofia_glue_recover(switch_bool_t flush)
2379{
2380 sofia_profile_t *profile;
2381 int r = 0;
2382 switch_console_callback_match_t *matches;
2383
2384
2385 if (list_profiles_full(NULL((void*)0), NULL((void*)0), &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
2386 switch_console_callback_match_node_t *m;
2387 for (m = matches->head; m; m = m->next) {
2388 if ((profile = sofia_glue_find_profile(m->val)sofia_glue_find_profile__("sofia_glue.c", (const char *)__func__
, 2388, m->val)
)) {
2389 r += sofia_glue_profile_recover(profile, flush);
2390 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_glue.c", (const char *)__func__
, 2390, profile)
;
2391 }
2392 }
2393 switch_console_free_matches(&matches);
2394 }
2395 return r;
2396}
2397
2398int sofia_glue_profile_recover(sofia_profile_t *profile, switch_bool_t flush)
2399{
2400 int r = 0;
2401
2402 if (profile) {
2403 sofia_clear_pflag_locked(profile, PFLAG_STANDBY)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_STANDBY] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
2404
2405 if (flush) {
2406 switch_core_recovery_flush(SOFIA_RECOVER"sofia", profile->name);
2407 } else {
2408 r = switch_core_recovery_recover(SOFIA_RECOVER"sofia", profile->name);
2409 }
2410 }
2411
2412 return r;
2413}
2414
2415
2416int sofia_glue_init_sql(sofia_profile_t *profile)
2417{
2418 char *test_sql = NULL((void*)0);
2419
2420 char reg_sql[] =
2421 "CREATE TABLE sip_registrations (\n"
2422 " call_id VARCHAR(255),\n"
2423 " sip_user VARCHAR(255),\n"
2424 " sip_host VARCHAR(255),\n"
2425 " presence_hosts VARCHAR(255),\n"
2426 " contact VARCHAR(1024),\n"
2427 " status VARCHAR(255),\n"
2428 " ping_status VARCHAR(255),\n"
2429 " ping_count INTEGER,\n"
2430 " ping_time BIGINT,\n"
2431 " force_ping INTEGER,\n"
2432 " rpid VARCHAR(255),\n"
2433 " expires BIGINT,\n"
2434 " ping_expires INTEGER not null default 0,\n"
2435 " user_agent VARCHAR(255),\n"
2436 " server_user VARCHAR(255),\n"
2437 " server_host VARCHAR(255),\n"
2438 " profile_name VARCHAR(255),\n"
2439 " hostname VARCHAR(255),\n"
2440 " network_ip VARCHAR(255),\n"
2441 " network_port VARCHAR(6),\n"
2442 " sip_username VARCHAR(255),\n"
2443 " sip_realm VARCHAR(255),\n"
2444 " mwi_user VARCHAR(255),\n"
2445 " mwi_host VARCHAR(255),\n"
2446 " orig_server_host VARCHAR(255),\n"
2447 " orig_hostname VARCHAR(255),\n"
2448 " sub_host VARCHAR(255)\n"
2449 ");\n";
2450
2451 char pres_sql[] =
2452 "CREATE TABLE sip_presence (\n"
2453 " sip_user VARCHAR(255),\n"
2454 " sip_host VARCHAR(255),\n"
2455 " status VARCHAR(255),\n"
2456 " rpid VARCHAR(255),\n"
2457 " expires BIGINT,\n"
2458 " user_agent VARCHAR(255),\n"
2459 " profile_name VARCHAR(255),\n"
2460 " hostname VARCHAR(255),\n"
2461 " network_ip VARCHAR(255),\n"
2462 " network_port VARCHAR(6),\n"
2463 " open_closed VARCHAR(255)\n"
2464 ");\n";
2465
2466 char dialog_sql[] =
2467 "CREATE TABLE sip_dialogs (\n"
2468 " call_id VARCHAR(255),\n"
2469 " uuid VARCHAR(255),\n"
2470 " sip_to_user VARCHAR(255),\n"
2471 " sip_to_host VARCHAR(255),\n"
2472 " sip_from_user VARCHAR(255),\n"
2473 " sip_from_host VARCHAR(255),\n"
2474 " contact_user VARCHAR(255),\n"
2475 " contact_host VARCHAR(255),\n"
2476 " state VARCHAR(255),\n"
2477 " direction VARCHAR(255),\n"
2478 " user_agent VARCHAR(255),\n"
2479 " profile_name VARCHAR(255),\n"
2480 " hostname VARCHAR(255),\n"
2481 " contact VARCHAR(255),\n"
2482 " presence_id VARCHAR(255),\n"
2483 " presence_data VARCHAR(255),\n"
2484 " call_info VARCHAR(255),\n"
2485 " call_info_state VARCHAR(255) default '',\n"
2486 " expires BIGINT default 0,\n"
2487 " status VARCHAR(255),\n"
2488 " rpid VARCHAR(255),\n"
2489 " sip_to_tag VARCHAR(255),\n"
2490 " sip_from_tag VARCHAR(255),\n"
2491 " rcd INTEGER not null default 0\n"
2492 ");\n";
2493
2494 char sub_sql[] =
2495 "CREATE TABLE sip_subscriptions (\n"
2496 " proto VARCHAR(255),\n"
2497 " sip_user VARCHAR(255),\n"
2498 " sip_host VARCHAR(255),\n"
2499 " sub_to_user VARCHAR(255),\n"
2500 " sub_to_host VARCHAR(255),\n"
2501 " presence_hosts VARCHAR(255),\n"
2502 " event VARCHAR(255),\n"
2503 " contact VARCHAR(1024),\n"
2504 " call_id VARCHAR(255),\n"
2505 " full_from VARCHAR(255),\n"
2506 " full_via VARCHAR(255),\n"
2507 " expires BIGINT,\n"
2508 " user_agent VARCHAR(255),\n"
2509 " accept VARCHAR(255),\n"
2510 " profile_name VARCHAR(255),\n"
2511 " hostname VARCHAR(255),\n"
2512 " network_port VARCHAR(6),\n"
2513 " network_ip VARCHAR(255),\n"
2514 " version INTEGER DEFAULT 0 NOT NULL,\n"
2515 " orig_proto VARCHAR(255),\n"
2516 " full_to VARCHAR(255)\n"
2517 ");\n";
2518
2519 char auth_sql[] =
2520 "CREATE TABLE sip_authentication (\n"
2521 " nonce VARCHAR(255),\n"
2522 " expires BIGINT,"
2523 " profile_name VARCHAR(255),\n"
2524 " hostname VARCHAR(255),\n"
2525 " last_nc INTEGER\n"
2526 ");\n";
2527
2528 /* should we move this glue to sofia_sla or keep it here where all db init happens? XXX MTK */
2529 char shared_appearance_sql[] =
2530 "CREATE TABLE sip_shared_appearance_subscriptions (\n"
2531 " subscriber VARCHAR(255),\n"
2532 " call_id VARCHAR(255),\n"
2533 " aor VARCHAR(255),\n"
2534 " profile_name VARCHAR(255),\n"
2535 " hostname VARCHAR(255),\n"
2536 " contact_str VARCHAR(255),\n"
2537 " network_ip VARCHAR(255)\n"
2538 ");\n";
2539
2540 char shared_appearance_dialogs_sql[] =
2541 "CREATE TABLE sip_shared_appearance_dialogs (\n"
2542 " profile_name VARCHAR(255),\n"
2543 " hostname VARCHAR(255),\n"
2544 " contact_str VARCHAR(255),\n"
2545 " call_id VARCHAR(255),\n"
2546 " network_ip VARCHAR(255),\n"
2547 " expires BIGINT\n"
2548 ");\n";
2549
2550
2551 int x;
2552 char *indexes[] = {
2553 "create index sr_call_id on sip_registrations (call_id)",
2554 "create index sr_sip_user on sip_registrations (sip_user)",
2555 "create index sr_sip_host on sip_registrations (sip_host)",
2556 "create index sr_sub_host on sip_registrations (sub_host)",
2557 "create index sr_mwi_user on sip_registrations (mwi_user)",
2558 "create index sr_mwi_host on sip_registrations (mwi_host)",
2559 "create index sr_profile_name on sip_registrations (profile_name)",
2560 "create index sr_presence_hosts on sip_registrations (presence_hosts)",
2561 "create index sr_contact on sip_registrations (contact)",
2562 "create index sr_expires on sip_registrations (expires)",
2563 "create index sr_ping_expires on sip_registrations (ping_expires)",
2564 "create index sr_hostname on sip_registrations (hostname)",
2565 "create index sr_status on sip_registrations (status)",
2566 "create index sr_ping_status on sip_registrations (ping_status)",
2567 "create index sr_network_ip on sip_registrations (network_ip)",
2568 "create index sr_network_port on sip_registrations (network_port)",
2569 "create index sr_sip_username on sip_registrations (sip_username)",
2570 "create index sr_sip_realm on sip_registrations (sip_realm)",
2571 "create index sr_orig_server_host on sip_registrations (orig_server_host)",
2572 "create index sr_orig_hostname on sip_registrations (orig_hostname)",
2573 "create index ss_call_id on sip_subscriptions (call_id)",
2574 "create index ss_multi on sip_subscriptions (call_id, profile_name, hostname)",
2575 "create index ss_hostname on sip_subscriptions (hostname)",
2576 "create index ss_network_ip on sip_subscriptions (network_ip)",
2577 "create index ss_sip_user on sip_subscriptions (sip_user)",
2578 "create index ss_sip_host on sip_subscriptions (sip_host)",
2579 "create index ss_presence_hosts on sip_subscriptions (presence_hosts)",
2580 "create index ss_event on sip_subscriptions (event)",
2581 "create index ss_proto on sip_subscriptions (proto)",
2582 "create index ss_sub_to_user on sip_subscriptions (sub_to_user)",
2583 "create index ss_sub_to_host on sip_subscriptions (sub_to_host)",
2584 "create index ss_expires on sip_subscriptions (expires)",
2585 "create index ss_orig_proto on sip_subscriptions (orig_proto)",
2586 "create index ss_network_port on sip_subscriptions (network_port)",
2587 "create index ss_profile_name on sip_subscriptions (profile_name)",
2588 "create index ss_version on sip_subscriptions (version)",
2589 "create index ss_full_from on sip_subscriptions (full_from)",
2590 "create index ss_contact on sip_subscriptions (contact)",
2591 "create index sd_uuid on sip_dialogs (uuid)",
2592 "create index sd_hostname on sip_dialogs (hostname)",
2593 "create index sd_presence_data on sip_dialogs (presence_data)",
2594 "create index sd_call_info on sip_dialogs (call_info)",
2595 "create index sd_call_info_state on sip_dialogs (call_info_state)",
2596 "create index sd_expires on sip_dialogs (expires)",
2597 "create index sd_rcd on sip_dialogs (rcd)",
2598 "create index sd_sip_to_tag on sip_dialogs (sip_to_tag)",
2599 "create index sd_sip_from_user on sip_dialogs (sip_from_user)",
2600 "create index sd_sip_from_host on sip_dialogs (sip_from_host)",
2601 "create index sd_sip_to_host on sip_dialogs (sip_to_host)",
2602 "create index sd_presence_id on sip_dialogs (presence_id)",
2603 "create index sd_call_id on sip_dialogs (call_id)",
2604 "create index sd_sip_from_tag on sip_dialogs (sip_from_tag)",
2605 "create index sp_hostname on sip_presence (hostname)",
2606 "create index sp_open_closed on sip_presence (open_closed)",
2607 "create index sp_sip_user on sip_presence (sip_user)",
2608 "create index sp_sip_host on sip_presence (sip_host)",
2609 "create index sp_profile_name on sip_presence (profile_name)",
2610 "create index sp_expires on sip_presence (expires)",
2611 "create index sa_nonce on sip_authentication (nonce)",
2612 "create index sa_hostname on sip_authentication (hostname)",
2613 "create index sa_expires on sip_authentication (expires)",
2614 "create index sa_last_nc on sip_authentication (last_nc)",
2615 "create index ssa_hostname on sip_shared_appearance_subscriptions (hostname)",
2616 "create index ssa_network_ip on sip_shared_appearance_subscriptions (network_ip)",
2617 "create index ssa_subscriber on sip_shared_appearance_subscriptions (subscriber)",
2618 "create index ssa_profile_name on sip_shared_appearance_subscriptions (profile_name)",
2619 "create index ssa_aor on sip_shared_appearance_subscriptions (aor)",
2620 "create index ssd_profile_name on sip_shared_appearance_dialogs (profile_name)",
2621 "create index ssd_hostname on sip_shared_appearance_dialogs (hostname)",
2622 "create index ssd_contact_str on sip_shared_appearance_dialogs (contact_str)",
2623 "create index ssd_call_id on sip_shared_appearance_dialogs (call_id)",
2624 "create index ssd_expires on sip_shared_appearance_dialogs (expires)",
2625 NULL((void*)0)
2626 };
2627
2628 switch_cache_db_handle_t *dbh = sofia_glue_get_db_handle(profile)_sofia_glue_get_db_handle(profile, "sofia_glue.c", (const char
*)__func__, 2628)
;
2629 char *test2;
2630 char *err;
2631
2632 if (!dbh) {
2633 return 0;
2634 }
2635
2636
2637 test_sql = switch_mprintf("delete from sip_registrations where sub_host is null "
2638 "and hostname='%q' "
2639 "and network_ip like '%%' and network_port like '%%' and sip_username "
2640 "like '%%' and mwi_user like '%%' and mwi_host like '%%' "
2641 "and orig_server_host like '%%' and orig_hostname like '%%'", mod_sofia_globals.hostname);
2642
2643
2644 switch_cache_db_test_reactive(dbh, test_sql, "drop table sip_registrations", reg_sql);
2645
2646 switch_cache_db_test_reactive(dbh, "select ping_count from sip_registrations", NULL((void*)0), "alter table sip_registrations add column ping_count INTEGER default 0");
2647 switch_cache_db_test_reactive(dbh, "select ping_status from sip_registrations", NULL((void*)0), "alter table sip_registrations add column ping_status VARCHAR(255) default 'Reachable'");
2648 switch_cache_db_test_reactive(dbh, "select ping_expires from sip_registrations", NULL((void*)0), "alter table sip_registrations add column ping_expires INTEGER not null default 0");
2649 switch_cache_db_test_reactive(dbh, "select ping_time from sip_registrations", NULL((void*)0), "alter table sip_registrations add column ping_time BIGINT not null default 0");
2650 switch_cache_db_test_reactive(dbh, "select force_ping from sip_registrations", NULL((void*)0), "alter table sip_registrations add column force_ping INTEGER not null default 0");
2651
2652 test2 = switch_mprintf("%s;%s", test_sql, test_sql);
2653
2654 if (switch_cache_db_execute_sql(dbh, test2, &err) != SWITCH_STATUS_SUCCESS) {
2655
2656 if (switch_stristr("read-only", err)) {
2657 free(err);
2658 } else {
2659 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2659, ((void*)0)
, SWITCH_LOG_CRIT, "GREAT SCOTT!!! Cannot execute batched statements! [%s]\n"
2660 "If you are using mysql, make sure you are using MYODBC 3.51.18 or higher and enable FLAG_MULTI_STATEMENTS\n", err);
2661
2662 switch_cache_db_release_db_handle(&dbh);
2663 free(test2);
2664 free(test_sql);
2665 free(err);
2666 return 0;
2667 }
2668 }
2669
2670 free(test2);
2671
2672
2673 free(test_sql);
2674
2675 test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and full_to='XXX'", mod_sofia_globals.hostname);
2676
2677 switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_subscriptions", sub_sql);
2678
2679 free(test_sql);
2680 test_sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and (expires <> -9999 or rpid='' or sip_from_tag='' or rcd > 0)",
2681 mod_sofia_globals.hostname);
2682
2683
2684 switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_dialogs", dialog_sql);
2685
2686 free(test_sql);
2687 test_sql = switch_mprintf("delete from sip_presence where hostname='%q' or open_closed=''", mod_sofia_globals.hostname);
2688
2689 switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_presence", pres_sql);
2690
2691 free(test_sql);
2692 test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' or last_nc >= 0", mod_sofia_globals.hostname);
2693
2694 switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_authentication", auth_sql);
2695
2696 free(test_sql);
2697 test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str='' or hostname='%q' and network_ip like '%%'",
2698 mod_sofia_globals.hostname);
2699
2700 switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_shared_appearance_subscriptions", shared_appearance_sql);
2701
2702 free(test_sql);
2703 test_sql = switch_mprintf("delete from sip_shared_appearance_dialogs where contact_str='' or hostname='%q' and network_ip like '%%'",
2704 mod_sofia_globals.hostname);
2705
2706 switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_shared_appearance_dialogs", shared_appearance_dialogs_sql);
2707
2708 free(test_sql);
2709
2710 for (x = 0; indexes[x]; x++) {
2711 switch_cache_db_create_schema(dbh, indexes[x], NULL((void*)0));
2712 }
2713
2714 switch_cache_db_release_db_handle(&dbh);
2715
2716 return 1;
2717
2718}
2719
2720void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic)
2721{
2722 char *sql;
2723
2724 switch_assert(sqlp && *sqlp)((sqlp && *sqlp) ? (void) (0) : __assert_fail ("sqlp && *sqlp"
, "sofia_glue.c", 2724, __extension__ __PRETTY_FUNCTION__))
;
2725 sql = *sqlp;
2726
2727 switch_sql_queue_manager_push(profile->qm, sql, 1, !sql_already_dynamic);
2728
2729 if (sql_already_dynamic) {
2730 *sqlp = NULL((void*)0);
2731 }
2732}
2733
2734
2735void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic)
2736{
2737 char *sql;
2738
2739 switch_assert(sqlp && *sqlp)((sqlp && *sqlp) ? (void) (0) : __assert_fail ("sqlp && *sqlp"
, "sofia_glue.c", 2739, __extension__ __PRETTY_FUNCTION__))
;
2740 sql = *sqlp;
2741
2742 switch_mutex_lock(profile->dbh_mutex);
2743 switch_sql_queue_manager_push_confirm(profile->qm, sql, 0, !sql_already_dynamic);
2744 switch_mutex_unlock(profile->dbh_mutex);
2745
2746 if (sql_already_dynamic) {
2747 *sqlp = NULL((void*)0);
2748 }
2749}
2750
2751void sofia_glue_execute_sql_soon(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic)
2752{
2753 char *sql;
2754
2755 switch_assert(sqlp && *sqlp)((sqlp && *sqlp) ? (void) (0) : __assert_fail ("sqlp && *sqlp"
, "sofia_glue.c", 2755, __extension__ __PRETTY_FUNCTION__))
;
2756 sql = *sqlp;
2757
2758 switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic);
2759
2760 if (sql_already_dynamic) {
2761 *sqlp = NULL((void*)0);
2762 }
2763}
2764
2765
2766switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line)
2767{
2768 switch_cache_db_handle_t *dbh = NULL((void*)0);
2769 char *dsn;
2770
2771 if (!zstr(profile->odbc_dsn)_zstr(profile->odbc_dsn)) {
2772 dsn = profile->odbc_dsn;
2773 } else {
2774 dsn = profile->dbname;
2775 }
2776
2777 if (_switch_cache_db_get_db_handle_dsn(&dbh, dsn, file, func, line) != SWITCH_STATUS_SUCCESS) {
2778 dbh = NULL((void*)0);
2779 }
2780
2781 return dbh;
2782}
2783
2784void sofia_glue_actually_execute_sql_trans(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex)
2785{
2786 switch_cache_db_handle_t *dbh = NULL((void*)0);
2787
2788 if (mutex) {
2789 switch_mutex_lock(mutex);
2790 }
2791
2792
2793 if (!(dbh = sofia_glue_get_db_handle(profile)_sofia_glue_get_db_handle(profile, "sofia_glue.c", (const char
*)__func__, 2793)
)) {
2794 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2794, ((void*)0)
, SWITCH_LOG_ERROR, "Error Opening DB\n");
2795
2796 goto end;
2797 }
2798
2799 switch_cache_db_persistant_execute_trans_full(dbh, sql, 1,
2800 profile->pre_trans_execute,
2801 profile->post_trans_execute,
2802 profile->inner_pre_trans_execute,
2803 profile->inner_post_trans_execute
2804 );
2805
2806 switch_cache_db_release_db_handle(&dbh);
2807
2808 end:
2809
2810 if (mutex) {
2811 switch_mutex_unlock(mutex);
2812 }
2813}
2814
2815void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex)
2816{
2817 switch_cache_db_handle_t *dbh = NULL((void*)0);
2818 char *err = NULL((void*)0);
2819
2820 if (mutex) {
2821 switch_mutex_lock(mutex);
2822 }
2823
2824 if (!(dbh = sofia_glue_get_db_handle(profile)_sofia_glue_get_db_handle(profile, "sofia_glue.c", (const char
*)__func__, 2824)
)) {
2825 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2825, ((void*)0)
, SWITCH_LOG_ERROR, "Error Opening DB\n");
2826
2827 if (mutex) {
2828 switch_mutex_unlock(mutex);
2829 }
2830
2831 return;
2832 }
2833
2834 switch_cache_db_execute_sql(dbh, sql, &err);
2835
2836 if (mutex) {
2837 switch_mutex_unlock(mutex);
2838 }
2839
2840 if (err) {
2841 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2841, ((void*)0)
, SWITCH_LOG_ERROR, "SQL ERR: [%s]\n%s\n", err, sql);
2842 free(err);
2843 }
2844
2845 switch_cache_db_release_db_handle(&dbh);
2846}
2847
2848switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
2849 switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata)
2850{
2851 switch_bool_t ret = SWITCH_FALSE;
2852 char *errmsg = NULL((void*)0);
2853 switch_cache_db_handle_t *dbh = NULL((void*)0);
2854
2855 if (mutex) {
2856 switch_mutex_lock(mutex);
2857 }
2858
2859 if (!(dbh = sofia_glue_get_db_handle(profile)_sofia_glue_get_db_handle(profile, "sofia_glue.c", (const char
*)__func__, 2859)
)) {
2860 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2860, ((void*)0)
, SWITCH_LOG_ERROR, "Error Opening DB\n");
2861
2862 if (mutex) {
2863 switch_mutex_unlock(mutex);
2864 }
2865
2866 return ret;
2867 }
2868
2869 switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, &errmsg);
2870
2871 if (mutex) {
2872 switch_mutex_unlock(mutex);
2873 }
2874
2875 if (errmsg) {
2876 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2876, ((void*)0)
, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg);
2877 free(errmsg);
2878 }
2879
2880 switch_cache_db_release_db_handle(&dbh);
2881
2882 return ret;
2883}
2884
2885char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len)
2886{
2887 char *ret = NULL((void*)0);
2888 char *err = NULL((void*)0);
2889 switch_cache_db_handle_t *dbh = NULL((void*)0);
2890
2891 if (mutex) {
2892 switch_mutex_lock(mutex);
2893 }
2894
2895 if (!(dbh = sofia_glue_get_db_handle(profile)_sofia_glue_get_db_handle(profile, "sofia_glue.c", (const char
*)__func__, 2895)
)) {
2896 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2896, ((void*)0)
, SWITCH_LOG_ERROR, "Error Opening DB\n");
2897
2898 if (mutex) {
2899 switch_mutex_unlock(mutex);
2900 }
2901
2902 return NULL((void*)0);
2903 }
2904
2905 ret = switch_cache_db_execute_sql2str(dbh, sql, resbuf, len, &err);
2906
2907 if (mutex) {
2908 switch_mutex_unlock(mutex);
2909 }
2910
2911 if (err) {
2912 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 2912, ((void*)0)
, SWITCH_LOG_ERROR, "SQL ERR: [%s]\n%s\n", err, sql);
2913 free(err);
2914 }
2915
2916 switch_cache_db_release_db_handle(&dbh);
2917
2918 return ret;
2919}
2920
2921char *sofia_glue_get_register_host(const char *uri)
2922{
2923 char *register_host = NULL((void*)0);
2924 const char *s;
2925 char *p = NULL((void*)0);
2926
2927 if (zstr(uri)_zstr(uri)) {
2928 return NULL((void*)0);
2929 }
2930
2931 if ((s = switch_stristr("sip:", uri))) {
2932 s += 4;
2933 } else if ((s = switch_stristr("sips:", uri))) {
2934 s += 5;
2935 }
2936
2937 if (!s) {
2938 return NULL((void*)0);
2939 }
2940
2941 register_host = strdup(s);
2942
2943 switch_assert(register_host)((register_host) ? (void) (0) : __assert_fail ("register_host"
, "sofia_glue.c", 2943, __extension__ __PRETTY_FUNCTION__))
;
2944
2945 /* remove port for register_host for testing nat acl take into account
2946 ipv6 addresses which are required to have brackets around the addr
2947 */
2948
2949 if ((p = strchr(register_host, ']'))) {
2950 if (*(p + 1) == ':') {
2951 *(p + 1) = '\0';
2952 }
2953 } else {
2954 if ((p = strrchr(register_host, ':'))) {
2955 *p = '\0';
2956 }
2957 }
2958
2959 /* register_proxy should always start with "sip:" or "sips:" */
2960 assert(register_host)((register_host) ? (void) (0) : __assert_fail ("register_host"
, "sofia_glue.c", 2960, __extension__ __PRETTY_FUNCTION__))
;
2961
2962 return register_host;
2963}
2964
2965const char *sofia_glue_strip_proto(const char *uri)
2966{
2967 char *p;
2968
2969 if ((p = strchr(uri, ':'))) {
2970 return p + 1;
2971 }
2972
2973 return uri;
2974}
2975
2976sofia_cid_type_t sofia_cid_name2type(const char *name)
2977{
2978 if (!strcasecmp(name, "rpid")) {
2979 return CID_TYPE_RPID;
2980 }
2981
2982 if (!strcasecmp(name, "pid")) {
2983 return CID_TYPE_PID;
2984 }
2985
2986 return CID_TYPE_NONE;
2987
2988}
2989
2990/* all the values of the structure are initialized to NULL */
2991/* in case of failure the function returns NULL */
2992/* sofia_destination->route can be NULL */
2993sofia_destination_t *sofia_glue_get_destination(char *data)
2994{
2995 sofia_destination_t *dst = NULL((void*)0);
2996 char *to = NULL((void*)0);
2997 char *contact = NULL((void*)0);
2998 char *route = NULL((void*)0);
2999 char *route_uri = NULL((void*)0);
3000 char *eoc = NULL((void*)0);
3001 char *p = NULL((void*)0);
3002
3003 if (zstr(data)_zstr(data)) {
3004 return NULL((void*)0);
3005 }
3006
3007 if (!(dst = (sofia_destination_t *) malloc(sizeof(sofia_destination_t)))) {
3008 return NULL((void*)0);
3009 }
3010
3011 /* return a copy of what is in the buffer between the first < and > */
3012 if (!(contact = sofia_glue_get_url_from_contact(data, 1))) {
3013 goto mem_fail;
3014 }
3015
3016 if ((eoc = strstr(contact, ";fs_path="))) {
3017 *eoc = '\0';
3018
3019 if (!(route = strdup(eoc + 9))) {
3020 goto mem_fail;
3021 }
3022
3023 for (p = route; p && *p; p++) {
3024 if (*p == '>' || *p == ';') {
3025 *p = '\0';
3026 break;
3027 }
3028 }
3029
3030 switch_url_decode(route);
3031
3032 if (!(route_uri = strdup(route))) {
3033 goto mem_fail;
3034 }
3035 if ((p = strchr(route_uri, ','))) {
3036 do {
3037 *p = '\0';
3038 } while ((--p > route_uri) && *p == ' ');
3039 }
3040 }
3041
3042 if (!(to = strdup(data))) {
3043 goto mem_fail;
3044 }
3045
3046 if ((eoc = strstr(to, ";fs_path="))) {
3047 *eoc++ = '>';
3048 *eoc = '\0';
3049 }
3050
3051 if ((p = strstr(contact, ";fs_"))) {
3052 *p = '\0';
3053 }
3054
3055 dst->contact = contact;
3056 dst->to = to;
3057 dst->route = route;
3058 dst->route_uri = route_uri;
3059 return dst;
3060
3061 mem_fail:
3062 switch_safe_free(contact)if (contact) {free(contact);contact=((void*)0);};
3063 switch_safe_free(to)if (to) {free(to);to=((void*)0);};
3064 switch_safe_free(route)if (route) {free(route);route=((void*)0);};
3065 switch_safe_free(route_uri)if (route_uri) {free(route_uri);route_uri=((void*)0);};
3066 switch_safe_free(dst)if (dst) {free(dst);dst=((void*)0);};
3067 return NULL((void*)0);
3068}
3069
3070void sofia_glue_free_destination(sofia_destination_t *dst)
3071{
3072 if (dst) {
3073 switch_safe_free(dst->contact)if (dst->contact) {free(dst->contact);dst->contact=(
(void*)0);}
;
3074 switch_safe_free(dst->route)if (dst->route) {free(dst->route);dst->route=((void*
)0);}
;
3075 switch_safe_free(dst->route_uri)if (dst->route_uri) {free(dst->route_uri);dst->route_uri
=((void*)0);}
;
3076 switch_safe_free(dst->to)if (dst->to) {free(dst->to);dst->to=((void*)0);};
3077 switch_safe_free(dst)if (dst) {free(dst);dst=((void*)0);};
3078 }
3079}
3080
3081switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *user, const char *host, const char *event, const char *contenttype,
3082 const char *body, const char *o_contact, const char *network_ip, const char *call_id)
3083{
3084 char *id = NULL((void*)0);
3085 nua_handle_t *nh;
3086 sofia_destination_t *dst = NULL((void*)0);
3087 char *contact_str, *contact, *user_via = NULL((void*)0);
3088 char *route_uri = NULL((void*)0), *p;
3089 char *ptr;
3090
3091 contact = sofia_glue_get_url_from_contact((char *) o_contact, 1);
3092
3093 if ((p = strstr(contact, ";fs_"))) {
3094 *p = '\0';
3095 }
3096
3097 if (!zstr(network_ip)_zstr(network_ip) && sofia_glue_check_nat(profile, network_ip)) {
3098 id = switch_mprintf("sip:%s@%s", user, profile->extsipip);
3099 switch_assert(id)((id) ? (void) (0) : __assert_fail ("id", "sofia_glue.c", 3099
, __extension__ __PRETTY_FUNCTION__))
;
3100
3101 if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) {
3102 sofia_transport_t transport = sofia_glue_str2transport( ptr + 10 );
3103
3104 switch (transport) {
3105 case SOFIA_TRANSPORT_TCP:
3106 contact_str = profile->tcp_public_contact;
3107 break;
3108 case SOFIA_TRANSPORT_TCP_TLS:
3109 contact_str = sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) ?
3110 profile->tls_public_contact : profile->tcp_public_contact;
3111 break;
3112 default:
3113 contact_str = profile->public_url;
3114 break;
3115 }
3116 user_via = sofia_glue_create_external_via(NULL((void*)0), profile, transport);
3117 } else {
3118 user_via = sofia_glue_create_external_via(NULL((void*)0), profile, SOFIA_TRANSPORT_UDP);
3119 contact_str = profile->public_url;
3120 }
3121 } else {
3122 id = switch_mprintf("sip:%s@%s", user, host);
3123 switch_assert(id)((id) ? (void) (0) : __assert_fail ("id", "sofia_glue.c", 3123
, __extension__ __PRETTY_FUNCTION__))
;
3124
3125 if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) {
3126 sofia_transport_t transport = sofia_glue_str2transport( ptr + 10 );
3127
3128 switch (transport) {
3129 case SOFIA_TRANSPORT_TCP:
3130 contact_str = profile->tcp_contact;
3131 break;
3132 case SOFIA_TRANSPORT_TCP_TLS:
3133 contact_str = sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) ?
3134 profile->tls_contact : profile->tcp_contact;
3135 break;
3136 default:
3137 contact_str = profile->url;
3138 break;
3139 }
3140 } else {
3141 contact_str = profile->url;
3142 }
3143 }
3144
3145 dst = sofia_glue_get_destination((char *) o_contact);
3146 switch_assert(dst)((dst) ? (void) (0) : __assert_fail ("dst", "sofia_glue.c", 3146
, __extension__ __PRETTY_FUNCTION__))
;
3147
3148 if (dst->route_uri) {
3149 route_uri = sofia_glue_strip_uri(dst->route_uri);
3150 }
3151
3152 nh = nua_handle(profile->nua, NULL((void*)0), NUTAG_URL(contact)nutag_url, urltag_url_v(contact), SIPTAG_FROM_STR(id)siptag_from_str, tag_str_v(id), SIPTAG_TO_STR(id)siptag_to_str, tag_str_v(id), SIPTAG_CONTACT_STR(contact_str)siptag_contact_str, tag_str_v(contact_str), TAG_END()(tag_type_t)0, (tag_value_t)0);
3153 nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
3154
3155 nua_notify(nh,
3156 NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1),
3157 TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri))!(dst->route_uri) ? tag_skip : ntatag_default_proxy, urltag_url_v
((route_uri))
, TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route))!(dst->route) ? tag_skip : siptag_route_str, tag_str_v(dst
->route)
,
3158 TAG_IF(user_via, SIPTAG_VIA_STR(user_via))!(user_via) ? tag_skip : siptag_via_str, tag_str_v(user_via),
3159 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
3160 TAG_IF(event, SIPTAG_EVENT_STR(event))!(event) ? tag_skip : siptag_event_str, tag_str_v(event),
3161 TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id))!(call_id) ? tag_skip : siptag_call_id_str, tag_str_v(call_id
)
,
3162 TAG_IF(contenttype, SIPTAG_CONTENT_TYPE_STR(contenttype))!(contenttype) ? tag_skip : siptag_content_type_str, tag_str_v
(contenttype)
, TAG_IF(body, SIPTAG_PAYLOAD_STR(body))!(body) ? tag_skip : siptag_payload_str, tag_str_v(body), TAG_END()(tag_type_t)0, (tag_value_t)0);
3163
3164 switch_safe_free(contact)if (contact) {free(contact);contact=((void*)0);};
3165 switch_safe_free(route_uri)if (route_uri) {free(route_uri);route_uri=((void*)0);};
3166 switch_safe_free(id)if (id) {free(id);id=((void*)0);};
3167 sofia_glue_free_destination(dst);
3168 switch_safe_free(user_via)if (user_via) {free(user_via);user_via=((void*)0);};
3169
3170 return SWITCH_STATUS_SUCCESS;
3171}
3172
3173
3174int sofia_glue_tech_simplify(private_object_t *tech_pvt)
3175{
3176 const char *uuid, *network_addr_a = NULL((void*)0), *network_addr_b = NULL((void*)0), *simplify, *simplify_other_channel;
3177 switch_channel_t *other_channel = NULL((void*)0), *inbound_channel = NULL((void*)0);
3178 switch_core_session_t *other_session = NULL((void*)0), *inbound_session = NULL((void*)0);
3179 uint8_t did_simplify = 0;
3180 int r = 0;
3181
3182 if (!switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED) || switch_channel_test_flag(tech_pvt->channel, CF_SIMPLIFY)) {
3183 goto end;
3184 }
3185
3186 if (switch_channel_test_flag(tech_pvt->channel, CF_BRIDGED) &&
3187 (uuid = switch_channel_get_partner_uuid(tech_pvt->channel)) && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia_glue.c", (const
char *)__func__, 3187)
)) {
3188
3189 other_channel = switch_core_session_get_channel(other_session);
3190
3191 if (switch_channel_test_flag(other_channel, CF_ANSWERED)) { /* Check if the other channel is answered */
3192 simplify = switch_channel_get_variable(tech_pvt->channel, "sip_auto_simplify")switch_channel_get_variable_dup(tech_pvt->channel, "sip_auto_simplify"
, SWITCH_TRUE, -1)
;
3193 simplify_other_channel = switch_channel_get_variable(other_channel, "sip_auto_simplify")switch_channel_get_variable_dup(other_channel, "sip_auto_simplify"
, SWITCH_TRUE, -1)
;
3194
3195 r = 1;
3196
3197 if (switch_true(simplify) && !switch_channel_test_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR)) {
3198 network_addr_a = switch_channel_get_variable(tech_pvt->channel, "network_addr")switch_channel_get_variable_dup(tech_pvt->channel, "network_addr"
, SWITCH_TRUE, -1)
;
3199 network_addr_b = switch_channel_get_variable(other_channel, "network_addr")switch_channel_get_variable_dup(other_channel, "network_addr"
, SWITCH_TRUE, -1)
;
3200 inbound_session = other_session;
3201 inbound_channel = other_channel;
3202 } else if (switch_true(simplify_other_channel) && !switch_channel_test_flag(other_channel, CF_BRIDGE_ORIGINATOR)) {
3203 network_addr_a = switch_channel_get_variable(other_channel, "network_addr")switch_channel_get_variable_dup(other_channel, "network_addr"
, SWITCH_TRUE, -1)
;
3204 network_addr_b = switch_channel_get_variable(tech_pvt->channel, "network_addr")switch_channel_get_variable_dup(tech_pvt->channel, "network_addr"
, SWITCH_TRUE, -1)
;
3205 inbound_session = tech_pvt->session;
3206 inbound_channel = tech_pvt->channel;
3207 }
3208
3209 if (inbound_channel && inbound_session && !zstr(network_addr_a)_zstr(network_addr_a) && !zstr(network_addr_b)_zstr(network_addr_b) && !strcmp(network_addr_a, network_addr_b)) {
3210 if (strcmp(network_addr_a, switch_str_nil(tech_pvt->profile->sipip)(tech_pvt->profile->sipip ? tech_pvt->profile->sipip
: "")
)
3211 && strcmp(network_addr_a, switch_str_nil(tech_pvt->profile->extsipip)(tech_pvt->profile->extsipip ? tech_pvt->profile->
extsipip : "")
)) {
3212
3213 switch_core_session_message_t *msg;
3214
3215 switch_log_printf(SWITCH_CHANNEL_ID_LOG, __FILE__"sofia_glue.c", __SWITCH_FUNC__(const char *)__func__, __LINE__3215, switch_channel_get_uuid(inbound_channel),
3216 SWITCH_LOG_NOTICE, "Will simplify channel [%s]\n", switch_channel_get_name(inbound_channel));
3217
3218 msg = switch_core_session_alloc(inbound_session, sizeof(*msg))switch_core_perform_session_alloc(inbound_session, sizeof(*msg
), "sofia_glue.c", (const char *)__func__, 3218)
;
3219 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia_glue.c"; msg->_func = (const char *
)__func__; msg->_line = 3219
;
3220 msg->message_id = SWITCH_MESSAGE_INDICATE_SIMPLIFY;
3221 msg->from = __FILE__"sofia_glue.c";
3222 switch_core_session_receive_message(inbound_session, msg)switch_core_session_perform_receive_message(inbound_session, msg
, "sofia_glue.c", (const char *)__func__, 3222)
;
3223
3224 did_simplify = 1;
3225
3226 switch_core_recovery_track(inbound_session);
3227
3228 switch_channel_set_flag(inbound_channel, CF_SIMPLIFY)switch_channel_set_flag_value(inbound_channel, CF_SIMPLIFY, 1
)
;
3229
3230 }
3231 }
3232
3233 if (!did_simplify && inbound_channel) {
3234 switch_log_printf(SWITCH_CHANNEL_ID_LOG, __FILE__"sofia_glue.c", __SWITCH_FUNC__(const char *)__func__, __LINE__3234, switch_channel_get_uuid(inbound_channel), SWITCH_LOG_NOTICE,
3235 "Could not simplify channel [%s]\n", switch_channel_get_name(inbound_channel));
3236 }
3237 }
3238
3239 switch_core_session_rwunlock(other_session);
3240 }
3241
3242
3243 end:
3244
3245 return r;
3246}
3247
3248void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on)
3249{
3250 switch_core_session_message_t *msg;
3251 msg = switch_core_session_alloc(session, sizeof(*msg))switch_core_perform_session_alloc(session, sizeof(*msg), "sofia_glue.c"
, (const char *)__func__, 3251)
;
3252 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia_glue.c"; msg->_func = (const char *
)__func__; msg->_line = 3252
;
3253 msg->message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER;
3254 msg->string_arg = switch_core_session_strdup(session, on ? "pause" : "resume")switch_core_perform_session_strdup(session, on ? "pause" : "resume"
, "sofia_glue.c", (const char *)__func__, 3254)
;
3255 msg->from = __FILE__"sofia_glue.c";
3256
3257 switch_core_session_queue_message(session, msg);
3258}
3259
3260
3261void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl)
3262{
3263 switch_core_session_message_t *msg;
3264 msg = switch_core_session_alloc(session, sizeof(*msg))switch_core_perform_session_alloc(session, sizeof(*msg), "sofia_glue.c"
, (const char *)__func__, 3264)
;
3265 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia_glue.c"; msg->_func = (const char *
)__func__; msg->_line = 3265
;
3266 msg->message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
3267 if (pl) {
3268 msg->string_arg = switch_core_session_strdup(session, pl)switch_core_perform_session_strdup(session, pl, "sofia_glue.c"
, (const char *)__func__, 3268)
;
3269 }
3270 msg->from = __FILE__"sofia_glue.c";
3271
3272 switch_core_session_queue_message(session, msg);
3273}
3274
3275
3276char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np)
3277{
3278 char *contact_str = NULL((void*)0);
3279 const char *contact_host;//, *contact_user;
3280 sip_contact_t const *contact;
3281 char *port;
3282 const char *display = "\"user\"";
3283 char new_port[25] = "";
3284 sofia_nat_parse_t lnp = { { 0 } };
3285 const char *ipv6;
3286 sip_from_t const *from;
3287
3288 if (!sip || !sip->sip_contact) {
3289 return NULL((void*)0);
3290 }
3291
3292 from = sip->sip_from;
3293 contact = sip->sip_contact;
3294
3295 if (!np) {
3296 np = &lnp;
3297 }
3298
3299 sofia_glue_get_addr(de->data->e_msg, np->network_ip, sizeof(np->network_ip), &np->network_port);
3300
3301 if (sofia_glue_check_nat(profile, np->network_ip)) {
3302 np->is_auto_nat = 1;
3303 }
3304
3305 port = (char *) contact->m_url->url_port;
3306 contact_host = sip->sip_contact->m_url->url_host;
3307 //contact_user = sip->sip_contact->m_url->url_user;
3308
3309 display = contact->m_display;
3310
3311
3312 if (zstr(display)_zstr(display)) {
3313 if (from) {
3314 display = from->a_display;
3315 if (zstr(display)_zstr(display)) {
3316 display = "\"user\"";
3317 }
3318 }
3319 } else {
3320 display = "\"user\"";
3321 }
3322
3323 if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)((profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] ? 1 : 0
)
) {
3324 if (sip->sip_via) {
3325 const char *v_port = sip->sip_via->v_port;
3326 const char *v_host = sip->sip_via->v_host;
3327
3328 if (v_host && sip->sip_via->v_received) {
3329 np->is_nat = "via received";
3330 } else if (v_host && strcmp(np->network_ip, v_host)) {
3331 np->is_nat = "via host";
3332 } else if (v_port && atoi(v_port) != np->network_port) {
3333 np->is_nat = "via port";
3334 }
3335 }
3336 }
3337
3338 if (!np->is_nat && sip->sip_via && sip->sip_via->v_port &&
3339 atoi(sip->sip_via->v_port) == 5060 && np->network_port != 5060 ) {
3340 np->is_nat = "via port";
3341 }
3342
3343 if (!np->is_nat && profile->nat_acl_count) {
3344 uint32_t x = 0;
3345 int ok = 1;
3346 char *last_acl = NULL((void*)0);
3347
3348 if (!zstr(contact_host)_zstr(contact_host)) {
3349 for (x = 0; x < profile->nat_acl_count; x++) {
3350 last_acl = profile->nat_acl[x];
3351 if (!(ok = switch_check_network_list_ip(contact_host, last_acl)switch_check_network_list_ip_token(contact_host, last_acl, ((
void*)0))
)) {
3352 break;
3353 }
3354 }
3355
3356 if (ok) {
3357 np->is_nat = last_acl;
3358 }
3359 }
3360 }
3361
3362 if (np->is_nat && profile->local_network && switch_check_network_list_ip(np->network_ip, profile->local_network)switch_check_network_list_ip_token(np->network_ip, profile
->local_network, ((void*)0))
) {
3363 if (profile->debug) {
3364 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_glue.c", (const char *)__func__
, 3364, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s is on local network, not seting NAT mode.\n", np->network_ip);
3365 }
3366 np->is_nat = NULL((void*)0);
3367 }
3368
3369 if (sip->sip_record_route) {
3370 char *full_contact = sip_header_as_string(nua_handle_get_home(nh), (void *) contact);
3371 char *route = sofia_glue_strip_uri(sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_record_route));
3372 char *full_contact_dup;
3373 char *route_encoded;
3374 int route_encoded_len;
3375 full_contact_dup = sofia_glue_get_url_from_contact(full_contact, 1);
3376 route_encoded_len = (int)(strlen(route) * 3) + 1;
3377 switch_zmalloc(route_encoded, route_encoded_len)(void)((((route_encoded = switch_calloc(1, (route_encoded_len
)))) ? (void) (0) : __assert_fail ("(route_encoded = switch_calloc(1, (route_encoded_len)))"
, "sofia_glue.c", 3377, __extension__ __PRETTY_FUNCTION__)),route_encoded
)
;
3378 switch_url_encode(route, route_encoded, route_encoded_len);
3379 contact_str = switch_mprintf("%s <%s;fs_path=%s>", display, full_contact_dup, route_encoded);
3380 free(route);
3381 free(full_contact_dup);
3382 free(route_encoded);
3383 }
3384 else if (np->is_nat && np->fs_path) {
3385 char *full_contact = sip_header_as_string(nua_handle_get_home(nh), (void *) contact);
3386 char *full_contact_dup;
3387 char *path_encoded;
3388 int path_encoded_len;
3389 char *path_val;
3390 const char *tp;
3391
3392 full_contact_dup = sofia_glue_get_url_from_contact(full_contact, 1);
3393
3394 if ((tp = switch_stristr("transport=", full_contact_dup))) {
3395 tp += 10;
3396 }
3397
3398 if (zstr(tp)_zstr(tp)) {
3399 tp = "udp";
3400 }
3401
3402 path_val = switch_mprintf("sip:%s:%d;transport=%s", np->network_ip, np->network_port, tp);
3403 path_encoded_len = (int)(strlen(path_val) * 3) + 1;
3404
3405 switch_zmalloc(path_encoded, path_encoded_len)(void)((((path_encoded = switch_calloc(1, (path_encoded_len))
)) ? (void) (0) : __assert_fail ("(path_encoded = switch_calloc(1, (path_encoded_len)))"
, "sofia_glue.c", 3405, __extension__ __PRETTY_FUNCTION__)),path_encoded
)
;
3406 switch_copy_string(path_encoded, ";fs_path=", 10);
3407 switch_url_encode(path_val, path_encoded + 9, path_encoded_len - 9);
3408
3409 contact_str = switch_mprintf("%s <%s;fs_nat=yes%s>", display, full_contact_dup, path_encoded);
3410
3411 free(full_contact_dup);
3412 free(path_encoded);
3413 free(path_val);
3414
3415 } else {
3416
3417 if (zstr(contact_host)_zstr(contact_host)) {
3418 np->is_nat = "No contact host";
3419 }
3420
3421 if (np->is_nat) {
3422 contact_host = np->network_ip;
3423 switch_snprintf(new_port, sizeof(new_port), ":%d", np->network_port);
3424 port = NULL((void*)0);
3425 }
3426
3427
3428 if (port) {
3429 switch_snprintf(new_port, sizeof(new_port), ":%s", port);
3430 }
3431
3432 ipv6 = strchr(contact_host, ':');
3433
3434
3435 if (contact->m_url->url_params) {
3436 contact_str = switch_mprintf("%s <sip:%s%s%s%s%s%s;%s>%s",
3437 display, contact->m_url->url_user,
3438 contact->m_url->url_user ? "@" : "",
3439 ipv6 ? "[" : "",
3440 contact_host, ipv6 ? "]" : "", new_port, contact->m_url->url_params, np->is_nat ? ";fs_nat=yes" : "");
3441 } else {
3442 contact_str = switch_mprintf("%s <sip:%s%s%s%s%s%s>%s",
3443 display,
3444 contact->m_url->url_user,
3445 contact->m_url->url_user ? "@" : "",
3446 ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, np->is_nat ? ";fs_nat=yes" : "");
3447 }
3448 }
3449
3450 return contact_str;
3451}
3452
3453char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool)
3454{
3455 char *s, *p;
3456
3457 if ((p = strchr(str, '@'))) {
62
Assuming 'p' is not null
63
Taking true branch
3458 p++;
3459 } else {
3460 return NULL((void*)0);
3461 }
3462
3463 if (pool) {
64
Assuming 'pool' is null
65
Taking false branch
3464 s = switch_core_strdup(pool, p)switch_core_perform_strdup(pool, p, "sofia_glue.c", (const char
*)__func__, 3464)
;
3465 } else {
3466 s = strdup(p);
66
Memory is allocated
3467 }
3468
3469 for (p = s; p && *p; p++) {
67
Assuming 'p' is non-null
68
Loop condition is false. Execution continues on line 3476
3470 if ((*p == ';') || (*p == '>')) {
3471 *p = '\0';
3472 break;
3473 }
3474 }
3475
3476 return s;
3477}
3478
3479void sofia_glue_fire_events(sofia_profile_t *profile)
3480{
3481 void *pop = NULL((void*)0);
3482
3483 while (profile->event_queue && switch_queue_trypop(profile->event_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
3484 switch_event_t *event = (switch_event_t *) pop;
3485 switch_event_fire(&event)switch_event_fire_detailed("sofia_glue.c", (const char * )(const
char *)__func__, 3485, &event, ((void*)0))
;
3486 }
3487
3488}
3489
3490void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event)
3491{
3492 switch_queue_push(profile->event_queue, *event);
3493 *event = NULL((void*)0);
3494}
3495
3496void sofia_glue_clear_soa(switch_core_session_t *session, switch_bool_t partner)
3497{
3498 switch_core_session_t *other_session;
3499 struct private_object *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
3500
3501 sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA)(tech_pvt)->flags[TFLAG_ENABLE_SOA] = 0;
3502
3503 if (partner && switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia_glue.c", (const char *)__func__, 3503)
== SWITCH_STATUS_SUCCESS) {
3504 if (switch_core_session_compare(session, other_session)) {
3505 struct private_object *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
3506
3507 sofia_clear_flag(other_tech_pvt, TFLAG_ENABLE_SOA)(other_tech_pvt)->flags[TFLAG_ENABLE_SOA] = 0;
3508 }
3509 switch_core_session_rwunlock(other_session);
3510 }
3511
3512}
3513
3514char *sofia_glue_get_profile_url(sofia_profile_t *profile, char *remote_ip, const sofia_transport_t transport)
3515{
3516 char *url = NULL((void*)0);
3517 int check_nat = 0;
3518
3519 if (!zstr(remote_ip)_zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) {
3520 check_nat = 1;
3521 }
3522
3523 if (sofia_glue_transport_has_tls(transport)) {
3524 if (check_nat && profile->tls_public_url) {
3525 url = profile->tls_public_url;
3526 } else {
3527 url = profile->tls_url;
3528 }
3529 } else {
3530 if (check_nat && profile->public_url) {
3531 url = profile->public_url;
3532 } else {
3533 url = profile->url;
3534 }
3535 }
3536
3537 if (!url) url = profile->url;
3538
3539 return url;
3540}
3541
3542/* gets the IP or HOST from a sip uri or from x.x.x.x:port format */
3543char *sofia_glue_get_host_from_cfg(const char *uri, switch_memory_pool_t *pool)
3544{
3545 char *host = NULL((void*)0);
3546 const char *s;
3547 char *p = NULL((void*)0);
3548
3549 if (zstr(uri)_zstr(uri)) {
3550 return NULL((void*)0);
3551 }
3552
3553 if ((s = switch_stristr("sip:", uri)) && s == uri) {
3554 s += 4;
3555 } else if ((s = switch_stristr("sips:", uri)) && s == uri) {
3556 s += 5;
3557 }
3558
3559 if (!s) {
3560 s = uri;
3561 }
3562
3563 host = switch_core_strdup(pool, s)switch_core_perform_strdup(pool, s, "sofia_glue.c", (const char
*)__func__, 3563)
;
3564
3565 if ((p = strchr(host, ']'))) {
3566 if (*(p + 1) == ':') {
3567 *(p + 1) = '\0';
3568 }
3569 } else {
3570 if ((p = strrchr(host, ':'))) {
3571 *p = '\0';
3572 }
3573 }
3574
3575 return host;
3576}
3577
3578/* For Emacs:
3579 * Local Variables:
3580 * mode:c
3581 * indent-tabs-mode:t
3582 * tab-width:4
3583 * c-basic-offset:4
3584 * End:
3585 * For VIM:
3586 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3587 */