Bug Summary

File:sofia/sofia.c
Warning:line 348, column 16
Potential leak of memory pointed to by 'p'

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.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-230655-401-1 -x c sofia.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 * Marcel Barbulescu <marcelbarbulescu@gmail.com>
31 * Norman Brandinger
32 * Raymond Chandler <intralanman@freeswitch.org>
33 * Nathan Patrick <npatrick at corp.sonic.net>
34 * Joseph Sullivan <jossulli@amazon.com>
35 * Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
36 * William King <william.king@quentustech.com>
37 * David Knell <david.knell@telng.com>
38 *
39 * sofia.c -- SOFIA SIP Endpoint (sofia code)
40 *
41 */
42#include "mod_sofia.h"
43#include <switch_ssl.h>
44
45extern su_log_t tport_log[];
46extern su_log_t iptsec_log[];
47extern su_log_t nea_log[];
48extern su_log_t nta_log[];
49extern su_log_t nth_client_log[];
50extern su_log_t nth_server_log[];
51extern su_log_t nua_log[];
52extern su_log_t soa_log[];
53extern su_log_t sresolv_log[];
54#ifdef HAVE_SOFIA_STUN
55extern su_log_t stun_log[];
56#endif
57extern su_log_t su_log_default[];
58
59static void config_sofia_profile_urls(sofia_profile_t * profile);
60static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag, const char *gwname);
61static void parse_domain_tag(sofia_profile_t *profile, switch_xml_t x_domain_tag, const char *dname, const char *parse, const char *alias);
62
63void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
64 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
65 sofia_dispatch_event_t *de,
66 tagi_t tags[]);
67
68static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params);
69
70
71
72static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
73 char const *phrase,
74 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
75 sofia_dispatch_event_t *de,
76 tagi_t tags[]);
77
78static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
79 char const *phrase,
80 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
81 sofia_dispatch_event_t *de,
82 tagi_t tags[]);
83static void sofia_handle_sip_r_options(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile,
84 nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
85 sofia_dispatch_event_t *de, tagi_t tags[]);
86
87static void sofia_set_accept_language_channel_variable(switch_channel_t *channel, sip_t const *sip)
88{
89 if (sip->sip_accept_language) {
90 sip_accept_language_t *sip_accept_language = NULL((void*)0);
91 int count = 0;
92
93 for(sip_accept_language = sip->sip_accept_language; sip_accept_language; sip_accept_language = sip_accept_language->aa_next) {
94 char var_name[64] = "";
95
96 if (zstr(sip_accept_language->aa_value)_zstr(sip_accept_language->aa_value)) {
97 continue;
98
99 }
100 if (count == 0) {
101 switch_channel_set_variable(channel, "sip_accept_language", sip_accept_language->aa_value)switch_channel_set_variable_var_check(channel, "sip_accept_language"
, sip_accept_language->aa_value, SWITCH_TRUE)
;
102 }
103
104 switch_snprintf(var_name, sizeof(var_name), "sip_accept_language_%d_value", count);
105 switch_channel_set_variable(channel, var_name, sip_accept_language->aa_value)switch_channel_set_variable_var_check(channel, var_name, sip_accept_language
->aa_value, SWITCH_TRUE)
;
106
107 if (!zstr(sip_accept_language->aa_q)_zstr(sip_accept_language->aa_q)) {
108 switch_snprintf(var_name, sizeof(var_name), "sip_accept_language_%d_q", count);
109 switch_channel_set_variable(channel, var_name, sip_accept_language->aa_q)switch_channel_set_variable_var_check(channel, var_name, sip_accept_language
->aa_q, SWITCH_TRUE)
;
110 }
111
112 count++;
113 }
114 switch_channel_set_variable_printf(channel, "sip_accept_language_count", "%d", count);
115 }
116}
117
118void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
119 char const *phrase,
120 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
121 sofia_dispatch_event_t *de, tagi_t tags[])
122{
123 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
124 switch_core_session_t *other_session;
125
126 if (tech_pvt->proxy_refer_uuid && (other_session = switch_core_session_locate(tech_pvt->proxy_refer_uuid)switch_core_session_perform_locate(tech_pvt->proxy_refer_uuid
, "sofia.c", (const char *)__func__, 126)
)) {
127 switch_core_session_message_t *msg;
128
129 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 129)
;
130 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
131 msg->from = __FILE__"sofia.c";
132 msg->numeric_arg = status;
133 msg->string_arg = switch_core_session_strdup(other_session, phrase)switch_core_perform_session_strdup(other_session, phrase, "sofia.c"
, (const char *)__func__, 133)
;
134 switch_core_session_queue_message(other_session, msg);
135 switch_core_session_rwunlock(other_session);
136 } else {
137 tech_pvt->proxy_refer_uuid = NULL((void*)0);
138 }
139
140
141 if (status == 481 && sip && !sip->sip_retry_after && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) {
142 char *sql;
143
144 sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", sip->sip_call_id->i_id);
145 switch_assert(sql != NULL)((sql != ((void*)0)) ? (void) (0) : __assert_fail ("sql != ((void*)0)"
, "sofia.c", 145, __extension__ __PRETTY_FUNCTION__))
;
146 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
147 nua_handle_destroy(nh);
148 }
149
150}
151
152#define url_set_chanvars(session, url, varprefix)_url_set_chanvars(session, url, "varprefix" "_user", "varprefix"
"_host", "varprefix" "_port", "varprefix" "_uri", "varprefix"
"_params")
_url_set_chanvars(session, url, #varprefix "_user", #varprefix "_host", #varprefix "_port", #varprefix "_uri", #varprefix "_params")
153
154static const char *_url_set_chanvars(switch_core_session_t *session, url_t *url, const char *user_var,
155 const char *host_var, const char *port_var, const char *uri_var, const char *params_var)
156{
157 const char *user = NULL((void*)0), *host = NULL((void*)0), *port = NULL((void*)0);
158 char *uri = NULL((void*)0);
159 switch_channel_t *channel = switch_core_session_get_channel(session);
160 char new_port[25] = "";
161
162 if (url) {
163 user = url->url_user;
164 host = url->url_host;
165 port = url->url_port;
166 if (!zstr(url->url_params)_zstr(url->url_params)) {
167 switch_channel_set_variable(channel, params_var, url->url_params)switch_channel_set_variable_var_check(channel, params_var, url
->url_params, SWITCH_TRUE)
;
168 }
169 }
170
171 if (zstr(user)_zstr(user)) {
172 user = "nobody";
173 }
174
175 if (zstr(host)_zstr(host)) {
176 host = "nowhere";
177 }
178
179 check_decode(user, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 179, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(user))
{ int d = 0; char *p; if (strchr(user, '%')) { char *tmp = switch_core_perform_session_strdup
(session, user, "sofia.c", (const char *)__func__, 179); switch_url_decode
(tmp); user = tmp; d++; } if ((p = strchr(user, '"'))) { if (
!d) { char *tmp = switch_core_perform_session_strdup(session,
user, "sofia.c", (const char *)__func__, 179); user = tmp; }
if ((p = strchr(user, '"'))) { user = p+1; } if ((p = strrchr
(user, '"'))) { *p = '\0'; } } } break; } while (0)
;
180
181 if (user) {
182 switch_channel_set_variable(channel, user_var, user)switch_channel_set_variable_var_check(channel, user_var, user
, SWITCH_TRUE)
;
183 }
184
185
186 if (port) {
187 switch_snprintf(new_port, sizeof(new_port), ":%s", port);
188 }
189
190 switch_channel_set_variable(channel, port_var, port)switch_channel_set_variable_var_check(channel, port_var, port
, SWITCH_TRUE)
;
191 if (host) {
192 if (user) {
193 uri = switch_core_session_sprintf(session, "%s@%s%s", user, host, new_port);
194 } else {
195 uri = switch_core_session_sprintf(session, "%s%s", host, new_port);
196 }
197 switch_channel_set_variable(channel, uri_var, uri)switch_channel_set_variable_var_check(channel, uri_var, uri, SWITCH_TRUE
)
;
198 switch_channel_set_variable(channel, host_var, host)switch_channel_set_variable_var_check(channel, host_var, host
, SWITCH_TRUE)
;
199 }
200
201 return uri;
202}
203
204static char *strip_quotes(const char *in)
205{
206 char *t = (char *) in;
207 char *r = (char *) in;
208
209 if (t && *t == '"') {
63
Assuming 't' is non-null
64
Assuming the condition is true
65
Taking true branch
210 t++;
211
212 if (end_of(t)*(*t == '\0' ? t : t + strlen(t) - 1) == '"') {
66
Taking true branch
213 r = strdup(t);
67
Memory is allocated
214 switch_assert(r)((r) ? (void) (0) : __assert_fail ("r", "sofia.c", 214, __extension__
__PRETTY_FUNCTION__))
;
68
Within the expansion of the macro 'switch_assert':
a
Assuming 'r' is non-null
215 end_of(r)*(*r == '\0' ? r : r + strlen(r) - 1) = '\0';
216 }
217 }
218
219 return r;
220}
221
222static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip,
223 switch_core_session_t *session, nua_handle_t *nh)
224{
225 switch_channel_t *channel = switch_core_session_get_channel(session);
226 char *full;
227
228 if (sip) {
49
Taking true branch
229 if (sip->sip_route) {
50
Assuming the condition is false
51
Taking false branch
230 const char *v = switch_channel_get_variable(channel, "sip_full_route")switch_channel_get_variable_dup(channel, "sip_full_route", SWITCH_TRUE
, -1)
;
231
232 if (!v) {
233 sip_route_t *rp;
234 switch_stream_handle_t stream = { 0 };
235 int x = 0;
236
237 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 237, __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
;
238
239 for (rp = sip->sip_route; rp; rp = rp->r_next) {
240 char *route = sip_header_as_string(nua_handle_get_home(nh), (void *) rp);
241 stream.write_function(&stream, x == 0 ? "%s" : ",%s", route);
242 su_free(nua_handle_get_home(nh), route);
243 x++;
244 }
245 switch_channel_set_variable(channel, "sip_full_route", stream.data)switch_channel_set_variable_var_check(channel, "sip_full_route"
, stream.data, SWITCH_TRUE)
;
246 free(stream.data);
247 }
248 }
249
250 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
52
Assuming the condition is false
53
Taking false branch
251 if (sip->sip_contact) {
252 char *c = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_contact);
253 switch_channel_set_variable(channel, "sip_recover_contact", c)switch_channel_set_variable_var_check(channel, "sip_recover_contact"
, c, SWITCH_TRUE)
;
254 su_free(nua_handle_get_home(nh), c);
255 }
256 }
257
258 if (sip->sip_record_route) {
54
Assuming the condition is false
55
Taking false branch
259 sip_record_route_t *rrp;
260 switch_stream_handle_t forward_stream = { 0 };
261 switch_stream_handle_t reverse_stream = { 0 };
262 int x = 0;
263 char *tmp[128] = { 0 };
264 int y = 0;
265
266 SWITCH_STANDARD_STREAM(forward_stream)memset(&forward_stream, 0, sizeof(forward_stream)); forward_stream
.data = malloc(1024); ((forward_stream.data) ? (void) (0) : __assert_fail
("forward_stream.data", "sofia.c", 266, __extension__ __PRETTY_FUNCTION__
)); memset(forward_stream.data, 0, 1024); forward_stream.end =
forward_stream.data; forward_stream.data_size = 1024; forward_stream
.write_function = switch_console_stream_write; forward_stream
.raw_write_function = switch_console_stream_raw_write; forward_stream
.alloc_len = 1024; forward_stream.alloc_chunk = 1024
;
267 SWITCH_STANDARD_STREAM(reverse_stream)memset(&reverse_stream, 0, sizeof(reverse_stream)); reverse_stream
.data = malloc(1024); ((reverse_stream.data) ? (void) (0) : __assert_fail
("reverse_stream.data", "sofia.c", 267, __extension__ __PRETTY_FUNCTION__
)); memset(reverse_stream.data, 0, 1024); reverse_stream.end =
reverse_stream.data; reverse_stream.data_size = 1024; reverse_stream
.write_function = switch_console_stream_write; reverse_stream
.raw_write_function = switch_console_stream_raw_write; reverse_stream
.alloc_len = 1024; reverse_stream.alloc_chunk = 1024
;
268
269 for(rrp = sip->sip_record_route; rrp; rrp = rrp->r_next) {
270 char *rr = sip_header_as_string(nua_handle_get_home(nh), (void *) rrp);
271 forward_stream.write_function(&forward_stream, x == 0 ? "%s" : ",%s", rr);
272 tmp[y++] = rr;
273 if (y == 127) break;
274 x++;
275 }
276
277 y--;
278
279 x = 0;
280
281 while(y >= 0) {
282 reverse_stream.write_function(&reverse_stream, x == 0 ? "%s" : ",%s", tmp[y]);
283 su_free(nua_handle_get_home(nh), tmp[y]);
284 y--;
285 x++;
286 }
287
288 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND || switch_channel_test_flag(channel, CF_RECOVERED)) {
289 switch_channel_set_variable(channel, "sip_invite_route_uri", (char *)reverse_stream.data)switch_channel_set_variable_var_check(channel, "sip_invite_route_uri"
, (char *)reverse_stream.data, SWITCH_TRUE)
;
290 switch_channel_set_variable(channel, "sip_invite_record_route", (char *)forward_stream.data)switch_channel_set_variable_var_check(channel, "sip_invite_record_route"
, (char *)forward_stream.data, SWITCH_TRUE)
;
291 } else {
292 switch_channel_set_variable(channel, "sip_invite_route_uri", (char *)forward_stream.data)switch_channel_set_variable_var_check(channel, "sip_invite_route_uri"
, (char *)forward_stream.data, SWITCH_TRUE)
;
293 switch_channel_set_variable(channel, "sip_invite_record_route", (char *)reverse_stream.data)switch_channel_set_variable_var_check(channel, "sip_invite_record_route"
, (char *)reverse_stream.data, SWITCH_TRUE)
;
294 }
295
296 free(reverse_stream.data);
297 free(forward_stream.data);
298 }
299
300 if (sip->sip_via) {
56
Assuming the condition is false
57
Taking false branch
301 sip_via_t *vp;
302 switch_stream_handle_t stream = { 0 };
303 int x = 0;
304
305 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 305, __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
;
306
307 for(vp = sip->sip_via; vp; vp = vp->v_next) {
308 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
309
310 stream.write_function(&stream, x == 0 ? "%s" : ",%s", v);
311 su_free(nua_handle_get_home(nh), v);
312
313 x++;
314 }
315
316 switch_channel_set_variable(channel, "sip_full_via", (char *)stream.data)switch_channel_set_variable_var_check(channel, "sip_full_via"
, (char *)stream.data, SWITCH_TRUE)
;
317
318 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND || switch_stristr("TCP", (char *)stream.data)) {
319 switch_channel_set_variable(channel, "sip_recover_via", (char *)stream.data)switch_channel_set_variable_var_check(channel, "sip_recover_via"
, (char *)stream.data, SWITCH_TRUE)
;
320 }
321
322 free(stream.data);
323
324 }
325
326 if (sip->sip_from) {
58
Assuming the condition is false
59
Taking false branch
327 char *p = strip_quotes(sip->sip_from->a_display);
328
329 if (p) {
330 switch_channel_set_variable(channel, "sip_from_display", p)switch_channel_set_variable_var_check(channel, "sip_from_display"
, p, SWITCH_TRUE)
;
331 }
332 if (p != sip->sip_from->a_display) free(p);
333 if ((full = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_from))) {
334 switch_channel_set_variable(channel, "sip_full_from", full)switch_channel_set_variable_var_check(channel, "sip_full_from"
, full, SWITCH_TRUE)
;
335 su_free(nua_handle_get_home(nh), full);
336 }
337 }
338
339 if (sip->sip_to) {
60
Assuming the condition is true
61
Taking true branch
340 char *p = strip_quotes(sip->sip_to->a_display);
62
Calling 'strip_quotes'
69
Returned allocated memory
341
342 if (p) {
70
Taking true branch
343 switch_channel_set_variable(channel, "sip_to_display", p)switch_channel_set_variable_var_check(channel, "sip_to_display"
, p, SWITCH_TRUE)
;
344 }
345
346 if (p != sip->sip_to->a_display) free(p);
71
Assuming the condition is false
72
Taking false branch
347
348 if ((full = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_to))) {
73
Potential leak of memory pointed to by 'p'
349 switch_channel_set_variable(channel, "sip_full_to", full)switch_channel_set_variable_var_check(channel, "sip_full_to",
full, SWITCH_TRUE)
;
350 su_free(nua_handle_get_home(nh), full);
351 }
352 }
353
354 }
355}
356
357static void extract_vars(sofia_profile_t *profile, sip_t const *sip,
358 switch_core_session_t *session)
359{
360 switch_channel_t *channel = switch_core_session_get_channel(session);
361
362 if (sip) {
363 if (sip->sip_from)
364 url_set_chanvars(session, sip->sip_from->a_url, sip_from)_url_set_chanvars(session, sip->sip_from->a_url, "sip_from"
"_user", "sip_from" "_host", "sip_from" "_port", "sip_from" "_uri"
, "sip_from" "_params")
;
365 if (sip->sip_request)
366 url_set_chanvars(session, sip->sip_request->rq_url, sip_req)_url_set_chanvars(session, sip->sip_request->rq_url, "sip_req"
"_user", "sip_req" "_host", "sip_req" "_port", "sip_req" "_uri"
, "sip_req" "_params")
;
367 if (sip->sip_to)
368 url_set_chanvars(session, sip->sip_to->a_url, sip_to)_url_set_chanvars(session, sip->sip_to->a_url, "sip_to"
"_user", "sip_to" "_host", "sip_to" "_port", "sip_to" "_uri"
, "sip_to" "_params")
;
369 if (sip->sip_contact)
370 url_set_chanvars(session, sip->sip_contact->m_url, sip_contact)_url_set_chanvars(session, sip->sip_contact->m_url, "sip_contact"
"_user", "sip_contact" "_host", "sip_contact" "_port", "sip_contact"
"_uri", "sip_contact" "_params")
;
371 if (sip->sip_referred_by)
372 url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by)_url_set_chanvars(session, sip->sip_referred_by->b_url,
"sip_referred_by" "_user", "sip_referred_by" "_host", "sip_referred_by"
"_port", "sip_referred_by" "_uri", "sip_referred_by" "_params"
)
;
373 if (sip->sip_to && sip->sip_to->a_tag) {
374 switch_channel_set_variable(channel, "sip_to_tag", sip->sip_to->a_tag)switch_channel_set_variable_var_check(channel, "sip_to_tag", sip
->sip_to->a_tag, SWITCH_TRUE)
;
375 }
376 if (sip->sip_from && sip->sip_from->a_tag) {
377 switch_channel_set_variable(channel, "sip_from_tag", sip->sip_from->a_tag)switch_channel_set_variable_var_check(channel, "sip_from_tag"
, sip->sip_from->a_tag, SWITCH_TRUE)
;
378 }
379 if (sip->sip_cseq && sip->sip_cseq->cs_seq) {
380 char sip_cseq[40] = "";
381 switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq);
382 switch_channel_set_variable(channel, "sip_cseq", sip_cseq)switch_channel_set_variable_var_check(channel, "sip_cseq", sip_cseq
, SWITCH_TRUE)
;
383 }
384 if (sip->sip_call_id && sip->sip_call_id->i_id) {
385 switch_channel_set_variable(channel, "sip_call_id", sip->sip_call_id->i_id)switch_channel_set_variable_var_check(channel, "sip_call_id",
sip->sip_call_id->i_id, SWITCH_TRUE)
;
386 }
387 }
388}
389
390/**
391 * Add a specific SIP INVITE header to the channel variables, prefixed with "sip_i_"
392 */
393static void sofia_add_invite_header_to_chanvars(switch_channel_t *channel, nua_handle_t *nh, void *sip_header, const char *var)
394{
395 switch_assert(channel)((channel) ? (void) (0) : __assert_fail ("channel", "sofia.c"
, 395, __extension__ __PRETTY_FUNCTION__))
;
396 switch_assert(nh)((nh) ? (void) (0) : __assert_fail ("nh", "sofia.c", 396, __extension__
__PRETTY_FUNCTION__))
;
397 switch_assert(var)((var) ? (void) (0) : __assert_fail ("var", "sofia.c", 397, __extension__
__PRETTY_FUNCTION__))
;
398
399 if (sip_header) {
400 char *full;
401 if ((full = sip_header_as_string(nua_handle_get_home(nh), sip_header))) {
402 switch_channel_set_variable(channel, var, full)switch_channel_set_variable_var_check(channel, var, full, SWITCH_TRUE
)
;
403 su_free(nua_handle_get_home(nh), full);
404 }
405 }
406}
407
408/**
409 * Deep search into the SIP message to recreate the original headers, including multiple Diversions, etc.
410 * Finally sets the "sip_invite_headers" to a string containing the 'original' SIP headers, except that the order may have changed.
411 * Multiple headers will have the original internal order, though.
412 *
413 * @param sip A sip_t struct containing the parsed message
414 * @param session A call session
415 * @param nh A NUA handle for string allocation
416 */
417static void sofia_parse_all_invite_headers(sip_t const *sip, switch_core_session_t *session, nua_handle_t *nh)
418{
419 switch_channel_t *channel = switch_core_session_get_channel(session);
420 sip_unknown_t *un;
421 sip_p_asserted_identity_t *passerted;
422 sip_p_preferred_identity_t *ppreferred;
423 sip_remote_party_id_t *rpid;
424 sip_reply_to_t *reply_to;
425 sip_alert_info_t *alert_info;
426
427 if (!sip) return;
428
429 /* Add simple (unique) headers first */
430 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_from, "sip_i_from");
431 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_to, "sip_i_to");
432 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_call_id, "sip_i_call_id");
433 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_cseq, "sip_i_cseq");
434 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_identity, "sip_i_identity");
435 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_route, "sip_i_route");
436 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_max_forwards, "sip_i_max_forwards");
437 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_proxy_require, "sip_i_proxy_require");
438 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_contact, "sip_i_contact");
439 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_user_agent, "sip_i_user_agent");
440 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_subject, "sip_i_subject");
441 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_priority, "sip_i_priority");
442 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_organization, "sip_i_organization");
443 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_in_reply_to, "sip_i_in_reply_to");
444 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_accept_encoding, "sip_i_accept_encoding");
445 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_accept_language, "sip_i_accept_language");
446 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_i_allow");
447 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_require, "sip_i_require");
448 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_supported, "sip_i_supported");
449 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_date, "sip_i_date");
450 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_timestamp, "sip_i_timestamp");
451 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_expires, "sip_i_expires");
452 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_min_expires, "sip_i_min_expires");
453 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_session_expires, "sip_i_session_expires");
454 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_min_se, "sip_i_min_se");
455 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_privacy, "sip_i_privacy");
456 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_mime_version, "sip_i_mime_version");
457 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_type, "sip_i_content_type");
458 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_encoding, "sip_i_content_encoding");
459 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_language, "sip_i_content_language");
460 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_disposition, "sip_i_content_disposition");
461 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_length, "sip_i_content_length");
462
463 /* Add all other headers - which might exist more than once */
464
465 if (sip->sip_via) {
466 sip_via_t *vp;
467 for (vp = sip->sip_via; vp; vp = vp->v_next) {
468 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
469 switch_channel_add_variable_var_check(channel, "sip_i_via", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
470 su_free(nua_handle_get_home(nh), v);
471 }
472 }
473
474 if (sip->sip_record_route) {
475 sip_record_route_t *rrp;
476 for (rrp = sip->sip_record_route; rrp; rrp = rrp->r_next) {
477 char *rr = sip_header_as_string(nua_handle_get_home(nh), (void *) rrp);
478 switch_channel_add_variable_var_check(channel, "sip_i_record_route", rr, SWITCH_FALSE, SWITCH_STACK_PUSH);
479 su_free(nua_handle_get_home(nh), rr);
480 }
481 }
482
483 if (sip->sip_proxy_authorization) {
484 sip_proxy_authorization_t *vp;
485 for (vp = sip->sip_proxy_authorization; vp; vp = vp->au_next) {
486 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
487 switch_channel_add_variable_var_check(channel, "sip_i_proxy_authorization", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
488 su_free(nua_handle_get_home(nh), v);
489 }
490 }
491
492 if (sip->sip_call_info) {
493 sip_call_info_t *vp;
494 for (vp = sip->sip_call_info; vp; vp = vp->ci_next) {
495 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
496 switch_channel_add_variable_var_check(channel, "sip_i_call_info", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
497 su_free(nua_handle_get_home(nh), v);
498 }
499 }
500
501 if (sip->sip_accept) {
502 sip_accept_t *vp;
503 for (vp = sip->sip_accept; vp; vp = vp->ac_next) {
504 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
505 switch_channel_add_variable_var_check(channel, "sip_i_accept", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
506 su_free(nua_handle_get_home(nh), v);
507 }
508 }
509
510 if (sip->sip_authorization) {
511 sip_authorization_t *vp;
512 for (vp = sip->sip_authorization; vp; vp = vp->au_next) {
513 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
514 switch_channel_add_variable_var_check(channel, "sip_i_authorization", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
515 su_free(nua_handle_get_home(nh), v);
516 }
517 }
518
519 if ((alert_info = sip_alert_info(sip)((sip_alert_info_t *)msg_header_access((msg_pub_t*)(sip), sip_alert_info_class
))
)) {
520 sip_alert_info_t *vp;
521 for (vp = alert_info; vp; vp = vp->ai_next) {
522 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
523 switch_channel_add_variable_var_check(channel, "sip_i_alert_info", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
524 su_free(nua_handle_get_home(nh), v);
525 }
526 }
527
528 if ((passerted = sip_p_asserted_identity(sip)((sip_p_asserted_identity_t *)msg_header_access((msg_pub_t*)(
sip), sip_p_asserted_identity_class))
)) {
529 sip_p_asserted_identity_t *vp;
530 for (vp = passerted; vp; vp = vp->paid_next) {
531 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
532 switch_channel_add_variable_var_check(channel, "sip_i_p_asserted_identity", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
533 su_free(nua_handle_get_home(nh), v);
534 }
535 }
536
537 if ((ppreferred = sip_p_preferred_identity(sip)((sip_p_preferred_identity_t *)msg_header_access((msg_pub_t*)
(sip), sip_p_preferred_identity_class))
)) {
538 sip_p_preferred_identity_t *vp;
539 for (vp = ppreferred; vp; vp = vp->ppid_next) {
540 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
541 switch_channel_add_variable_var_check(channel, "sip_i_p_preferred_identity", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
542 su_free(nua_handle_get_home(nh), v);
543 }
544 }
545
546 if ((rpid = sip_remote_party_id(sip)((sip_remote_party_id_t *)msg_header_access((msg_pub_t*)(sip)
, sip_remote_party_id_class))
)) {
547 sip_remote_party_id_t *vp;
548 for (vp = rpid; vp; vp = vp->rpid_next) {
549 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
550 switch_channel_add_variable_var_check(channel, "sip_i_remote_party_id", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
551 su_free(nua_handle_get_home(nh), v);
552 }
553 }
554
555 if ((reply_to = sip_reply_to(sip)((sip_reply_to_t *)msg_header_access((msg_pub_t*)(sip), sip_reply_to_class
))
)) {
556 sip_reply_to_t *vp;
557 for (vp = reply_to; vp; vp = vp->rplyto_next) {
558 char *v = sip_header_as_string(nua_handle_get_home(nh), (void *) vp);
559 switch_channel_add_variable_var_check(channel, "sip_i_reply_to", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
560 su_free(nua_handle_get_home(nh), v);
561 }
562 }
563
564 /* Loop through the unknown headers */
565 for (un = sip->sip_unknown; un; un = un->un_next) {
566 if (!zstr(un->un_name)_zstr(un->un_name) && !zstr(un->un_value)_zstr(un->un_value)) {
567 char *parsed_name;
568 if ((parsed_name = switch_mprintf("sip_i_%s", un->un_name))) {
569 char *p, *x = parsed_name;
570 switch_tolower_max(x);
571 while ((p = strchr(x, '-'))) {
572 *p = '_';
573 x = ++p;
574 }
575 switch_channel_add_variable_var_check(channel, parsed_name, un->un_value, SWITCH_FALSE, SWITCH_STACK_PUSH);
576 free(parsed_name);
577 }
578 }
579 }
580}
581
582static switch_status_t sofia_pass_notify(switch_core_session_t *session, const char *uuid, const char *payload)
583{
584 switch_core_session_t *other_session;
585
586 if ((other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 586)
)) {
587 switch_core_session_message_t *msg;
588
589 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 589)
;
590 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 590
;
591 msg->message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE;
592 msg->string_arg = switch_core_session_strdup(other_session, payload)switch_core_perform_session_strdup(other_session, payload, "sofia.c"
, (const char *)__func__, 592)
;
593 msg->from = __FILE__"sofia.c";
594 switch_core_session_queue_message(other_session, msg);
595 switch_core_session_rwunlock(other_session);
596 return SWITCH_STATUS_SUCCESS;
597 }
598
599 return SWITCH_STATUS_FALSE;
600}
601
602
603void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
604 char const *phrase,
605 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
606 sofia_dispatch_event_t *de, tagi_t tags[])
607{
608 switch_channel_t *channel = NULL((void*)0);
609 private_object_t *tech_pvt = NULL((void*)0);
610 switch_event_t *s_event = NULL((void*)0);
611 sofia_gateway_subscription_t *gw_sub_ptr;
612 int sub_state;
613 sofia_gateway_t *gateway = NULL((void*)0);
614 const char *session_id_header = sofia_glue_session_id_header(session, profile);
615
616 tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state)nutag_substate_ref, tag_int_vr(&(sub_state)), TAG_END()(tag_type_t)0, (tag_value_t)0);
617
618 /* make sure we have a proper event */
619 if (!sip || !sip->sip_event) {
620 goto error;
621 }
622
623 /* Automatically return a 200 OK for Event: keep-alive */
624 if (!strcasecmp(sip->sip_event->o_type, "keep-alive")) {
625 /* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */
626 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
627 goto end;
628 }
629
630 if (session) {
631 channel = switch_core_session_get_channel(session);
632 switch_assert(channel != NULL)((channel != ((void*)0)) ? (void) (0) : __assert_fail ("channel != ((void*)0)"
, "sofia.c", 632, __extension__ __PRETTY_FUNCTION__))
;
633 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
634 switch_assert(tech_pvt != NULL)((tech_pvt != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt != ((void*)0)"
, "sofia.c", 634, __extension__ __PRETTY_FUNCTION__))
;
635 }
636
637
638 if (tech_pvt && tech_pvt->proxy_refer_uuid && sofia_test_pflag(profile, PFLAG_PROXY_REFER)((profile)->pflags[PFLAG_PROXY_REFER] ? 1 : 0) && sip->sip_payload && sip->sip_payload->pl_data &&
639 sip->sip_content_type && sip->sip_content_type->c_type && switch_stristr("sipfrag", sip->sip_content_type->c_type)) {
640
641 if (sofia_pass_notify(session, tech_pvt->proxy_refer_uuid, sip->sip_payload->pl_data) == SWITCH_STATUS_SUCCESS) {
642 if (tech_pvt->proxy_refer_msg) {
643 msg_ref_destroy(tech_pvt->proxy_refer_msg);
644 tech_pvt->proxy_refer_msg = NULL((void*)0);
645 }
646 tech_pvt->proxy_refer_msg = msg_ref_create(de->data->e_msg);
647 //nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
648 } else {
649 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 649, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
650 }
651
652 goto end;
653 }
654
655 /* For additional NOTIFY event packages see http://www.iana.org/assignments/sip-events. */
656 if (sip->sip_content_type &&
657 sip->sip_content_type->c_type && sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(sip->sip_event->o_type, "refer")) {
658 if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_NOTIFY_REFER)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 658, &s_event, SWITCH_EVENT_CUSTOM
, "sofia::notify_refer")
== SWITCH_STATUS_SUCCESS) {
659 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "content-type", sip->sip_content_type->c_type);
660 switch_event_add_body(s_event, "%s", sip->sip_payload->pl_data);
661 }
662 }
663
664 /* add common headers for the NOTIFY to the switch_event and fire if it exists */
665 if (s_event != NULL((void*)0)) {
666 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event-package", sip->sip_event->o_type);
667 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event-id", sip->sip_event->o_id);
668
669 if (sip->sip_contact) {
670 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s@%s",
671 sip->sip_contact->m_url->url_user, sip->sip_contact->m_url->url_host);
672 }
673
674 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host);
675 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-tag", sip->sip_from->a_tag);
676 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
677 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-tag", sip->sip_to->a_tag);
678
679 if (sip->sip_call_id && sip->sip_call_id->i_id) {
680 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", sip->sip_call_id->i_id);
681 }
682 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_substate) {
683 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-substate", sip->sip_subscription_state->ss_substate);
684 }
685 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_reason) {
686 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-reason", sip->sip_subscription_state->ss_reason);
687 }
688 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_retry_after) {
689 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-retry-after", sip->sip_subscription_state->ss_retry_after);
690 }
691 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_expires) {
692 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-expires", sip->sip_subscription_state->ss_expires);
693 }
694 if (session) {
695 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "UniqueID", switch_core_session_get_uuid(session));
696 }
697 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 697, &s_event, ((void*)0))
;
698 }
699
700 if (!strcasecmp(sip->sip_event->o_type, "refer")) {
701 if (session && channel && tech_pvt) {
702 if (sip->sip_payload && sip->sip_payload->pl_data) {
703 char *p;
704 int status_val = 0;
705 if ((p = strchr(sip->sip_payload->pl_data, ' '))) {
706 p++;
707 status_val = atoi(p);
708 }
709 if (!status_val || status_val >= 200) {
710 switch_channel_set_variable(channel, "sip_refer_reply", sip->sip_payload->pl_data)switch_channel_set_variable_var_check(channel, "sip_refer_reply"
, sip->sip_payload->pl_data, SWITCH_TRUE)
;
711 if (status_val == 200) {
712 switch_channel_hangup(channel, SWITCH_CAUSE_BLIND_TRANSFER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 712, SWITCH_CAUSE_BLIND_TRANSFER)
;
713 }
714 if ((int)tech_pvt->want_event == 9999) {
715 tech_pvt->want_event = 0;
716 }
717 }
718 }
719 }
720 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
721 }
722
723 /* if no session, assume it could be an incoming notify from a gateway subscription */
724 if (session) {
725 if (!zstr(profile->proxy_notify_events)_zstr(profile->proxy_notify_events) && (!strcasecmp(profile->proxy_notify_events, "all") || strstr(profile->proxy_notify_events, sip->sip_event->o_type))) {
726 switch_core_session_t *other_session;
727 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 727)
== SWITCH_STATUS_SUCCESS) {
728 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
729 const char *full_to = NULL((void*)0);
730 char *pl = NULL((void*)0);
731 char *unknown = NULL((void*)0);
732
733 full_to = switch_str_nil(switch_channel_get_variable(switch_core_session_get_channel(other_session), "sip_full_to"))(switch_channel_get_variable_dup(switch_core_session_get_channel
(other_session), "sip_full_to", SWITCH_TRUE, -1) ? switch_channel_get_variable_dup
(switch_core_session_get_channel(other_session), "sip_full_to"
, SWITCH_TRUE, -1) : "")
;
734 if (sip->sip_payload && sip->sip_payload->pl_data) {
735 pl = switch_core_session_strdup(other_session, (char*)sip->sip_payload->pl_data)switch_core_perform_session_strdup(other_session, (char*)sip->
sip_payload->pl_data, "sofia.c", (const char *)__func__, 735
)
;
736 }
737 unknown = sofia_glue_get_non_extra_unknown_headers(sip);
738 nua_notify(other_tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), NUTAG_SUBSTATE(nua_substate_active)nutag_substate, tag_int_v(nua_substate_active),
739 TAG_IF((full_to), SIPTAG_TO_STR(full_to))!((full_to)) ? tag_skip : siptag_to_str, tag_str_v(full_to), SIPTAG_SUBSCRIPTION_STATE_STR("active")siptag_subscription_state_str, tag_str_v("active"),
740 SIPTAG_EVENT_STR(sip->sip_event->o_type)siptag_event_str, tag_str_v(sip->sip_event->o_type), TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown))!(!_zstr(unknown)) ? tag_skip : siptag_header_str, tag_str_v(
(unknown))
,
741 TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl))!(!_zstr(pl)) ? tag_skip : siptag_payload_str, tag_str_v(pl),
742 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))
,
743 TAG_END()(tag_type_t)0, (tag_value_t)0);
744 switch_safe_free(unknown)if (unknown) {free(unknown);unknown=((void*)0);};
745 switch_core_session_rwunlock(other_session);
746 }
747 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
748 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
749 goto end;
750 }
751 /* make sure we have a proper "talk" event */
752 if (strcasecmp(sip->sip_event->o_type, "talk")) {
753 goto error;
754 }
755
756 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
757 switch_channel_answer(channel)switch_channel_perform_answer(channel, "sofia.c", (const char
*)__func__, 757)
;
758 switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number"))switch_channel_set_variable_var_check(channel, "auto_answer_destination"
, switch_channel_get_variable_dup(channel, "destination_number"
, SWITCH_TRUE, -1), SWITCH_TRUE)
;
759 switch_ivr_session_transfer(session, "auto_answer", NULL((void*)0), NULL((void*)0));
760 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
761 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
762 goto end;
763 }
764 }
765
766 if (!sofia_private || zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
767 if (profile->debug) {
768 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
768, (const char*)(session)
, SWITCH_LOG_DEBUG, "Gateway information missing Subscription Event: %s\n",
769 sip->sip_event->o_type);
770 }
771 goto error;
772 }
773
774
775 if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 775
, sofia_private->gateway_name)
)) {
776 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 776
, ((void*)0)
, SWITCH_LOG_ERROR, "Gateway information missing\n");
777 goto error;
778 }
779
780 /* find the corresponding gateway subscription (if any) */
781 if (!(gw_sub_ptr = sofia_find_gateway_subscription(gateway, sip->sip_event->o_type))) {
782 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
782, (const char*)(session)
, SWITCH_LOG_WARNING,
783 "Could not find gateway subscription. Gateway: %s. Subscription Event: %s\n",
784 gateway->name, sip->sip_event->o_type);
785 goto error;
786 }
787
788 if (!(gw_sub_ptr->state == SUB_STATE_SUBED || gw_sub_ptr->state == SUB_STATE_SUBSCRIBE)) {
789 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
789, (const char*)(session)
, SWITCH_LOG_WARNING, "Ignoring notify due to subscription state: %d\n", gw_sub_ptr->state);
790 goto error;
791 }
792
793 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_expires) {
794 int delta = atoi(sip->sip_subscription_state->ss_expires);
795
796 delta /= 2;
797
798 if (delta < 1) {
799 delta = 1;
800 }
801 gw_sub_ptr->expires = switch_epoch_time_now(NULL((void*)0)) + delta;
802 }
803
804 /* dispatch freeswitch event */
805 if (switch_event_create(&s_event, SWITCH_EVENT_NOTIFY_IN)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 805, &s_event, SWITCH_EVENT_NOTIFY_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
806 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event", sip->sip_event->o_type);
807 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "pl_data", sip->sip_payload ? sip->sip_payload->pl_data : "");
808 if ( sip->sip_content_type != NULL((void*)0) )
809 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_content_type", sip->sip_content_type->c_type);
810 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", gateway->profile->sip_port);
811 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
812 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", gateway->profile->name);
813 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", gateway->profile->url);
814 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "gateway_name", gateway->name);
815 if ( sip->sip_call_info != NULL((void*)0) ) {
816 sip_call_info_t *call_info = sip->sip_call_info;
817 char *nua_hold = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) call_info);
818 size_t cur_len = strlen(nua_hold);
819 char *hold = strdup(nua_hold);
820 su_free(nua_handle_home(nh)((su_home_t *)(nh)), nua_hold);
821
822 while ((call_info = call_info->ci_next) != NULL((void*)0)) {
823 char *tmp = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) call_info);
824 size_t tmp_len = strlen(tmp);
825 char *tmp_hold = realloc(hold, cur_len + tmp_len + 2);
826 if (!tmp_hold) {
827 /* Avoid leak if realloc failed */
828 free(hold);
829 }
830 switch_assert(tmp_hold)((tmp_hold) ? (void) (0) : __assert_fail ("tmp_hold", "sofia.c"
, 830, __extension__ __PRETTY_FUNCTION__))
;
831 hold = tmp_hold;
832 strncpy(hold + cur_len, ",", 2);
833 strncpy(hold + cur_len + 1, tmp, tmp_len +1);
834 su_free(nua_handle_home(nh)((su_home_t *)(nh)), tmp);
835 cur_len = cur_len + tmp_len + 2;
836 }
837 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Call-Info", hold);
838 switch_safe_free(hold)if (hold) {free(hold);hold=((void*)0);};
839 }
840 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 840, &s_event, ((void*)0))
;
841 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
841, (const char*)(session)
, SWITCH_LOG_DEBUG, "dispatched freeswitch event for message-summary NOTIFY\n");
842 } else {
843 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
843, (const char*)(session)
, SWITCH_LOG_ERROR, "Failed to create event\n");
844 goto error;
845 }
846
847 goto end;
848
849 error:
850
851
852 if (sip && sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "message-summary")) {
853 /* unsolicited mwi, just say ok */
854 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
855 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
856
857 if (sofia_test_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)((profile)->pflags[PFLAG_FORWARD_MWI_NOTIFY] ? 1 : 0)) {
858 const char *mwi_status = NULL((void*)0);
859 char network_ip[80] = "";
860 uint32_t x = 0;
861 int acl_ok = 1;
862 char *last_acl = NULL((void*)0);
863
864 if (sip->sip_to && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host
865 && sip->sip_payload && sip->sip_payload->pl_data ) {
866
867 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL((void*)0));
868 for (x = 0; x < profile->acl_count; x++) {
869 last_acl = profile->acl[x];
870 if (!(acl_ok = switch_check_network_list_ip(network_ip, last_acl)switch_check_network_list_ip_token(network_ip, last_acl, ((void
*)0))
)) {
871 break;
872 }
873 }
874
875 if ( acl_ok )
876 {
877 mwi_status = switch_stristr("Messages-Waiting: ", sip->sip_payload->pl_data);
878
879 if ( mwi_status ) {
880 char *mwi_stat;
881 mwi_status += strlen( "Messages-Waiting: " );
882 mwi_stat = switch_strip_whitespace( mwi_status );
883
884 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
884, (const char*)(session)
, SWITCH_LOG_DEBUG,
885 "Forwarding unsolicited MWI ( %s : %s@%s )\n",
886 mwi_stat, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
887 if (switch_event_create(&s_event, SWITCH_EVENT_MESSAGE_WAITING)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 887, &s_event, SWITCH_EVENT_MESSAGE_WAITING
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
888 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", mwi_stat );
889 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM,
890 "MWI-Message-Account", "%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
891 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 891, &s_event, ((void*)0))
;
892 }
893 switch_safe_free(mwi_stat)if (mwi_stat) {free(mwi_stat);mwi_stat=((void*)0);};
894 }
895 } else {
896 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
896, (const char*)(session)
, SWITCH_LOG_DEBUG, "Dropping unsolicited MWI ( %s@%s ) because of ACL\n",
897 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
898 };
899
900 }
901 }
902
903 } else {
904 nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
905 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
906 }
907
908 end:
909
910 if (!gateway && sub_state == nua_substate_terminated && sofia_private && sofia_private != &mod_sofia_globals.destroy_private &&
911 sofia_private != &mod_sofia_globals.keep_private) {
912 sofia_private->destroy_nh = 1;
913 sofia_private->destroy_me = 1;
914 }
915
916 if (gateway) {
917 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 917, gateway);
;
918 }
919
920}
921
922/*
923 * This will fire an event containing X-headers from the BYE response
924 */
925void sofia_handle_sip_r_bye(switch_core_session_t *session, int status,
926 char const *phrase,
927 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
928 sofia_dispatch_event_t *de, tagi_t tags[])
929{
930 if (profile && sofia_test_pflag(profile, PFLAG_FIRE_BYE_RESPONSE_EVENTS)((profile)->pflags[PFLAG_FIRE_BYE_RESPONSE_EVENTS] ? 1 : 0
)
&& sip && sip->sip_call_id && !zstr(sip->sip_call_id->i_id)_zstr(sip->sip_call_id->i_id) && sofia_private && !zstr_buf(sofia_private->uuid_str)(*(sofia_private->uuid_str) == '\0')) {
931 switch_event_t *bye_response_event = NULL((void*)0);
932 sip_unknown_t *un;
933 if (switch_event_create_subclass(&bye_response_event, SWITCH_EVENT_CUSTOM, MY_EVENT_BYE_RESPONSE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 933, &bye_response_event, SWITCH_EVENT_CUSTOM
, "sofia::bye_response")
== SWITCH_STATUS_SUCCESS) {
934 switch_event_add_header(bye_response_event, SWITCH_STACK_BOTTOM, "call-id", "%s", sip->sip_call_id->i_id);
935 switch_event_add_header(bye_response_event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", sofia_private->uuid_str);
936 for (un = sip->sip_unknown; un; un = un->un_next) {
937 if (!zstr(un->un_value)_zstr(un->un_value)) {
938 switch_event_add_header(bye_response_event, SWITCH_STACK_BOTTOM, un->un_name, "%s", un->un_value);
939 }
940 }
941 switch_event_fire(&bye_response_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 941, &bye_response_event, ((void*)0))
;
942 }
943 }
944}
945
946void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
947 char const *phrase,
948 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
949 sofia_dispatch_event_t *de, tagi_t tags[])
950{
951 const char *tmp;
952 switch_channel_t *channel;
953 private_object_t *tech_pvt;
954 char *extra_headers;
955 const char *call_info = NULL((void*)0);
956 const char *vval = NULL((void*)0);
957 const char *session_id_header = sofia_glue_session_id_header(session, profile);
958#ifdef MANUAL_BYE1
959 int cause;
960 char st[80] = "";
961#endif
962
963 if (!session || !sip) {
964 return;
965 }
966
967 channel = switch_core_session_get_channel(session);
968 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
969
970#ifdef MANUAL_BYE1
971 status = 200;
972 phrase = "OK";
973
974 if (switch_channel_test_flag(tech_pvt->channel, CF_SLA_BARGING)) {
975 const char *bargee_uuid = switch_channel_get_variable(channel, "sip_barging_uuid")switch_channel_get_variable_dup(channel, "sip_barging_uuid", SWITCH_TRUE
, -1)
;
976 switch_core_session_t *bargee_session;
977 uint32_t ttl = 0;
978
979 if ((bargee_session = switch_core_session_locate(bargee_uuid)switch_core_session_perform_locate(bargee_uuid, "sofia.c", (const
char *)__func__, 979)
)) {
980 //switch_channel_t *bargee_channel = switch_core_session_get_channel(bargee_session);
981 if ((ttl = switch_core_media_bug_count(bargee_session, "eavesdrop")) == 1) {
982 if (switch_core_session_check_interface(bargee_session, sofia_endpoint_interface)) {
983 switch_channel_clear_flag(switch_core_session_get_channel(bargee_session), CF_SLA_BARGE);
984 }
985 }
986 switch_core_session_rwunlock(bargee_session);
987 }
988 }
989
990 if (switch_channel_test_flag(tech_pvt->channel, CF_SLA_BARGE)) {
991 switch_core_session_t *new_session, *other_session;
992 const char *other_uuid = switch_channel_get_partner_uuid(tech_pvt->channel);
993 char *cmd = NULL((void*)0);
994
995 if (!zstr(other_uuid)_zstr(other_uuid) && (other_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "sofia.c", (const
char *)__func__, 995)
)) {
996 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
997
998 switch_mutex_lock(profile->ireg_mutex);
999 if (switch_ivr_eavesdrop_pop_eavesdropper(session, &new_session) == SWITCH_STATUS_SUCCESS) {
1000 switch_channel_t *new_channel = switch_core_session_get_channel(new_session);
1001 const char *new_uuid = switch_core_session_get_uuid(new_session);
1002 switch_caller_profile_t *cp = switch_channel_get_caller_profile(new_channel);
1003
1004 cp->caller_id_name = cp->orig_caller_id_name;
1005 cp->caller_id_number = cp->orig_caller_id_number;
1006
1007
1008 switch_channel_set_variable(new_channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL)switch_channel_set_variable_var_check(new_channel, "signal_bond"
, ((void*)0), SWITCH_TRUE)
;
1009
1010 switch_channel_set_flag(other_channel, CF_REDIRECT)switch_channel_set_flag_value(other_channel, CF_REDIRECT, 1);
1011
1012 switch_channel_set_state(new_channel, CS_RESET)switch_channel_perform_set_state(new_channel, "sofia.c", (const
char *)__func__, 1012, CS_RESET)
;
1013
1014 switch_ivr_uuid_bridge(new_uuid, other_uuid);
1015 cmd = switch_core_session_sprintf(session, "sleep:500,sofia_sla:%s inline", new_uuid);
1016
1017 switch_channel_clear_flag(other_channel, CF_REDIRECT);
1018
1019 switch_core_session_rwunlock(new_session);
1020 }
1021 switch_mutex_unlock(profile->ireg_mutex);
1022
1023 switch_core_session_rwunlock(other_session);
1024 }
1025
1026 if (!zstr(cmd)_zstr(cmd)) {
1027 switch_ivr_eavesdrop_exec_all(session, "transfer", cmd);
1028 }
1029 }
1030
1031 sofia_set_flag_locked(tech_pvt, TFLAG_BYE)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 1031, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_BYE] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
1032 call_info = switch_channel_get_variable(channel, "presence_call_info_full")switch_channel_get_variable_dup(channel, "presence_call_info_full"
, SWITCH_TRUE, -1)
;
1033
1034 if (sip->sip_reason) {
1035 char *reason_header = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_reason);
1036
1037 if (!zstr(reason_header)_zstr(reason_header)) {
1038 switch_channel_set_variable(channel, "sip_reason", reason_header)switch_channel_set_variable_var_check(channel, "sip_reason", reason_header
, SWITCH_TRUE)
;
1039 switch_channel_set_variable_partner(channel, "sip_reason", reason_header)switch_channel_set_variable_partner_var_check(channel, "sip_reason"
, reason_header, SWITCH_TRUE)
;
1040 }
1041 }
1042
1043 if (sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
1044 || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
1045 || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
1046 tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
1047 cause = tech_pvt->q850_cause;
1048 } else {
1049 cause = sofia_glue_sip_cause_to_freeswitch(status);
1050 }
1051
1052 if (sip->sip_content_type && sip->sip_content_type->c_type) {
1053 switch_channel_set_variable(channel, "sip_bye_content_type", sip->sip_content_type->c_type)switch_channel_set_variable_var_check(channel, "sip_bye_content_type"
, sip->sip_content_type->c_type, SWITCH_TRUE)
;
1054 }
1055
1056 if (sip->sip_payload && sip->sip_payload->pl_data) {
1057 switch_channel_set_variable(channel, "sip_bye_payload", sip->sip_payload->pl_data)switch_channel_set_variable_var_check(channel, "sip_bye_payload"
, sip->sip_payload->pl_data, SWITCH_TRUE)
;
1058 }
1059
1060 switch_snprintf(st, sizeof(st), "%d", status);
1061 switch_channel_set_variable(channel, "sip_term_status", st)switch_channel_set_variable_var_check(channel, "sip_term_status"
, st, SWITCH_TRUE)
;
1062 switch_snprintf(st, sizeof(st), "sip:%d", status);
1063 switch_channel_set_variable(channel, SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE, st)switch_channel_set_variable_var_check(channel, "proto_specific_hangup_cause"
, st, SWITCH_TRUE)
;
1064
1065 switch_channel_set_variable_partner(channel, "sip_hangup_phrase", phrase)switch_channel_set_variable_partner_var_check(channel, "sip_hangup_phrase"
, phrase, SWITCH_TRUE)
;
1066
1067 switch_snprintf(st, sizeof(st), "%d", cause);
1068 switch_channel_set_variable(channel, "sip_term_cause", st)switch_channel_set_variable_var_check(channel, "sip_term_cause"
, st, SWITCH_TRUE)
;
1069
1070 extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_BYE_HEADER_PREFIX"sip_bye_h_");
1071 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_BYE_HEADER_PREFIX"sip_bye_h_");
1072
1073 if (!(vval = switch_channel_get_variable(channel, "sip_copy_custom_headers")switch_channel_get_variable_dup(channel, "sip_copy_custom_headers"
, SWITCH_TRUE, -1)
) || switch_true(vval)) {
1074 switch_core_session_t *nsession = NULL((void*)0);
1075
1076 switch_core_session_get_partner(session, &nsession)switch_core_session_perform_get_partner(session, &nsession
, "sofia.c", (const char *)__func__, 1076)
;
1077
1078 if (nsession) {
1079 const char *vval;
1080 switch_channel_t *nchannel = switch_core_session_get_channel(nsession);
1081
1082 if (!(vval = switch_channel_get_variable(nchannel, "sip_copy_custom_headers")switch_channel_get_variable_dup(nchannel, "sip_copy_custom_headers"
, SWITCH_TRUE, -1)
) || switch_true(vval)) {
1083 switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_BYE_HEADER_PREFIX_T"~sip_bye_h_");
1084 }
1085 switch_core_session_rwunlock(nsession);
1086 }
1087 }
1088
1089
1090 switch_channel_hangup(channel, cause)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 1090, cause)
;
1091 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
1092 TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info))!(call_info) ? tag_skip : siptag_call_info_str, tag_str_v(call_info
)
, TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers))!(!_zstr(extra_headers)) ? tag_skip : siptag_header_str, tag_str_v
((extra_headers))
,
1093 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
1094
1095 switch_safe_free(extra_headers)if (extra_headers) {free(extra_headers);extra_headers=((void*
)0);}
;
1096
1097 if (sofia_private) {
1098 sofia_private->destroy_me = 1;
1099 sofia_private->destroy_nh = 1;
1100 }
1101#endif
1102
1103
1104 if (sip->sip_user_agent && !zstr(sip->sip_user_agent->g_string)_zstr(sip->sip_user_agent->g_string)) {
1105 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_user_agent->g_string)switch_channel_set_variable_var_check(channel, "sip_user_agent"
, sip->sip_user_agent->g_string, SWITCH_TRUE)
;
1106 } else if (sip->sip_server && !zstr(sip->sip_server->g_string)_zstr(sip->sip_server->g_string)) {
1107 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_server->g_string)switch_channel_set_variable_var_check(channel, "sip_user_agent"
, sip->sip_server->g_string, SWITCH_TRUE)
;
1108 }
1109
1110 sofia_set_accept_language_channel_variable(channel, sip);
1111
1112 if ((tmp = sofia_glue_get_unknown_header(sip, "rtp-txstat"))) {
1113 switch_channel_set_variable(channel, "sip_rtp_txstat", tmp)switch_channel_set_variable_var_check(channel, "sip_rtp_txstat"
, tmp, SWITCH_TRUE)
;
1114 }
1115 if ((tmp = sofia_glue_get_unknown_header(sip, "rtp-rxstat"))) {
1116 switch_channel_set_variable(channel, "sip_rtp_rxstat", tmp)switch_channel_set_variable_var_check(channel, "sip_rtp_rxstat"
, tmp, SWITCH_TRUE)
;
1117 }
1118 if ((tmp = sofia_glue_get_unknown_header(sip, "P-RTP-Stat"))) {
1119 switch_channel_set_variable(channel, "sip_p_rtp_stat", tmp)switch_channel_set_variable_var_check(channel, "sip_p_rtp_stat"
, tmp, SWITCH_TRUE)
;
1120 }
1121
1122 tech_pvt->got_bye = 1;
1123 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_bye")switch_channel_set_variable_var_check(channel, "sip_hangup_disposition"
, "recv_bye", SWITCH_TRUE)
;
1124
1125 return;
1126}
1127
1128void sofia_handle_sip_r_message(int status, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip)
1129{
1130 const char *call_id;
1131 int *mstatus;
1132
1133 if (!(sip && sip->sip_call_id)) {
1134 nua_handle_destroy(nh);
1135 return;
1136 }
1137
1138 call_id = sip->sip_call_id->i_id;
1139
1140
1141
1142 switch_mutex_lock(profile->flag_mutex);
1143 mstatus = switch_core_hash_find(profile->chat_hash, call_id);
1144 switch_mutex_unlock(profile->flag_mutex);
1145
1146 if (mstatus) {
1147 *mstatus = status;
1148 }
1149
1150}
1151
1152void sofia_wait_for_reply(struct private_object *tech_pvt, nua_event_t event, uint32_t timeout)
1153{
1154 time_t exp = switch_epoch_time_now(NULL((void*)0)) + timeout;
1155
1156 tech_pvt->want_event = event;
1157
1158 while (switch_channel_ready(tech_pvt->channel)switch_channel_test_ready(tech_pvt->channel, SWITCH_TRUE, SWITCH_FALSE
)
&& tech_pvt->want_event && switch_epoch_time_now(NULL((void*)0)) < exp) {
1159 switch_yield(100000)switch_sleep(100000);;
1160 }
1161
1162}
1163
1164void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number)
1165{
1166 const char *uuid;
1167 switch_core_session_t *session_b;
1168 switch_channel_t *channel = switch_core_session_get_channel(session);
1169 switch_caller_profile_t *caller_profile = switch_channel_get_caller_profile(channel);
1170
1171
1172 if (switch_channel_inbound_display(channel)((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND
&& !switch_channel_test_flag(channel, CF_BLEG)) || (
switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
&& switch_channel_test_flag(channel, CF_DIALPLAN)))
) {
1173 if (zstr(name)_zstr(name)) {
1174 name = caller_profile->caller_id_name;
1175 }
1176
1177 if (zstr(number)_zstr(number)) {
1178 number = caller_profile->caller_id_number;
1179 }
1180
1181 if (zstr(name)_zstr(name)) {
1182 name = number;
1183 }
1184
1185 if (zstr(number)_zstr(number)) {
1186 name = number = "UNKNOWN";
1187 }
1188
1189 if (!zstr(name)_zstr(name) && !strcmp(name,"_undef_")) {
1190 name = "";
1191 }
1192 } else {
1193 if (zstr(name)_zstr(name)) {
1194 name = caller_profile->callee_id_name;
1195 }
1196
1197 if (zstr(number)_zstr(number)) {
1198 number = caller_profile->callee_id_number;
1199 }
1200
1201 if (zstr(name)_zstr(name)) {
1202 name = number;
1203 }
1204
1205 if (zstr(number)_zstr(number)) {
1206 number = caller_profile->destination_number;
1207 }
1208
1209 if (!zstr(name)_zstr(name) && !strcmp(name,"_undef_")) {
1210 name = "";
1211 }
1212 }
1213
1214 if ((uuid = switch_channel_get_partner_uuid(channel)) && (session_b = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 1214)
)) {
1215 switch_core_session_message_t *msg;
1216 //switch_channel_t *channel_b = switch_core_session_get_channel(session_b);
1217
1218 //switch_channel_set_profile_var(channel_b, "callee_id_name", name);
1219 //switch_channel_set_profile_var(channel_b, "callee_id_number", number);
1220
1221 msg = switch_core_session_alloc(session_b, sizeof(*msg))switch_core_perform_session_alloc(session_b, sizeof(*msg), "sofia.c"
, (const char *)__func__, 1221)
;
1222 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 1222
;
1223 msg->message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
1224 msg->string_array_arg[0] = switch_core_session_strdup(session_b, name)switch_core_perform_session_strdup(session_b, name, "sofia.c"
, (const char *)__func__, 1224)
;
1225 msg->string_array_arg[1] = switch_core_session_strdup(session_b, number)switch_core_perform_session_strdup(session_b, number, "sofia.c"
, (const char *)__func__, 1225)
;
1226 msg->from = __FILE__"sofia.c";
1227 switch_core_session_queue_message(session_b, msg);
1228 switch_core_session_rwunlock(session_b);
1229 }
1230}
1231
1232void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip,
1233 switch_bool_t send)
1234{
1235 switch_channel_t *channel = switch_core_session_get_channel(session);
1236 sip_p_asserted_identity_t *passerted = NULL((void*)0);
1237 char *name = NULL((void*)0);
1238 const char *number = "unknown", *tmp;
1239 switch_caller_profile_t *caller_profile;
1240 char *dup = NULL((void*)0);
1241 switch_event_t *event;
1242 const char *val;
1243 int fs = 0, lazy = 0, att = 0;
1244 const char *name_var = "callee_id_name";
1245 const char *num_var = "callee_id_number";
1246
1247 if (switch_true(switch_channel_get_variable(channel, SWITCH_IGNORE_DISPLAY_UPDATES_VARIABLE)switch_channel_get_variable_dup(channel, "ignore_display_updates"
, SWITCH_TRUE, -1)
) || !sofia_test_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)((profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] ? 1 : 0)) {
1248 return;
1249 }
1250
1251
1252 if (switch_channel_inbound_display(channel)((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND
&& !switch_channel_test_flag(channel, CF_BLEG)) || (
switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
&& switch_channel_test_flag(channel, CF_DIALPLAN)))
) {
1253 name_var = "caller_id_name";
1254 num_var = "caller_id_number";
1255 }
1256
1257
1258 number = (char *) switch_channel_get_variable(channel, num_var)switch_channel_get_variable_dup(channel, num_var, SWITCH_TRUE
, -1)
;
1259 name = (char *) switch_channel_get_variable(channel, name_var)switch_channel_get_variable_dup(channel, name_var, SWITCH_TRUE
, -1)
;
1260
1261
1262 if (zstr(number)_zstr(number) && sip->sip_to) {
1263 number = sip->sip_to->a_url->url_user;
1264 }
1265
1266 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Display-Number"))) {
1267 number = val;
1268 fs++;
1269 }
1270
1271 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Display-Name"))) {
1272 name = (char *) val;
1273 check_decode(name, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 1273, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(name)
) { int d = 0; char *p; if (strchr(name, '%')) { char *tmp = switch_core_perform_session_strdup
(session, name, "sofia.c", (const char *)__func__, 1273); switch_url_decode
(tmp); name = tmp; d++; } if ((p = strchr(name, '"'))) { if (
!d) { char *tmp = switch_core_perform_session_strdup(session,
name, "sofia.c", (const char *)__func__, 1273); name = tmp; }
if ((p = strchr(name, '"'))) { name = p+1; } if ((p = strrchr
(name, '"'))) { *p = '\0'; } } } break; } while (0)
;
1274 fs++;
1275 }
1276
1277 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Lazy-Attended-Transfer"))) {
1278 lazy = switch_true(val);
1279 fs++;
1280 }
1281
1282 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Attended-Transfer"))) {
1283 att = switch_true(val);
1284 fs++;
1285 }
1286
1287 if (!fs) {
1288 sip_remote_party_id_t *rpid;
1289 if ((passerted = sip_p_asserted_identity(sip)((sip_p_asserted_identity_t *)msg_header_access((msg_pub_t*)(
sip), sip_p_asserted_identity_class))
)) {
1290 if (passerted->paid_url->url_user) {
1291 number = passerted->paid_url->url_user;
1292 }
1293 if (!zstr(passerted->paid_display)_zstr(passerted->paid_display)) {
1294 dup = strdup(passerted->paid_display);
1295 switch_assert(dup)((dup) ? (void) (0) : __assert_fail ("dup", "sofia.c", 1295, __extension__
__PRETTY_FUNCTION__))
;
1296 if (*dup == '"') {
1297 name = dup + 1;
1298 } else {
1299 name = dup;
1300 }
1301 if (end_of(name)*(*name == '\0' ? name : name + strlen(name) - 1) == '"') {
1302 end_of(name)*(*name == '\0' ? name : name + strlen(name) - 1) = '\0';
1303 }
1304 }
1305 } else if ((rpid = sip_remote_party_id(sip)((sip_remote_party_id_t *)msg_header_access((msg_pub_t*)(sip)
, sip_remote_party_id_class))
)) {
1306 if (rpid->rpid_url->url_user) {
1307 number = rpid->rpid_url->url_user;
1308 }
1309 if (!zstr(rpid->rpid_display)_zstr(rpid->rpid_display)) {
1310 dup = strdup(rpid->rpid_display);
1311 switch_assert(dup)((dup) ? (void) (0) : __assert_fail ("dup", "sofia.c", 1311, __extension__
__PRETTY_FUNCTION__))
;
1312 if (*dup == '"') {
1313 name = dup + 1;
1314 } else {
1315 name = dup;
1316 }
1317 if (end_of(name)*(*name == '\0' ? name : name + strlen(name) - 1) == '"') {
1318 end_of(name)*(*name == '\0' ? name : name + strlen(name) - 1) = '\0';
1319 }
1320 }
1321 }
1322 }
1323
1324
1325 if (zstr(number)_zstr(number)) {
1326 if ((tmp = switch_channel_get_variable(channel, num_var)switch_channel_get_variable_dup(channel, num_var, SWITCH_TRUE
, -1)
) && !zstr(tmp)_zstr(tmp)) {
1327 number = (char *) tmp;
1328 }
1329
1330 if (zstr(number)_zstr(number)) {
1331 number = "unknown";
1332 }
1333 }
1334
1335 if (zstr(name)_zstr(name)) {
1336 if ((tmp = switch_channel_get_variable(channel, name_var)switch_channel_get_variable_dup(channel, name_var, SWITCH_TRUE
, -1)
) && !zstr(tmp)_zstr(tmp)) {
1337 name = (char *) tmp;
1338 }
1339 }
1340
1341 if (zstr(name)_zstr(name)) {
1342 name = (char *) number;
1343 }
1344
1345 if (zstr(name)_zstr(name) || zstr(number)_zstr(number)) {
1346 goto end;
1347 }
1348
1349 caller_profile = switch_channel_get_caller_profile(channel);
1350
1351 if (switch_channel_inbound_display(channel)((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND
&& !switch_channel_test_flag(channel, CF_BLEG)) || (
switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
&& switch_channel_test_flag(channel, CF_DIALPLAN)))
) {
1352
1353 if (!strcmp(caller_profile->caller_id_name, name) && !strcmp(caller_profile->caller_id_number, number)) {
1354 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1354
, ((void*)0)
, SWITCH_LOG_DEBUG1, "%s Same Caller ID \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1355 send = 0;
1356 } else {
1357 caller_profile->caller_id_name = switch_sanitize_number(switch_core_strdup(caller_profile->pool, name)switch_core_perform_strdup(caller_profile->pool, name, "sofia.c"
, (const char *)__func__, 1357)
);
1358 caller_profile->caller_id_number = switch_sanitize_number(switch_core_strdup(caller_profile->pool, number)switch_core_perform_strdup(caller_profile->pool, number, "sofia.c"
, (const char *)__func__, 1358)
);
1359 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1359
, ((void*)0)
, SWITCH_LOG_INFO, "%s Update Caller ID to \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1360 }
1361
1362 } else {
1363
1364 if (!strcmp(caller_profile->callee_id_name, name) && !strcmp(caller_profile->callee_id_number, number)) {
1365 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1365
, ((void*)0)
, SWITCH_LOG_DEBUG1, "%s Same Callee ID \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1366 send = 0;
1367 } else {
1368 caller_profile->callee_id_name = switch_sanitize_number(switch_core_strdup(caller_profile->pool, name)switch_core_perform_strdup(caller_profile->pool, name, "sofia.c"
, (const char *)__func__, 1368)
);
1369 caller_profile->callee_id_number = switch_sanitize_number(switch_core_strdup(caller_profile->pool, number)switch_core_perform_strdup(caller_profile->pool, number, "sofia.c"
, (const char *)__func__, 1369)
);
1370 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1370
, ((void*)0)
, SWITCH_LOG_INFO, "%s Update Callee ID to \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1371
1372 if (lazy || (att && !switch_channel_get_partner_uuid(channel))) {
1373 switch_channel_flip_cid(channel);
1374 }
1375 }
1376 }
1377
1378 if (send) {
1379
1380 if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 1380, &event, SWITCH_EVENT_CALL_UPDATE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1381 const char *uuid = switch_channel_get_partner_uuid(channel);
1382 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "RECV");
1383 if (uuid) {
1384 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
1385 }
1386 switch_channel_event_set_data(channel, event);
1387 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 1387, &event, ((void*)0))
;
1388 }
1389
1390 sofia_send_callee_id(session, NULL((void*)0), NULL((void*)0));
1391 }
1392
1393 end:
1394 switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);};
1395}
1396
1397static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const char *r_sdp)
1398{
1399 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)
;
1400 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)
;
1401 int soa = sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0);
1402 const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
1403
1404 if (sofia_test_pflag(tech_pvt->profile, PFLAG_TRACK_CALLS)((tech_pvt->profile)->pflags[PFLAG_TRACK_CALLS] ? 1 : 0
)
) {
1405 const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via")switch_channel_get_variable_dup(tech_pvt->channel, "sip_invite_full_via"
, SWITCH_TRUE, -1)
;
1406 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)
;
1407
1408 nua_ack(nh,
1409 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
)
,
1410 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
)
,
1411 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)
,
1412 TAG_IF((zstr(tech_pvt->user_via) && !zstr(invite_full_via)), SIPTAG_VIA_STR(invite_full_via))!((_zstr(tech_pvt->user_via) && !_zstr(invite_full_via
))) ? tag_skip : siptag_via_str, tag_str_v(invite_full_via)
,
1413 TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri))!(!_zstr(invite_route_uri)) ? tag_skip : siptag_route_str, tag_str_v
(invite_route_uri)
,
1414 TAG_IF(r_sdp && soa, SOATAG_USER_SDP_STR(r_sdp))!(r_sdp && soa) ? tag_skip : soatag_user_sdp_str, tag_str_v
(r_sdp)
,
1415 TAG_IF(r_sdp && soa, SOATAG_REUSE_REJECTED(1))!(r_sdp && soa) ? tag_skip : soatag_reuse_rejected, tag_bool_v
(1)
,
1416 TAG_IF(r_sdp && soa, SOATAG_AUDIO_AUX("cn telephone-event"))!(r_sdp && soa) ? tag_skip : soatag_audio_aux, tag_str_v
("cn telephone-event")
,
1417 TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp"))!(r_sdp && !soa) ? tag_skip : siptag_content_type_str
, tag_str_v("application/sdp")
,
1418 TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp))!(r_sdp && !soa) ? tag_skip : siptag_payload_str, tag_str_v
(r_sdp)
,
1419 TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0))!(r_sdp && !soa) ? tag_skip : nutag_media_enable, tag_bool_v
(0)
,
1420 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))
,
1421 TAG_END()(tag_type_t)0, (tag_value_t)0);
1422 } else {
1423 nua_ack(nh,
1424 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
)
,
1425 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
)
,
1426 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)
,
1427 TAG_IF(r_sdp && soa, SOATAG_USER_SDP_STR(r_sdp))!(r_sdp && soa) ? tag_skip : soatag_user_sdp_str, tag_str_v
(r_sdp)
,
1428 TAG_IF(r_sdp && soa, SOATAG_REUSE_REJECTED(1))!(r_sdp && soa) ? tag_skip : soatag_reuse_rejected, tag_bool_v
(1)
,
1429 TAG_IF(r_sdp && soa, SOATAG_AUDIO_AUX("cn telephone-event"))!(r_sdp && soa) ? tag_skip : soatag_audio_aux, tag_str_v
("cn telephone-event")
,
1430 TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp"))!(r_sdp && !soa) ? tag_skip : siptag_content_type_str
, tag_str_v("application/sdp")
,
1431 TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp))!(r_sdp && !soa) ? tag_skip : siptag_payload_str, tag_str_v
(r_sdp)
,
1432 TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0))!(r_sdp && !soa) ? tag_skip : nutag_media_enable, tag_bool_v
(0)
,
1433 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))
,
1434 TAG_END()(tag_type_t)0, (tag_value_t)0);
1435 }
1436
1437}
1438
1439static void notify_watched_header(switch_core_session_t *session, const char *msgline, const char *hdrname, const char *hdrval)
1440{
1441 switch_event_t *event = NULL((void*)0);
1442 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
1442, (const char*)(session)
, SWITCH_LOG_DEBUG, "Found known watched header in message '%s', %s: %s\n", msgline, hdrname, hdrval);
1443 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_NOTIFY_WATCHED_HEADER)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 1443, &event, SWITCH_EVENT_CUSTOM
, "sofia::notify_watched_header")
== SWITCH_STATUS_SUCCESS) {
1444 switch_channel_t *channel = switch_core_session_get_channel(session);
1445 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Message", msgline);
1446 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Header-Name", hdrname);
1447 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Header-Value", hdrval);
1448 switch_channel_event_set_data(channel, event);
1449 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 1449, &event, ((void*)0))
;
1450 } else {
1451 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
1451, (const char*)(session)
, SWITCH_LOG_CRIT, "Failed creating event of type %s!\n", MY_EVENT_NOTIFY_WATCHED_HEADER"sofia::notify_watched_header");
1452 }
1453}
1454
1455
1456static void sofia_handle_sip_r_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, int status, const char *phrase, sip_t const *sip, sofia_dispatch_event_t *de, tagi_t tags[])
1457{
1458 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
1459 switch_core_session_t *other_session;
1460 switch_channel_t *channel = switch_core_session_get_channel(session);
1461
1462 switch_channel_set_variable_printf(channel, "sip_refer_status_code", "%d", status);
1463
1464 if (status < 200) {
1465 return;
1466 }
1467
1468 if (tech_pvt->proxy_refer_uuid && (other_session = switch_core_session_locate(tech_pvt->proxy_refer_uuid)switch_core_session_perform_locate(tech_pvt->proxy_refer_uuid
, "sofia.c", (const char *)__func__, 1468)
)) {
1469 switch_core_session_message_t *msg;
1470
1471 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 1471)
;
1472 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
1473 msg->from = __FILE__"sofia.c";
1474 msg->numeric_arg = status;
1475 msg->string_arg = switch_core_session_strdup(other_session, phrase)switch_core_perform_session_strdup(other_session, phrase, "sofia.c"
, (const char *)__func__, 1475)
;
1476 switch_core_session_queue_message(other_session, msg);
1477 switch_core_session_rwunlock(other_session);
1478 } else {
1479 tech_pvt->proxy_refer_uuid = NULL((void*)0);
1480 }
1481}
1482
1483
1484
1485
1486//sofia_dispatch_event_t *de
1487static void our_sofia_event_callback(nua_event_t event,
1488 int status,
1489 char const *phrase,
1490 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
1491 sofia_dispatch_event_t *de, tagi_t tags[])
1492{
1493 struct private_object *tech_pvt = NULL((void*)0);
1494 auth_res_t auth_res = AUTH_FORBIDDEN;
1495 switch_core_session_t *session = NULL((void*)0);
1496 switch_channel_t *channel = NULL((void*)0);
1497 sofia_gateway_t *gateway = NULL((void*)0);
1498 int locked = 0;
1499 int check_destroy = 1;
1500
1501 profile->last_sip_event = switch_time_now();
1502
1503 /* sofia_private will be == &mod_sofia_globals.keep_private whenever a request is done with a new handle that has to be
1504 freed whenever the request is done */
1505 if (nh && sofia_private == &mod_sofia_globals.keep_private) {
1506 if (status >= 300) {
1507 nua_handle_bind(nh, NULL((void*)0));
1508 nua_handle_destroy(nh);
1509 return;
1510 }
1511 }
1512
1513
1514 if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
1515 if (!zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
1516 if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 1516
, sofia_private->gateway_name)
)) {
1517 return;
1518 }
1519 } else if (!zstr(sofia_private->uuid)_zstr(sofia_private->uuid)) {
1520 if ((session = de->init_session)) {
1521 de->init_session = NULL((void*)0);
1522 } else if ((session = de->session) || (session = switch_core_session_locate(sofia_private->uuid)switch_core_session_perform_locate(sofia_private->uuid, "sofia.c"
, (const char *)__func__, 1522)
)) {
1523 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
1524 channel = switch_core_session_get_channel(session);
1525 if (tech_pvt) {
1526 switch_mutex_lock(tech_pvt->sofia_mutex);
1527 locked = 1;
1528 } else {
1529 if (session != de->session) switch_core_session_rwunlock(session);
1530 return;
1531 }
1532
1533 if (status >= 180 && !*sofia_private->auth_gateway_name) {
1534 const char *gwname = switch_channel_get_variable(channel, "sip_use_gateway")switch_channel_get_variable_dup(channel, "sip_use_gateway", SWITCH_TRUE
, -1)
;
1535 if (!zstr(gwname)_zstr(gwname)) {
1536 switch_set_string(sofia_private->auth_gateway_name, gwname)switch_copy_string(sofia_private->auth_gateway_name, gwname
, sizeof(sofia_private->auth_gateway_name))
;
1537 }
1538 }
1539 if (!tech_pvt->call_id && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
1540 tech_pvt->call_id = switch_core_session_strdup(session, sip->sip_call_id->i_id)switch_core_perform_session_strdup(session, sip->sip_call_id
->i_id, "sofia.c", (const char *)__func__, 1540)
;
1541 switch_channel_set_variable(channel, "sip_call_id", tech_pvt->call_id)switch_channel_set_variable_var_check(channel, "sip_call_id",
tech_pvt->call_id, SWITCH_TRUE)
;
1542 }
1543
1544 if (tech_pvt->gateway_name) {
1545 gateway = sofia_reg_find_gateway(tech_pvt->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 1545
, tech_pvt->gateway_name)
;
1546 }
1547
1548 if (channel && switch_channel_down(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) >= CS_HANGUP)
) {
1549 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
1549, (const char*)(session)
, SWITCH_LOG_DEBUG, "Channel is already hungup.\n");
1550 goto done;
1551 }
1552 } else {
1553 /* we can't find the session it must be hanging up or something else, its too late to do anything with it. */
1554 return;
1555 }
1556 }
1557 }
1558
1559 if (session && tech_pvt && tech_pvt->watch_headers && sip) {
1560 char msgline[512];
1561 int hi;
1562 msg_header_t *h = NULL((void*)0);
1563 if (sip->sip_request) {
1564 h = (msg_header_t *)sip->sip_request;
1565 msg_header_field_e(msgline, sizeof(msgline), h, 0);
1566 } else if (sip->sip_status) {
1567 h = (msg_header_t *)sip->sip_status;
1568 msg_header_field_e(msgline, sizeof(msgline), h, 0);
1569 }
1570 if (h) {
1571 sip_unknown_t *un = NULL((void*)0);
1572 char buf[512];
1573 char *c = NULL((void*)0);
1574
1575 msgline[sizeof(msgline)-1] = '\0';
1576 c = strchr(msgline, '\r');
1577 if (c) {
1578 *c = '\0';
1579 }
1580
1581 /* Faster (ie hash-based) search here would be nice? ie, make watch_headers a hash? */
1582
1583 /* Search first in the valid headers */
1584 for (h = h->sh_succsh_common->h_succ; h; h = h->sh_succsh_common->h_succ) {
1585 sip_header_t *sh = (sip_header_t *)h;
1586 if (!sh->sh_classsh_common->h_class->hc_name) {
1587 continue;
1588 }
1589 for (hi = 0; tech_pvt->watch_headers[hi]; hi++) {
1590 if (!strcasecmp(tech_pvt->watch_headers[hi], sh->sh_classsh_common->h_class->hc_name)) {
1591 msg_header_field_e(buf, sizeof(buf), h, 0);
1592 buf[sizeof(buf)-1] = '\0';
1593 notify_watched_header(session, msgline, sh->sh_classsh_common->h_class->hc_name, buf);
1594 }
1595 }
1596 }
1597
1598 /* Search now in the unknown headers */
1599 for (un = sip->sip_unknown; un; un = un->un_next) {
1600 for (hi = 0; tech_pvt->watch_headers[hi]; hi++) {
1601 if (!strcasecmp(tech_pvt->watch_headers[hi], un->un_name)) {
1602 notify_watched_header(session, msgline, un->un_name, un->un_value);
1603 }
1604 }
1605 }
1606 }
1607 }
1608
1609 if (sofia_test_pflag(profile, PFLAG_AUTH_ALL)((profile)->pflags[PFLAG_AUTH_ALL] ? 1 : 0) && tech_pvt && tech_pvt->key && sip && (event < nua_r_set_params || event > nua_r_authenticate)) {
1610 sip_authorization_t const *authorization = NULL((void*)0);
1611
1612 if (sip->sip_authorization) {
1613 authorization = sip->sip_authorization;
1614 } else if (sip->sip_proxy_authorization) {
1615 authorization = sip->sip_proxy_authorization;
1616 }
1617
1618 if (authorization && sip->sip_request) {
1619 char network_ip[80] = "";
1620 int network_port;
1621 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
1622 auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
1623 (char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, network_port, NULL((void*)0), 0,
1624 REG_INVITE, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
1625 }
1626
1627 if ((auth_res != AUTH_OK && auth_res != AUTH_RENEWED)) {
1628 //switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
1629 nua_respond(nh, SIP_401_UNAUTHORIZED401, sip_401_Unauthorized, TAG_END()(tag_type_t)0, (tag_value_t)0);
1630 goto done;
1631 }
1632
1633 if (channel) {
1634 switch_channel_set_variable(channel, "sip_authorized", "true")switch_channel_set_variable_var_check(channel, "sip_authorized"
, "true", SWITCH_TRUE)
;
1635 }
1636 }
1637
1638 if (sip && (status == 401 || status == 407)) {
1639 sofia_reg_handle_sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, session, gateway, sip, de, tags);
1640 goto done;
1641 }
1642
1643 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
1644 if (sip->sip_payload->pl_len != strlen(sip->sip_payload->pl_data)) {
1645 sip->sip_payload->pl_data = su_strndup(nua_handle_get_home(nh), sip->sip_payload->pl_data, sip->sip_payload->pl_len);
1646 }
1647 }
1648
1649 switch (event) {
1650 case nua_r_get_params:
1651 case nua_i_fork:
1652 case nua_r_info:
1653 break;
1654 case nua_r_unregister:
1655 case nua_r_unsubscribe:
1656 case nua_i_terminated:
1657 case nua_r_publish:
1658 case nua_i_error:
1659 case nua_i_active:
1660 case nua_r_set_params:
1661 case nua_i_prack:
1662 case nua_r_prack:
1663 break;
1664
1665 case nua_i_cancel:
1666
1667 if (sip && channel) {
1668 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_cancel")switch_channel_set_variable_var_check(channel, "sip_hangup_disposition"
, "recv_cancel", SWITCH_TRUE)
;
1669 switch_channel_set_variable(channel, "sip_invite_failure_status", "487")switch_channel_set_variable_var_check(channel, "sip_invite_failure_status"
, "487", SWITCH_TRUE)
;
1670 switch_channel_set_variable(channel, "sip_invite_failure_phrase", "CANCEL")switch_channel_set_variable_var_check(channel, "sip_invite_failure_phrase"
, "CANCEL", SWITCH_TRUE)
;
1671
1672 if (sip->sip_reason) {
1673 char *reason_header = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_reason);
1674
1675 if (!zstr(reason_header)_zstr(reason_header)) {
1676 switch_channel_set_variable(channel, "sip_reason", reason_header)switch_channel_set_variable_var_check(channel, "sip_reason", reason_header
, SWITCH_TRUE)
;
1677 switch_channel_set_variable_partner(channel, "sip_reason", reason_header)switch_channel_set_variable_partner_var_check(channel, "sip_reason"
, reason_header, SWITCH_TRUE)
;
1678 }
1679 }
1680 }
1681
1682 break;
1683 case nua_r_cancel:
1684 {
1685 if (status > 299 && nh) {
1686 nua_handle_destroy(nh);
1687 }
1688 }
1689 break;
1690 case nua_i_ack:
1691 {
1692 if (channel && sip) {
1693 const char *r_sdp = NULL((void*)0);
1694 sofia_glue_store_session_id(session, profile, sip, 0);
1695
1696 if (sip->sip_payload && sip->sip_payload->pl_data) {
1697 if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)((tech_pvt)->flags[TFLAG_PASS_ACK] ? 1 : 0)) {
1698 r_sdp = sip->sip_payload->pl_data;
1699
1700 if (tech_pvt->mparams.last_sdp_str) {
1701 tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
1702 }
1703 tech_pvt->mparams.last_sdp_str = NULL((void*)0);
1704
1705
1706 if (!zstr(tech_pvt->mparams.prev_sdp_str)_zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) {
1707 switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data)switch_channel_set_variable_var_check(channel, "sip_reinvite_sdp"
, sip->sip_payload->pl_data, SWITCH_TRUE)
;
1708 tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data)switch_core_perform_session_strdup(session, sip->sip_payload
->pl_data, "sofia.c", (const char *)__func__, 1708)
;
1709 } else {
1710 tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str;
1711 }
1712 } else {
1713 switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data)switch_channel_set_variable_var_check(channel, "sip_reinvite_sdp"
, sip->sip_payload->pl_data, SWITCH_TRUE)
;
1714 tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data)switch_core_perform_session_strdup(session, sip->sip_payload
->pl_data, "sofia.c", (const char *)__func__, 1714)
;
1715 }
1716 }
1717
1718 if (sip->sip_to && sip->sip_to->a_tag) {
1719 switch_channel_set_variable(channel, "sip_to_tag", sip->sip_to->a_tag)switch_channel_set_variable_var_check(channel, "sip_to_tag", sip
->sip_to->a_tag, SWITCH_TRUE)
;
1720 }
1721
1722 if (sip->sip_from && sip->sip_from->a_tag) {
1723 switch_channel_set_variable(channel, "sip_from_tag", sip->sip_from->a_tag)switch_channel_set_variable_var_check(channel, "sip_from_tag"
, sip->sip_from->a_tag, SWITCH_TRUE)
;
1724 }
1725
1726 if (sip->sip_cseq && sip->sip_cseq->cs_seq) {
1727 char sip_cseq[40] = "";
1728 switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq);
1729 switch_channel_set_variable(channel, "sip_cseq", sip_cseq)switch_channel_set_variable_var_check(channel, "sip_cseq", sip_cseq
, SWITCH_TRUE)
;
1730 }
1731
1732 if (sip->sip_call_id && sip->sip_call_id->i_id) {
1733 switch_channel_set_variable(channel, "sip_call_id", sip->sip_call_id->i_id)switch_channel_set_variable_var_check(channel, "sip_call_id",
sip->sip_call_id->i_id, SWITCH_TRUE)
;
1734 }
1735
1736 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
1737 switch_channel_set_variable(channel, "dlg_req_swap_direction", "true")switch_channel_set_variable_var_check(channel, "dlg_req_swap_direction"
, "true", SWITCH_TRUE)
;
1738 }
1739
1740 extract_header_vars(profile, sip, session, nh);
1741 switch_core_recovery_track(session);
1742 sofia_set_flag(tech_pvt, TFLAG_GOT_ACK)(tech_pvt)->flags[TFLAG_GOT_ACK] = 1;
1743
1744 if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) && r_sdp) {
1745 if (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY)((tech_pvt->profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
1746 switch_channel_set_variable_partner(tech_pvt->channel, SWITCH_B_SDP_VARIABLE, r_sdp)switch_channel_set_variable_partner_var_check(tech_pvt->channel
, "switch_m_sdp", r_sdp, SWITCH_TRUE)
;
1747
1748 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
1748, (const char*)(tech_pvt->session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
1749 sofia_media_activate_rtp(tech_pvt);
1750 switch_core_media_proxy_remote_addr(tech_pvt->session, r_sdp);
1751 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
1752 sofia_clear_flag(tech_pvt, TFLAG_PASS_ACK)(tech_pvt)->flags[TFLAG_PASS_ACK] = 0;
1753
1754 }
1755
1756 }
1757
1758
1759 if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)((tech_pvt)->flags[TFLAG_PASS_ACK] ? 1 : 0)) {
1760 switch_core_session_t *other_session;
1761
1762 sofia_clear_flag(tech_pvt, TFLAG_PASS_ACK)(tech_pvt)->flags[TFLAG_PASS_ACK] = 0;
1763
1764 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 1764)
== SWITCH_STATUS_SUCCESS) {
1765 if (switch_core_session_compare(session, other_session)) {
1766 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
1767 tech_send_ack(other_tech_pvt->nh, other_tech_pvt, r_sdp);
1768 }
1769 switch_core_session_rwunlock(other_session);
1770 }
1771
1772 }
1773
1774
1775 }
1776 }
1777 case nua_r_ack:
1778 if (channel)
1779 switch_channel_set_flag(channel, CF_MEDIA_ACK)switch_channel_set_flag_value(channel, CF_MEDIA_ACK, 1);
1780 break;
1781 case nua_r_shutdown:
1782 if (status >= 200) {
1783 sofia_set_pflag(profile, PFLAG_SHUTDOWN)(profile)->pflags[PFLAG_SHUTDOWN] = 1;
1784 su_root_break(profile->s_root);
1785 }
1786 break;
1787 case nua_r_message:
1788 sofia_handle_sip_r_message(status, profile, nh, sip);
1789 break;
1790 case nua_r_invite:
1791 sofia_handle_sip_r_invite(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1792 break;
1793 case nua_r_options:
1794 sofia_handle_sip_r_options(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1795 break;
1796 case nua_i_bye:
1797 sofia_handle_sip_i_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1798 break;
1799 case nua_r_bye:
1800 sofia_handle_sip_r_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1801 break;
1802 case nua_r_notify:
1803 if (session) {
1804 sofia_handle_sip_r_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1805 }
1806 break;
1807 case nua_i_notify:
1808 sofia_handle_sip_i_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1809 break;
1810 case nua_r_register:
1811 sofia_reg_handle_sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1812 break;
1813 case nua_i_options:
1814 sofia_handle_sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1815 break;
1816 case nua_i_invite:
1817 if (session && sofia_private) {
1818 if (sofia_private->is_call > 1) {
1819 sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, de, tags);
1820 } else {
1821 sofia_private->is_call++;
1822 sofia_handle_sip_i_invite(session, nua, profile, nh, sofia_private, sip, de, tags);
1823 }
1824 }
1825 break;
1826 case nua_i_publish:
1827 sofia_presence_handle_sip_i_publish(nua, profile, nh, sofia_private, sip, de, tags);
1828 break;
1829 case nua_i_register:
1830 //nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
1831 //nua_handle_destroy(nh);
1832 sofia_reg_handle_sip_i_register(nua, profile, nh, &sofia_private, sip, de, tags);
1833 break;
1834 case nua_i_state:
1835 sofia_handle_sip_i_state(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1836 break;
1837 case nua_i_message:
1838 {
1839 int handle_message = 1;
1840 int proxy_message = sofia_test_pflag(profile, PFLAG_PROXY_MESSAGE)((profile)->pflags[PFLAG_PROXY_MESSAGE] ? 1 : 0);
1841
1842 if (!proxy_message && session) {
1843 switch_channel_t *channel = switch_core_session_get_channel(session);
1844 proxy_message = switch_channel_var_true(channel, "sip_proxy_message");
1845 }
1846
1847 if (proxy_message) {
1848 if (sofia_proxy_sip_i_message(nua, profile, nh, session, sip, de, tags) == SWITCH_STATUS_SUCCESS) {
1849 handle_message = 0;
1850 }
1851 }
1852
1853 if (handle_message) {
1854 sofia_presence_handle_sip_i_message(status, phrase, nua, profile, nh, session, sofia_private, sip, de, tags);
1855 }
1856 }
1857 break;
1858 case nua_i_info:
1859 {
1860 int handle_info = 1;
1861 int proxy_info = sofia_test_pflag(profile, PFLAG_PROXY_INFO)((profile)->pflags[PFLAG_PROXY_INFO] ? 1 : 0);
1862
1863 if (!proxy_info && session) {
1864 switch_channel_t *channel = switch_core_session_get_channel(session);
1865 proxy_info = switch_channel_var_true(channel, "sip_proxy_info");
1866 }
1867
1868 if (proxy_info) {
1869 if (sofia_proxy_sip_i_info(nua, profile, nh, session, sip, de, tags) == SWITCH_STATUS_SUCCESS) {
1870 handle_info = 0;
1871 }
1872 }
1873
1874 if (handle_info) {
1875 sofia_handle_sip_i_info(nua, profile, nh, session, sip, de, tags);
1876 }
1877
1878 }
1879 break;
1880 case nua_i_update:
1881 if (session) {
1882 sofia_update_callee_id(session, profile, sip, SWITCH_TRUE);
1883 }
1884 break;
1885 case nua_r_update:
1886 if (session && tech_pvt && locked) {
1887 sofia_clear_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_UPDATING_DISPLAY] = 0; switch_mutex_unlock(tech_pvt->
flag_mutex);
;
1888 }
1889 break;
1890 case nua_r_refer:
1891 if (session) {
1892 sofia_handle_sip_r_refer(nua, profile, nh, session, status, phrase, sip, de, tags);
1893 }
1894 break;
1895 case nua_i_refer:
1896 if (session) {
1897 sofia_handle_sip_i_refer(nua, profile, nh, session, sip, de, tags);
1898 } else if (sip) {
1899 const char *req_user = NULL((void*)0), *req_host = NULL((void*)0), *action = NULL((void*)0), *ref_by_user = NULL((void*)0), *ref_to_user = NULL((void*)0), *ref_to_host = NULL((void*)0);
1900 char *refer_to = NULL((void*)0), *referred_by = NULL((void*)0), *method = NULL((void*)0), *full_url = NULL((void*)0);
1901 char *params = NULL((void*)0), *iparams = NULL((void*)0);
1902 switch_event_t *event;
1903 char *tmp;
1904
1905 if (sip->sip_refer_to) {
1906 ref_to_user = sip->sip_refer_to->r_url->url_user;
1907 ref_to_host = sip->sip_refer_to->r_url->url_host;
1908
1909 if (sip->sip_refer_to->r_url->url_params && switch_stristr("method=", sip->sip_refer_to->r_url->url_params)) {
1910 params = su_strdup(nua_handle_home(nh)((su_home_t *)(nh)), sip->sip_refer_to->r_url->url_params);
1911 }
1912
1913
1914 if ((refer_to = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_refer_to))) {
1915 if ((iparams = strchr(refer_to, ';'))) {
1916 *iparams++ = '\0';
1917
1918 if (!params || !switch_stristr("method=", params)) {
1919 params = iparams;
1920 }
1921 }
1922
1923 if ((tmp = sofia_glue_get_url_from_contact(refer_to, 0))) {
1924 refer_to = tmp;
1925 }
1926 }
1927
1928 if (params) {
1929 method = switch_find_parameter(params, "method", NULL((void*)0));
1930 full_url = switch_find_parameter(params, "full_url", NULL((void*)0));
1931 }
1932
1933
1934 }
1935
1936 if (!method) {
1937 method = strdup("INVITE");
1938 switch_assert(method)((method) ? (void) (0) : __assert_fail ("method", "sofia.c", 1938
, __extension__ __PRETTY_FUNCTION__))
;
1939 }
1940
1941 if (!strcasecmp(method, "INVITE")) {
1942 action = "call";
1943 } else if (!strcasecmp(method, "BYE")) {
1944 action = "end";
1945 } else {
1946 action = method;
1947 }
1948
1949 if (sip->sip_referred_by) {
1950 referred_by = sofia_glue_get_url_from_contact(sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_referred_by), 0);
1951 ref_by_user = sip->sip_referred_by->b_url->url_user;
1952 } else if(sip->sip_to){
1953 referred_by = sofia_glue_get_url_from_contact(sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_to), 0);
1954 ref_by_user = sip->sip_to->a_url->url_user;
1955 }
1956
1957 if (sip->sip_to) {
1958 req_user = sip->sip_to->a_url->url_user;
1959 req_host = sip->sip_to->a_url->url_host;
1960 }
1961
1962 if (switch_event_create(&event, SWITCH_EVENT_CALL_SETUP_REQ)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 1962, &event, SWITCH_EVENT_CALL_SETUP_REQ
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1963 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Requesting-Component", "mod_sofia");
1964 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Component", req_user);
1965 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Domain", req_host);
1966 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Action", action);
1967 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Target", "sofia/%s/%s", profile->name, refer_to);
1968 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Target-URI", "%s", refer_to);
1969 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Target-Extension", ref_to_user);
1970 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Target-Domain", ref_to_host);
1971 if (switch_true(full_url)) {
1972 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "full_url", "true");
1973 }
1974
1975 if (sip->sip_call_id && sip->sip_call_id->i_id) {
1976 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Call-ID", sip->sip_call_id->i_id);
1977 }
1978
1979 if (!zstr(referred_by)_zstr(referred_by)) {
1980 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Sender", "sofia/%s/%s", profile->name, referred_by);
1981 }
1982
1983 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_number", ref_by_user);
1984 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_name", ref_by_user);
1985 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 1985, &event, ((void*)0))
;
1986 }
1987
1988
1989
1990 {
1991 char *sql;
1992 sofia_nat_parse_t np = { { 0 } };
1993 char *contact_str;
1994 char *proto = "sip", *orig_proto = "sip";
1995 const char *call_id, *full_from, *full_to, *full_via, *from_user = NULL((void*)0), *from_host = NULL((void*)0), *to_user, *to_host, *full_agent;
1996 char to_tag[13] = "";
1997 char *event_str = "refer";
1998 sip_accept_t *ap = sip->sip_accept;
1999 char accept_header[256] = "";
2000
2001 np.fs_path = 1;
2002 contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, &np);
2003
2004 call_id = sip->sip_call_id ? sip->sip_call_id->i_id : "";
2005 full_from = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_from);
2006 full_to = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_to);
2007 full_via = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_via);
2008
2009 full_agent = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_user_agent);
2010
2011 switch_stun_random_string(to_tag, 12, NULL((void*)0));
2012
2013 if (sip->sip_from) {
2014 from_user = sip->sip_from->a_url->url_user;
2015 from_host = sip->sip_from->a_url->url_host;
2016 } else {
2017 from_user = "n/a";
2018 from_host = "n/a";
2019 }
2020
2021 if (sip->sip_to) {
2022 to_user = sip->sip_to->a_url->url_user;
2023 to_host = sip->sip_to->a_url->url_host;
2024 } else {
2025 to_user = "n/a";
2026 to_host = "n/a";
2027 }
2028
2029 while (ap) {
2030 switch_snprintf(accept_header + strlen(accept_header), sizeof(accept_header) - strlen(accept_header),
2031 "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
2032 ap = ap->ac_next;
2033 }
2034
2035 sql = switch_mprintf("insert into sip_subscriptions "
2036 "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
2037 "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip,version,orig_proto, full_to) "
2038 "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q',-1,'%q','%q;tag=%q')",
2039 proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : "",
2040 event_str, contact_str, call_id, full_from, full_via,
2041 (long) switch_epoch_time_now(NULL((void*)0)) + 60,
2042 full_agent, accept_header, profile->name, mod_sofia_globals.hostname,
2043 np.network_port, np.network_ip, orig_proto, full_to, to_tag);
2044
2045 switch_assert(sql != NULL)((sql != ((void*)0)) ? (void) (0) : __assert_fail ("sql != ((void*)0)"
, "sofia.c", 2045, __extension__ __PRETTY_FUNCTION__))
;
2046
2047
2048 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
2049 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2049
, ((void*)0)
, SWITCH_LOG_CRIT, "%s REFER SUBSCRIBE %s@%s %s@%s\n%s\n",
2050 profile->name, from_user, from_host, to_user, to_host, sql);
2051 }
2052
2053
2054 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
2055
2056 sip_to_tag(nua_handle_get_home(nh), sip->sip_to, to_tag);
2057 }
2058
2059 nua_respond(nh, SIP_202_ACCEPTED202, sip_202_Accepted, SIPTAG_TO(sip->sip_to)siptag_to, siptag_to_v(sip->sip_to), NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
2060 switch_safe_free(method)if (method) {free(method);method=((void*)0);};
2061 switch_safe_free(full_url)if (full_url) {free(full_url);full_url=((void*)0);};
2062
2063 }
2064 break;
2065 case nua_r_subscribe:
2066 sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
2067 break;
2068 case nua_i_subscribe:
2069 sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
2070 break;
2071 case nua_i_media_error:
2072 {
2073
2074 if (sofia_private && sofia_private->call_id && sofia_private->network_ip && sofia_private->network_port) {
2075 char *sql;
2076 switch_event_t *event = NULL((void*)0);
2077
2078 sql = switch_mprintf("delete from sip_registrations where call_id='%q' and network_ip='%q' and network_port='%q'",
2079 sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
2080 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2080
, ((void*)0)
, SWITCH_LOG_DEBUG1, "SOCKET DISCONNECT: %s %s:%s\n",
2081 sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
2082 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2083
2084 switch_core_del_registration(sofia_private->user, sofia_private->realm, sofia_private->call_id);
2085
2086
2087
2088 if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2088, &event, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2089 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
2090 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
2091 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
2092 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent",
2093 (sip && sip->sip_user_agent) ? sip->sip_user_agent->g_string : "unknown");
2094 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", sofia_private->user, sofia_private->realm);
2095 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Unregistered");
2096 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-source", "register");
2097 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
2098 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 2098, &event, ((void*)0))
;
2099 }
2100
2101
2102 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2102, &event, SWITCH_EVENT_CUSTOM
, "sofia::unregister")
== SWITCH_STATUS_SUCCESS) {
2103 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
2104 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from-user", sofia_private->user);
2105 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from-host", sofia_private->realm);
2106 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-id", sofia_private->call_id);
2107 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
2108 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "reason", "socket-disconnection");
2109 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 2109, &event, ((void*)0))
;
2110 }
2111
2112
2113 sofia_reg_check_socket(profile, sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
2114 nua_handle_destroy(nh);
2115 }
2116 }
2117 break;
2118 case nua_r_authenticate:
2119
2120 if (status >= 500) {
2121 if (sofia_private && !zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
2122 sofia_gateway_t *gateway = NULL((void*)0);
2123
2124 if ((gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 2124
, sofia_private->gateway_name)
)) {
2125 gateway->state = REG_STATE_FAILED;
2126 gateway->failure_status = status;
2127 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 2127, gateway);
;
2128 }
2129 } else {
2130 nua_handle_destroy(nh);
2131 }
2132 }
2133
2134 break;
2135 default:
2136 if (status > 100) {
2137 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
2137, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s: unknown event %d: %03d %s\n", nua_event_name(event), event,
2138 status, phrase);
2139 } else {
2140 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
2140, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s: unknown event %d\n", nua_event_name(event), event);
2141 }
2142 break;
2143 }
2144
2145 done:
2146
2147 if (tech_pvt && tech_pvt->want_event && event == tech_pvt->want_event) {
2148 tech_pvt->want_event = 0;
2149 }
2150
2151 if (sofia_private && sofia_private->call_id) {
2152 check_destroy = 0;
2153 }
2154
2155 switch (event) {
2156 case nua_i_subscribe:
2157 case nua_r_notify:
2158 check_destroy = 0;
2159 break;
2160
2161 case nua_i_notify:
2162
2163 if (sip && sip->sip_event && !strcmp(sip->sip_event->o_type, "dialog") && sip->sip_event->o_params && !strcmp(sip->sip_event->o_params[0], "sla")) {
2164 check_destroy = 0;
2165 }
2166
2167 break;
2168 default:
2169 break;
2170 }
2171
2172 if ((sofia_private && sofia_private == &mod_sofia_globals.destroy_private)) {
2173 nua_handle_bind(nh, NULL((void*)0));
2174 nua_handle_destroy(nh);
2175 nh = NULL((void*)0);
2176 }
2177
2178 if (check_destroy) {
2179 if (nh && ((sofia_private && sofia_private->destroy_nh) || !nua_handle_magic(nh))) {
2180 if (sofia_private) {
2181 nua_handle_bind(nh, NULL((void*)0));
2182 }
2183
2184 if (tech_pvt && (tech_pvt->nh == nh)) {
2185 tech_pvt->nh = NULL((void*)0);
2186 }
2187
2188 nua_handle_destroy(nh);
2189 nh = NULL((void*)0);
2190 }
2191 }
2192
2193 if (sofia_private && sofia_private->destroy_me) {
2194 if (tech_pvt) {
2195 tech_pvt->sofia_private = NULL((void*)0);
2196 }
2197
2198 if (nh) {
2199 nua_handle_bind(nh, NULL((void*)0));
2200 }
2201 sofia_private->destroy_me = 12;
2202 sofia_private_free(sofia_private)if (sofia_private && ! sofia_private->is_static) {
free(sofia_private);} sofia_private = ((void*)0);
;
2203
2204 }
2205
2206 if (gateway) {
2207 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 2207, gateway);
;
2208 }
2209
2210 if (locked && tech_pvt) {
2211 switch_mutex_unlock(tech_pvt->sofia_mutex);
2212 }
2213
2214 if (session && session != de->session) {
2215 switch_core_session_rwunlock(session);
2216 }
2217}
2218
2219static uint32_t DE_THREAD_CNT = 0;
2220
2221void *SWITCH_THREAD_FUNC sofia_msg_thread_run_once(switch_thread_t *thread, void *obj)
2222{
2223 sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) obj;
2224 switch_memory_pool_t *pool = NULL((void*)0);
2225
2226 switch_mutex_lock(mod_sofia_globals.mutex);
2227 DE_THREAD_CNT++;
2228 switch_mutex_unlock(mod_sofia_globals.mutex);
2229
2230 if (de) {
2231 pool = de->pool;
2232 de->pool = NULL((void*)0);
2233 sofia_process_dispatch_event(&de);
2234 }
2235
2236 if (pool) {
2237 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia.c",
(const char *)__func__, 2237)
;
2238 }
2239
2240 switch_mutex_lock(mod_sofia_globals.mutex);
2241 DE_THREAD_CNT--;
2242 switch_mutex_unlock(mod_sofia_globals.mutex);
2243
2244 return NULL((void*)0);
2245}
2246
2247void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep)
2248{
2249 sofia_dispatch_event_t *de = *dep;
2250 switch_memory_pool_t *pool;
2251 //sofia_profile_t *profile = (*dep)->profile;
2252 switch_thread_data_t *td;
2253
2254 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "sofia.c", (const
char *)__func__, 2254)
;
2255
2256 *dep = NULL((void*)0);
2257 de->pool = pool;
2258
2259 td = switch_core_alloc(pool, sizeof(*td))switch_core_perform_alloc(pool, sizeof(*td), "sofia.c", (const
char *)__func__, 2259)
;
2260 td->func = sofia_msg_thread_run_once;
2261 td->obj = de;
2262
2263 switch_thread_pool_launch_thread(&td);
2264}
2265
2266void sofia_process_dispatch_event(sofia_dispatch_event_t **dep)
2267{
2268 sofia_dispatch_event_t *de = *dep;
2269 nua_handle_t *nh = de->nh;
2270 nua_t *nua = de->nua;
2271 sofia_profile_t *profile = de->profile;
2272 sofia_private_t *sofia_private = nua_handle_magic(de->nh);
2273 *dep = NULL((void*)0);
2274
2275 our_sofia_event_callback(de->data->e_event, de->data->e_status, de->data->e_phrase, de->nua, de->profile,
2276 de->nh, sofia_private, de->sip, de, (tagi_t *) de->data->e_tags);
2277
2278 nua_destroy_event(de->event);
2279 su_free(nua_handle_get_home(nh), de);
2280
2281 switch_mutex_lock(profile->flag_mutex);
2282 profile->queued_events--;
2283 switch_mutex_unlock(profile->flag_mutex);
2284
2285 /* This is not a stack thread, need to call via stack (_user) using events */
2286 if (nh) nua_handle_unref_user(nh);
2287 nua_unref_user(nua);
2288}
2289
2290
2291
2292static int msg_queue_threads = 0;
2293//static int count = 0;
2294
2295void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj)
2296{
2297 void *pop;
2298 switch_queue_t *q = (switch_queue_t *) obj;
2299 int my_id;
2300
2301
2302 for (my_id = 0; my_id < mod_sofia_globals.msg_queue_len; my_id++) {
2303 if (mod_sofia_globals.msg_queue_thread[my_id] == thread) {
2304 break;
2305 }
2306 }
2307
2308 switch_mutex_lock(mod_sofia_globals.mutex);
2309 msg_queue_threads++;
2310 switch_mutex_unlock(mod_sofia_globals.mutex);
2311
2312 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2312
, ((void*)0)
, SWITCH_LOG_WARNING, "MSG Thread %d Started\n", my_id);
2313
2314
2315 for(;;) {
2316
2317 if (switch_queue_pop(q, &pop) != SWITCH_STATUS_SUCCESS) {
2318 switch_cond_next();
2319 continue;
2320 }
2321
2322 if (pop) {
2323 sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop;
2324 sofia_process_dispatch_event(&de);
2325 } else {
2326 break;
2327 }
2328 }
2329
2330 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2330
, ((void*)0)
, SWITCH_LOG_WARNING, "MSG Thread Ended\n");
2331
2332 switch_mutex_lock(mod_sofia_globals.mutex);
2333 msg_queue_threads--;
2334 switch_mutex_unlock(mod_sofia_globals.mutex);
2335
2336 return NULL((void*)0);
2337}
2338
2339void sofia_msg_thread_start(int idx)
2340{
2341
2342 if (idx >= mod_sofia_globals.max_msg_queues ||
2343 idx >= SOFIA_MAX_MSG_QUEUE64 || (idx < mod_sofia_globals.msg_queue_len && mod_sofia_globals.msg_queue_thread[idx])) {
2344 return;
2345 }
2346
2347 switch_mutex_lock(mod_sofia_globals.mutex);
2348
2349 if (idx >= mod_sofia_globals.msg_queue_len) {
2350 int i;
2351 mod_sofia_globals.msg_queue_len = idx + 1;
2352
2353 for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) {
2354 if (!mod_sofia_globals.msg_queue_thread[i]) {
2355 switch_threadattr_t *thd_attr = NULL((void*)0);
2356
2357 switch_threadattr_create(&thd_attr, mod_sofia_globals.pool);
2358 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
2359 //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
2360 switch_thread_create(&mod_sofia_globals.msg_queue_thread[i],
2361 thd_attr,
2362 sofia_msg_thread_run,
2363 mod_sofia_globals.msg_queue,
2364 mod_sofia_globals.pool);
2365 }
2366 }
2367 }
2368
2369 switch_mutex_unlock(mod_sofia_globals.mutex);
2370}
2371
2372//static int foo = 0;
2373void sofia_queue_message(sofia_dispatch_event_t *de)
2374{
2375 int launch = 0;
2376
2377 if (mod_sofia_globals.running == 0 || !mod_sofia_globals.msg_queue) {
2378 /* Calling with SWITCH_TRUE as we are sure this is the stack's thread */
2379 sofia_process_dispatch_event(&de);
2380 return;
2381 }
2382
2383
2384 if (de->profile && sofia_test_pflag(de->profile, PFLAG_THREAD_PER_REG)((de->profile)->pflags[PFLAG_THREAD_PER_REG] ? 1 : 0) &&
2385 de->data->e_event == nua_i_register && DE_THREAD_CNT < mod_sofia_globals.max_reg_threads) {
2386 sofia_process_dispatch_event_in_thread(&de);
2387 return;
2388 }
2389
2390
2391 if ((switch_queue_size(mod_sofia_globals.msg_queue) > (SOFIA_MSG_QUEUE_SIZE1000 * (unsigned int)msg_queue_threads))) {
2392 launch++;
2393 }
2394
2395
2396 if (launch) {
2397 if (mod_sofia_globals.msg_queue_len < mod_sofia_globals.max_msg_queues) {
2398 sofia_msg_thread_start(mod_sofia_globals.msg_queue_len + 1);
2399 }
2400 }
2401
2402 switch_queue_push(mod_sofia_globals.msg_queue, de);
2403}
2404
2405static void set_call_id(private_object_t *tech_pvt, sip_t const *sip)
2406{
2407 if (!tech_pvt->call_id && tech_pvt->session && tech_pvt->channel && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
2408 tech_pvt->call_id = switch_core_session_strdup(tech_pvt->session, sip->sip_call_id->i_id)switch_core_perform_session_strdup(tech_pvt->session, sip->
sip_call_id->i_id, "sofia.c", (const char *)__func__, 2408
)
;
2409 switch_channel_set_variable(tech_pvt->channel, "sip_call_id", tech_pvt->call_id)switch_channel_set_variable_var_check(tech_pvt->channel, "sip_call_id"
, tech_pvt->call_id, SWITCH_TRUE)
;
2410 }
2411}
2412
2413
2414void sofia_event_callback(nua_event_t event,
2415 int status,
2416 char const *phrase,
2417 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
2418 tagi_t tags[])
2419{
2420 sofia_dispatch_event_t *de;
2421 int critical = (((SOFIA_MSG_QUEUE_SIZE1000 * mod_sofia_globals.max_msg_queues) * 900) / 1000);
2422 uint32_t sess_count = switch_core_session_count();
2423 uint32_t sess_max = switch_core_session_limit(0);
2424
2425 switch(event) {
2426 case nua_i_terminated:
2427 if ((status == 401 || status == 407 || status == 403) && sofia_private) {
2428 switch_core_session_t *session;
2429
2430 if ((session = switch_core_session_locate(sofia_private->uuid)switch_core_session_perform_locate(sofia_private->uuid, "sofia.c"
, (const char *)__func__, 2430)
)) {
2431 switch_channel_t *channel = switch_core_session_get_channel(session);
2432 int end = 0;
2433
2434 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_ANSWERED)) {
2435 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
2436
2437 if (status == 403) {
2438 switch_channel_set_flag(channel, CF_NO_CDR)switch_channel_set_flag_value(channel, CF_NO_CDR, 1);
2439 switch_channel_hangup(channel, SWITCH_CAUSE_CALL_REJECTED)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 2439, SWITCH_CAUSE_CALL_REJECTED)
;
2440 } else {
2441 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2441
, ((void*)0)
, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid);
2442
2443 if (!zstr(tech_pvt->call_id)_zstr(tech_pvt->call_id)) {
2444 tech_pvt->sofia_private = NULL((void*)0);
2445 tech_pvt->nh = NULL((void*)0);
2446 sofia_set_flag(tech_pvt, TFLAG_BYE)(tech_pvt)->flags[TFLAG_BYE] = 1;
2447 switch_mutex_lock(profile->flag_mutex);
2448 switch_core_hash_insert_dup_auto_free(profile->chat_hash, tech_pvt->call_id, switch_core_session_get_uuid(session));
2449 switch_mutex_unlock(profile->flag_mutex);
2450 nua_handle_destroy(nh);
2451 } else {
2452 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 2452, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
2453 }
2454 }
2455 end++;
2456 }
2457
2458 switch_core_session_rwunlock(session);
2459
2460 if (end) {
2461 goto end;
2462 }
2463 }
2464 }
2465 break;
2466 case nua_i_invite:
2467 case nua_i_register:
2468 case nua_i_options:
2469 case nua_i_notify:
2470 case nua_i_info:
2471
2472
2473 if (event == nua_i_invite) {
2474 if (sip->sip_session_expires && profile->minimum_session_expires) {
2475 if (sip->sip_session_expires->x_delta < profile->minimum_session_expires) {
2476 char buf[64] = "";
2477 switch_snprintf(buf, sizeof(buf), "Min-SE: %d", profile->minimum_session_expires);
2478 nua_respond(nh, SIP_422_SESSION_TIMER_TOO_SMALL422, sip_422_Session_timer, SIPTAG_HEADER_STR(buf)siptag_header_str, tag_str_v((buf)),TAG_END()(tag_type_t)0, (tag_value_t)0);
2479 goto end;
2480 }
2481 }
2482 }
2483
2484 if (!sofia_private) {
2485 if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0) || !switch_core_ready_inbound()) {
2486 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300")siptag_retry_after_str, tag_str_v("300"), NUTAG_WITH_THIS(nua)nutag_with, tag_ptr_v(nua_current_request((nua))), TAG_END()(tag_type_t)0, (tag_value_t)0);
2487 goto end;
2488 }
2489
2490
2491 if (switch_queue_size(mod_sofia_globals.msg_queue) > (unsigned int)critical) {
2492 nua_respond(nh, 503, "System Busy", SIPTAG_RETRY_AFTER_STR("300")siptag_retry_after_str, tag_str_v("300"), NUTAG_WITH_THIS(nua)nutag_with, tag_ptr_v(nua_current_request((nua))), TAG_END()(tag_type_t)0, (tag_value_t)0);
2493 goto end;
2494 }
2495
2496 if (sofia_test_pflag(profile, PFLAG_STANDBY)((profile)->pflags[PFLAG_STANDBY] ? 1 : 0)) {
2497 nua_respond(nh, 503, "System Paused", NUTAG_WITH_THIS(nua)nutag_with, tag_ptr_v(nua_current_request((nua))), TAG_END()(tag_type_t)0, (tag_value_t)0);
2498 goto end;
2499 }
2500 }
2501
2502 break;
2503
2504 default:
2505 break;
2506
2507 }
2508
2509 switch_mutex_lock(profile->flag_mutex);
2510 profile->queued_events++;
2511 switch_mutex_unlock(profile->flag_mutex);
2512
2513 de = su_alloc(nua_handle_get_home(nh), sizeof(*de));
2514 memset(de, 0, sizeof(*de));
2515 nua_save_event(nua, de->event);
2516 de->nh = nh ? nua_handle_ref(nh) : NULL((void*)0);
2517 de->data = nua_event_data(de->event);
2518 de->sip = sip_object(de->data->e_msg);
2519 de->profile = profile;
2520 de->nua = (nua_t *)su_home_ref(nua_get_home(nua));
2521
2522 if (event == nua_i_invite && !sofia_private) {
2523 switch_core_session_t *session;
2524 private_object_t *tech_pvt = NULL((void*)0);
2525
2526 if (!(sofia_private = su_alloc(nua_handle_get_home(nh), sizeof(*sofia_private)))) {
2527 abort();
2528 }
2529
2530 memset(sofia_private, 0, sizeof(*sofia_private));
2531 sofia_private->is_call++;
2532 sofia_private->is_static++;
2533 nua_handle_bind(nh, sofia_private);
2534
2535
2536 if (sip->sip_call_id && sip->sip_call_id->i_id) {
2537 char *uuid = NULL((void*)0), *tmp;
2538
2539 switch_mutex_lock(profile->flag_mutex);
2540 if ((tmp = (char *) switch_core_hash_find(profile->chat_hash, sip->sip_call_id->i_id))) {
2541 uuid = strdup(tmp);
2542 switch_core_hash_delete(profile->chat_hash, sip->sip_call_id->i_id);
2543 }
2544 switch_mutex_unlock(profile->flag_mutex);
2545
2546 if (uuid) {
2547 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 2547)
)) {
2548 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
2549 switch_copy_string(sofia_private->uuid_str, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid_str));
2550 sofia_private->uuid = sofia_private->uuid_str;
2551 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2551
, ((void*)0)
, SWITCH_LOG_DEBUG, "Re-attaching to session %s\n", sofia_private->uuid);
2552 de->init_session = session;
2553 sofia_clear_flag(tech_pvt, TFLAG_BYE)(tech_pvt)->flags[TFLAG_BYE] = 0;
2554 tech_pvt->sofia_private = NULL((void*)0);
2555 tech_pvt->nh = NULL((void*)0);
2556 switch_core_session_queue_signal_data(session, de);
2557 switch_core_session_rwunlock(session);
2558 session = NULL((void*)0);
2559 free(uuid);
2560 uuid = NULL((void*)0);
2561 goto end;
2562 } else {
2563 free(uuid);
2564 uuid = NULL((void*)0);
2565 sip = NULL((void*)0);
2566 }
2567 }
2568 }
2569
2570 if (!sip || !sip->sip_call_id || zstr(sip->sip_call_id->i_id)_zstr(sip->sip_call_id->i_id)) {
2571 nua_respond(nh, 503, "INVALID INVITE", TAG_END()(tag_type_t)0, (tag_value_t)0);
2572 nua_destroy_event(de->event);
2573 su_free(nua_handle_get_home(nh), de);
2574
2575 switch_mutex_lock(profile->flag_mutex);
2576 profile->queued_events--;
2577 switch_mutex_unlock(profile->flag_mutex);
2578
2579 nua_handle_unref_user(nh);
2580 nua_unref_user(nua);
2581
2582 goto end;
2583 }
2584
2585 if (sofia_test_pflag(profile, PFLAG_CALLID_AS_UUID)((profile)->pflags[PFLAG_CALLID_AS_UUID] ? 1 : 0)) {
2586 session = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL((void*)0), sip->sip_call_id->i_id);
2587 } else {
2588 session = switch_core_session_request(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL)switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND
, SOF_NONE, ((void*)0), ((void*)0))
;
2589 }
2590
2591 if (session) {
2592 const char *channel_name = NULL((void*)0);
2593 tech_pvt = sofia_glue_new_pvt(session);
2594
2595 if (sip->sip_from) {
2596 channel_name = url_set_chanvars(session, sip->sip_from->a_url, sip_from)_url_set_chanvars(session, sip->sip_from->a_url, "sip_from"
"_user", "sip_from" "_host", "sip_from" "_port", "sip_from" "_uri"
, "sip_from" "_params")
;
2597 }
2598 if (!channel_name && sip->sip_contact) {
2599 channel_name = url_set_chanvars(session, sip->sip_contact->m_url, sip_contact)_url_set_chanvars(session, sip->sip_contact->m_url, "sip_contact"
"_user", "sip_contact" "_host", "sip_contact" "_port", "sip_contact"
"_uri", "sip_contact" "_params")
;
2600 }
2601 if (sip->sip_referred_by) {
2602 channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by)_url_set_chanvars(session, sip->sip_referred_by->b_url,
"sip_referred_by" "_user", "sip_referred_by" "_host", "sip_referred_by"
"_port", "sip_referred_by" "_uri", "sip_referred_by" "_params"
)
;
2603 }
2604
2605 sofia_glue_attach_private(session, profile, tech_pvt, channel_name);
2606
2607 set_call_id(tech_pvt, sip);
2608 } else {
2609 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300")siptag_retry_after_str, tag_str_v("300"), TAG_END()(tag_type_t)0, (tag_value_t)0);
2610 nua_destroy_event(de->event);
2611 su_free(nua_handle_get_home(nh), de);
2612
2613 switch_mutex_lock(profile->flag_mutex);
2614 profile->queued_events--;
2615 switch_mutex_unlock(profile->flag_mutex);
2616
2617 nua_handle_unref_user(nh);
2618 nua_unref_user(nua);
2619
2620 goto end;
2621 }
2622
2623
2624 if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
2625 char *uuid;
2626
2627 if (!switch_core_session_running(session) && !switch_core_session_started(session)) {
2628 nua_handle_bind(nh, NULL((void*)0));
2629 sofia_private_free(sofia_private)if (sofia_private && ! sofia_private->is_static) {
free(sofia_private);} sofia_private = ((void*)0);
;
2630 switch_core_session_destroy(&session)switch_core_session_perform_destroy(&session, "sofia.c", (
const char *)__func__, 2630)
;
2631 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300")siptag_retry_after_str, tag_str_v("300"), TAG_END()(tag_type_t)0, (tag_value_t)0);
2632 }
2633 switch_mutex_lock(profile->flag_mutex);
2634 if ((uuid = switch_core_hash_find(profile->chat_hash, tech_pvt->call_id))) {
2635 free(uuid);
2636 uuid = NULL((void*)0);
2637 switch_core_hash_delete(profile->chat_hash, tech_pvt->call_id);
2638 }
2639 switch_mutex_unlock(profile->flag_mutex);
2640
2641 goto end;
2642 }
2643
2644 switch_copy_string(sofia_private->uuid_str, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid_str));
2645 sofia_private->uuid = sofia_private->uuid_str;
2646
2647 de->init_session = session;
2648 switch_core_session_queue_signal_data(session, de);
2649 goto end;
2650 }
2651
2652 if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
2653 switch_core_session_t *session;
2654
2655 if ((session = switch_core_session_locate(sofia_private->uuid)switch_core_session_perform_locate(sofia_private->uuid, "sofia.c"
, (const char *)__func__, 2655)
)) {
2656 switch_core_session_queue_signal_data(session, de);
2657 switch_core_session_rwunlock(session);
2658 goto end;
2659 }
2660 }
2661
2662 sofia_queue_message(de);
2663
2664 end:
2665 //switch_cond_next();
2666
2667 return;
2668}
2669
2670
2671void event_handler(switch_event_t *event)
2672{
2673 char *subclass, *sql;
2674 char *class;
2675 switch_event_t *pevent;
2676
2677 /* Get Original Event Name */
2678 class = switch_event_get_header_nil(event, "orig-event-name")(switch_event_get_header_idx(event, "orig-event-name", -1) ? switch_event_get_header_idx
(event, "orig-event-name", -1) : "")
;
2679 if (!strcasecmp(class, "PRESENCE_IN")) {
2680 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2680
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nGot Presence IN event via MultiCast\n");
2681 if (switch_event_create(&pevent, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2681, &pevent, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2682 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "alt_event_type", switch_event_get_header_nil(event, "orig-alt_event_type")(switch_event_get_header_idx(event, "orig-alt_event_type", -1
) ? switch_event_get_header_idx(event, "orig-alt_event_type",
-1) : "")
);
2683 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "answer-state", switch_event_get_header_nil(event, "orig-answer-state")(switch_event_get_header_idx(event, "orig-answer-state", -1) ?
switch_event_get_header_idx(event, "orig-answer-state", -1) :
"")
);
2684 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "astate", switch_event_get_header_nil(event, "orig-astate")(switch_event_get_header_idx(event, "orig-astate", -1) ? switch_event_get_header_idx
(event, "orig-astate", -1) : "")
);
2685 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "call-direction", switch_event_get_header_nil(event, "orig-call-direction")(switch_event_get_header_idx(event, "orig-call-direction", -1
) ? switch_event_get_header_idx(event, "orig-call-direction",
-1) : "")
);
2686 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Callee-ID-Number", switch_event_get_header_nil(event, "Orig-Caller-Callee-ID-Number")(switch_event_get_header_idx(event, "Orig-Caller-Callee-ID-Number"
, -1) ? switch_event_get_header_idx(event, "Orig-Caller-Callee-ID-Number"
, -1) : "")
);
2687 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Caller-ID-Name", switch_event_get_header_nil(event, "Orig-Caller-Caller-ID-Name")(switch_event_get_header_idx(event, "Orig-Caller-Caller-ID-Name"
, -1) ? switch_event_get_header_idx(event, "Orig-Caller-Caller-ID-Name"
, -1) : "")
);
2688 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Caller-ID-Number", switch_event_get_header_nil(event, "Orig-Caller-Caller-ID-Number")(switch_event_get_header_idx(event, "Orig-Caller-Caller-ID-Number"
, -1) ? switch_event_get_header_idx(event, "Orig-Caller-Caller-ID-Number"
, -1) : "")
);
2689 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Destination-Number", switch_event_get_header_nil(event, "Orig-Caller-Destination-Number")(switch_event_get_header_idx(event, "Orig-Caller-Destination-Number"
, -1) ? switch_event_get_header_idx(event, "Orig-Caller-Destination-Number"
, -1) : "")
);
2690 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Direction", switch_event_get_header_nil(event, "Orig-Caller-Direction")(switch_event_get_header_idx(event, "Orig-Caller-Direction", -
1) ? switch_event_get_header_idx(event, "Orig-Caller-Direction"
, -1) : "")
);
2691 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Username", switch_event_get_header_nil(event, "Orig-Caller-Username")(switch_event_get_header_idx(event, "Orig-Caller-Username", -
1) ? switch_event_get_header_idx(event, "Orig-Caller-Username"
, -1) : "")
);
2692 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "channel-state", switch_event_get_header_nil(event, "orig-channel-state")(switch_event_get_header_idx(event, "orig-channel-state", -1)
? switch_event_get_header_idx(event, "orig-channel-state", -
1) : "")
);
2693 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "force-status", switch_event_get_header_nil(event, "orig-force-status")(switch_event_get_header_idx(event, "orig-force-status", -1) ?
switch_event_get_header_idx(event, "orig-force-status", -1) :
"")
);
2694 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "from", switch_event_get_header_nil(event, "orig-from")(switch_event_get_header_idx(event, "orig-from", -1) ? switch_event_get_header_idx
(event, "orig-from", -1) : "")
);
2695 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "login", switch_event_get_header_nil(event, "orig-login")(switch_event_get_header_idx(event, "orig-login", -1) ? switch_event_get_header_idx
(event, "orig-login", -1) : "")
);
2696 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Other-Leg-Caller-ID-Name", switch_event_get_header_nil(event, "Orig-Other-Leg-Caller-ID-Name")(switch_event_get_header_idx(event, "Orig-Other-Leg-Caller-ID-Name"
, -1) ? switch_event_get_header_idx(event, "Orig-Other-Leg-Caller-ID-Name"
, -1) : "")
);
2697 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Other-Leg-Caller-ID-Number", switch_event_get_header_nil(event, "Orig-Other-Leg-Caller-ID-Number")(switch_event_get_header_idx(event, "Orig-Other-Leg-Caller-ID-Number"
, -1) ? switch_event_get_header_idx(event, "Orig-Other-Leg-Caller-ID-Number"
, -1) : "")
);
2698 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "presence-call-direction", switch_event_get_header_nil(event, "orig-presence-call-direction")(switch_event_get_header_idx(event, "orig-presence-call-direction"
, -1) ? switch_event_get_header_idx(event, "orig-presence-call-direction"
, -1) : "")
);
2699 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "presence-call-info-state", switch_event_get_header_nil(event, "orig-presence-call-info-state")(switch_event_get_header_idx(event, "orig-presence-call-info-state"
, -1) ? switch_event_get_header_idx(event, "orig-presence-call-info-state"
, -1) : "")
);
2700 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Presence-Privacy", switch_event_get_header_nil(event, "Orig-Presence-Privacy")(switch_event_get_header_idx(event, "Orig-Presence-Privacy", -
1) ? switch_event_get_header_idx(event, "Orig-Presence-Privacy"
, -1) : "")
);
2701 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "proto", switch_event_get_header_nil(event, "orig-proto")(switch_event_get_header_idx(event, "orig-proto", -1) ? switch_event_get_header_idx
(event, "orig-proto", -1) : "")
);
2702 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "register-source", switch_event_get_header_nil(event, "orig-register-source")(switch_event_get_header_idx(event, "orig-register-source", -
1) ? switch_event_get_header_idx(event, "orig-register-source"
, -1) : "")
);
2703 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "resub", switch_event_get_header_nil(event, "orig-resub")(switch_event_get_header_idx(event, "orig-resub", -1) ? switch_event_get_header_idx
(event, "orig-resub", -1) : "")
);
2704 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "rpid", switch_event_get_header_nil(event, "orig-rpid")(switch_event_get_header_idx(event, "orig-rpid", -1) ? switch_event_get_header_idx
(event, "orig-rpid", -1) : "")
);
2705 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "status", switch_event_get_header_nil(event, "orig-status")(switch_event_get_header_idx(event, "orig-status", -1) ? switch_event_get_header_idx
(event, "orig-status", -1) : "")
);
2706 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Unique-ID", switch_event_get_header_nil(event, "Orig-Unique-ID")(switch_event_get_header_idx(event, "Orig-Unique-ID", -1) ? switch_event_get_header_idx
(event, "Orig-Unique-ID", -1) : "")
);
2707 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "variable_sip_from_user", switch_event_get_header_nil(event, "Orig-variable_sip_from_user")(switch_event_get_header_idx(event, "Orig-variable_sip_from_user"
, -1) ? switch_event_get_header_idx(event, "Orig-variable_sip_from_user"
, -1) : "")
);
2708 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "variable_sip_to_user", switch_event_get_header_nil(event, "Orig-variable_sip_to_user")(switch_event_get_header_idx(event, "Orig-variable_sip_to_user"
, -1) ? switch_event_get_header_idx(event, "Orig-variable_sip_to_user"
, -1) : "")
);
2709
2710 /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
2711 sofia_presence_event_handler(pevent);
2712 return;
2713 } else {
2714 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2714
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nCannot inject PRESENCE_IN event\n");
2715 return;
2716 }
2717 } else if (!strcasecmp(class, "MESSAGE_WAITING")) {
2718 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2718
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nGot MWI event via MultiCast\n");
2719 if (switch_event_create(&pevent, SWITCH_EVENT_MESSAGE_WAITING)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2719, &pevent, SWITCH_EVENT_MESSAGE_WAITING
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2720 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", switch_event_get_header_nil(event, "orig-MWI-Messages-Waiting")(switch_event_get_header_idx(event, "orig-MWI-Messages-Waiting"
, -1) ? switch_event_get_header_idx(event, "orig-MWI-Messages-Waiting"
, -1) : "")
);
2721 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "MWI-Message-Account", switch_event_get_header_nil(event, "orig-MWI-Message-Account")(switch_event_get_header_idx(event, "orig-MWI-Message-Account"
, -1) ? switch_event_get_header_idx(event, "orig-MWI-Message-Account"
, -1) : "")
);
2722 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", switch_event_get_header_nil(event, "orig-MWI-Voice-Message")(switch_event_get_header_idx(event, "orig-MWI-Voice-Message",
-1) ? switch_event_get_header_idx(event, "orig-MWI-Voice-Message"
, -1) : "")
);
2723 /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
2724 sofia_presence_event_handler(pevent);
2725 return;
2726 } else {
2727 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2727
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nCannot inject MWI event\n");
2728 return;
2729 }
2730 } else if ((subclass = switch_event_get_header_nil(event, "orig-event-subclass")(switch_event_get_header_idx(event, "orig-event-subclass", -1
) ? switch_event_get_header_idx(event, "orig-event-subclass",
-1) : "")
) && !strcasecmp(subclass, MY_EVENT_UNREGISTER"sofia::unregister")) {
2731 char *profile_name = switch_event_get_header_nil(event, "orig-profile-name")(switch_event_get_header_idx(event, "orig-profile-name", -1) ?
switch_event_get_header_idx(event, "orig-profile-name", -1) :
"")
;
2732 char *from_user = switch_event_get_header_nil(event, "orig-from-user")(switch_event_get_header_idx(event, "orig-from-user", -1) ? switch_event_get_header_idx
(event, "orig-from-user", -1) : "")
;
2733 char *from_host = switch_event_get_header_nil(event, "orig-from-host")(switch_event_get_header_idx(event, "orig-from-host", -1) ? switch_event_get_header_idx
(event, "orig-from-host", -1) : "")
;
2734 char *call_id = switch_event_get_header_nil(event, "orig-call-id")(switch_event_get_header_idx(event, "orig-call-id", -1) ? switch_event_get_header_idx
(event, "orig-call-id", -1) : "")
;
2735 char *contact_str = switch_event_get_header_nil(event, "orig-contact")(switch_event_get_header_idx(event, "orig-contact", -1) ? switch_event_get_header_idx
(event, "orig-contact", -1) : "")
;
2736
2737 sofia_profile_t *profile = NULL((void*)0);
2738
2739 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2739
, profile_name)
)) {
2740 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2740
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2741 return;
2742 }
2743
2744 if (sofia_test_pflag(profile, PFLAG_MULTIREG)((profile)->pflags[PFLAG_MULTIREG] ? 1 : 0)) {
2745 sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
2746 } else {
2747 sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", from_user, from_host);
2748 }
2749
2750 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2751 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2751
, ((void*)0)
, SWITCH_LOG_DEBUG, "Expired propagated registration for %s@%s->%s\n", from_user, from_host, contact_str);
2752
2753 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2753, profile)
;
2754 } else if ((subclass = switch_event_get_header_nil(event, "orig-event-subclass")(switch_event_get_header_idx(event, "orig-event-subclass", -1
) ? switch_event_get_header_idx(event, "orig-event-subclass",
-1) : "")
) && !strcasecmp(subclass, MY_EVENT_REGISTER"sofia::register")) {
2755 char *from_user = switch_event_get_header_nil(event, "orig-from-user")(switch_event_get_header_idx(event, "orig-from-user", -1) ? switch_event_get_header_idx
(event, "orig-from-user", -1) : "")
;
2756 char *from_host = switch_event_get_header_nil(event, "orig-from-host")(switch_event_get_header_idx(event, "orig-from-host", -1) ? switch_event_get_header_idx
(event, "orig-from-host", -1) : "")
;
2757 char *to_host = switch_event_get_header_nil(event, "orig-to-host")(switch_event_get_header_idx(event, "orig-to-host", -1) ? switch_event_get_header_idx
(event, "orig-to-host", -1) : "")
;
2758 char *contact_str = switch_event_get_header_nil(event, "orig-contact")(switch_event_get_header_idx(event, "orig-contact", -1) ? switch_event_get_header_idx
(event, "orig-contact", -1) : "")
;
2759 char *exp_str = switch_event_get_header_nil(event, "orig-expires")(switch_event_get_header_idx(event, "orig-expires", -1) ? switch_event_get_header_idx
(event, "orig-expires", -1) : "")
;
2760 char *rpid = switch_event_get_header_nil(event, "orig-rpid")(switch_event_get_header_idx(event, "orig-rpid", -1) ? switch_event_get_header_idx
(event, "orig-rpid", -1) : "")
;
2761 char *call_id = switch_event_get_header_nil(event, "orig-call-id")(switch_event_get_header_idx(event, "orig-call-id", -1) ? switch_event_get_header_idx
(event, "orig-call-id", -1) : "")
;
2762 char *user_agent = switch_event_get_header_nil(event, "orig-user-agent")(switch_event_get_header_idx(event, "orig-user-agent", -1) ? switch_event_get_header_idx
(event, "orig-user-agent", -1) : "")
;
2763 long expires = (long) switch_epoch_time_now(NULL((void*)0));
2764 char *profile_name = switch_event_get_header_nil(event, "orig-profile-name")(switch_event_get_header_idx(event, "orig-profile-name", -1) ?
switch_event_get_header_idx(event, "orig-profile-name", -1) :
"")
;
2765 char *to_user = switch_event_get_header_nil(event, "orig-to-user")(switch_event_get_header_idx(event, "orig-to-user", -1) ? switch_event_get_header_idx
(event, "orig-to-user", -1) : "")
;
2766 char *presence_hosts = switch_event_get_header_nil(event, "orig-presence-hosts")(switch_event_get_header_idx(event, "orig-presence-hosts", -1
) ? switch_event_get_header_idx(event, "orig-presence-hosts",
-1) : "")
;
2767 char *network_ip = switch_event_get_header_nil(event, "orig-network-ip")(switch_event_get_header_idx(event, "orig-network-ip", -1) ? switch_event_get_header_idx
(event, "orig-network-ip", -1) : "")
;
2768 char *network_port = switch_event_get_header_nil(event, "orig-network-port")(switch_event_get_header_idx(event, "orig-network-port", -1) ?
switch_event_get_header_idx(event, "orig-network-port", -1) :
"")
;
2769 char *username = switch_event_get_header_nil(event, "orig-username")(switch_event_get_header_idx(event, "orig-username", -1) ? switch_event_get_header_idx
(event, "orig-username", -1) : "")
;
2770 char *realm = switch_event_get_header_nil(event, "orig-realm")(switch_event_get_header_idx(event, "orig-realm", -1) ? switch_event_get_header_idx
(event, "orig-realm", -1) : "")
;
2771 char *orig_server_host = switch_event_get_header_nil(event, "orig-FreeSWITCH-IPv4")(switch_event_get_header_idx(event, "orig-FreeSWITCH-IPv4", -
1) ? switch_event_get_header_idx(event, "orig-FreeSWITCH-IPv4"
, -1) : "")
;
2772 char *orig_hostname = switch_event_get_header_nil(event, "orig-FreeSWITCH-Hostname")(switch_event_get_header_idx(event, "orig-FreeSWITCH-Hostname"
, -1) ? switch_event_get_header_idx(event, "orig-FreeSWITCH-Hostname"
, -1) : "")
;
2773 char *fixed_contact_str = NULL((void*)0);
2774
2775 sofia_profile_t *profile = NULL((void*)0);
2776 char guess_ip4[256];
2777
2778 char *mwi_account = NULL((void*)0);
2779 char *dup_mwi_account = NULL((void*)0);
2780 char *mwi_user = NULL((void*)0);
2781 char *mwi_host = NULL((void*)0);
2782
2783 if ((mwi_account = switch_event_get_header_nil(event, "orig-mwi-account")(switch_event_get_header_idx(event, "orig-mwi-account", -1) ?
switch_event_get_header_idx(event, "orig-mwi-account", -1) :
"")
)) {
2784 dup_mwi_account = strdup(mwi_account);
2785 switch_assert(dup_mwi_account != NULL)((dup_mwi_account != ((void*)0)) ? (void) (0) : __assert_fail
("dup_mwi_account != ((void*)0)", "sofia.c", 2785, __extension__
__PRETTY_FUNCTION__))
;
2786 switch_split_user_domain(dup_mwi_account, &mwi_user, &mwi_host);
2787 }
2788
2789 if (!mwi_user) {
2790 mwi_user = (char *) from_user;
2791 }
2792 if (!mwi_host) {
2793 mwi_host = (char *) from_host;
2794 }
2795
2796 if (exp_str) {
2797 expires += atol(exp_str);
2798 }
2799
2800 if (!rpid) {
2801 rpid = "unknown";
2802 }
2803
2804 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2804
, profile_name)
)) {
2805 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2805
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2806 goto end;
2807 }
2808 if (sofia_test_pflag(profile, PFLAG_MULTIREG)((profile)->pflags[PFLAG_MULTIREG] ? 1 : 0)) {
2809 sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
2810 } else {
2811 sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", from_user, from_host);
2812 }
2813
2814 if (mod_sofia_globals.rewrite_multicasted_fs_path && contact_str) {
2815 const char *needle = ";fs_path=";
2816 char *sptr, *eptr = NULL((void*)0);
2817 /* allocate enough room for worst-case scenario, depends on rewrite_multicased_fs_path setting */
2818 size_t len;
2819 switch (mod_sofia_globals.rewrite_multicasted_fs_path) {
2820 case 1:
2821 len = strlen(contact_str) + strlen(to_host) + 14;
2822 break;
2823 case 2:
2824 len = strlen(contact_str) + strlen(orig_server_host) + 14;
2825 break;
2826 case 3:
2827 len = strlen(contact_str) + strlen(orig_hostname) + 14;
2828 break;
2829 default:
2830 len = strlen(contact_str) + strlen(to_host) + 14;
2831 break;
2832 }
2833
2834 fixed_contact_str = malloc(len);
2835 switch_assert(fixed_contact_str)((fixed_contact_str) ? (void) (0) : __assert_fail ("fixed_contact_str"
, "sofia.c", 2835, __extension__ __PRETTY_FUNCTION__))
;
2836 switch_copy_string(fixed_contact_str, contact_str, len);
2837
2838 if ((sptr = strstr(fixed_contact_str, needle))) {
2839 char *origsptr = strstr(contact_str, needle);
2840 eptr = strchr(++origsptr, ';');
2841 } else {
2842 sptr = strchr(fixed_contact_str, '\0') - 1;
2843 }
2844
2845 switch (mod_sofia_globals.rewrite_multicasted_fs_path) {
2846 case 1:
2847 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", to_host, eptr ? eptr : ">");
2848 break;
2849 case 2:
2850 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", orig_server_host, eptr ? eptr : ">");
2851 break;
2852 case 3:
2853 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", orig_hostname, eptr ? eptr : ">");
2854 break;
2855 default:
2856 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", to_host, eptr ? eptr : ">");
2857 break;
2858 }
2859
2860 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2860
, ((void*)0)
, SWITCH_LOG_DEBUG, "Rewrote contact string from '%s' to '%s'\n", contact_str, fixed_contact_str);
2861 contact_str = fixed_contact_str;
2862 }
2863
2864
2865 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2866
2867 switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL((void*)0), AF_INET2);
2868 sql = switch_mprintf("insert into sip_registrations "
2869 "(call_id, sip_user, sip_host, presence_hosts, contact, status, rpid, expires,"
2870 "user_agent, server_user, server_host, profile_name, hostname, network_ip, network_port, sip_username, sip_realm,"
2871 "mwi_user, mwi_host, orig_server_host, orig_hostname, ping_status, ping_count) "
2872 "values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)",
2873 call_id, from_user, from_host, presence_hosts, contact_str, rpid, expires, user_agent, to_user, guess_ip4,
2874 profile_name, mod_sofia_globals.hostname, network_ip, network_port, username, realm, mwi_user, mwi_host,
2875 orig_server_host, orig_hostname, "Reachable", 0);
2876
2877 if (sql) {
2878 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2879 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2879
, ((void*)0)
, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str);
2880 }
2881
2882
2883 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2883, profile)
;
2884 end:
2885 switch_safe_free(fixed_contact_str)if (fixed_contact_str) {free(fixed_contact_str);fixed_contact_str
=((void*)0);}
;
2886 switch_safe_free(dup_mwi_account)if (dup_mwi_account) {free(dup_mwi_account);dup_mwi_account=(
(void*)0);}
;
2887 } else if ((subclass = switch_event_get_header_nil(event, "orig-event-subclass")(switch_event_get_header_idx(event, "orig-event-subclass", -1
) ? switch_event_get_header_idx(event, "orig-event-subclass",
-1) : "")
) && !strcasecmp(subclass, MY_EVENT_SIP_USER_STATE"sofia::sip_user_state")) {
2888 char *profile_name = switch_event_get_header_nil(event, "orig-profile-name")(switch_event_get_header_idx(event, "orig-profile-name", -1) ?
switch_event_get_header_idx(event, "orig-profile-name", -1) :
"")
;
2889 char *from_user = switch_event_get_header_nil(event, "orig-from-user")(switch_event_get_header_idx(event, "orig-from-user", -1) ? switch_event_get_header_idx
(event, "orig-from-user", -1) : "")
;
2890 char *from_host = switch_event_get_header_nil(event, "orig-from-host")(switch_event_get_header_idx(event, "orig-from-host", -1) ? switch_event_get_header_idx
(event, "orig-from-host", -1) : "")
;
2891 const char *call_id = switch_event_get_header_nil(event, "orig-call-id")(switch_event_get_header_idx(event, "orig-call-id", -1) ? switch_event_get_header_idx
(event, "orig-call-id", -1) : "")
;
2892 char *ping_status = switch_event_get_header_nil(event, "orig-Ping-Status")(switch_event_get_header_idx(event, "orig-Ping-Status", -1) ?
switch_event_get_header_idx(event, "orig-Ping-Status", -1) :
"")
;
2893 sofia_profile_t *profile = NULL((void*)0);
2894
2895 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2895
, profile_name)
)) {
2896 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2896
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2897 } else {
2898 if (!strcmp(ping_status, "REACHABLE")) {
2899 sql = switch_mprintf("update sip_registrations set ping_status='%q' where sip_user='%q' and sip_host='%q' and call_id='%q'",
2900 "Reachable", from_user, from_host, call_id);
2901 } else {
2902 sql = switch_mprintf("update sip_registrations set ping_status='%q' where sip_user='%q' and sip_host='%q' and call_id='%q'",
2903 "Unreachable", from_user, from_host, call_id);
2904 }
2905 if (sql) {
2906 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2907 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2907
, ((void*)0)
, SWITCH_LOG_DEBUG, "Propagating sip_user_state for %s@%s. Ping-Status: %s\n", from_user, from_host, ping_status);
2908 }
2909
2910 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2910, profile)
;
2911 }
2912 }
2913}
2914
2915static void sofia_perform_profile_start_failure(sofia_profile_t *profile, char *profile_name, char *file, int line)
2916{
2917 int arg = 0;
2918 switch_event_t *s_event;
2919
2920 if (profile) {
2921 if (!strcasecmp(profile->shutdown_type, "true")) {
2922 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2922
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Shutting down!\n", profile->name);
2923 switch_core_session_ctl(SCSC_SHUTDOWN, &arg);
2924 } else if (!strcasecmp(profile->shutdown_type, "elegant")) {
2925 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2925
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Waiting for calls to finish, then shutting down!\n",
2926 profile->name);
2927 switch_core_session_ctl(SCSC_SHUTDOWN_ELEGANT, &arg);
2928 } else if (!strcasecmp(profile->shutdown_type, "asap")) {
2929 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2929
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Shutting down ASAP!\n", profile->name);
2930 switch_core_session_ctl(SCSC_SHUTDOWN_ASAP, &arg);
2931 } else if (!strcasecmp(profile->shutdown_type, "reincarnate-now")) {
2932 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2932
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Asking for reincarnation now!\n", profile->name);
2933 switch_core_session_ctl(SCSC_REINCARNATE_NOW, &arg);
2934 }
2935 }
2936
2937 if ((switch_event_create(&s_event, SWITCH_EVENT_FAILURE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2937, &s_event, SWITCH_EVENT_FAILURE
, ((void*)0))
== SWITCH_STATUS_SUCCESS)) {
2938 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
2939 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile_name);
2940 if (profile) {
2941 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
2942 }
2943 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "failure_message", "Profile failed to start.");
2944 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "file", file);
2945 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "line", "%d", line);
2946
2947 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 2947, &s_event, ((void*)0))
;
2948 }
2949}
2950
2951/* not a static function so that it's still visible on stacktraces */
2952void watchdog_triggered_abort(void) {
2953 abort();
2954}
2955
2956#define sofia_profile_start_failure(p, xp)sofia_perform_profile_start_failure(p, xp, "sofia.c", 2956) sofia_perform_profile_start_failure(p, xp, __FILE__"sofia.c", __LINE__2956)
2957
2958
2959#define SQLLEN1024 * 1024 1024 * 1024
2960void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread, void *obj)
2961{
2962 sofia_profile_t *profile = (sofia_profile_t *) obj;
2963 uint32_t ireg_loops = profile->ireg_seconds; /* Number of loop iterations done when we haven't checked for registrations */
2964 uint32_t iping_loops = profile->iping_freq; /* Number of loop iterations done when we haven't checked for ping expires */
2965 uint32_t gateway_loops = GATEWAY_SECONDS1; /* Number of loop iterations done when we haven't checked for gateways */
2966 void *pop;
2967 int tick = 0, x = 0;
2968
2969 sofia_set_pflag_locked(profile, PFLAG_WORKER_RUNNING)((profile->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("profile->flag_mutex != NULL", "sofia.c", 2969, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(profile->flag_mutex
);(profile)->pflags[PFLAG_WORKER_RUNNING] = 1;switch_mutex_unlock
(profile->flag_mutex);
;
2970
2971 while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0))) {
2972
2973 if (tick) {
2974 if (profile->watchdog_enabled) {
2975 uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0;
2976
2977 if (profile->step_timeout) {
2978 step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000);
2979
2980 if (step_diff > profile->step_timeout) {
2981 step_fail = 1;
2982 }
2983 }
2984
2985 if (profile->event_timeout) {
2986 event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000);
2987
2988 if (event_diff > profile->event_timeout) {
2989 event_fail = 1;
2990 }
2991 }
2992
2993 if (step_fail && profile->event_timeout && !event_fail) {
2994 step_fail = 0;
2995 }
2996
2997 if (event_fail || step_fail) {
2998 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2998
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED BY WATCHDOG!\n"
2999 "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name);
3000 switch_yield(2000000)switch_sleep(2000000);;
3001 watchdog_triggered_abort();
3002 }
3003 }
3004
3005
3006 if (!sofia_test_pflag(profile, PFLAG_STANDBY)((profile)->pflags[PFLAG_STANDBY] ? 1 : 0)) {
3007 if (++ireg_loops >= (uint32_t)profile->ireg_seconds) {
3008 time_t now = switch_epoch_time_now(NULL((void*)0));
3009 sofia_reg_check_expire(profile, now, 0);
3010 ireg_loops = 0;
3011 }
3012
3013 if(++iping_loops >= (uint32_t)profile->iping_freq) {
3014 time_t now = switch_epoch_time_now(NULL((void*)0));
3015 sofia_reg_check_ping_expire(profile, now, profile->iping_seconds);
3016 iping_loops = 0;
3017 }
3018
3019 if (++gateway_loops >= GATEWAY_SECONDS1) {
3020 sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3021 sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3022 gateway_loops = 0;
3023 }
3024 }
3025
3026 tick = 0;
3027 }
3028
3029 if (switch_queue_pop_timeout(mod_sofia_globals.general_event_queue, &pop, 100000) == SWITCH_STATUS_SUCCESS) {
3030
3031 do {
3032 switch_event_t *event = (switch_event_t *) pop;
3033 general_event_handler(event);
3034 switch_event_destroy(&event);
3035
3036 pop = NULL((void*)0);
3037 switch_queue_trypop(mod_sofia_globals.general_event_queue, &pop);
3038 } while (pop);
3039
3040 }
3041
3042 sofia_glue_fire_events(profile);
3043
3044 if (++x == 10) {
3045 tick = 1;
3046 x = 0;
3047 }
3048
3049 }
3050
3051 sofia_clear_pflag_locked(profile, PFLAG_WORKER_RUNNING)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_WORKER_RUNNING] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3052
3053 return NULL((void*)0);
3054}
3055
3056switch_thread_t *launch_sofia_worker_thread(sofia_profile_t *profile)
3057{
3058 switch_thread_t *thread = NULL((void*)0);
3059 switch_threadattr_t *thd_attr = NULL((void*)0);
3060 int x = 0;
3061 switch_xml_t cfg = NULL((void*)0), xml = NULL((void*)0), xprofile = NULL((void*)0), xprofiles = NULL((void*)0), gateways_tag = NULL((void*)0), domains_tag = NULL((void*)0), domain_tag = NULL((void*)0);
3062 switch_event_t *params = NULL((void*)0);
3063 char *cf = "sofia.conf";
3064
3065 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3065
, ((void*)0)
, SWITCH_LOG_DEBUG, "Launching worker thread for %s\n", profile->name);
3066
3067 /* Parse gateways */
3068 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3068, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
3069 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "sofia.c", 3069
, __extension__ __PRETTY_FUNCTION__))
;
3070 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile->name);
3071
3072 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
3073 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3073
, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
3074 goto end;
3075 }
3076
3077 if ((xprofiles = switch_xml_child(cfg, "profiles"))) {
3078 if ((xprofile = switch_xml_find_child(xprofiles, "profile", "name", profile->name))) {
3079
3080 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
3081 parse_gateways(profile, gateways_tag, NULL((void*)0));
3082 }
3083
3084 if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
3085 switch_event_t *xml_params;
3086 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3086, &xml_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
3087 switch_assert(xml_params)((xml_params) ? (void) (0) : __assert_fail ("xml_params", "sofia.c"
, 3087, __extension__ __PRETTY_FUNCTION__))
;
3088 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways");
3089 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
3090
3091 for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
3092 switch_xml_t droot, x_domain_tag;
3093 const char *dname = switch_xml_attr_soft(domain_tag, "name");
3094 const char *parse = switch_xml_attr_soft(domain_tag, "parse");
3095 const char *alias = switch_xml_attr_soft(domain_tag, "alias");
3096
3097 if (!zstr(dname)_zstr(dname)) {
3098 if (!strcasecmp(dname, "all")) {
3099 switch_xml_t xml_root, x_domains;
3100 if (switch_xml_locate("directory", NULL((void*)0), NULL((void*)0), NULL((void*)0), &xml_root, &x_domains, xml_params, SWITCH_FALSE) ==
3101 SWITCH_STATUS_SUCCESS) {
3102 for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
3103 dname = switch_xml_attr_soft(x_domain_tag, "name");
3104 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
3105 }
3106 switch_xml_free(xml_root);
3107 }
3108 } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) {
3109 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
3110 switch_xml_free(droot);
3111 }
3112 }
3113 }
3114
3115 switch_event_destroy(&xml_params);
3116 }
3117
3118 }
3119 }
3120
3121 switch_threadattr_create(&thd_attr, profile->pool);
3122 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
3123 //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
3124 switch_thread_create(&thread, thd_attr, sofia_profile_worker_thread_run, profile, profile->pool);
3125
3126 while (!sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)((profile)->pflags[PFLAG_WORKER_RUNNING] ? 1 : 0)) {
3127 switch_yield(100000)switch_sleep(100000);;
3128 if (++x >= 100) {
3129 break;
3130 }
3131 }
3132
3133 end:
3134 switch_event_destroy(&params);
3135
3136 if (xml) {
3137 switch_xml_free(xml);
3138 }
3139
3140 return thread;
3141}
3142
3143void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj)
3144{
3145 sofia_profile_t *profile = (sofia_profile_t *) obj;
3146 //switch_memory_pool_t *pool;
3147 sip_alias_node_t *node;
3148 switch_event_t *s_event;
3149 int use_100rel = !sofia_test_pflag(profile, PFLAG_DISABLE_100REL)((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0);
3150 int use_timer = !sofia_test_pflag(profile, PFLAG_DISABLE_TIMER)((profile)->pflags[PFLAG_DISABLE_TIMER] ? 1 : 0);
3151 int use_rfc_5626 = sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626)((profile)->pflags[PFLAG_ENABLE_RFC5626] ? 1 : 0);
3152 const char *supported = NULL((void*)0);
3153 int sanity, attempts = 0;
3154 switch_thread_t *worker_thread;
3155 switch_status_t st;
3156 char qname [128] = "";
3157
3158#if defined(HAVE_OPENSSL1)
3159 char *key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
3160 char *cert = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
3161 char *chain = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
3162 SSL_CTX *ssl_ctx;
3163 const SSL_METHOD *ssl_method = SSLv23_server_methodTLS_server_method();
3164#endif
3165
3166 switch_bool_t ssl_error = SWITCH_FALSE;
3167
3168 switch_mutex_lock(mod_sofia_globals.mutex);
3169 mod_sofia_globals.threads++;
3170 switch_mutex_unlock(mod_sofia_globals.mutex);
3171
3172 profile->s_root = su_root_create(NULL((void*)0));
3173 //profile->home = su_home_new(sizeof(*profile->home));
3174
3175 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3175
, ((void*)0)
, SWITCH_LOG_DEBUG, "Creating agent for %s\n", profile->name);
3176
3177 if (!sofia_glue_init_sql(profile)) {
3178 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3178
, ((void*)0)
, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name);
3179 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 3179)
;
3180 goto db_fail;
3181 }
3182
3183 supported = switch_core_sprintf(profile->pool, "%s%s%spath, replaces", use_100rel ? "100rel, " : "", use_timer ? "timer, " : "", use_rfc_5626 ? "outbound, " : "");
3184
3185 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0) && switch_nat_get_type()) {
3186 if ( (! sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) || ! profile->tls_only) && switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_UDP, NULL((void*)0), SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
3187 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3187
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3188 }
3189 if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_TCP, NULL((void*)0), SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
3190 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3190
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3191 }
3192 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)
3193 && switch_nat_add_mapping(profile->tls_sip_port, SWITCH_NAT_TCP, NULL((void*)0), SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
3194 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3194
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
3195 }
3196 }
3197
3198 /* We have to init the verify_subjects here as during config stage profile->home isn't setup, it should be freed when profile->home is freed */
3199 if ( (profile->tls_verify_policy & TPTLS_VERIFY_SUBJECTS_IN) && profile->tls_verify_in_subjects_str && ! profile->tls_verify_in_subjects) {
3200 profile->tls_verify_in_subjects = su_strlst_dup_split((su_home_t *)profile->nua, profile->tls_verify_in_subjects_str, "|");
3201 }
3202
3203#if defined(HAVE_OPENSSL1)
3204 ssl_ctx = SSL_CTX_new((SSL_METHOD *)ssl_method);
3205 switch_assert(ssl_ctx)((ssl_ctx) ? (void) (0) : __assert_fail ("ssl_ctx", "sofia.c"
, 3205, __extension__ __PRETTY_FUNCTION__))
;
3206
3207 /* Disable SSLv2 */
3208 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv20x0);
3209 /* Disable SSLv3 */
3210 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv30x02000000U);
3211 /* Disable TLSv1 */
3212 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv10x04000000U);
3213 /* Disable Compression CRIME (Compression Ratio Info-leak Made Easy) */
3214 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_COMPRESSION0x00020000U);
3215
3216 if (!SSL_CTX_use_certificate_chain_file(ssl_ctx, chain)) {
3217 ssl_error = SWITCH_TRUE;
3218 }
3219
3220 if (!ssl_error && !SSL_CTX_use_certificate_file(ssl_ctx, cert, SSL_FILETYPE_PEM1)) {
3221 ssl_error = SWITCH_TRUE;
3222 }
3223
3224 if (!ssl_error && !SSL_CTX_use_PrivateKey_file(ssl_ctx, key, SSL_FILETYPE_PEM1)) {
3225 ssl_error = SWITCH_TRUE;
3226 }
3227
3228 if (!ssl_error && !SSL_CTX_check_private_key(ssl_ctx)) {
3229 ssl_error = SWITCH_TRUE;
3230 }
3231
3232 if (ssl_error) {
3233 attempts = profile->bind_attempts;
3234 }
3235
3236 SSL_CTX_free(ssl_ctx);
3237#endif
3238
3239 do {
3240 profile->nua = nua_create(profile->s_root, /* Event loop */
3241 sofia_event_callback, /* Callback for processing events */
3242 profile, /* Additional data to pass to callback */
3243 TAG_IF( ! sofia_test_pflag(profile, PFLAG_TLS) || ! profile->tls_only, NUTAG_URL(profile->bindurl))!(! ((profile)->pflags[PFLAG_TLS] ? 1 : 0) || ! profile->
tls_only) ? tag_skip : nutag_url, urltag_url_v(profile->bindurl
)
,
3244 NTATAG_USER_VIA(1)ntatag_user_via, tag_bool_v((1)),
3245 TPTAG_PONG2PING(1)tptag_pong2ping, tag_bool_v((1)),
3246 NTATAG_TCP_RPORT(0)ntatag_tcp_rport, tag_bool_v((0)),
3247 NTATAG_TLS_RPORT(0)ntatag_tls_rport, tag_bool_v((0)),
3248 NUTAG_RETRY_AFTER_ENABLE(0)nutag_retry_after_enable, tag_bool_v(0),
3249 NUTAG_AUTO_INVITE_100(0)nutag_auto_invite_100, tag_bool_v(0),
3250 TAG_IF(!strchr(profile->sipip, ':'),!(!strchr(profile->sipip, ':')) ? tag_skip : soatag_af, tag_int_v
((SOA_AF_IP4_ONLY))
3251 SOATAG_AF(SOA_AF_IP4_ONLY))!(!strchr(profile->sipip, ':')) ? tag_skip : soatag_af, tag_int_v
((SOA_AF_IP4_ONLY))
,
3252 TAG_IF(strchr(profile->sipip, ':'),!(strchr(profile->sipip, ':')) ? tag_skip : soatag_af, tag_int_v
((SOA_AF_IP6_ONLY))
3253 SOATAG_AF(SOA_AF_IP6_ONLY))!(strchr(profile->sipip, ':')) ? tag_skip : soatag_af, tag_int_v
((SOA_AF_IP6_ONLY))
,
3254 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : nutag_sips_url
, urltag_url_v(profile->tls_bindurl)
3255 NUTAG_SIPS_URL(profile->tls_bindurl))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : nutag_sips_url
, urltag_url_v(profile->tls_bindurl)
,
3256 TAG_IF(profile->ws_bindurl,!(profile->ws_bindurl) ? tag_skip : nutag_ws_url, urltag_url_v
(profile->ws_bindurl)
3257 NUTAG_WS_URL(profile->ws_bindurl))!(profile->ws_bindurl) ? tag_skip : nutag_ws_url, urltag_url_v
(profile->ws_bindurl)
,
3258 TAG_IF(profile->wss_bindurl,!(profile->wss_bindurl) ? tag_skip : nutag_wss_url, urltag_url_v
(profile->wss_bindurl)
3259 NUTAG_WSS_URL(profile->wss_bindurl))!(profile->wss_bindurl) ? tag_skip : nutag_wss_url, urltag_url_v
(profile->wss_bindurl)
,
3260 TAG_IF(profile->tls_cert_dir,!(profile->tls_cert_dir) ? tag_skip : nutag_certificate_dir
, tag_str_v(profile->tls_cert_dir)
3261 NUTAG_CERTIFICATE_DIR(profile->tls_cert_dir))!(profile->tls_cert_dir) ? tag_skip : nutag_certificate_dir
, tag_str_v(profile->tls_cert_dir)
,
3262 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_passphrase,!(((profile)->pflags[PFLAG_TLS] ? 1 : 0) && profile
->tls_passphrase) ? tag_skip : tptag_tls_passphrase, tag_str_v
(profile->tls_passphrase)
3263 TPTAG_TLS_PASSPHRASE(profile->tls_passphrase))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0) && profile
->tls_passphrase) ? tag_skip : tptag_tls_passphrase, tag_str_v
(profile->tls_passphrase)
,
3264 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_verify_policy
, tag_uint_v((profile->tls_verify_policy))
3265 TPTAG_TLS_VERIFY_POLICY(profile->tls_verify_policy))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_verify_policy
, tag_uint_v((profile->tls_verify_policy))
,
3266 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_verify_depth
, tag_uint_v((profile->tls_verify_depth))
3267 TPTAG_TLS_VERIFY_DEPTH(profile->tls_verify_depth))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_verify_depth
, tag_uint_v((profile->tls_verify_depth))
,
3268 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_verify_date
, tag_uint_v((profile->tls_verify_date))
3269 TPTAG_TLS_VERIFY_DATE(profile->tls_verify_date))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_verify_date
, tag_uint_v((profile->tls_verify_date))
,
3270 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_verify_in_subjects,!(((profile)->pflags[PFLAG_TLS] ? 1 : 0) && profile
->tls_verify_in_subjects) ? tag_skip : tptag_tls_verify_subjects
, tag_cptr_v((profile->tls_verify_in_subjects))
3271 TPTAG_TLS_VERIFY_SUBJECTS(profile->tls_verify_in_subjects))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0) && profile
->tls_verify_in_subjects) ? tag_skip : tptag_tls_verify_subjects
, tag_cptr_v((profile->tls_verify_in_subjects))
,
3272 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_ciphers
, tag_str_v((profile->tls_ciphers))
3273 TPTAG_TLS_CIPHERS(profile->tls_ciphers))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_ciphers
, tag_str_v((profile->tls_ciphers))
,
3274 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_version
, tag_uint_v((profile->tls_version))
3275 TPTAG_TLS_VERSION(profile->tls_version))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_version
, tag_uint_v((profile->tls_version))
,
3276 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_timeout,!(((profile)->pflags[PFLAG_TLS] ? 1 : 0) && profile
->tls_timeout) ? tag_skip : tptag_tls_timeout, tag_uint_v(
(profile->tls_timeout))
3277 TPTAG_TLS_TIMEOUT(profile->tls_timeout))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0) && profile
->tls_timeout) ? tag_skip : tptag_tls_timeout, tag_uint_v(
(profile->tls_timeout))
,
3278 TAG_IF(!strchr(profile->sipip, ':'),!(!strchr(profile->sipip, ':')) ? tag_skip : ntatag_udp_mtu
, tag_uint_v((65535))
3279 NTATAG_UDP_MTU(65535))!(!strchr(profile->sipip, ':')) ? tag_skip : ntatag_udp_mtu
, tag_uint_v((65535))
,
3280 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV),!(((profile)->pflags[PFLAG_DISABLE_SRV] ? 1 : 0)) ? tag_skip
: ntatag_use_srv, tag_bool_v((0))
3281 NTATAG_USE_SRV(0))!(((profile)->pflags[PFLAG_DISABLE_SRV] ? 1 : 0)) ? tag_skip
: ntatag_use_srv, tag_bool_v((0))
,
3282 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_NAPTR),!(((profile)->pflags[PFLAG_DISABLE_NAPTR] ? 1 : 0)) ? tag_skip
: ntatag_use_naptr, tag_bool_v((0))
3283 NTATAG_USE_NAPTR(0))!(((profile)->pflags[PFLAG_DISABLE_NAPTR] ? 1 : 0)) ? tag_skip
: ntatag_use_naptr, tag_bool_v((0))
,
3284 TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_PINGPONG),!(((profile)->pflags[PFLAG_TCP_PINGPONG] ? 1 : 0)) ? tag_skip
: tptag_pingpong, tag_uint_v((profile->tcp_pingpong))
3285 TPTAG_PINGPONG(profile->tcp_pingpong))!(((profile)->pflags[PFLAG_TCP_PINGPONG] ? 1 : 0)) ? tag_skip
: tptag_pingpong, tag_uint_v((profile->tcp_pingpong))
,
3286 TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_PING2PONG),!(((profile)->pflags[PFLAG_TCP_PING2PONG] ? 1 : 0)) ? tag_skip
: tptag_pingpong, tag_uint_v((profile->tcp_ping2pong))
3287 TPTAG_PINGPONG(profile->tcp_ping2pong))!(((profile)->pflags[PFLAG_TCP_PING2PONG] ? 1 : 0)) ? tag_skip
: tptag_pingpong, tag_uint_v((profile->tcp_ping2pong))
,
3288 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV503),!(((profile)->pflags[PFLAG_DISABLE_SRV503] ? 1 : 0)) ? tag_skip
: ntatag_srv_503, tag_bool_v((0))
3289 NTATAG_SRV_503(0))!(((profile)->pflags[PFLAG_DISABLE_SRV503] ? 1 : 0)) ? tag_skip
: ntatag_srv_503, tag_bool_v((0))
,
3290 TAG_IF(sofia_test_pflag(profile, PFLAG_SOCKET_TCP_KEEPALIVE),!(((profile)->pflags[PFLAG_SOCKET_TCP_KEEPALIVE] ? 1 : 0))
? tag_skip : tptag_socket_keepalive, tag_uint_v((profile->
socket_tcp_keepalive))
3291 TPTAG_SOCKET_KEEPALIVE(profile->socket_tcp_keepalive))!(((profile)->pflags[PFLAG_SOCKET_TCP_KEEPALIVE] ? 1 : 0))
? tag_skip : tptag_socket_keepalive, tag_uint_v((profile->
socket_tcp_keepalive))
,
3292 TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_KEEPALIVE),!(((profile)->pflags[PFLAG_TCP_KEEPALIVE] ? 1 : 0)) ? tag_skip
: tptag_keepalive, tag_uint_v((profile->tcp_keepalive))
3293 TPTAG_KEEPALIVE(profile->tcp_keepalive))!(((profile)->pflags[PFLAG_TCP_KEEPALIVE] ? 1 : 0)) ? tag_skip
: tptag_keepalive, tag_uint_v((profile->tcp_keepalive))
,
3294 NTATAG_DEFAULT_PROXY(profile->outbound_proxy)ntatag_default_proxy, urltag_url_v((profile->outbound_proxy
))
,
3295 NTATAG_SERVER_RPORT(profile->server_rport_level)ntatag_server_rport, tag_int_v((profile->server_rport_level
))
,
3296 NTATAG_CLIENT_RPORT(profile->client_rport_level)ntatag_client_rport, tag_bool_v((profile->client_rport_level
))
,
3297 TPTAG_LOG(sofia_test_flag(profile, TFLAG_TPORT_LOG))tptag_log, tag_bool_v((((profile)->flags[TFLAG_TPORT_LOG] ?
1 : 0)))
,
3298 TPTAG_CAPT(sofia_test_flag(profile, TFLAG_CAPTURE) ? mod_sofia_globals.capture_server : NULL)tptag_capt, tag_str_v((((profile)->flags[TFLAG_CAPTURE] ? 1
: 0) ? mod_sofia_globals.capture_server : ((void*)0)))
,
3299 TAG_IF(sofia_test_pflag(profile, PFLAG_SIPCOMPACT),!(((profile)->pflags[PFLAG_SIPCOMPACT] ? 1 : 0)) ? tag_skip
: ntatag_sipflags, tag_uint_v((MSG_FLG_COMPACT))
3300 NTATAG_SIPFLAGS(MSG_DO_COMPACT))!(((profile)->pflags[PFLAG_SIPCOMPACT] ? 1 : 0)) ? tag_skip
: ntatag_sipflags, tag_uint_v((MSG_FLG_COMPACT))
,
3301 TAG_IF(profile->timer_t1, NTATAG_SIP_T1(profile->timer_t1))!(profile->timer_t1) ? tag_skip : ntatag_sip_t1, tag_uint_v
((profile->timer_t1))
,
3302 TAG_IF(profile->timer_t1x64, NTATAG_SIP_T1X64(profile->timer_t1x64))!(profile->timer_t1x64) ? tag_skip : ntatag_sip_t1x64, tag_uint_v
((profile->timer_t1x64))
,
3303 TAG_IF(profile->timer_t2, NTATAG_SIP_T2(profile->timer_t2))!(profile->timer_t2) ? tag_skip : ntatag_sip_t2, tag_uint_v
((profile->timer_t2))
,
3304 TAG_IF(profile->timer_t4, NTATAG_SIP_T4(profile->timer_t4))!(profile->timer_t4) ? tag_skip : ntatag_sip_t4, tag_uint_v
((profile->timer_t4))
,
3305 SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed")siptag_accept_str, tag_str_v("application/sdp, multipart/mixed"
)
,
3306 TAG_IF(sofia_test_pflag(profile, PFLAG_NO_CONNECTION_REUSE),!(((profile)->pflags[PFLAG_NO_CONNECTION_REUSE] ? 1 : 0)) ?
tag_skip : tptag_reuse, tag_bool_v((0))
3307 TPTAG_REUSE(0))!(((profile)->pflags[PFLAG_NO_CONNECTION_REUSE] ? 1 : 0)) ?
tag_skip : tptag_reuse, tag_bool_v((0))
,
3308 TAG_END()(tag_type_t)0, (tag_value_t)0); /* Last tag should always finish the sequence */
3309
3310 if (!ssl_error && !profile->nua) {
3311 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3311
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s) ATTEMPT %d (RETRY IN %d SEC)\n",
3312 profile->name, profile->bindurl, attempts + 1, profile->bind_attempt_interval);
3313 if (attempts < profile->bind_attempts) {
3314 switch_yield(1000000 * profile->bind_attempt_interval)switch_sleep(1000000 * profile->bind_attempt_interval);;
3315 }
3316 }
3317
3318 } while (!profile->nua && attempts++ < profile->bind_attempts);
3319
3320 if (!profile->nua) {
3321 if (!ssl_error) {
3322 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3322
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s)\n"
3323 "The likely causes for this are:\n" "1) Another application is already listening on the specified address.\n"
3324 "2) The IP the profile is attempting to bind to is not local to this system.\n", profile->name, profile->bindurl);
3325 } else {
3326 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3326
, ((void*)0)
, SWITCH_LOG_ERROR,
3327 "Error Creating SIP UA for profile: %s (%s). Bad WSS.PEM certificate.\n", profile->name, profile->bindurl);
3328 }
3329
3330 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 3330)
;
3331 goto nua_fail;
3332 }
3333
3334 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3334
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created agent for %s\n", profile->name);
3335
3336 nua_set_params(profile->nua,
3337 SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO")siptag_allow_str, tag_str_v("INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO"
)
,
3338 SIPTAG_USER_AGENT(SIP_NONE)siptag_user_agent, siptag_user_agent_v(((void const *)-1L)),
3339 NUTAG_AUTOANSWER(0)nutag_autoanswer, tag_bool_v(0),
3340 NUTAG_AUTOACK(0)nutag_autoack, tag_bool_v(0),
3341 NUTAG_AUTOALERT(0)nutag_autoalert, tag_bool_v(0),
3342 NUTAG_ENABLEMESSENGER(1)nutag_enablemessenger, tag_bool_v(1),
3343 NTATAG_EXTRA_100(0)ntatag_extra_100, tag_bool_v((0)),
3344 TAG_IF(sofia_test_pflag(profile, PFLAG_ALLOW_UPDATE), NUTAG_ALLOW("UPDATE"))!(((profile)->pflags[PFLAG_ALLOW_UPDATE] ? 1 : 0)) ? tag_skip
: nutag_allow, tag_str_v("UPDATE")
,
3345 TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER"))!((profile->mflags & MFLAG_REGISTER)) ? tag_skip : nutag_allow
, tag_str_v("REGISTER")
,
3346 TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER"))!((profile->mflags & MFLAG_REFER)) ? tag_skip : nutag_allow
, tag_str_v("REFER")
,
3347 TAG_IF(!sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_ALLOW("PRACK"))!(!((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0)) ? tag_skip
: nutag_allow, tag_str_v("PRACK")
,
3348 NUTAG_ALLOW("INFO")nutag_allow, tag_str_v("INFO"),
3349 NUTAG_ALLOW("NOTIFY")nutag_allow, tag_str_v("NOTIFY"),
3350 NUTAG_ALLOW_EVENTS("talk")nutag_allow_events, tag_str_v("talk"),
3351 NUTAG_ALLOW_EVENTS("hold")nutag_allow_events, tag_str_v("hold"),
3352 NUTAG_ALLOW_EVENTS("conference")nutag_allow_events, tag_str_v("conference"),
3353 NUTAG_APPL_METHOD("OPTIONS")nutag_appl_method, tag_str_v("OPTIONS"),
3354 NUTAG_APPL_METHOD("INVITE")nutag_appl_method, tag_str_v("INVITE"),
3355 NUTAG_APPL_METHOD("REFER")nutag_appl_method, tag_str_v("REFER"),
3356 NUTAG_APPL_METHOD("REGISTER")nutag_appl_method, tag_str_v("REGISTER"),
3357 NUTAG_APPL_METHOD("NOTIFY")nutag_appl_method, tag_str_v("NOTIFY"), NUTAG_APPL_METHOD("INFO")nutag_appl_method, tag_str_v("INFO"), NUTAG_APPL_METHOD("ACK")nutag_appl_method, tag_str_v("ACK"), NUTAG_APPL_METHOD("SUBSCRIBE")nutag_appl_method, tag_str_v("SUBSCRIBE"),
3358#ifdef MANUAL_BYE1
3359 NUTAG_APPL_METHOD("BYE")nutag_appl_method, tag_str_v("BYE"),
3360#endif
3361 NUTAG_APPL_METHOD("MESSAGE")nutag_appl_method, tag_str_v("MESSAGE"),
3362
3363 TAG_IF(profile->session_timeout && profile->minimum_session_expires, NUTAG_MIN_SE(profile->minimum_session_expires))!(profile->session_timeout && profile->minimum_session_expires
) ? tag_skip : nutag_min_se, tag_uint_v((profile->minimum_session_expires
))
,
3364 NUTAG_SESSION_TIMER(profile->session_timeout)nutag_session_timer, tag_uint_v((profile->session_timeout)
)
,
3365 NTATAG_MAX_PROCEEDING(profile->max_proceeding)ntatag_max_proceeding, tag_usize_v((profile->max_proceeding
))
,
3366 TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"PUBLISH")
,
3367 TAG_IF(profile->pres_type, NUTAG_ALLOW("SUBSCRIBE"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"SUBSCRIBE")
,
3368 TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1))!(profile->pres_type) ? tag_skip : nutag_enablemessage, tag_bool_v
(1)
,
3369 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("presence")
,
3370 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("as-feature-event"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("as-feature-event")
,
3371 TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("dialog"))!((profile->pres_type || ((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE
] ? 1 : 0))) ? tag_skip : nutag_allow_events, tag_str_v("dialog"
)
,
3372 TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("line-seize"))!((profile->pres_type || ((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE
] ? 1 : 0))) ? tag_skip : nutag_allow_events, tag_str_v("line-seize"
)
,
3373 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("call-info"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("call-info")
,
3374 TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("sla"))!((profile->pres_type || ((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE
] ? 1 : 0))) ? tag_skip : nutag_allow_events, tag_str_v("sla"
)
,
3375 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("include-session-description"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("include-session-description")
,
3376 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence.winfo"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("presence.winfo")
,
3377 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("message-summary"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("message-summary")
,
3378 TAG_IF(profile->pres_type == PRES_TYPE_PNP, NUTAG_ALLOW_EVENTS("ua-profile"))!(profile->pres_type == PRES_TYPE_PNP) ? tag_skip : nutag_allow_events
, tag_str_v("ua-profile")
,
3379 NUTAG_ALLOW_EVENTS("refer")nutag_allow_events, tag_str_v("refer"), SIPTAG_SUPPORTED_STR(supported)siptag_supported_str, tag_str_v(supported),
3380 TAG_IF(strcasecmp(profile->user_agent, "_undef_"), SIPTAG_USER_AGENT_STR(profile->user_agent))!(strcasecmp(profile->user_agent, "_undef_")) ? tag_skip :
siptag_user_agent_str, tag_str_v(profile->user_agent)
,
3381 TAG_END()(tag_type_t)0, (tag_value_t)0);
3382
3383 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3383
, ((void*)0)
, SWITCH_LOG_DEBUG, "Set params for %s\n", profile->name);
3384
3385 if (sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_PORT] ? 1 : 0) || sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] ? 1 : 0)) {
3386 sip_via_t *vias = nta_agent_via(nua_get_agent(profile->nua));
3387 sip_via_t *via = NULL((void*)0);
3388
3389 for (via = vias; via; via = via->v_next) {
3390 if (sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_PORT] ? 1 : 0) && !strcmp(via->v_protocol, "SIP/2.0/UDP")) {
3391 profile->sip_port = (switch_port_t)atoi(via->v_port);
3392 if (!profile->extsipport) profile->extsipport = profile->sip_port;
3393 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3393
, ((void*)0)
, SWITCH_LOG_DEBUG, "Found auto sip port %d for %s\n", profile->sip_port, profile->name);
3394 }
3395
3396 if (sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] ? 1 : 0) && !strcmp(via->v_protocol, "SIP/2.0/TLS")) {
3397 profile->tls_sip_port = (switch_port_t)atoi(via->v_port);
3398 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3398
, ((void*)0)
, SWITCH_LOG_DEBUG, "Found auto sip port %d for %s (TLS)\n", profile->tls_sip_port, profile->name);
3399 }
3400
3401 }
3402
3403 config_sofia_profile_urls(profile);
3404 }
3405
3406 for (node = profile->aliases; node; node = node->next) {
3407 node->nua = nua_create(profile->s_root, /* Event loop */
3408 sofia_event_callback, /* Callback for processing events */
3409 profile, /* Additional data to pass to callback */
3410 NTATAG_SERVER_RPORT(profile->server_rport_level)ntatag_server_rport, tag_int_v((profile->server_rport_level
))
, NUTAG_URL(node->url)nutag_url, urltag_url_v(node->url), TAG_END()(tag_type_t)0, (tag_value_t)0); /* Last tag should always finish the sequence */
3411
3412 nua_set_params(node->nua,
3413 SIPTAG_USER_AGENT(SIP_NONE)siptag_user_agent, siptag_user_agent_v(((void const *)-1L)),
3414 NUTAG_APPL_METHOD("OPTIONS")nutag_appl_method, tag_str_v("OPTIONS"),
3415 NUTAG_APPL_METHOD("REFER")nutag_appl_method, tag_str_v("REFER"),
3416 NUTAG_APPL_METHOD("SUBSCRIBE")nutag_appl_method, tag_str_v("SUBSCRIBE"),
3417 NUTAG_AUTOANSWER(0)nutag_autoanswer, tag_bool_v(0),
3418 NUTAG_AUTOACK(0)nutag_autoack, tag_bool_v(0),
3419 NUTAG_AUTOALERT(0)nutag_autoalert, tag_bool_v(0),
3420 TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER"))!((profile->mflags & MFLAG_REGISTER)) ? tag_skip : nutag_allow
, tag_str_v("REGISTER")
,
3421 TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER"))!((profile->mflags & MFLAG_REFER)) ? tag_skip : nutag_allow
, tag_str_v("REFER")
,
3422 NUTAG_ALLOW("INFO")nutag_allow, tag_str_v("INFO"),
3423 TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"PUBLISH")
,
3424 TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1))!(profile->pres_type) ? tag_skip : nutag_enablemessage, tag_bool_v
(1)
,
3425 SIPTAG_SUPPORTED_STR(supported)siptag_supported_str, tag_str_v(supported),
3426 TAG_IF(strcasecmp(profile->user_agent, "_undef_"), SIPTAG_USER_AGENT_STR(profile->user_agent))!(strcasecmp(profile->user_agent, "_undef_")) ? tag_skip :
siptag_user_agent_str, tag_str_v(profile->user_agent)
,
3427 TAG_END()(tag_type_t)0, (tag_value_t)0);
3428 }
3429
3430 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3430
, ((void*)0)
, SWITCH_LOG_DEBUG, "Activated db for %s\n", profile->name);
3431
3432 switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
3433 switch_mutex_init(&profile->dbh_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
3434 switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
3435 switch_queue_create(&profile->event_queue, SOFIA_QUEUE_SIZE50000, profile->pool);
3436
3437
3438 switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name);
3439 switch_sql_queue_manager_init_name(qname,
3440 &profile->qm,
3441 2,
3442 profile->odbc_dsn ? profile->odbc_dsn : profile->dbname,
3443 SWITCH_MAX_TRANS2000,
3444 profile->pre_trans_execute,
3445 profile->post_trans_execute,
3446 profile->inner_pre_trans_execute,
3447 profile->inner_post_trans_execute);
3448 switch_sql_queue_manager_start(profile->qm);
3449
3450 if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3450, &s_event, SWITCH_EVENT_PUBLISH
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
3451 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s",
3452 (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? ",_sips._tcp" : "");
3453
3454 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
3455 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
3456 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
3457 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
3458
3459 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
3460 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "tls_port", "%d", profile->tls_sip_port);
3461 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_tls_uri", profile->tls_url);
3462 }
3463 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 3463, &s_event, ((void*)0))
;
3464 }
3465
3466 sofia_glue_add_profile(profile->name, profile);
3467
3468 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3468
, ((void*)0)
, SWITCH_LOG_DEBUG, "Starting thread for %s\n", profile->name);
3469
3470 profile->started = switch_epoch_time_now(NULL((void*)0));
3471
3472 sofia_set_pflag_locked(profile, PFLAG_RUNNING)((profile->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("profile->flag_mutex != NULL", "sofia.c", 3472, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(profile->flag_mutex
);(profile)->pflags[PFLAG_RUNNING] = 1;switch_mutex_unlock
(profile->flag_mutex);
;
3473 worker_thread = launch_sofia_worker_thread(profile);
3474
3475 switch_yield(1000000)switch_sleep(1000000);;
3476
3477
3478 while (mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0) && sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)((profile)->pflags[PFLAG_WORKER_RUNNING] ? 1 : 0)) {
3479 su_root_step(profile->s_root, 1000);
3480 profile->last_root_step = switch_time_now();
3481 }
3482
3483 sofia_clear_pflag_locked(profile, PFLAG_RUNNING)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_RUNNING] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3484 sofia_reg_close_handles(profile);
3485
3486 switch_core_session_hupall_matching_var("sofia_profile_name", profile->name, SWITCH_CAUSE_MANAGER_REQUEST)switch_core_session_hupall_matching_var_ans("sofia_profile_name"
, profile->name, SWITCH_CAUSE_MANAGER_REQUEST, SHT_UNANSWERED
| SHT_ANSWERED)
;
3487 sanity = 10;
3488 while (profile->inuse) {
3489 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3489
, ((void*)0)
, SWITCH_LOG_CRIT, "Waiting for %d session(s)\n", profile->inuse);
3490 su_root_step(profile->s_root, 1000);
3491 if (!--sanity) {
3492 break;
3493 } else if (sanity == 5) {
3494 switch_core_session_hupall_matching_var("sofia_profile_name", profile->name, SWITCH_CAUSE_MANAGER_REQUEST)switch_core_session_hupall_matching_var_ans("sofia_profile_name"
, profile->name, SWITCH_CAUSE_MANAGER_REQUEST, SHT_UNANSWERED
| SHT_ANSWERED)
;
3495 }
3496 }
3497
3498 /* Gateway cleanup start */
3499 /* Mark all gateways as deleted and set REG_STATE_UNREGISTER state on REG gateways */
3500 sofia_glue_del_every_gateway(profile);
3501 /* First call will unregister and set state to DOWN so a gateway is ready for deletion */
3502 sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3503 sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3504 /*
3505 * The gateway life cycle requires a gateway to go though different states before it's destroyed.
3506 * Normally sofia_reg_check_gateway() is called periodically
3507 * but it's not the case on profile shutdown.
3508 *
3509 * All REG gateways should be DOWN now and can be finally deleted.
3510 * Calling sofia_reg_check_gateway() second time.
3511 */
3512 sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3513 sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3514 /* Gateway cleanup end */
3515
3516 sofia_glue_fire_events(profile);
3517
3518 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3518
, ((void*)0)
, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
3519
3520 if (worker_thread) {
3521 switch_thread_join(&st, worker_thread);
3522 }
3523 else {
3524 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3524
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n");
3525 }
3526
3527 sofia_reg_unregister(profile);
3528 nua_shutdown(profile->nua);
3529
3530 sanity = 100;
3531 while (!sofia_test_pflag(profile, PFLAG_SHUTDOWN)((profile)->pflags[PFLAG_SHUTDOWN] ? 1 : 0) || profile->queued_events > 0) {
3532 su_root_step(profile->s_root, 1000);
3533 if (!--sanity) {
3534 break;
3535 }
3536 }
3537
3538 sofia_clear_pflag_locked(profile, PFLAG_RUNNING)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_RUNNING] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3539 sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_SHUTDOWN] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3540
3541 sanity = 4;
3542 while (profile->inuse) {
3543 switch_core_session_hupall_matching_var("sofia_profile_name", profile->name, SWITCH_CAUSE_MANAGER_REQUEST)switch_core_session_hupall_matching_var_ans("sofia_profile_name"
, profile->name, SWITCH_CAUSE_MANAGER_REQUEST, SHT_UNANSWERED
| SHT_ANSWERED)
;
3544 switch_yield(5000000)switch_sleep(5000000);;
3545 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3545
, ((void*)0)
, SWITCH_LOG_CRIT, "Waiting for %d session(s)\n", profile->inuse);
3546 if (!--sanity) {
3547 break;
3548 }
3549 }
3550 nua_destroy(profile->nua);
3551
3552 switch_mutex_lock(profile->ireg_mutex);
3553 switch_mutex_unlock(profile->ireg_mutex);
3554
3555 switch_mutex_lock(profile->flag_mutex);
3556 switch_mutex_unlock(profile->flag_mutex);
3557
3558 switch_sql_queue_manager_destroy(&profile->qm);
3559
3560 if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3560, &s_event, SWITCH_EVENT_UNPUBLISH
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
3561 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s",
3562 (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? ",_sips._tcp" : "");
3563
3564 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
3565 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
3566 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
3567 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
3568
3569 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
3570 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "tls_port", "%d", profile->tls_sip_port);
3571 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_tls_uri", profile->tls_url);
3572 }
3573 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 3573, &s_event, ((void*)0))
;
3574 }
3575
3576 nua_fail:
3577 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0) && switch_nat_get_type()) {
3578 if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_UDP) == SWITCH_STATUS_SUCCESS) {
3579 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3579
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3580 }
3581 if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_TCP) == SWITCH_STATUS_SUCCESS) {
3582 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3582
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3583 }
3584 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) && switch_nat_del_mapping(profile->tls_sip_port, SWITCH_NAT_TCP) == SWITCH_STATUS_SUCCESS) {
3585 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3585
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
3586 }
3587 }
3588
3589 db_fail:
3590 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3590
, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name);
3591 switch_thread_rwlock_wrlock(profile->rwlock);
3592
3593 //su_home_unref(profile->home);
3594 su_root_destroy(profile->s_root);
3595 //pool = profile->pool;
3596
3597 sofia_glue_del_profile(profile);
3598 switch_core_hash_destroy(&profile->chat_hash);
3599 switch_core_hash_destroy(&profile->reg_nh_hash);
3600 switch_core_hash_destroy(&profile->mwi_debounce_hash);
3601
3602 switch_thread_rwlock_unlock(profile->rwlock);
3603 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3603
, ((void*)0)
, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name);
3604
3605 if (sofia_test_pflag(profile, PFLAG_RESPAWN)((profile)->pflags[PFLAG_RESPAWN] ? 1 : 0)) {
3606 config_sofia(SOFIA_CONFIG_RESPAWN, profile->name);
3607 }
3608
3609 sofia_profile_destroy(profile);
3610
3611 switch_mutex_lock(mod_sofia_globals.mutex);
3612 mod_sofia_globals.threads--;
3613 switch_mutex_unlock(mod_sofia_globals.mutex);
3614
3615 return NULL((void*)0);
3616}
3617
3618void sofia_profile_destroy(sofia_profile_t *profile)
3619{
3620 if (!profile->inuse) {
3621 switch_memory_pool_t *pool = profile->pool;
3622 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia.c",
(const char *)__func__, 3622)
;
3623 } else {
3624 sofia_set_pflag(profile, PFLAG_DESTROY)(profile)->pflags[PFLAG_DESTROY] = 1;
3625 }
3626}
3627
3628void launch_sofia_profile_thread(sofia_profile_t *profile)
3629{
3630 //switch_thread_t *thread;
3631 switch_threadattr_t *thd_attr = NULL((void*)0);
3632
3633 switch_threadattr_create(&thd_attr, profile->pool);
3634 switch_threadattr_detach_set(thd_attr, 1);
3635 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
3636 switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
3637 switch_thread_create(&profile->thread, thd_attr, sofia_profile_thread_run, profile, profile->pool);
3638}
3639
3640static void logger(void *logarg, char const *fmt, va_list ap)
3641{
3642 if (!fmt) return;
3643
3644 switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEANSWITCH_CHANNEL_ID_LOG_CLEAN, "sofia.c", (const char *)__func__
, 3644, ((void*)0)
, mod_sofia_globals.tracelevel, fmt, ap);
3645}
3646
3647static su_log_t *sofia_get_logger(const char *name)
3648{
3649 if (!strcasecmp(name, "tport")) {
3650 return tport_log;
3651 } else if (!strcasecmp(name, "iptsec")) {
3652 return iptsec_log;
3653 } else if (!strcasecmp(name, "nea")) {
3654 return nea_log;
3655 } else if (!strcasecmp(name, "nta")) {
3656 return nta_log;
3657 } else if (!strcasecmp(name, "nth_client")) {
3658 return nth_client_log;
3659 } else if (!strcasecmp(name, "nth_server")) {
3660 return nth_server_log;
3661 } else if (!strcasecmp(name, "nua")) {
3662 return nua_log;
3663 } else if (!strcasecmp(name, "soa")) {
3664 return soa_log;
3665 } else if (!strcasecmp(name, "sresolv")) {
3666 return sresolv_log;
3667#ifdef HAVE_SOFIA_STUN
3668 } else if (!strcasecmp(name, "stun")) {
3669 return stun_log;
3670#endif
3671 } else if (!strcasecmp(name, "default")) {
3672 return su_log_default;
3673 } else {
3674 return NULL((void*)0);
3675 }
3676}
3677
3678switch_status_t sofia_set_loglevel(const char *name, int level)
3679{
3680 su_log_t *log = NULL((void*)0);
3681
3682 if (level < 0 || level > 9) {
3683 return SWITCH_STATUS_FALSE;
3684 }
3685
3686 if (!strcasecmp(name, "all")) {
3687 su_log_set_level(su_log_default, level);
3688 su_log_set_level(tport_log, level);
3689 su_log_set_level(iptsec_log, level);
3690 su_log_set_level(nea_log, level);
3691 su_log_set_level(nta_log, level);
3692 su_log_set_level(nth_client_log, level);
3693 su_log_set_level(nth_server_log, level);
3694 su_log_set_level(nua_log, level);
3695 su_log_set_level(soa_log, level);
3696 su_log_set_level(sresolv_log, level);
3697#ifdef HAVE_SOFIA_STUN
3698 su_log_set_level(stun_log, level);
3699#endif
3700 return SWITCH_STATUS_SUCCESS;
3701 }
3702
3703 if (!(log = sofia_get_logger(name))) {
3704 return SWITCH_STATUS_FALSE;
3705 }
3706
3707 su_log_set_level(log, level);
3708
3709 return SWITCH_STATUS_SUCCESS;
3710}
3711
3712int sofia_get_loglevel(const char *name)
3713{
3714 su_log_t *log = NULL((void*)0);
3715
3716 if ((log = sofia_get_logger(name))) {
3717 return log->log_level;
3718 } else {
3719 return -1;
3720 }
3721}
3722
3723static void parse_gateway_subscriptions(sofia_profile_t *profile, sofia_gateway_t *gateway, switch_xml_t gw_subs_tag)
3724{
3725 switch_xml_t subscription_tag, param;
3726
3727 for (subscription_tag = switch_xml_child(gw_subs_tag, "subscription"); subscription_tag; subscription_tag = subscription_tag->next) {
3728 sofia_gateway_subscription_t *gw_sub;
3729
3730 if ((gw_sub = switch_core_alloc(profile->pool, sizeof(*gw_sub))switch_core_perform_alloc(profile->pool, sizeof(*gw_sub), "sofia.c"
, (const char *)__func__, 3730)
)) {
3731 char *expire_seconds = "3600", *retry_seconds = "30", *content_type = "NO_CONTENT_TYPE";
3732 uint32_t username_in_request = 0;
3733 char *event = (char *) switch_xml_attr_soft(subscription_tag, "event");
3734 gw_sub->event = switch_core_strdup(gateway->pool, event)switch_core_perform_strdup(gateway->pool, event, "sofia.c"
, (const char *)__func__, 3734)
;
3735 gw_sub->gateway = gateway;
3736 gw_sub->next = NULL((void*)0);
3737
3738 for (param = switch_xml_child(subscription_tag, "param"); param; param = param->next) {
3739 char *var = (char *) switch_xml_attr_soft(param, "name");
3740 char *val = (char *) switch_xml_attr_soft(param, "value");
3741 if (!strcmp(var, "expire-seconds")) {
3742 expire_seconds = val;
3743 } else if (!strcmp(var, "retry-seconds")) {
3744 retry_seconds = val;
3745 } else if (!strcmp(var, "content-type")) {
3746 content_type = val;
3747 } else if (!strcmp(var, "username-in-request")) {
3748 username_in_request = switch_true(val);
3749 }
3750 }
3751
3752 gw_sub->retry_seconds = atoi(retry_seconds);
3753 if (gw_sub->retry_seconds < 10) {
3754 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3754
, ((void*)0)
, SWITCH_LOG_WARNING, "INVALID: retry_seconds correcting the value to 30\n");
3755 gw_sub->retry_seconds = 30;
3756 }
3757
3758 gw_sub->expires_str = switch_core_strdup(gateway->pool, expire_seconds)switch_core_perform_strdup(gateway->pool, expire_seconds, "sofia.c"
, (const char *)__func__, 3758)
;
3759
3760 if ((gw_sub->freq = atoi(gw_sub->expires_str)) < 5) {
3761 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3761
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid Freq: %d. Setting Register-Frequency to 3600\n", gw_sub->freq);
3762 gw_sub->freq = 3600;
3763 }
3764
3765 if(username_in_request) {
3766 gw_sub->request_uri = gateway->register_to;
3767 } else {
3768 gw_sub->request_uri = gateway->register_url;
3769 }
3770
3771 gw_sub->freq -= 2;
3772 gw_sub->content_type = switch_core_strdup(gateway->pool, content_type)switch_core_perform_strdup(gateway->pool, content_type, "sofia.c"
, (const char *)__func__, 3772)
;
3773 gw_sub->next = gateway->subscriptions;
3774 }
3775 gateway->subscriptions = gw_sub;
3776 }
3777}
3778
3779static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag, const char *gwname)
3780{
3781 switch_xml_t gateway_tag, param = NULL((void*)0), x_params, gw_subs_tag;
3782 sofia_gateway_t *gp;
3783
3784 for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
3785 char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
3786 sofia_gateway_t *gateway;
3787 char *pkey = switch_mprintf("%s::%s", profile->name, name);
3788
3789 if (zstr(name)_zstr(name) || switch_regex_match(name, "^[\\w\\.\\-\\_]+$") != SWITCH_STATUS_SUCCESS) {
3790 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3790
, ((void*)0)
, SWITCH_LOG_ERROR, "Ignoring invalid name '%s'\n", name ? name : "NULL");
3791 free(pkey);
3792 goto skip;
3793 }
3794
3795 if (gwname && strcmp(gwname, name)) {
3796 free(pkey);
3797 goto skip;
3798 }
3799
3800 switch_mutex_lock(mod_sofia_globals.hash_mutex);
3801 if ((gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, name)) && (gp = switch_core_hash_find(mod_sofia_globals.gateway_hash, pkey)) && !gp->deleted) {
3802 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3802
, ((void*)0)
, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", name);
3803 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
3804 free(pkey);
3805 goto skip;
3806 }
3807 free(pkey);
3808 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
3809
3810 if ((gateway = switch_core_alloc(profile->pool, sizeof(*gateway))switch_core_perform_alloc(profile->pool, sizeof(*gateway),
"sofia.c", (const char *)__func__, 3810)
)) {
3811 const char *sipip, *format;
3812 switch_uuid_t uuid;
3813 uint32_t ping_freq = 0, extension_in_contact = 0, contact_in_ping = 0, ping_monitoring = 0, distinct_to = 0, rfc_5626 = 0;
3814 int ping_max = 1, ping_min = 1;
3815 char *register_str = "true", *scheme = "Digest",
3816 *realm = NULL((void*)0),
3817 *username = NULL((void*)0),
3818 *auth_username = NULL((void*)0),
3819 *password = NULL((void*)0),
3820 *caller_id_in_from = "false",
3821 *extension = NULL((void*)0),
3822 *proxy = NULL((void*)0),
3823 *options_user_agent = NULL((void*)0),
3824 *context = profile->context,
3825 *expire_seconds = "3600",
3826 *retry_seconds = "30",
3827 *fail_908_retry_seconds = NULL((void*)0),
3828 *timeout_seconds = "60",
3829 *from_user = "", *from_domain = NULL((void*)0), *outbound_proxy = NULL((void*)0), *register_proxy = NULL((void*)0), *contact_host = NULL((void*)0),
3830 *contact_params = "", *params = NULL((void*)0), *register_transport = NULL((void*)0),
3831 *reg_id = NULL((void*)0), *str_rfc_5626 = "";
3832
3833 if (!context) {
3834 context = "default";
3835 }
3836
3837 switch_uuid_get(&uuid);
3838 switch_uuid_format(gateway->uuid_str, &uuid);
3839
3840 gateway->register_transport = SOFIA_TRANSPORT_UDP;
3841 gateway->pool = profile->pool;
3842 gateway->profile = profile;
3843 gateway->name = switch_core_strdup(gateway->pool, name)switch_core_perform_strdup(gateway->pool, name, "sofia.c",
(const char *)__func__, 3843)
;
3844 gateway->freq = 0;
3845 gateway->next = NULL((void*)0);
3846 gateway->ping = 0;
3847 gateway->ping_freq = 0;
3848 gateway->ping_max = 0;
3849 gateway->ping_min = 0;
3850 gateway->ping_sent = 0;
3851 gateway->ping_time = 0;
3852 gateway->ping_count = 0;
3853 gateway->ping_monitoring = SWITCH_FALSE;
3854 gateway->ib_calls = 0;
3855 gateway->ob_calls = 0;
3856 gateway->ib_failed_calls = 0;
3857 gateway->ob_failed_calls = 0;
3858 gateway->destination_prefix = "";
3859
3860 if ((x_params = switch_xml_child(gateway_tag, "variables"))) {
3861 param = switch_xml_child(x_params, "variable");
3862 } else {
3863 param = switch_xml_child(gateway_tag, "variable");
3864 }
3865
3866
3867 for (; param; param = param->next) {
3868 const char *var = switch_xml_attr(param, "name");
3869 const char *val = switch_xml_attr(param, "value");
3870 const char *direction = switch_xml_attr(param, "direction");
3871 int in = 0, out = 0;
3872
3873 if (var && val) {
3874 if (direction) {
3875 if (!strcasecmp(direction, "inbound")) {
3876 in = 1;
3877 } else if (!strcasecmp(direction, "outbound")) {
3878 out = 1;
3879 }
3880 } else {
3881 in = out = 1;
3882 }
3883
3884 if (in) {
3885 if (!gateway->ib_vars) {
3886 switch_event_create_plain(&gateway->ib_vars, SWITCH_EVENT_GENERAL);
3887 }
3888 switch_event_add_header_string(gateway->ib_vars, SWITCH_STACK_BOTTOM, var, val);
3889 }
3890
3891 if (out) {
3892 if (!gateway->ob_vars) {
3893 switch_event_create_plain(&gateway->ob_vars, SWITCH_EVENT_GENERAL);
3894 }
3895 switch_event_add_header_string(gateway->ob_vars, SWITCH_STACK_BOTTOM, var, val);
3896 }
3897 }
3898 }
3899
3900 if ((x_params = switch_xml_child(gateway_tag, "params"))) {
3901 param = switch_xml_child(x_params, "param");
3902 } else {
3903 param = switch_xml_child(gateway_tag, "param");
3904 }
3905
3906 for (; param; param = param->next) {
3907 char *var = (char *) switch_xml_attr_soft(param, "name");
3908 char *val = (char *) switch_xml_attr_soft(param, "value");
3909
3910 if (!strcmp(var, "register")) {
3911 register_str = val;
3912 } else if (!strcmp(var, "scheme")) {
3913 scheme = val;
3914 } else if (!strcmp(var, "realm")) {
3915 realm = val;
3916 } else if (!strcmp(var, "username")) {
3917 username = val;
3918 } else if (!strcmp(var, "extension-in-contact")) {
3919 extension_in_contact = switch_true(val);
3920 } else if (!strcmp(var, "auth-username")) {
3921 auth_username = val;
3922 } else if (!strcmp(var, "password")) {
3923 password = val;
3924 } else if (!strcmp(var, "caller-id-in-from")) {
3925 caller_id_in_from = val;
3926 } else if (!strcmp(var, "extension")) {
3927 extension = val;
3928 } else if (!strcmp(var, "contact-in-ping")) {
3929 contact_in_ping = switch_true(val);
3930 } else if (!strcmp(var, "ping")) {
3931 ping_freq = atoi(val);
3932 } else if (!strcmp(var, "ping-max")) {
3933 ping_max = atoi(val);
3934 } else if (!strcmp(var, "ping-min")) {
3935 ping_min = atoi(val);
3936 } else if (!strcmp(var, "ping-user-agent")) {
3937 options_user_agent = val;
3938 } else if (!strcmp(var, "ping-monitoring")) { // if true then every gw ping result will fire a gateway status event
3939 ping_monitoring = switch_true(val);
3940 } else if (!strcmp(var, "proxy")) {
3941 proxy = val;
3942 } else if (!strcmp(var, "context")) {
3943 context = val;
3944 } else if (!strcmp(var, "expire-seconds")) {
3945 expire_seconds = val;
3946 } else if (!strcmp(var, "908-retry-seconds")) {
3947 fail_908_retry_seconds = val;
3948 } else if (!strcmp(var, "retry-seconds")) {
3949 retry_seconds = val;
3950 } else if (!strcmp(var, "timeout-seconds")) {
3951 timeout_seconds = val;
3952 } else if (!strcmp(var, "retry_seconds")) { // support typo for back compat
3953 retry_seconds = val;
3954 } else if (!strcmp(var, "from-user")) {
3955 from_user = val;
3956 } else if (!strcmp(var, "from-domain")) {
3957 from_domain = val;
3958 } else if (!strcmp(var, "contact-host")) {
3959 contact_host = val;
3960 } else if (!strcmp(var, "register-proxy")) {
3961 register_proxy = val;
3962 gateway->register_proxy_host_cfg = sofia_glue_get_host_from_cfg(register_proxy, gateway->pool);
3963 } else if (!strcmp(var, "outbound-proxy")) {
3964 outbound_proxy = val;
3965 gateway->outbound_proxy_host_cfg = sofia_glue_get_host_from_cfg(outbound_proxy, gateway->pool);
3966 } else if (!strcmp(var, "distinct-to")) {
3967 distinct_to = switch_true(val);
3968 } else if (!strcmp(var, "destination-prefix")) {
3969 if (!zstr(val)_zstr(val)) {
3970 gateway->destination_prefix = switch_core_strdup(gateway->pool, val)switch_core_perform_strdup(gateway->pool, val, "sofia.c", (
const char *)__func__, 3970)
;
3971 }
3972 } else if (!strcmp(var, "rfc-5626")) {
3973 rfc_5626 = switch_true(val);
3974 } else if (!strcmp(var, "reg-id")) {
3975 reg_id = val;
3976 } else if (!strcmp(var, "contact-params")) {
3977 contact_params = val;
3978 } else if (!strcmp(var, "register-transport")) {
3979 sofia_transport_t transport = sofia_glue_str2transport(val);
3980
3981 if (transport == SOFIA_TRANSPORT_UNKNOWN || (!sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) && sofia_glue_transport_has_tls(transport))) {
3982 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3982
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: unsupported transport\n");
3983 goto skip;
3984 }
3985
3986 gateway->register_transport = transport;
3987 } else if (!strcmp(var, "gw-auth-acl")) {
3988 if (!zstr(val)_zstr(val)) {
3989 gateway->gw_auth_acl = switch_core_strdup(gateway->pool, val)switch_core_perform_strdup(gateway->pool, val, "sofia.c", (
const char *)__func__, 3989)
;
3990 }
3991 }
3992 }
3993
3994 /* RFC 5626 enable in the GW profile and the UA profile */
3995 if (rfc_5626 && sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626)((profile)->pflags[PFLAG_ENABLE_RFC5626] ? 1 : 0)) {
3996 char str_guid[su_guid_strlen + 1];
3997 su_guid_t guid[1];
3998 su_guid_generate(guid);
3999 su_guid_sprintf(str_guid, su_guid_strlen + 1, guid);
4000 str_rfc_5626 = switch_core_sprintf(gateway->pool, ";reg-id=%s;+sip.instance=\"<urn:uuid:%s>\"",reg_id,str_guid);
4001 }
4002
4003 if (zstr(realm)_zstr(realm)) {
4004 if (zstr(proxy)_zstr(proxy)) {
4005 realm = name;
4006 } else {
4007 realm = proxy;
4008 }
4009 }
4010
4011 if (switch_true(register_str)) {
4012 if (zstr(username)_zstr(username)) {
4013 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4013
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: username param is REQUIRED!\n");
4014 goto skip;
4015 }
4016
4017 if (zstr(password)_zstr(password)) {
4018 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4018
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: password param is REQUIRED!\n");
4019 goto skip;
4020 }
4021 } else {
4022 if (zstr(username)_zstr(username)) {
4023 username = "FreeSWITCH";
4024 }
4025
4026 if (zstr(password)_zstr(password)) {
4027 password = "";
4028 }
4029 }
4030
4031 if (zstr(from_user)_zstr(from_user)) {
4032 from_user = username;
4033 }
4034
4035 if (zstr(proxy)_zstr(proxy)) {
4036 proxy = realm;
4037 }
4038
4039 gateway->proxy_host_cfg = sofia_glue_get_host_from_cfg(proxy, gateway->pool);
4040
4041 if (!switch_true(register_str)) {
4042 gateway->state = REG_STATE_NOREG;
4043 gateway->status = SOFIA_GATEWAY_UP;
4044 gateway->uptime = switch_time_now();
4045 }
4046
4047 if (zstr(auth_username)_zstr(auth_username)) {
4048 auth_username = username;
4049 }
4050
4051 if (!zstr(register_proxy)_zstr(register_proxy)) {
4052 if (strncasecmp(register_proxy, "sip:", 4) && strncasecmp(register_proxy, "sips:", 5)) {
4053 gateway->register_sticky_proxy = switch_core_sprintf(gateway->pool, "sip:%s", register_proxy);
4054 } else {
4055 gateway->register_sticky_proxy = switch_core_strdup(gateway->pool, register_proxy)switch_core_perform_strdup(gateway->pool, register_proxy, "sofia.c"
, (const char *)__func__, 4055)
;
4056 }
4057 }
4058
4059 if (!zstr(outbound_proxy)_zstr(outbound_proxy)) {
4060 if (strncasecmp(outbound_proxy, "sip:", 4) && strncasecmp(outbound_proxy, "sips:", 5)) {
4061 gateway->outbound_sticky_proxy = switch_core_sprintf(gateway->pool, "sip:%s", outbound_proxy);
4062 } else {
4063 gateway->outbound_sticky_proxy = switch_core_strdup(gateway->pool, outbound_proxy)switch_core_perform_strdup(gateway->pool, outbound_proxy, "sofia.c"
, (const char *)__func__, 4063)
;
4064 }
4065 }
4066
4067 gateway->retry_seconds = atoi(retry_seconds);
4068
4069 if (fail_908_retry_seconds) {
4070 gateway->fail_908_retry_seconds = atoi(fail_908_retry_seconds);
4071 }
4072
4073 if (gateway->retry_seconds < 5) {
4074 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4074
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid retry-seconds of %d on gateway %s, using the value of 30 instead.\n",
4075 gateway->retry_seconds, name);
4076 gateway->retry_seconds = 30;
4077 }
4078
4079 gateway->reg_timeout_seconds = atoi(timeout_seconds);
4080
4081 if (gateway->reg_timeout_seconds < 5) {
4082 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4082
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid timeout-seconds of %d on gateway %s, using the value of 60 instead.\n",
4083 gateway->reg_timeout_seconds, name);
4084 gateway->reg_timeout_seconds = 60;
4085 }
4086
4087
4088 gateway->register_scheme = switch_core_strdup(gateway->pool, scheme)switch_core_perform_strdup(gateway->pool, scheme, "sofia.c"
, (const char *)__func__, 4088)
;
4089 gateway->register_context = switch_core_strdup(gateway->pool, context)switch_core_perform_strdup(gateway->pool, context, "sofia.c"
, (const char *)__func__, 4089)
;
4090 gateway->register_realm = switch_core_strdup(gateway->pool, realm)switch_core_perform_strdup(gateway->pool, realm, "sofia.c"
, (const char *)__func__, 4090)
;
4091 gateway->register_username = switch_core_strdup(gateway->pool, username)switch_core_perform_strdup(gateway->pool, username, "sofia.c"
, (const char *)__func__, 4091)
;
4092 gateway->auth_username = switch_core_strdup(gateway->pool, auth_username)switch_core_perform_strdup(gateway->pool, auth_username, "sofia.c"
, (const char *)__func__, 4092)
;
4093 gateway->register_password = switch_core_strdup(gateway->pool, password)switch_core_perform_strdup(gateway->pool, password, "sofia.c"
, (const char *)__func__, 4093)
;
4094 gateway->distinct_to = distinct_to;
4095 gateway->options_user_agent = options_user_agent;
4096
4097 if (switch_true(caller_id_in_from)) {
4098 sofia_set_flag(gateway, REG_FLAG_CALLERID)(gateway)->flags[REG_FLAG_CALLERID] = 1;
4099 }
4100
4101 register_transport = (char *) sofia_glue_transport2str(gateway->register_transport);
4102
4103 if (! zstr(contact_params)_zstr(contact_params)) {
4104 if (*contact_params == ';') {
4105 params = switch_core_sprintf(gateway->pool, "%s;transport=%s;gw=%s", contact_params, register_transport, gateway->name);
4106 } else {
4107 params = switch_core_sprintf(gateway->pool, ";%s;transport=%s;gw=%s", contact_params, register_transport, gateway->name);
4108 }
4109 } else {
4110 params = switch_core_sprintf(gateway->pool, ";transport=%s;gw=%s", register_transport, gateway->name);
4111 }
4112
4113 if (!zstr(from_domain)_zstr(from_domain)) {
4114 gateway->from_domain = switch_core_strdup(gateway->pool, from_domain)switch_core_perform_strdup(gateway->pool, from_domain, "sofia.c"
, (const char *)__func__, 4114)
;
4115 }
4116
4117 if (!zstr(register_transport)_zstr(register_transport) && !switch_stristr("transport=", proxy)) {
4118 gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", proxy, register_transport);
4119 } else {
4120 gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
4121 }
4122
4123 gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s>",
4124 from_user, !zstr(from_domain)_zstr(from_domain) ? from_domain : proxy);
4125
4126 if (ping_freq) {
4127 if (ping_freq >= 5) {
4128 gateway->ping_freq = ping_freq;
4129 gateway->ping_max = ping_max;
4130 gateway->ping_min = ping_min;
4131 gateway->ping_monitoring = ping_monitoring;
4132 gateway->ping = switch_epoch_time_now(NULL((void*)0)) + ping_freq;
4133 gateway->options_to_uri = switch_core_sprintf(gateway->pool, "<sip:%s>",
4134 !zstr(from_domain)_zstr(from_domain) ? from_domain : proxy);
4135 gateway->options_from_uri = gateway->options_to_uri;
4136 if (contact_in_ping) {
4137 gateway->contact_in_ping = contact_in_ping;
4138 }
4139 } else {
4140 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4140
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: invalid ping!\n");
4141 }
4142 }
4143
4144 if (contact_host) {
4145 if (!strcmp(contact_host, "sip-ip")) {
4146 sipip = profile->sipip;
4147 } else {
4148 sipip = contact_host;
4149 }
4150 } else if (profile->extsipip) {
4151 sipip = profile->extsipip;
4152 } else {
4153 sipip = profile->sipip;
4154 }
4155
4156 if (zstr(extension)_zstr(extension)) {
4157 extension = username;
4158 } else {
4159 gateway->real_extension = switch_core_strdup(gateway->pool, extension)switch_core_perform_strdup(gateway->pool, extension, "sofia.c"
, (const char *)__func__, 4159)
;
4160 }
4161
4162 gateway->extension = switch_core_strdup(gateway->pool, extension)switch_core_perform_strdup(gateway->pool, extension, "sofia.c"
, (const char *)__func__, 4162)
;
4163
4164 if (!strncasecmp(proxy, "sip:", 4)) {
4165 gateway->register_proxy = switch_core_strdup(gateway->pool, proxy)switch_core_perform_strdup(gateway->pool, proxy, "sofia.c"
, (const char *)__func__, 4165)
;
4166 gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy + 4);
4167 } else {
4168 gateway->register_proxy = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
4169 gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy);
4170 }
4171
4172 /* This checks to make sure we provide the right contact on register for targets behind nat with us. */
4173 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
4174 char *register_host = NULL((void*)0);
4175
4176 register_host = sofia_glue_get_register_host(gateway->register_proxy);
4177
4178 if (register_host && switch_is_lan_addr(register_host)) {
4179 sipip = profile->sipip;
4180 }
4181
4182 switch_safe_free(register_host)if (register_host) {free(register_host);register_host=((void*
)0);}
;
4183 }
4184
4185 if (extension_in_contact) {
4186 if (rfc_5626) {
4187 format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d>%s" : "<sip:%s@%s:%d%s>%s";
4188 gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
4189 sipip,
4190 sofia_glue_transport_has_tls(gateway->register_transport) ?
4191 profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
4192
4193 } else {
4194 format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d%s>" : "<sip:%s@%s:%d%s>";
4195 gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
4196 sipip,
4197 sofia_glue_transport_has_tls(gateway->register_transport) ?
4198 profile->tls_sip_port : profile->extsipport, params);
4199 }
4200 } else {
4201 if (rfc_5626) {
4202 format = strchr(sipip, ':') ? "<sip:gw+%s@[%s]:%d%s>%s" : "<sip:gw+%s@%s:%d%s>%s";
4203 gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
4204 sipip,
4205 sofia_glue_transport_has_tls(gateway->register_transport) ?
4206 profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
4207
4208 } else {
4209 format = strchr(sipip, ':') ? "<sip:gw+%s@[%s]:%d%s>" : "<sip:gw+%s@%s:%d%s>";
4210 gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
4211 sipip,
4212 sofia_glue_transport_has_tls(gateway->register_transport) ?
4213 profile->tls_sip_port : profile->extsipport, params);
4214
4215 }
4216 }
4217
4218 gateway->expires_str = switch_core_strdup(gateway->pool, expire_seconds)switch_core_perform_strdup(gateway->pool, expire_seconds, "sofia.c"
, (const char *)__func__, 4218)
;
4219
4220 if ((gateway->freq = atoi(gateway->expires_str)) < 5) {
4221 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4221
, ((void*)0)
, SWITCH_LOG_WARNING,
4222 "Invalid register-frequency of %d on gateway %s, using the value of 3600 instead\n", gateway->freq, name);
4223 gateway->freq = 3600;
4224 }
4225
4226 if ((gw_subs_tag = switch_xml_child(gateway_tag, "subscriptions"))) {
4227 parse_gateway_subscriptions(profile, gateway, gw_subs_tag);
4228 }
4229
4230 sofia_reg_add_gateway(profile, gateway->name, gateway);
4231
4232 }
4233
4234 skip:
4235 switch_assert(gateway_tag)((gateway_tag) ? (void) (0) : __assert_fail ("gateway_tag", "sofia.c"
, 4235, __extension__ __PRETTY_FUNCTION__))
;
4236 }
4237}
4238
4239static void parse_domain_tag(sofia_profile_t *profile, switch_xml_t x_domain_tag, const char *dname, const char *parse, const char *alias)
4240{
4241 if (switch_true(alias)) {
4242 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, dname)switch_core_perform_strdup(profile->pool, dname, "sofia.c"
, (const char *)__func__, 4242)
, profile) == SWITCH_STATUS_SUCCESS) {
4243 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4243
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", dname, profile->name);
4244 } else {
4245 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4245
, ((void*)0)
, SWITCH_LOG_DEBUG1, "Alias [%s] for profile [%s] (already exists)\n", dname, profile->name);
4246 }
4247 }
4248
4249 if (switch_true(parse)) {
4250 switch_xml_t gts, gt, uts, ut, gateways_tag;
4251 /* Backwards Compatibility */
4252 for (ut = switch_xml_child(x_domain_tag, "user"); ut; ut = ut->next) {
4253 if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
4254 parse_gateways(profile, gateways_tag, NULL((void*)0));
4255 }
4256 }
4257 /* New Method with <groups> tags and users are now inside a <users> tag */
4258 for (gts = switch_xml_child(x_domain_tag, "groups"); gts; gts = gts->next) {
4259 for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
4260 for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
4261 for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
4262 if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
4263 parse_gateways(profile, gateways_tag, NULL((void*)0));
4264 }
4265 }
4266 }
4267 }
4268 }
4269 }
4270}
4271
4272static void config_sofia_profile_urls(sofia_profile_t * profile)
4273{
4274
4275 if (profile->extsipip) {
4276 char *ipv6 = strchr(profile->extsipip, ':');
4277 profile->public_url = switch_core_sprintf(profile->pool,
4278 "sip:%s@%s%s%s:%d",
4279 profile->contact_user,
4280 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
4281 }
4282
4283 if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
4284 char *ipv6 = strchr(profile->extsipip, ':');
4285 profile->url = switch_core_sprintf(profile->pool,
4286 "sip:%s@%s%s%s:%d",
4287 profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
4288 profile->bindurl = switch_core_sprintf(profile->pool, "%s;maddr=%s", profile->url, profile->sipip);
4289 } else {
4290 char *ipv6 = strchr(profile->sipip, ':');
4291 profile->url = switch_core_sprintf(profile->pool,
4292 "sip:%s@%s%s%s:%d",
4293 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->sip_port);
4294 profile->bindurl = profile->url;
4295 }
4296
4297 profile->tcp_contact = switch_core_sprintf(profile->pool, "<%s;transport=tcp>", profile->url);
4298
4299 if (profile->public_url) {
4300 profile->tcp_public_contact = switch_core_sprintf(profile->pool, "<%s;transport=tcp>", profile->public_url);
4301 }
4302
4303 if (profile->bind_params) {
4304 char *bindurl;
4305 if (!switch_stristr("transport=", profile->bind_params)) {
4306 profile->bind_params = switch_core_sprintf(profile->pool, "%s;transport=udp,tcp", profile->bind_params);
4307 }
4308 bindurl = switch_core_sprintf(profile->pool, "%s;%s", profile->bindurl, profile->bind_params);
4309 profile->bindurl = bindurl;
4310 } else {
4311 char *bindurl = switch_core_sprintf(profile->pool, "%s;transport=udp,tcp", profile->bindurl);
4312 profile->bindurl = bindurl;
4313 }
4314
4315
4316 if ( profile->ws_port ) {
4317 char *ip = !zstr(profile->ws_ip)_zstr(profile->ws_ip) ? profile->ws_ip : profile->sipip;
4318 switch_port_t port = profile->ws_port;
4319 char *ipv6 = strchr(ip, ':');
4320 profile->ws_bindurl =
4321 switch_core_sprintf(profile->pool,
4322 "sip:%s@%s%s%s:%d;transport=ws",
4323 profile->contact_user, ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
4324 }
4325
4326 if ( profile->wss_port ) {
4327 char *ip = !zstr(profile->wss_ip)_zstr(profile->wss_ip) ? profile->wss_ip : profile->sipip;
4328 switch_port_t port = profile->wss_port;
4329 char *ipv6 = strchr(ip, ':');
4330 profile->wss_bindurl =
4331 switch_core_sprintf(profile->pool,
4332 "sips:%s@%s%s%s:%d;transport=wss",
4333 profile->contact_user, ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
4334 }
4335
4336 /*
4337 * handle TLS params #2
4338 */
4339 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
4340 if (!profile->tls_sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] ? 1 : 0)) {
4341 profile->tls_sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_TLS_PORT"5061");
4342 }
4343
4344 if (profile->extsipip) {
4345 char *ipv6 = strchr(profile->extsipip, ':');
4346 profile->tls_public_url = switch_core_sprintf(profile->pool,
4347 "sip:%s@%s%s%s:%d",
4348 profile->contact_user,
4349 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port);
4350 }
4351
4352 if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
4353 char *ipv6 = strchr(profile->extsipip, ':');
4354 profile->tls_url =
4355 switch_core_sprintf(profile->pool,
4356 "sip:%s@%s%s%s:%d",
4357 profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port);
4358 profile->tls_bindurl =
4359 switch_core_sprintf(profile->pool,
4360 "sips:%s@%s%s%s:%d;maddr=%s",
4361 profile->contact_user,
4362 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port, profile->sipip);
4363 } else {
4364 char *ipv6 = strchr(profile->sipip, ':');
4365 profile->tls_url =
4366 switch_core_sprintf(profile->pool,
4367 "sip:%s@%s%s%s:%d",
4368 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->tls_sip_port);
4369 profile->tls_bindurl =
4370 switch_core_sprintf(profile->pool,
4371 "sips:%s@%s%s%s:%d",
4372 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->tls_sip_port);
4373 }
4374
4375 if (profile->tls_bind_params) {
4376 char *tls_bindurl = profile->tls_bindurl;
4377 profile->tls_bindurl = switch_core_sprintf(profile->pool, "%s;%s", tls_bindurl, profile->tls_bind_params);
4378 }
4379
4380 profile->tls_contact = switch_core_sprintf(profile->pool, "<%s;transport=tls>", profile->tls_url);
4381 if (profile->tls_public_url) {
4382 profile->tls_public_contact = switch_core_sprintf(profile->pool, "<%s;transport=tls>", profile->tls_public_url);
4383 }
4384
4385
4386 }
4387}
4388
4389#ifdef SOFIA_CUSTOM_TIME
4390/* appears to not be granular enough */
4391static void sofia_time(su_time_t *tv)
4392{
4393 switch_time_t now;
4394
4395 if (tv) {
4396 now = switch_micro_time_now();
4397 tv->tv_sec = ((uint32_t) (now / 1000000)) + 2208988800UL;
4398 tv->tv_usec = (uint32_t) (now % 1000000);
4399 }
4400
4401}
4402#endif
4403
4404switch_status_t sofia_init(void)
4405{
4406 su_init();
4407 if (sip_update_default_mclass(sip_extend_mclass(NULL((void*)0))) < 0) {
4408 su_deinit();
4409 sip_cloned_parser_destroy();
4410 return SWITCH_STATUS_GENERR;
4411 }
4412
4413#ifdef SOFIA_TIME
4414 su_set_time_func(sofia_time);
4415#endif
4416
4417 /* Redirect loggers in sofia */
4418 su_log_redirect(su_log_default, logger, NULL((void*)0));
4419 su_log_redirect(tport_log, logger, NULL((void*)0));
4420 su_log_redirect(iptsec_log, logger, NULL((void*)0));
4421 su_log_redirect(nea_log, logger, NULL((void*)0));
4422 su_log_redirect(nta_log, logger, NULL((void*)0));
4423 su_log_redirect(nth_client_log, logger, NULL((void*)0));
4424 su_log_redirect(nth_server_log, logger, NULL((void*)0));
4425 su_log_redirect(nua_log, logger, NULL((void*)0));
4426 su_log_redirect(soa_log, logger, NULL((void*)0));
4427 su_log_redirect(sresolv_log, logger, NULL((void*)0));
4428#ifdef HAVE_SOFIA_STUN
4429 su_log_redirect(stun_log, logger, NULL((void*)0));
4430#endif
4431
4432 return SWITCH_STATUS_SUCCESS;
4433}
4434
4435switch_status_t config_gateway(const char *profile_name, const char *gateway_name)
4436{
4437 switch_xml_t cfg, xml = NULL((void*)0), xprofiles, xprofile, gateways_tag;
4438 switch_status_t status = SWITCH_STATUS_SUCCESS;
4439 sofia_profile_t *profile = NULL((void*)0);
4440 switch_event_t *params = NULL((void*)0);
4441 const char *cf = "sofia.conf";
4442
4443 if (zstr(profile_name)_zstr(profile_name) || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 4443
, profile_name)
)) {
4444 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4444
, ((void*)0)
, SWITCH_LOG_WARNING, "Profile [%s] does not exist.\n", profile_name);
4445 status = SWITCH_STATUS_FALSE;
4446 return status;
4447 }
4448
4449 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 4449, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
4450 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "sofia.c", 4450
, __extension__ __PRETTY_FUNCTION__))
;
4451 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile_name);
4452 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true");
4453 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "gateway", gateway_name);
4454
4455 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4456 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4456
, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", gateway_name);
4457 status = SWITCH_STATUS_FALSE;
4458 goto done;
4459 }
4460
4461 if ((xprofiles = switch_xml_child(cfg, "profiles"))) {
4462 if ((xprofile = switch_xml_find_child(xprofiles, "profile", "name", profile->name))) {
4463 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
4464 parse_gateways(profile, gateways_tag, strcmp(gateway_name, "_all_") ? gateway_name : NULL((void*)0));
4465 }
4466 }
4467 }
4468
4469 status = SWITCH_STATUS_SUCCESS;
4470
4471done:
4472
4473 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 4473, profile)
;
4474 if (xml) switch_xml_free(xml);
4475
4476 switch_event_destroy(&params);
4477
4478 return status;
4479}
4480
4481switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
4482{
4483 char *cf = "sofia.conf";
4484 switch_xml_t cfg, xml = NULL((void*)0), xprofile, param, settings, profiles;
4485 switch_status_t status = SWITCH_STATUS_SUCCESS;
4486 sofia_profile_t *profile = NULL((void*)0);
4487 char url[512] = "";
4488 int profile_found = 0;
4489 switch_event_t *params = NULL((void*)0);
4490 sofia_profile_t *profile_already_started = NULL((void*)0);
4491
4492 if (!zstr(profile_name)_zstr(profile_name) && (profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 4492
, profile_name)
)) {
4493 if (reload == SOFIA_CONFIG_RESCAN) {
4494 profile_already_started = profile;
4495 } else {
4496 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4496
, ((void*)0)
, SWITCH_LOG_WARNING, "Profile [%s] Already exists.\n", switch_str_nil(profile_name)(profile_name ? profile_name : ""));
4497 status = SWITCH_STATUS_FALSE;
4498 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 4498, profile)
;
4499 return status;
4500 }
4501 }
4502
4503 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 4503, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
4504 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "sofia.c", 4504
, __extension__ __PRETTY_FUNCTION__))
;
4505 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile_name);
4506 if (reload == SOFIA_CONFIG_RESCAN) {
4507 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true");
4508 }
4509
4510 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4511 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4511
, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
4512 status = SWITCH_STATUS_FALSE;
4513 goto done;
4514 }
4515
4516 mod_sofia_globals.auto_restart = SWITCH_TRUE;
4517 mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = SWITCH_FALSE; /* handle backwards compatilibity - by default use new behavior */
4518 mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
4519
4520 if ((settings = switch_xml_child(cfg, "global_settings"))) {
4521 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
4522 char *var = (char *) switch_xml_attr_soft(param, "name");
4523 char *val = (char *) switch_xml_attr_soft(param, "value");
4524 if (!strcasecmp(var, "log-level")) {
4525 su_log_set_level(NULL((void*)0), atoi(val));
4526 } else if (!strcasecmp(var, "abort-on-empty-external-ip")) {
4527 mod_sofia_globals.abort_on_empty_external_ip = switch_true(val);
4528 } else if (!strcasecmp(var, "tracelevel")) {
4529 mod_sofia_globals.tracelevel = switch_log_str2level(val);
4530 } else if (!strcasecmp(var, "debug-presence")) {
4531 mod_sofia_globals.debug_presence = atoi(val);
4532 } else if (!strcasecmp(var, "debug-sla")) {
4533 mod_sofia_globals.debug_sla = atoi(val);
4534 } else if (!strcasecmp(var, "max-reg-threads") && val) {
4535 int x = atoi(val);
4536
4537 if (x > 0) {
4538 mod_sofia_globals.max_reg_threads = x;
4539 }
4540
4541 } else if (!strcasecmp(var, "auto-restart")) {
4542 mod_sofia_globals.auto_restart = switch_true(val);
4543 } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
4544 mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
4545 if (switch_true(val)) {
4546 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4546
, ((void*)0)
, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
4547 "deprecated and will be removed - let FS devs know if you think it should stay\n");
4548 }
4549 } else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
4550 if(val && (!strcasecmp(val, "to_host") || !strcasecmp(val, "1")) ) {
4551 /* old behaviour */
4552 mod_sofia_globals.rewrite_multicasted_fs_path = 1;
4553 } else if (val && !strcasecmp(val, "original_server_host")) {
4554 mod_sofia_globals.rewrite_multicasted_fs_path = 2;
4555 } else if (val && !strcasecmp(val, "original_hostname")) {
4556 mod_sofia_globals.rewrite_multicasted_fs_path = 3;
4557 } else {
4558 mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
4559 }
4560 } else if (!strcasecmp(var, "capture-server")) {
4561 mod_sofia_globals.capture_server = switch_core_strdup(mod_sofia_globals.pool, val)switch_core_perform_strdup(mod_sofia_globals.pool, val, "sofia.c"
, (const char *)__func__, 4561)
;
4562 } else if (!strcasecmp(var, "stir-shaken-as-key")) {
4563 /* The private key to authenticate SIP Identity when sip_identity_attest is set */
4564 mod_sofia_globals.stir_shaken_as_key = switch_core_strdup(mod_sofia_globals.pool, val)switch_core_perform_strdup(mod_sofia_globals.pool, val, "sofia.c"
, (const char *)__func__, 4564)
;
4565 } else if (!strcasecmp(var, "stir-shaken-as-url")) {
4566 /* The x5u URL to advertise when sip_identity_attest is set */
4567 mod_sofia_globals.stir_shaken_as_url = switch_core_strdup(mod_sofia_globals.pool, val)switch_core_perform_strdup(mod_sofia_globals.pool, val, "sofia.c"
, (const char *)__func__, 4567)
;
4568 } else if (!strcasecmp(var, "stir-shaken-vs-ca-dir")) {
4569 /* The dir that contains the trusted CA root certs. */
4570 mod_sofia_globals.stir_shaken_vs_ca_dir = switch_core_strdup(mod_sofia_globals.pool, val)switch_core_perform_strdup(mod_sofia_globals.pool, val, "sofia.c"
, (const char *)__func__, 4570)
;
4571 } else if (!strcasecmp(var, "stir-shaken-vs-cert-path-check")) {
4572 mod_sofia_globals.stir_shaken_vs_cert_path_check = switch_true(val);
4573 } else if (!strcasecmp(var, "stir-shaken-vs-require-date")) {
4574 mod_sofia_globals.stir_shaken_vs_require_date = switch_true(val);
4575 }
4576 }
4577 }
4578
4579 if ((profiles = switch_xml_child(cfg, "profiles"))) {
4580 for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
4581 char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name");
4582 char *xprofiledomain = (char *) switch_xml_attr(xprofile, "domain");
4583 if (!(settings = switch_xml_child(xprofile, "settings"))) {
4584 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4584
, ((void*)0)
, SWITCH_LOG_ERROR, "No Settings, check the new config!\n");
4585 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4585)
;
4586 } else {
4587 switch_memory_pool_t *pool = NULL((void*)0);
4588 char *auth_messages_value = NULL((void*)0);
4589 char *auth_subscriptions_value = NULL((void*)0);
4590 uint8_t disable_message_auth_flag = 0;
4591 uint8_t disable_subscription_auth_flag = 0;
4592
4593 if (!xprofilename) {
4594 xprofilename = "unnamed";
4595 }
4596
4597 if (profile_name) {
4598 if (strcasecmp(profile_name, xprofilename)) {
4599 continue;
4600 } else {
4601 profile_found = 1;
4602 }
4603 }
4604
4605 if (!profile_already_started) {
4606
4607 /* Setup the pool */
4608 if ((status = switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "sofia.c", (const
char *)__func__, 4608)
) != SWITCH_STATUS_SUCCESS) {
4609 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4609
, ((void*)0)
, SWITCH_LOG_CRIT, "Memory Error!\n");
4610 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4610)
;
4611 goto done;
4612 }
4613
4614 if (!(profile = (sofia_profile_t *) switch_core_alloc(pool, sizeof(*profile))switch_core_perform_alloc(pool, sizeof(*profile), "sofia.c", (
const char *)__func__, 4614)
)) {
4615 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4615
, ((void*)0)
, SWITCH_LOG_ERROR, "Memory Error!\n");
4616 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4616)
;
4617 goto done;
4618 }
4619
4620 profile->tls_verify_policy = TPTLS_VERIFY_NONE;
4621 sofia_set_pflag(profile, PFLAG_AUTO_INVITE_100)(profile)->pflags[PFLAG_AUTO_INVITE_100] = 1;
4622 /* lib default */
4623 profile->tls_verify_depth = 2;
4624
4625
4626 switch_mutex_init(&profile->gw_mutex, SWITCH_MUTEX_NESTED0x1, pool);
4627
4628 profile->trans_timeout = 100;
4629
4630 profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
4631
4632 profile->pool = pool;
4633
4634 profile->user_agent = switch_core_sprintf(profile->pool, "FreeSWITCH-mod_sofia/%s", switch_version_full());
4635
4636 profile->sip_user_ping_max = 3;
4637 profile->sip_user_ping_min = 1;
4638
4639 profile->name = switch_core_strdup(profile->pool, xprofilename)switch_core_perform_strdup(profile->pool, xprofilename, "sofia.c"
, (const char *)__func__, 4639)
;
4640 switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
4641
4642 if (xprofiledomain) {
4643 profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain)switch_core_perform_strdup(profile->pool, xprofiledomain, "sofia.c"
, (const char *)__func__, 4643)
;
4644 }
4645
4646 profile->dbname = switch_core_strdup(profile->pool, url)switch_core_perform_strdup(profile->pool, url, "sofia.c", (
const char *)__func__, 4646)
;
4647 switch_core_hash_init(&profile->chat_hash)switch_core_hash_init_case(&profile->chat_hash, SWITCH_TRUE
)
;
4648 switch_core_hash_init(&profile->reg_nh_hash)switch_core_hash_init_case(&profile->reg_nh_hash, SWITCH_TRUE
)
;
4649 switch_core_hash_init(&profile->mwi_debounce_hash)switch_core_hash_init_case(&profile->mwi_debounce_hash
, SWITCH_TRUE)
;
4650 switch_thread_rwlock_create(&profile->rwlock, profile->pool);
4651 switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
4652 profile->dtmf_duration = 100;
4653 profile->rtp_digit_delay = 40;
4654 profile->sip_force_expires = 0;
4655 profile->sip_force_expires_min = 0;
4656 profile->sip_force_expires_max = 0;
4657 profile->sip_expires_max_deviation = 0;
4658 profile->sip_expires_late_margin = 60;
4659 profile->sip_subscription_max_deviation = 0;
4660 profile->tls_ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
4661 profile->tls_version = SOFIA_TLS_VERSION_TLSv1;
4662 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_1;
4663 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
4664 profile->tls_timeout = 300;
4665 profile->mflags = MFLAG_REFER | MFLAG_REGISTER;
4666 profile->server_rport_level = 1;
4667 profile->client_rport_level = 1;
4668 profile->tls_cert_dir = SWITCH_GLOBAL_dirs.certs_dir;
4669 sofia_set_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 1;
4670 sofia_set_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 1;
4671 profile->auto_restart = 1;
4672 sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 1;
4673 sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE)(profile)->media_flags[SCMF_RTP_AUTOFLUSH_DURING_BRIDGE] =
1
;
4674 profile->contact_user = SOFIA_DEFAULT_CONTACT_USER"mod_sofia";
4675 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
4676 sofia_set_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 1;
4677 sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 1;
4678 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
1
;
4679 //sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
4680
4681 sofia_clear_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)(profile)->pflags[PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER
] = 0
;
4682 sofia_clear_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)(profile)->pflags[PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE] =
0
;
4683 sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)(profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] = 0;
4684 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)(profile)->pflags[PFLAG_BLIND_AUTH_ENFORCE_RESULT] = 0;
4685 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)(profile)->pflags[PFLAG_BLIND_AUTH_REPLY_403] = 0;
4686 sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER)(profile)->pflags[PFLAG_AUTH_REQUIRE_USER] = 0;
4687 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)(profile)->pflags[PFLAG_AUTH_CALLS_ACL_ONLY] = 0;
4688 sofia_clear_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK)(profile)->pflags[PFLAG_USE_PORT_FOR_ACL_CHECK] = 0;
4689 profile->shutdown_type = "false";
4690 profile->local_network = "localnet.auto";
4691 sofia_set_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 1;
4692 sofia_set_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 1;
4693 profile->mndlb |= SM_NDLB_ALLOW_NONDUP_SDP;
4694 profile->te = 101;
4695 profile->ireg_seconds = IREG_SECONDS30;
4696 profile->iping_seconds = IPING_SECONDS30;
4697 profile->iping_freq = IPING_FREQUENCY1;
4698 profile->paid_type = PAID_DEFAULT;
4699 profile->bind_attempts = 2;
4700 profile->bind_attempt_interval = 5;
4701 profile->dtmf_type = DTMF_2833;
4702 profile->tls_verify_policy = TPTLS_VERIFY_NONE;
4703 /* lib default */
4704 profile->tls_verify_depth = 2;
4705 profile->tls_verify_date = SWITCH_TRUE;
4706 } else {
4707
4708 /* you could change profile->foo here if it was a minor change like context or dialplan ... */
4709 profile->acl_count = 0;
4710 profile->nat_acl_count = 0;
4711 profile->reg_acl_count = 0;
4712 profile->proxy_acl_count = 0;
4713 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
4714 profile->ib_calls = 0;
4715 profile->ob_calls = 0;
4716 profile->ib_failed_calls = 0;
4717 profile->ob_failed_calls = 0;
4718 profile->shutdown_type = "false";
4719 profile->rtpip_index = 0;
4720 profile->rtpip_index6 = 0;
4721
4722 if (xprofiledomain) {
4723 profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain)switch_core_perform_strdup(profile->pool, xprofiledomain, "sofia.c"
, (const char *)__func__, 4723)
;
4724 }
4725 }
4726
4727 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
4728 char *var = (char *) switch_xml_attr_soft(param, "name");
4729 char *val = (char *) switch_xml_attr_soft(param, "value");
4730 int found = 1; // Used to break up long if/elseif chain (MSVC2015 fails (parser stack overflow) otherwise)
4731
4732 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4732
, ((void*)0)
, SWITCH_LOG_DEBUG, "%s [%s]\n", var, val);
4733
4734 if (!strcasecmp(var, "debug") && val) {
4735 profile->debug = atoi(val);
4736 } else if (!strcasecmp(var, "parse-invite-tel-params")) {
4737 profile->parse_invite_tel_params = switch_true(val);
4738 } else if (!strcasecmp(var, "keepalive-method") && !zstr(val)_zstr(val)) {
4739 if (!strcasecmp(val, "info")) {
4740 profile->keepalive = KA_INFO;
4741 } else {
4742 profile->keepalive = KA_MESSAGE;
4743 }
4744 } else if (!strcasecmp(var, "bind-attempts") && val) {
4745 int ba = atoi(val) - 1;
4746
4747 if (ba >= 0) {
4748 profile->bind_attempts = ba;
4749 }
4750 } else if (!strcasecmp(var, "bind-attempt-interval") && val) {
4751 int bai = atoi(val);
4752
4753 if (bai >= 0) {
4754 profile->bind_attempt_interval = bai;
4755 }
4756 } else if (!strcasecmp(var, "shutdown-on-fail")) {
4757 profile->shutdown_type = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4757)
;
4758 } else if (!strcasecmp(var, "sip-trace")) {
4759 if (switch_true(val)) {
4760 sofia_set_flag(profile, TFLAG_TPORT_LOG)(profile)->flags[TFLAG_TPORT_LOG] = 1;
4761 } else {
4762 sofia_clear_flag(profile, TFLAG_TPORT_LOG)(profile)->flags[TFLAG_TPORT_LOG] = 0;
4763 }
4764 } else if (!strcasecmp(var, "sip-capture")) {
4765 if (switch_true(val)) {
4766 sofia_set_flag(profile, TFLAG_CAPTURE)(profile)->flags[TFLAG_CAPTURE] = 1;
4767 nua_set_params(profile->nua, TPTAG_CAPT(mod_sofia_globals.capture_server)tptag_capt, tag_str_v((mod_sofia_globals.capture_server)), TAG_END()(tag_type_t)0, (tag_value_t)0);
4768 } else {
4769 sofia_clear_flag(profile, TFLAG_CAPTURE)(profile)->flags[TFLAG_CAPTURE] = 0;
4770 }
4771 } else if (!strcasecmp(var, "socket-tcp-keepalive") && !zstr(val)_zstr(val)) {
4772 profile->socket_tcp_keepalive = atoi(val);
4773 sofia_set_pflag(profile, PFLAG_SOCKET_TCP_KEEPALIVE)(profile)->pflags[PFLAG_SOCKET_TCP_KEEPALIVE] = 1;
4774 } else if (!strcasecmp(var, "tcp-keepalive") && !zstr(val)_zstr(val)) {
4775 profile->tcp_keepalive = atoi(val);
4776 sofia_set_pflag(profile, PFLAG_TCP_KEEPALIVE)(profile)->pflags[PFLAG_TCP_KEEPALIVE] = 1;
4777 } else if (!strcasecmp(var, "tcp-pingpong") && !zstr(val)_zstr(val)) {
4778 profile->tcp_pingpong = atoi(val);
4779 sofia_set_pflag(profile, PFLAG_TCP_PINGPONG)(profile)->pflags[PFLAG_TCP_PINGPONG] = 1;
4780 } else if (!strcasecmp(var, "tcp-ping2pong") && !zstr(val)_zstr(val)) {
4781 profile->tcp_ping2pong = atoi(val);
4782 sofia_set_pflag(profile, PFLAG_TCP_PING2PONG)(profile)->pflags[PFLAG_TCP_PING2PONG] = 1;
4783 } else if ((!strcasecmp(var, "proxy-refer-replaces") || !strcasecmp(var, "proxy-refer")) && !zstr(val)_zstr(val)) {
4784 if (switch_true(val)) {
4785 sofia_set_pflag(profile, PFLAG_PROXY_REFER)(profile)->pflags[PFLAG_PROXY_REFER] = 1;
4786 } else {
4787 sofia_clear_pflag(profile, PFLAG_PROXY_REFER)(profile)->pflags[PFLAG_PROXY_REFER] = 0;
4788 }
4789 } else if (!strcasecmp(var, "sip-messages-respond-200-ok") && !zstr(val)_zstr(val)) {
4790 if (switch_true(val)) {
4791 sofia_set_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK)(profile)->pflags[PFLAG_MESSAGES_RESPOND_200_OK] = 1;
4792 } else {
4793 sofia_clear_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK)(profile)->pflags[PFLAG_MESSAGES_RESPOND_200_OK] = 0;
4794 }
4795 } else if (!strcasecmp(var, "sip-subscribe-respond-200-ok") && !zstr(val)_zstr(val)) {
4796 if (switch_true(val)) {
4797 sofia_set_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK)(profile)->pflags[PFLAG_SUBSCRIBE_RESPOND_200_OK] = 1;
4798 } else {
4799 sofia_clear_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK)(profile)->pflags[PFLAG_SUBSCRIBE_RESPOND_200_OK] = 0;
4800 }
4801 } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)_zstr(val)) {
4802 profile->odbc_dsn = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4802)
;
4803 } else if (!strcasecmp(var, "db-pre-trans-execute") && !zstr(val)_zstr(val)) {
4804 profile->pre_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4804)
;
4805 } else if (!strcasecmp(var, "db-post-trans-execute") && !zstr(val)_zstr(val)) {
4806 profile->post_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4806)
;
4807 } else if (!strcasecmp(var, "db-inner-pre-trans-execute") && !zstr(val)_zstr(val)) {
4808 profile->inner_pre_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4808)
;
4809 } else if (!strcasecmp(var, "db-inner-post-trans-execute") && !zstr(val)_zstr(val)) {
4810 profile->inner_post_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4810)
;
4811 } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) {
4812 if (switch_true(val)) {
4813 sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)(profile)->pflags[PFLAG_FORWARD_MWI_NOTIFY] = 1;
4814 } else {
4815 sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)(profile)->pflags[PFLAG_FORWARD_MWI_NOTIFY] = 0;
4816 }
4817 } else if (!strcasecmp(var, "NDLB-proxy-never-patch-reinvites")) {
4818 if (switch_true(val)) {
4819 profile->mndlb |= SM_NDLB_NEVER_PATCH_REINVITE;
4820 } else {
4821 profile->mndlb &= ~SM_NDLB_NEVER_PATCH_REINVITE;
4822 }
4823 } else if (!strcasecmp(var, "registration-thread-frequency") && !zstr(val)_zstr(val)) {
4824 profile->ireg_seconds = atoi(val);
4825 if (profile->ireg_seconds < 0) {
4826 profile->ireg_seconds = IREG_SECONDS30;
4827 }
4828 } else if (!strcasecmp(var, "ping-mean-interval") && !zstr(val)_zstr(val)) {
4829 profile->iping_seconds = atoi(val);
4830 if (profile->iping_seconds < 0) {
4831 profile->iping_seconds = IPING_SECONDS30;
4832 }
4833 } else if (!strcasecmp(var, "ping-thread-frequency") && !zstr(val)_zstr(val)) {
4834 profile->iping_freq = atoi(val);
4835 if (profile->iping_freq < 0) {
4836 profile->iping_freq = IPING_FREQUENCY1;
4837 }
4838 } else if (!strcasecmp(var, "user-agent-string")) {
4839 profile->user_agent = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4839)
;
4840 } else if (!strcasecmp(var, "auto-restart")) {
4841 profile->auto_restart = switch_true(val);
4842 } else if (!strcasecmp(var, "log-auth-failures")) {
4843 if (switch_true(val)) {
4844 sofia_set_pflag(profile, PFLAG_LOG_AUTH_FAIL)(profile)->pflags[PFLAG_LOG_AUTH_FAIL] = 1;
4845 } else {
4846 sofia_clear_pflag(profile, PFLAG_LOG_AUTH_FAIL)(profile)->pflags[PFLAG_LOG_AUTH_FAIL] = 0;
4847 }
4848 } else if (!strcasecmp(var, "confirm-blind-transfer")) {
4849 if (switch_true(val)) {
4850 sofia_set_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)(profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] = 1;
4851 } else {
4852 sofia_clear_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)(profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] = 0;
4853 }
4854 } else if (!strcasecmp(var, "allow-update")) {
4855 if (switch_true(val)) {
4856 sofia_set_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 1;
4857 } else {
4858 sofia_clear_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 0;
4859 }
4860 } else if (!strcasecmp(var, "send-display-update")) {
4861 if (switch_true(val)) {
4862 sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 1;
4863 } else {
4864 sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 0;
4865 }
4866 } else if (!strcasecmp(var, "mwi-use-reg-callid")) {
4867 if (switch_true(val)) {
4868 sofia_set_pflag(profile, PFLAG_MWI_USE_REG_CALLID)(profile)->pflags[PFLAG_MWI_USE_REG_CALLID] = 1;
4869 } else {
4870 sofia_clear_pflag(profile, PFLAG_MWI_USE_REG_CALLID)(profile)->pflags[PFLAG_MWI_USE_REG_CALLID] = 0;
4871 }
4872 } else if (!strcasecmp(var, "tcp-unreg-on-socket-close")) {
4873 if (switch_true(val)) {
4874 sofia_set_pflag(profile, PFLAG_TCP_UNREG_ON_SOCKET_CLOSE)(profile)->pflags[PFLAG_TCP_UNREG_ON_SOCKET_CLOSE] = 1;
4875 } else {
4876 sofia_clear_pflag(profile, PFLAG_TCP_UNREG_ON_SOCKET_CLOSE)(profile)->pflags[PFLAG_TCP_UNREG_ON_SOCKET_CLOSE] = 0;
4877 }
4878 } else if (!strcasecmp(var, "tcp-always-nat")) {
4879 if (switch_true(val)) {
4880 sofia_set_pflag(profile, PFLAG_TCP_ALWAYS_NAT)(profile)->pflags[PFLAG_TCP_ALWAYS_NAT] = 1;
4881 } else {
4882 sofia_clear_pflag(profile, PFLAG_TCP_ALWAYS_NAT)(profile)->pflags[PFLAG_TCP_ALWAYS_NAT] = 0;
4883 }
4884 } else if (!strcasecmp(var, "tls-always-nat")) {
4885 if (switch_true(val)) {
4886 sofia_set_pflag(profile, PFLAG_TLS_ALWAYS_NAT)(profile)->pflags[PFLAG_TLS_ALWAYS_NAT] = 1;
4887 } else {
4888 sofia_clear_pflag(profile, PFLAG_TLS_ALWAYS_NAT)(profile)->pflags[PFLAG_TLS_ALWAYS_NAT] = 0;
4889 }
4890 } else if (!strcasecmp(var, "presence-proto-lookup")) {
4891 if (switch_true(val)) {
4892 sofia_set_pflag(profile, PFLAG_PRESENCE_MAP)(profile)->pflags[PFLAG_PRESENCE_MAP] = 1;
4893 } else {
4894 sofia_clear_pflag(profile, PFLAG_PRESENCE_MAP)(profile)->pflags[PFLAG_PRESENCE_MAP] = 0;
4895 }
4896 } else if (!strcasecmp(var, "profile-standby")) {
4897 if (switch_true(val)) {
4898 sofia_set_pflag(profile, PFLAG_STANDBY)(profile)->pflags[PFLAG_STANDBY] = 1;
4899 } else {
4900 sofia_clear_pflag(profile, PFLAG_STANDBY)(profile)->pflags[PFLAG_STANDBY] = 0;
4901 }
4902 } else if (!strcasecmp(var, "liberal-dtmf")) {
4903 if (switch_true(val)) {
4904 sofia_set_pflag(profile, PFLAG_LIBERAL_DTMF)(profile)->pflags[PFLAG_LIBERAL_DTMF] = 1;
4905 } else {
4906 sofia_clear_pflag(profile, PFLAG_LIBERAL_DTMF)(profile)->pflags[PFLAG_LIBERAL_DTMF] = 0;
4907 }
4908 } else if (!strcasecmp(var, "rtp-digit-delay") && !zstr(val)_zstr(val)) {
4909 int delay = atoi(val);
4910 if (delay < 0) {
4911 delay = 0;
4912 }
4913 profile->rtp_digit_delay = (uint32_t) delay;
4914 } else if (!strcasecmp(var, "watchdog-enabled")) {
4915 profile->watchdog_enabled = switch_true(val);
4916 } else if (!strcasecmp(var, "watchdog-step-timeout") && !zstr(val)_zstr(val)) {
4917 profile->step_timeout = atoi(val);
4918 } else if (!strcasecmp(var, "watchdog-event-timeout") && !zstr(val)_zstr(val)) {
4919 profile->event_timeout = atoi(val);
4920 } else if (!strcasecmp(var, "in-dialog-chat")) {
4921 if (switch_true(val)) {
4922 sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT)(profile)->pflags[PFLAG_IN_DIALOG_CHAT] = 1;
4923 } else {
4924 sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT)(profile)->pflags[PFLAG_IN_DIALOG_CHAT] = 0;
4925 }
4926 } else if (!strcasecmp(var, "enable-chat")) {
4927 if (switch_true(val)) {
4928 sofia_set_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 1;
4929 } else {
4930 sofia_clear_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 0;
4931 }
4932 } else if (!strcasecmp(var, "fire-bye-response-events")) {
4933 if (switch_true(val)) {
4934 sofia_set_pflag(profile, PFLAG_FIRE_BYE_RESPONSE_EVENTS)(profile)->pflags[PFLAG_FIRE_BYE_RESPONSE_EVENTS] = 1;
4935 } else {
4936 sofia_clear_pflag(profile, PFLAG_FIRE_BYE_RESPONSE_EVENTS)(profile)->pflags[PFLAG_FIRE_BYE_RESPONSE_EVENTS] = 0;
4937 }
4938 } else if (!strcasecmp(var, "fire-message-events")) {
4939 if (switch_true(val)) {
4940 sofia_set_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)(profile)->pflags[PFLAG_FIRE_MESSAGE_EVENTS] = 1;
4941 } else {
4942 sofia_clear_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)(profile)->pflags[PFLAG_FIRE_MESSAGE_EVENTS] = 0;
4943 }
4944 } else if (!strcasecmp(var, "t38-passthru")) {
4945 if (switch_true(val)) {
4946 sofia_set_pflag(profile, PFLAG_T38_PASSTHRU)(profile)->pflags[PFLAG_T38_PASSTHRU] = 1;
4947 } else {
4948 sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU)(profile)->pflags[PFLAG_T38_PASSTHRU] = 0;
4949 }
4950 } else if (!strcasecmp(var, "presence-disable-early")) {
4951 if (switch_true(val)) {
4952 sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY)(profile)->pflags[PFLAG_PRESENCE_DISABLE_EARLY] = 1;
4953 } else {
4954 sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY)(profile)->pflags[PFLAG_PRESENCE_DISABLE_EARLY] = 0;
4955 }
4956 } else if (!strcasecmp(var, "ignore-183nosdp")) {
4957 if (switch_true(val)) {
4958 sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP)(profile)->pflags[PFLAG_IGNORE_183NOSDP] = 1;
4959 } else {
4960 sofia_clear_pflag(profile, PFLAG_IGNORE_183NOSDP)(profile)->pflags[PFLAG_IGNORE_183NOSDP] = 0;
4961 }
4962 } else if (!strcasecmp(var, "presence-probe-on-register")) {
4963 if (switch_true(val)) {
4964 sofia_set_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_PROBE_ON_REGISTER] = 1;
4965 } else {
4966 sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_PROBE_ON_REGISTER] = 0;
4967 }
4968 } else if (!strcasecmp(var, "send-presence-on-register")) {
4969 if (val && (switch_true(val) || !strcasecmp(val, "all"))) {
4970 sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 1;
4971 } else if (val && !strcasecmp(val, "first-only")) {
4972 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 0;
4973 sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_FIRST_REGISTER] = 1;
4974 } else {
4975 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 0;
4976 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_FIRST_REGISTER] = 0;
4977 }
4978 } else if (!strcasecmp(var, "cid-in-1xx")) {
4979 if (switch_true(val)) {
4980 sofia_set_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 1;
4981 } else {
4982 sofia_clear_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 0;
4983 }
4984 } else if (!strcasecmp(var, "disable-hold")) {
4985 if (switch_true(val)) {
4986 sofia_set_media_flag(profile, SCMF_DISABLE_HOLD)(profile)->media_flags[SCMF_DISABLE_HOLD] = 1;
4987 } else {
4988 sofia_clear_media_flag(profile, SCMF_DISABLE_HOLD)(profile)->media_flags[SCMF_DISABLE_HOLD] = 0;
4989 }
4990 } else if (!strcasecmp(var, "auto-jitterbuffer-msec") && !zstr(val)_zstr(val)) {
4991 int msec = atoi(val);
4992 if (msec > 19) {
4993 profile->jb_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4993)
;
4994 }
4995 } else if (!strcasecmp(var, "dtmf-type")) {
4996 if (val && !strcasecmp(val, "rfc2833")) {
4997 profile->dtmf_type = DTMF_2833;
4998 } else if (val && !strcasecmp(val, "info")) {
4999 profile->dtmf_type = DTMF_INFO;
5000 } else {
5001 profile->dtmf_type = DTMF_NONE;
5002 }
5003 } else if (!strcasecmp(var, "NDLB-force-rport")) {
5004 if (val && !strcasecmp(val, "safe")) {
5005 profile->server_rport_level = 3;
5006 profile->client_rport_level = 1;
5007 } else if (val && !strcasecmp(val, "disabled")) {
5008 profile->server_rport_level = 0;
5009 profile->client_rport_level = 0;
5010 } else if (val && !strcasecmp(val, "client-only")) {
5011 profile->client_rport_level = 1;
5012 } else if (val && !strcasecmp(val, "server-only")) {
5013 profile->client_rport_level = 0;
5014 profile->server_rport_level = 1;
5015 } else if (switch_true(val)) {
5016 profile->server_rport_level = 2;
5017 profile->client_rport_level = 1;
5018 }
5019 } else if (!strcasecmp(var, "auto-rtp-bugs")) {
5020 switch_core_media_parse_rtp_bugs(&profile->auto_rtp_bugs, val);
5021 } else if (!strcasecmp(var, "manual-rtp-bugs")) {
5022 switch_core_media_parse_rtp_bugs(&profile->manual_rtp_bugs, val);
5023 } else if (!strcasecmp(var, "manual-video-rtp-bugs")) {
5024 switch_core_media_parse_rtp_bugs(&profile->manual_video_rtp_bugs, val);
5025 } else if (!strcasecmp(var, "dbname")) {
5026 profile->dbname = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5026)
;
5027 } else if (!strcasecmp(var, "presence-hosts")) {
5028 profile->presence_hosts = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5028)
;
5029 } else if (!strcasecmp(var, "caller-id-type")) {
5030 profile->cid_type = sofia_cid_name2type(val);
5031 } else if (!strcasecmp(var, "record-template")) {
5032 profile->record_template = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5032)
;
5033 } else if (!strcasecmp(var, "record-path")) {
5034 profile->record_path = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5034)
;
5035 } else if (!strcasecmp(var, "inbound-no-media") || !strcasecmp(var, "inbound-bypass-media")) {
5036 if (switch_true(val)) {
5037 sofia_set_flag(profile, TFLAG_INB_NOMEDIA)(profile)->flags[TFLAG_INB_NOMEDIA] = 1;
5038 } else {
5039 sofia_clear_flag(profile, TFLAG_INB_NOMEDIA)(profile)->flags[TFLAG_INB_NOMEDIA] = 0;
5040 }
5041 } else if (!strcasecmp(var, "inbound-late-negotiation")) {
5042 if (switch_true(val)) {
5043 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
5044 } else {
5045 sofia_clear_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 0;
5046 }
5047 } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) {
5048 if (switch_true(val)) {
5049 sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)(profile)->pflags[PFLAG_RTP_NOTIMER_DURING_BRIDGE] = 1;
5050 } else {
5051 sofia_clear_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)(profile)->pflags[PFLAG_RTP_NOTIMER_DURING_BRIDGE] = 0;
5052 }
5053 } else if (!strcasecmp(var, "manual-redirect")) {
5054 if (switch_true(val)) {
5055 sofia_set_pflag(profile, PFLAG_MANUAL_REDIRECT)(profile)->pflags[PFLAG_MANUAL_REDIRECT] = 1;
5056 } else {
5057 sofia_clear_pflag(profile, PFLAG_MANUAL_REDIRECT)(profile)->pflags[PFLAG_MANUAL_REDIRECT] = 0;
5058 }
5059 } else if (!strcasecmp(var, "inbound-proxy-media")) {
5060 if (switch_true(val)) {
5061 sofia_set_flag(profile, TFLAG_PROXY_MEDIA)(profile)->flags[TFLAG_PROXY_MEDIA] = 1;
5062 } else {
5063 sofia_clear_flag(profile, TFLAG_PROXY_MEDIA)(profile)->flags[TFLAG_PROXY_MEDIA] = 0;
5064 }
5065 } else if (!strcasecmp(var, "inbound-zrtp-passthru")) {
5066 if (switch_true(val)) {
5067 sofia_set_flag(profile, TFLAG_ZRTP_PASSTHRU)(profile)->flags[TFLAG_ZRTP_PASSTHRU] = 1;
5068 } else {
5069 sofia_clear_flag(profile, TFLAG_ZRTP_PASSTHRU)(profile)->flags[TFLAG_ZRTP_PASSTHRU] = 0;
5070 }
5071 } else if (!strcasecmp(var, "force-subscription-expires") && !zstr(val)_zstr(val)) {
5072 int tmp = atoi(val);
5073 if (tmp > 0) {
5074 profile->force_subscription_expires = tmp;
5075 }
5076 } else if (!strcasecmp(var, "force-publish-expires") && !zstr(val)_zstr(val)) {
5077 int tmp = atoi(val);
5078 if (tmp > 0) {
5079 profile->force_publish_expires = tmp;
5080 }
5081 } else if (!strcasecmp(var, "send-message-query-on-register")) {
5082 if (switch_true(val)) {
5083 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 1;
5084 } else if (val && !strcasecmp(val, "first-only")) {
5085 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 0;
5086 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
1
;
5087 } else {
5088 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 0;
5089 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
0
;
5090 }
5091 } else if (!strcasecmp(var, "inbound-reg-in-new-thread") && val) {
5092 if (switch_true(val)) {
5093 sofia_set_pflag(profile, PFLAG_THREAD_PER_REG)(profile)->pflags[PFLAG_THREAD_PER_REG] = 1;
5094 } else {
5095 sofia_clear_pflag(profile, PFLAG_THREAD_PER_REG)(profile)->pflags[PFLAG_THREAD_PER_REG] = 0;
5096 }
5097 } else if (!strcasecmp(var, "inbound-use-callid-as-uuid")) {
5098 if (switch_true(val)) {
5099 sofia_set_pflag(profile, PFLAG_CALLID_AS_UUID)(profile)->pflags[PFLAG_CALLID_AS_UUID] = 1;
5100 } else {
5101 sofia_clear_pflag(profile, PFLAG_CALLID_AS_UUID)(profile)->pflags[PFLAG_CALLID_AS_UUID] = 0;
5102 }
5103 } else if (!strcasecmp(var, "outbound-use-uuid-as-callid")) {
5104 if (switch_true(val)) {
5105 sofia_set_pflag(profile, PFLAG_UUID_AS_CALLID)(profile)->pflags[PFLAG_UUID_AS_CALLID] = 1;
5106 } else {
5107 sofia_clear_pflag(profile, PFLAG_UUID_AS_CALLID)(profile)->pflags[PFLAG_UUID_AS_CALLID] = 0;
5108 }
5109 } else if (!strcasecmp(var, "track-calls")) {
5110 if (switch_true(val)) {
5111 sofia_set_pflag(profile, PFLAG_TRACK_CALLS)(profile)->pflags[PFLAG_TRACK_CALLS] = 1;
5112 }
5113 } else if (!strcasecmp(var, "NDLB-received-in-nat-reg-contact")) {
5114 if (switch_true(val)) {
5115 sofia_set_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)(profile)->pflags[PFLAG_RECIEVED_IN_NAT_REG_CONTACT] = 1;
5116 } else {
5117 sofia_clear_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)(profile)->pflags[PFLAG_RECIEVED_IN_NAT_REG_CONTACT] = 0;
5118 }
5119 } else if (!strcasecmp(var, "aggressive-nat-detection")) {
5120 if (switch_true(val)) {
5121 sofia_set_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)(profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] = 1;
5122 } else {
5123 sofia_clear_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)(profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] = 0;
5124 }
5125 } else if (!strcasecmp(var, "disable-rtp-auto-adjust")) {
5126 if (switch_true(val)) {
5127 sofia_set_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ)(profile)->media_flags[SCMF_DISABLE_RTP_AUTOADJ] = 1;
5128 } else {
5129 sofia_clear_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ)(profile)->media_flags[SCMF_DISABLE_RTP_AUTOADJ] = 0;
5130 }
5131 } else if (!strcasecmp(var, "NDLB-support-asterisk-missing-srtp-auth")) {
5132 if (switch_true(val)) {
5133 profile->mndlb |= SM_NDLB_DISABLE_SRTP_AUTH;
5134 } else {
5135 profile->mndlb &= ~SM_NDLB_DISABLE_SRTP_AUTH;
5136 }
5137 } else if (!strcasecmp(var, "user-agent-filter")) {
5138 profile->user_agent_filter = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5138)
;
5139 } else if (!strcasecmp(var, "max-registrations-per-extension") && !zstr(val)_zstr(val)) {
5140 profile->max_registrations_perext = atoi(val);
5141 } else if (!strcasecmp(var, "rfc2833-pt") && !zstr(val)_zstr(val)) {
5142 profile->te = (switch_payload_t) atoi(val);
5143 } else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)((profile)->media_flags[SCMF_SUPPRESS_CNG] ? 1 : 0) && !zstr(val)_zstr(val)) {
5144 profile->cng_pt = (switch_payload_t) atoi(val);
5145 } else if (!strcasecmp(var, "sip-port") && !zstr(val)_zstr(val)) {
5146 if (!strcasecmp(val, "auto")) {
5147 sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_PORT] = 1;
5148 } else {
5149 profile->sip_port = (switch_port_t) atoi(val);
5150 if (!profile->extsipport) profile->extsipport = profile->sip_port;
5151 }
5152 } else if (!strcasecmp(var, "vad") && !zstr(val)_zstr(val)) {
5153 if (!strcasecmp(val, "in")) {
5154 profile->vflags |= VAD_IN;
5155 } else if (!strcasecmp(val, "out")) {
5156 profile->vflags |= VAD_OUT;
5157 } else if (!strcasecmp(val, "both")) {
5158 profile->vflags |= VAD_OUT | VAD_IN;
5159 } else if (strcasecmp(val, "none")) {
5160 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5160
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid option %s for VAD\n", val);
5161 }
5162 } else if (!strcasecmp(var, "ext-rtp-ip")) {
5163 if (!zstr(val)_zstr(val)) {
5164 char *ip = mod_sofia_globals.guess_ip;
5165
5166 if (!strcmp(val, "0.0.0.0")) {
5167 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5167
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n",
5168 mod_sofia_globals.guess_ip);
5169 } else if (!strcasecmp(val, "auto-nat")) {
5170 ip = NULL((void*)0);
5171 } else {
5172 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5173 sofia_clear_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 0;
5174 }
5175 if (ip) {
5176 if (!strncasecmp(ip, "autonat:", 8)) {
5177 profile->extrtpip = switch_core_strdup(profile->pool, ip + 8)switch_core_perform_strdup(profile->pool, ip + 8, "sofia.c"
, (const char *)__func__, 5177)
;
5178 if (zstr(profile->extsipip)_zstr(profile->extsipip)) {
5179 profile->extsipip = switch_core_strdup(profile->pool, profile->extrtpip)switch_core_perform_strdup(profile->pool, profile->extrtpip
, "sofia.c", (const char *)__func__, 5179)
;
5180 }
5181 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
5182 } else {
5183 profile->extrtpip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5183)
;
5184 }
5185 }
5186 } else {
5187 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5187
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid ext-rtp-ip\n");
5188 if (mod_sofia_globals.abort_on_empty_external_ip) {
5189 switch_goto_status(SWITCH_STATUS_GENERR, done)status = SWITCH_STATUS_GENERR; goto done;
5190 }
5191 }
5192 } else if (!strcasecmp(var, "rtp-ip")) {
5193 char *ip = mod_sofia_globals.guess_ip;
5194 char buf[64];
5195
5196 if (zstr(val)_zstr(val)) {
5197 ip = mod_sofia_globals.guess_ip;
5198 } else if (!strcmp(val, "0.0.0.0")) {
5199 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5199
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
5200 } else if (!strncasecmp(val, "interface:", 10)) {
5201 char *ifname = val+10;
5202 int family = AF_UNSPEC0;
5203 if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC0; }
5204 if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET2; }
5205 if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET610; }
5206 if (switch_find_interface_ip(buf, sizeof(buf), NULL((void*)0), ifname, family) == SWITCH_STATUS_SUCCESS) {
5207 ip = buf;
5208 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5208
, ((void*)0)
, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for rtp-ip\n", ip, val+10);
5209 } else {
5210 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5210
, ((void*)0)
, SWITCH_LOG_ERROR, "Unknown IP for interface %s for rtp-ip\n", val+10);
5211 }
5212 } else {
5213 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5214 }
5215
5216 if (strchr(ip, ':')) {
5217 if (profile->rtpip_index6 < MAX_RTPIP50) {
5218 profile->rtpip6[profile->rtpip_index6++] = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5218)
;
5219 } else {
5220 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5220
, ((void*)0)
, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
5221 }
5222 } else {
5223 if (profile->rtpip_index < MAX_RTPIP50) {
5224 profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5224)
;
5225 } else {
5226 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5226
, ((void*)0)
, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
5227 }
5228 }
5229 } else if (!strcasecmp(var, "sip-ip") && val) {
5230 char *ip = mod_sofia_globals.guess_ip;
5231 char buf[64];
5232
5233 if (!strcmp(val, "0.0.0.0")) {
5234 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5234
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
5235 } else if (!strncasecmp(val, "interface:", 10)) {
5236 char *ifname = val+10;
5237 int family = AF_UNSPEC0;
5238 if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC0; }
5239 if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET2; }
5240 if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET610; }
5241 if (switch_find_interface_ip(buf, sizeof(buf), NULL((void*)0), ifname, family) == SWITCH_STATUS_SUCCESS) {
5242 ip = buf;
5243 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5243
, ((void*)0)
, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for sip-ip\n", ip, val+10);
5244 } else {
5245 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5245
, ((void*)0)
, SWITCH_LOG_ERROR, "Unknown IP for interface %s for sip-ip\n", val+10);
5246 }
5247 } else {
5248 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5249 }
5250 profile->sipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5250)
;
5251 } else if (!strcasecmp(var, "ext-sip-port") && val) {
5252 int tmp = atoi(val);
5253 if (tmp > 0) profile->extsipport = (switch_port_t)tmp;
5254 } else if (!strcasecmp(var, "ext-sip-ip")) {
5255 if (!zstr(val)_zstr(val)) {
5256 char *ip = mod_sofia_globals.guess_ip;
5257 char stun_ip[50] = "";
5258 char *myip = stun_ip;
5259
5260 switch_copy_string(stun_ip, ip, sizeof(stun_ip));
5261
5262 if (!strcasecmp(val, "0.0.0.0")) {
5263 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5263
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n",
5264 mod_sofia_globals.guess_ip);
5265 } else if (!strcasecmp(val, "auto-nat")) {
5266 ip = NULL((void*)0);
5267 } else if (strcasecmp(val, "auto")) {
5268 if (sofia_glue_ext_address_lookup(profile, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
5269 ip = myip;
5270 sofia_clear_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 0;
5271 } else {
5272 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5272
, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to get external ip.\n");
5273 }
5274 }
5275 if (ip) {
5276 if (!strncasecmp(ip, "autonat:", 8)) {
5277 profile->extsipip = switch_core_strdup(profile->pool, ip + 8)switch_core_perform_strdup(profile->pool, ip + 8, "sofia.c"
, (const char *)__func__, 5277)
;
5278 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
5279 } else {
5280 profile->extsipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5280)
;
5281 }
5282 }
5283 } else {
5284 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5284
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid ext-sip-ip\n");
5285 switch_goto_status(SWITCH_STATUS_GENERR, done)status = SWITCH_STATUS_GENERR; goto done;
5286 }
5287 } else if (!strcasecmp(var, "local-network-acl")) {
5288 if (val && !strcasecmp(val, "none")) {
5289 profile->local_network = NULL((void*)0);
5290 } else {
5291 profile->local_network = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5291)
;
5292 }
5293 } else if (!strcasecmp(var, "force-register-domain")) {
5294 profile->reg_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5294)
;
5295 } else if (!strcasecmp(var, "force-register-db-domain")) {
5296 profile->reg_db_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5296)
;
5297 } else if (!strcasecmp(var, "force-subscription-domain")) {
5298 profile->sub_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5298)
;
5299 } else if (!strcasecmp(var, "bind-params")) {
5300 profile->bind_params = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5300)
;
5301 } else if (!strcasecmp(var, "sip-domain")) {
5302 profile->sipdomain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5302)
;
5303 } else if (!strcasecmp(var, "rtp-timer-name")) {
5304 profile->timer_name = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5304)
;
5305 } else if (!strcasecmp(var, "hold-music")) {
5306 profile->hold_music = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5306)
;
5307 } else if (!strcasecmp(var, "outbound-proxy") && val) {
5308 if (strncasecmp(val, "sip:", 4) && strncasecmp(val, "sips:", 5)) {
5309 profile->outbound_proxy = switch_core_sprintf(profile->pool, "sip:%s", val);
5310 } else {
5311 profile->outbound_proxy = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5311)
;
5312 }
5313 } else if (!strcasecmp(var, "rtcp-audio-interval-msec")) {
5314 profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5314)
;
5315 } else if (!strcasecmp(var, "rtcp-video-interval-msec")) {
5316 profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5316)
;
5317 } else if (!strcasecmp(var, "session-timeout") && !zstr(val)_zstr(val)) {
5318 int v_session_timeout = atoi(val);
5319 if (v_session_timeout >= 0) {
5320 profile->session_timeout = v_session_timeout;
5321 }
5322 } else if (!strcasecmp(var, "max-proceeding") && !zstr(val)_zstr(val)) {
5323 int v_max_proceeding = atoi(val);
5324 if (v_max_proceeding >= 0) {
5325 profile->max_proceeding = v_max_proceeding;
5326 }
5327 } else if (!strcasecmp(var, "rtp-timeout-sec") && !zstr(val)_zstr(val)) {
5328 int v = atoi(val);
5329 if (v >= 0) {
5330 profile->rtp_timeout_sec = v;
5331 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5331
, ((void*)0)
, SWITCH_LOG_WARNING,
5332 "rtp-timeout-sec deprecated use media_timeout variable.\n");
5333 }
5334 } else if (!strcasecmp(var, "rtp-hold-timeout-sec") && !zstr(val)_zstr(val)) {
5335 int v = atoi(val);
5336 if (v >= 0) {
5337 profile->rtp_hold_timeout_sec = v;
5338 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5338
, ((void*)0)
, SWITCH_LOG_WARNING,
5339 "rtp-hold-timeout-sec deprecated use media_hold_timeout variable.\n");
5340 }
5341 } else if (!strcasecmp(var, "disable-transfer")) {
5342 if (switch_true(val)) {
5343 profile->mflags &= ~MFLAG_REFER;
5344 } else {
5345 profile->mflags |= MFLAG_REFER;
5346 }
5347 } else if (!strcasecmp(var, "disable-register")) {
5348 if (switch_true(val)) {
5349 profile->mflags &= ~MFLAG_REGISTER;
5350 } else {
5351 profile->mflags |= MFLAG_REGISTER;
5352 }
5353 } else if (!strcasecmp(var, "media-option") && !zstr(val)_zstr(val)) {
5354 if (!strcasecmp(val, "resume-media-on-hold")) {
5355 profile->media_options |= MEDIA_OPT_MEDIA_ON_HOLD;
5356 } else if (!strcasecmp(val, "bypass-media-after-att-xfer")) {
5357 profile->media_options |= MEDIA_OPT_BYPASS_AFTER_ATT_XFER;
5358 } else if (!strcasecmp(val, "bypass-media-after-hold")) {
5359 if (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
5360 profile->media_options |= MEDIA_OPT_BYPASS_AFTER_HOLD;
5361 } else {
5362 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5362
, ((void*)0)
, SWITCH_LOG_ERROR,
5363 "bypass-media-after-hold can be set only with resume-media-on-hold media-option\n");
5364 }
5365 } else if (!strcasecmp(val, "none")) {
5366 profile->media_options = 0;
5367 }
5368 } else if (!strcasecmp(var, "pnp-provision-url")) {
5369 profile->pnp_prov_url = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5369)
;
5370 } else if (!strcasecmp(var, "manage-presence")) {
5371 if (val && !strcasecmp(val, "passive")) {
5372 profile->pres_type = PRES_TYPE_PASSIVE;
5373
5374 } else if (val && !strcasecmp(val, "pnp")) {
5375 profile->pres_type = PRES_TYPE_PNP;
5376 } else if (switch_true(val)) {
5377 profile->pres_type = PRES_TYPE_FULL;
5378 } else {
5379 profile->pres_type = 0;
5380 }
5381 } else if (!strcasecmp(var, "presence-hold-state")) {
5382 if (val && !strcasecmp(val, "confirmed")) {
5383 profile->pres_held_type = PRES_HELD_CONFIRMED;
5384 } else if (val && !strcasecmp(val, "terminated")) {
5385 profile->pres_held_type = PRES_HELD_TERMINATED;
5386 } else {
5387 profile->pres_held_type = 0;
5388 }
5389 } else if (!strcasecmp(var, "presence-privacy")) {
5390 if (switch_true(val)) {
5391 sofia_set_pflag(profile, PFLAG_PRESENCE_PRIVACY)(profile)->pflags[PFLAG_PRESENCE_PRIVACY] = 1;
5392 } else {
5393 sofia_clear_pflag(profile, PFLAG_PRESENCE_PRIVACY)(profile)->pflags[PFLAG_PRESENCE_PRIVACY] = 0;
5394 }
5395 } else if (!strcasecmp(var, "update-refresher")) {
5396 if (switch_true(val)) {
5397 sofia_set_pflag(profile, PFLAG_UPDATE_REFRESHER)(profile)->pflags[PFLAG_UPDATE_REFRESHER] = 1;
5398 } else {
5399 sofia_clear_pflag(profile, PFLAG_UPDATE_REFRESHER)(profile)->pflags[PFLAG_UPDATE_REFRESHER] = 0;
5400 }
5401 } else if (!strcasecmp(var, "rfc-7989")) {
5402 if (switch_true(val)) {
5403 sofia_set_pflag(profile, PFLAG_RFC7989_SESSION_ID)(profile)->pflags[PFLAG_RFC7989_SESSION_ID] = 1;
5404 } else {
5405 sofia_clear_pflag(profile, PFLAG_RFC7989_SESSION_ID)(profile)->pflags[PFLAG_RFC7989_SESSION_ID] = 0;
5406 }
5407 } else if (!strcasecmp(var, "rfc-7989-filter")) {
5408 profile->rfc7989_filter = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5408)
;
5409 } else if (!strcasecmp(var, "rfc-7989-force-old")) {
5410 if (switch_true(val)) {
5411 sofia_set_pflag(profile, PFLAG_RFC7989_FORCE_OLD)(profile)->pflags[PFLAG_RFC7989_FORCE_OLD] = 1;
5412 } else {
5413 sofia_clear_pflag(profile, PFLAG_RFC7989_FORCE_OLD)(profile)->pflags[PFLAG_RFC7989_FORCE_OLD] = 0;
5414 }
5415 } else if (!strcasecmp(var, "manage-shared-appearance")) {
5416 if (switch_true(val)) {
5417 sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 1;
5418 profile->pres_type = PRES_TYPE_FULL;
5419 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
5420
5421 } else if (val && !strcasecmp(val, "sylantro")) {
5422 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5422
, ((void*)0)
, SWITCH_LOG_ERROR,
5423 "Sylantro support has been removed.\n"
5424 "It was incomplete anyway, and we fully support the broadsoft SCA shared line spec.");
5425 sofia_clear_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 0;
5426 } else {
5427 sofia_clear_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 0;
5428 }
5429 } else if (!strcasecmp(var, "disable-srv")) {
5430 if (switch_true(val)) {
5431 sofia_set_pflag(profile, PFLAG_DISABLE_SRV)(profile)->pflags[PFLAG_DISABLE_SRV] = 1;
5432 } else {
5433 sofia_clear_pflag(profile, PFLAG_DISABLE_SRV)(profile)->pflags[PFLAG_DISABLE_SRV] = 0;
5434 }
5435 } else if (!strcasecmp(var, "disable-naptr")) {
5436 if (switch_true(val)) {
5437 sofia_set_pflag(profile, PFLAG_DISABLE_NAPTR)(profile)->pflags[PFLAG_DISABLE_NAPTR] = 1;
5438 } else {
5439 sofia_clear_pflag(profile, PFLAG_DISABLE_NAPTR)(profile)->pflags[PFLAG_DISABLE_NAPTR] = 0;
5440 }
5441 } else if (!strcasecmp(var, "disable-srv503")) {
5442 if (switch_true(val)) {
5443 sofia_set_pflag(profile, PFLAG_DISABLE_SRV503)(profile)->pflags[PFLAG_DISABLE_SRV503] = 1;
5444 } else {
5445 sofia_clear_pflag(profile, PFLAG_DISABLE_SRV503)(profile)->pflags[PFLAG_DISABLE_SRV503] = 0;
5446 }
5447 } else if (!strcasecmp(var, "unregister-on-options-fail")) {
5448 if (switch_true(val)) {
5449 sofia_set_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)(profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] = 1;
5450 } else {
5451 sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)(profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] = 0;
5452 }
5453 } else if (!strcasecmp(var, "sip-user-ping-max") && !zstr(val)_zstr(val)) {
5454 profile->sip_user_ping_max = atoi(val);
5455 } else if (!strcasecmp(var, "sip-user-ping-min") && !zstr(val)_zstr(val)) {
5456 profile->sip_user_ping_min = atoi(val);
5457 } else if (!strcasecmp(var, "require-secure-rtp")) {
5458 if (switch_true(val)) {
5459 sofia_set_pflag(profile, PFLAG_SECURE)(profile)->pflags[PFLAG_SECURE] = 1;
5460 } else {
5461 sofia_clear_pflag(profile, PFLAG_SECURE)(profile)->pflags[PFLAG_SECURE] = 0;
5462 }
5463 } else if (!strcasecmp(var, "auto-invite-100")) {
5464 if (switch_true(val)) {
5465 sofia_set_pflag(profile, PFLAG_AUTO_INVITE_100)(profile)->pflags[PFLAG_AUTO_INVITE_100] = 1;
5466 } else {
5467 sofia_clear_pflag(profile, PFLAG_AUTO_INVITE_100)(profile)->pflags[PFLAG_AUTO_INVITE_100] = 0;
5468 }
5469 } else {
5470 found = 0;
5471 }
5472 if (found) continue;
5473
5474 if (!strcasecmp(var, "multiple-registrations")) {
5475 if (val && !strcasecmp(val, "call-id")) {
5476 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
5477 } else if (val && (!strcasecmp(val, "contact") || switch_true(val))) {
5478 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
5479 sofia_set_pflag(profile, PFLAG_MULTIREG_CONTACT)(profile)->pflags[PFLAG_MULTIREG_CONTACT] = 1;
5480 } else if (!switch_true(val)) {
5481 sofia_clear_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 0;
5482 sofia_clear_pflag(profile, PFLAG_MULTIREG_CONTACT)(profile)->pflags[PFLAG_MULTIREG_CONTACT] = 0;
5483 }
5484 } else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) {
5485 if (switch_true(val)) {
5486 sofia_set_media_flag(profile, SCMF_SUPPRESS_CNG)(profile)->media_flags[SCMF_SUPPRESS_CNG] = 1;
5487 profile->cng_pt = 0;
5488 } else {
5489 sofia_clear_media_flag(profile, SCMF_SUPPRESS_CNG)(profile)->media_flags[SCMF_SUPPRESS_CNG] = 0;
5490 }
5491 } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
5492 if (switch_true(val)) {
5493 profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH;
5494 } else {
5495 profile->ndlb &= ~PFLAG_NDLB_BROKEN_AUTH_HASH;
5496 }
5497 } else if (!strcasecmp(var, "NDLB-sendrecv-in-session")) {
5498 if (switch_true(val)) {
5499 profile->mndlb |= SM_NDLB_SENDRECV_IN_SESSION;
5500 } else {
5501 profile->mndlb &= ~SM_NDLB_SENDRECV_IN_SESSION;
5502 }
5503 } else if (!strcasecmp(var, "NDLB-allow-bad-iananame")) {
5504 if (switch_true(val)) {
5505 profile->ndlb |= SM_NDLB_ALLOW_BAD_IANANAME;
5506 } else {
5507 profile->ndlb &= ~SM_NDLB_ALLOW_BAD_IANANAME;
5508 }
5509 } else if (!strcasecmp(var, "NDLB-expires-in-register-response")) {
5510 if (switch_true(val)) {
5511 profile->ndlb |= PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE;
5512 } else {
5513 profile->ndlb &= ~PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE;
5514 }
5515 } else if (!strcasecmp(var, "NDLB-allow-crypto-in-avp")) {
5516 if (switch_true(val)) {
5517 profile->mndlb |= SM_NDLB_ALLOW_CRYPTO_IN_AVP;
5518 } else {
5519 profile->mndlb &= ~SM_NDLB_ALLOW_CRYPTO_IN_AVP;
5520 }
5521 } else if (!strcasecmp(var, "NDLB-allow-nondup-sdp")) {
5522 if (switch_true(val)) {
5523 profile->mndlb |= SM_NDLB_ALLOW_NONDUP_SDP;
5524 } else {
5525 profile->mndlb &= ~SM_NDLB_ALLOW_NONDUP_SDP;
5526 }
5527 } else if (!strcasecmp(var, "pass-rfc2833")) {
5528 if (switch_true(val)) {
5529 sofia_set_pflag(profile, PFLAG_PASS_RFC2833)(profile)->pflags[PFLAG_PASS_RFC2833] = 1;
5530 } else {
5531 sofia_clear_pflag(profile, PFLAG_PASS_RFC2833)(profile)->pflags[PFLAG_PASS_RFC2833] = 0;
5532 }
5533 } else if (!strcasecmp(var, "rtp-autofix-timing")) {
5534 if (switch_true(val)) {
5535 sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 1;
5536 } else {
5537 sofia_clear_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 0;
5538 }
5539 } else if (!strcasecmp(var, "contact-user")) {
5540 profile->contact_user = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5540)
;
5541 } else if (!strcasecmp(var, "nat-options-ping")) {
5542 if (val && !strcasecmp(val, "udp-only")) {
5543 sofia_set_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_UDP_NAT_OPTIONS_PING] = 1;
5544 } else if (switch_true(val)) {
5545 sofia_set_pflag(profile, PFLAG_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_NAT_OPTIONS_PING] = 1;
5546 } else {
5547 sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_NAT_OPTIONS_PING] = 0;
5548 sofia_clear_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_UDP_NAT_OPTIONS_PING] = 0;
5549 }
5550 } else if (!strcasecmp(var, "all-reg-options-ping")) {
5551 if (switch_true(val)) {
5552 sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)(profile)->pflags[PFLAG_ALL_REG_OPTIONS_PING] = 1;
5553 } else {
5554 sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)(profile)->pflags[PFLAG_ALL_REG_OPTIONS_PING] = 0;
5555 }
5556 } else if (!strcasecmp(var, "inbound-codec-negotiation")) {
5557 if (val && !strcasecmp(val, "greedy")) {
5558 sofia_set_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 1;
5559 } else if (val && !strcasecmp(val, "scrooge")) {
5560 sofia_set_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 1;
5561 sofia_set_media_flag(profile, SCMF_CODEC_SCROOGE)(profile)->media_flags[SCMF_CODEC_SCROOGE] = 1;
5562 } else {
5563 sofia_clear_media_flag(profile, SCMF_CODEC_SCROOGE)(profile)->media_flags[SCMF_CODEC_SCROOGE] = 0;
5564 sofia_clear_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 0;
5565 }
5566 } else if (!strcasecmp(var, "disable-transcoding")) {
5567 if (switch_true(val)) {
5568 sofia_set_media_flag(profile, SCMF_DISABLE_TRANSCODING)(profile)->media_flags[SCMF_DISABLE_TRANSCODING] = 1;
5569 } else {
5570 sofia_clear_media_flag(profile, SCMF_DISABLE_TRANSCODING)(profile)->media_flags[SCMF_DISABLE_TRANSCODING] = 0;
5571 }
5572 } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) {
5573 if (switch_true(val)) {
5574 sofia_set_media_flag(profile, SCMF_REWRITE_TIMESTAMPS)(profile)->media_flags[SCMF_REWRITE_TIMESTAMPS] = 1;
5575 } else {
5576 sofia_clear_media_flag(profile, SCMF_REWRITE_TIMESTAMPS)(profile)->media_flags[SCMF_REWRITE_TIMESTAMPS] = 0;
5577 }
5578 } else if (!strcasecmp(var, "auth-calls")) {
5579 if (switch_true(val)) {
5580 sofia_set_pflag(profile, PFLAG_AUTH_CALLS)(profile)->pflags[PFLAG_AUTH_CALLS] = 1;
5581 } else {
5582 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS)(profile)->pflags[PFLAG_AUTH_CALLS] = 0;
5583 }
5584 } else if (!strcasecmp(var, "auth-messages")) {
5585 auth_messages_value = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5585)
;
5586 } else if (!strcasecmp(var, "disable-auth-messages")) {
5587 if (switch_true(val)) {
5588 sofia_clear_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 0;
5589 } else {
5590 sofia_set_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 1;
5591 }
5592
5593 disable_message_auth_flag = 1;
5594 } else if (!strcasecmp(var, "auth-subscriptions")) {
5595 auth_subscriptions_value = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5595)
;
5596 } else if (!strcasecmp(var, "disable-auth-subscriptions")) {
5597 if (switch_true(val)) {
5598 sofia_clear_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 0;
5599 } else {
5600 sofia_set_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 1;
5601 }
5602
5603 disable_subscription_auth_flag = 1;
5604 } else if (!strcasecmp(var, "extended-info-parsing")) {
5605 if (switch_true(val)) {
5606 sofia_set_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)(profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] = 1;
5607 } else {
5608 sofia_clear_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)(profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] = 0;
5609 }
5610 } else if (!strcasecmp(var, "nonce-ttl") && !zstr(val)_zstr(val)) {
5611 profile->nonce_ttl = atoi(val);
5612 } else if (!strcasecmp(var, "max-auth-validity") && !zstr(val)_zstr(val)) {
5613 profile->max_auth_validity = atoi(val);
5614 } else if (!strcasecmp(var, "auth-require-user")) {
5615 if (switch_true(val)) {
5616 sofia_set_pflag(profile, PFLAG_AUTH_REQUIRE_USER)(profile)->pflags[PFLAG_AUTH_REQUIRE_USER] = 1;
5617 } else {
5618 sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER)(profile)->pflags[PFLAG_AUTH_REQUIRE_USER] = 0;
5619 }
5620 } else if (!strcasecmp(var, "accept-blind-reg")) {
5621 if (switch_true(val)) {
5622 sofia_set_pflag(profile, PFLAG_BLIND_REG)(profile)->pflags[PFLAG_BLIND_REG] = 1;
5623 } else {
5624 sofia_clear_pflag(profile, PFLAG_BLIND_REG)(profile)->pflags[PFLAG_BLIND_REG] = 0;
5625 }
5626 } else if (!strcasecmp(var, "3pcc-reinvite-bridged-on-ack")) {
5627 if (switch_true(val)) {
5628 sofia_set_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)(profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] = 1;
5629 } else {
5630 sofia_clear_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)(profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] = 0;
5631 }
5632 } else if (!strcasecmp(var, "enable-3pcc")) {
5633 if (switch_true(val)) {
5634 sofia_set_pflag(profile, PFLAG_3PCC)(profile)->pflags[PFLAG_3PCC] = 1;
5635 } else if (!strcasecmp(val, "proxy")) {
5636 sofia_set_pflag(profile, PFLAG_3PCC_PROXY)(profile)->pflags[PFLAG_3PCC_PROXY] = 1;
5637 }
5638 } else if (!strcasecmp(var, "accept-blind-auth")) {
5639 if (switch_true(val)) {
5640 sofia_set_pflag(profile, PFLAG_BLIND_AUTH)(profile)->pflags[PFLAG_BLIND_AUTH] = 1;
5641 } else {
5642 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH)(profile)->pflags[PFLAG_BLIND_AUTH] = 0;
5643 }
5644 } else if (!strcasecmp(var, "auth-all-packets")) {
5645 if (switch_true(val)) {
5646 sofia_set_pflag(profile, PFLAG_AUTH_ALL)(profile)->pflags[PFLAG_AUTH_ALL] = 1;
5647 } else {
5648 sofia_clear_pflag(profile, PFLAG_AUTH_ALL)(profile)->pflags[PFLAG_AUTH_ALL] = 0;
5649 }
5650 } else if (!strcasecmp(var, "full-id-in-dialplan")) {
5651 if (switch_true(val)) {
5652 sofia_set_pflag(profile, PFLAG_FULL_ID)(profile)->pflags[PFLAG_FULL_ID] = 1;
5653 } else {
5654 sofia_clear_pflag(profile, PFLAG_FULL_ID)(profile)->pflags[PFLAG_FULL_ID] = 0;
5655 }
5656 } else if (!strcasecmp(var, "inbound-reg-force-matching-username")) {
5657 if (switch_true(val)) {
5658 sofia_set_pflag(profile, PFLAG_CHECKUSER)(profile)->pflags[PFLAG_CHECKUSER] = 1;
5659 } else {
5660 sofia_clear_pflag(profile, PFLAG_CHECKUSER)(profile)->pflags[PFLAG_CHECKUSER] = 0;
5661 }
5662 } else if (!strcasecmp(var, "enable-timer")) {
5663 if (!switch_true(val)) {
5664 sofia_set_pflag(profile, PFLAG_DISABLE_TIMER)(profile)->pflags[PFLAG_DISABLE_TIMER] = 1;
5665 } else {
5666 sofia_clear_pflag(profile, PFLAG_DISABLE_TIMER)(profile)->pflags[PFLAG_DISABLE_TIMER] = 0;
5667 }
5668 } else if (!strcasecmp(var, "enable-rfc-5626")) {
5669 if (switch_true(val)) {
5670 sofia_set_pflag(profile, PFLAG_ENABLE_RFC5626)(profile)->pflags[PFLAG_ENABLE_RFC5626] = 1;
5671 } else {
5672 sofia_clear_pflag(profile, PFLAG_ENABLE_RFC5626)(profile)->pflags[PFLAG_ENABLE_RFC5626] = 0;
5673 }
5674 } else if (!strcasecmp(var, "minimum-session-expires") && !zstr(val)_zstr(val)) {
5675 profile->minimum_session_expires = atoi(val);
5676 /* per RFC 4028: minimum_session_expires must be > 90 */
5677 if (profile->minimum_session_expires < 90) {
5678 profile->minimum_session_expires = 90;
5679 }
5680 } else if (!strcasecmp(var, "enable-100rel")) {
5681 if (switch_true(val)) {
5682 sofia_clear_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 0;
5683 } else {
5684 sofia_set_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 1;
5685 }
5686 } else if (!strcasecmp(var, "enable-compact-headers")) {
5687 if (switch_true(val)) {
5688 sofia_set_pflag(profile, PFLAG_SIPCOMPACT)(profile)->pflags[PFLAG_SIPCOMPACT] = 1;
5689 } else {
5690 sofia_clear_pflag(profile, PFLAG_SIPCOMPACT)(profile)->pflags[PFLAG_SIPCOMPACT] = 0;
5691 }
5692 } else if (!strcasecmp(var, "pass-callee-id")) {
5693 if (switch_true(val)) {
5694 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
5695 } else {
5696 sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 0;
5697 }
5698 } else if (!strcasecmp(var, "enable-soa")) {
5699 if (switch_true(val)) {
5700 sofia_set_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 1;
5701 } else {
5702 sofia_clear_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 0;
5703 }
5704 } else if (!strcasecmp(var, "parse-all-invite-headers")) {
5705 if (switch_true(val)) {
5706 sofia_set_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)(profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] = 1;
5707 } else {
5708 sofia_clear_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)(profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] = 0;
5709 }
5710 } else if (!strcasecmp(var, "bitpacking")) {
5711 if (val && !strcasecmp(val, "aal2")) {
5712 profile->codec_flags = SWITCH_CODEC_FLAG_AAL2;
5713 } else {
5714 profile->codec_flags = 0;
5715 }
5716 } else if (!strcasecmp(var, "username")) {
5717 profile->sdp_username = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5717)
;
5718 } else if (!strcasecmp(var, "context")) {
5719 profile->context = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5719)
;
5720 } else if (!strcasecmp(var, "apply-nat-acl") && !zstr(val)_zstr(val)) {
5721 if (!strcasecmp(val,"none")) {
5722 profile->nat_acl_count = 0;
5723 } else if (profile->nat_acl_count < SOFIA_MAX_ACL100) {
5724 if (!profile->extsipip && profile->sipip && switch_check_network_list_ip(profile->sipip, val)switch_check_network_list_ip_token(profile->sipip, val, ((
void*)0))
) {
5725 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5725
, ((void*)0)
, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val);
5726 } else {
5727 profile->nat_acl[profile->nat_acl_count++] = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5727)
;
5728 }
5729 } else {
5730 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5730
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5731 }
5732 } else if (!strcasecmp(var, "apply-inbound-acl") && !zstr(val)_zstr(val)) {
5733 if (!strcasecmp(val,"none")) {
5734 profile->acl_count = 0;
5735 } else if (profile->acl_count < SOFIA_MAX_ACL100) {
5736 char *list, *pass = NULL((void*)0), *fail = NULL((void*)0);
5737
5738 list = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5738)
;
5739
5740 if ((pass = strchr(list, ':'))) {
5741 *pass++ = '\0';
5742 if ((fail = strchr(pass, ':'))) {
5743 *fail++ = '\0';
5744 }
5745
5746 if (zstr(pass)_zstr(pass)) pass = NULL((void*)0);
5747 if (zstr(fail)_zstr(fail)) fail = NULL((void*)0);
5748
5749 profile->acl_pass_context[profile->acl_count] = pass;
5750 profile->acl_fail_context[profile->acl_count] = fail;
5751 }
5752
5753 profile->acl[profile->acl_count++] = list;
5754
5755 } else {
5756 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5756
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5757 }
5758 } else if (!strcasecmp(var, "apply-proxy-acl") && !zstr(val)_zstr(val)) {
5759 if (!strcasecmp(val,"none")) {
5760 profile->proxy_acl_count = 0;
5761 } else if (profile->proxy_acl_count < SOFIA_MAX_ACL100) {
5762 profile->proxy_acl[profile->proxy_acl_count++] = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5762)
;
5763 } else {
5764 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5764
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5765 }
5766 } else if (!strcasecmp(var, "apply-register-acl") && !zstr(val)_zstr(val)) {
5767 if (!strcasecmp(val,"none")) {
5768 profile->reg_acl_count = 0;
5769 } else if (profile->reg_acl_count < SOFIA_MAX_ACL100) {
5770 profile->reg_acl[profile->reg_acl_count++] = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5770)
;
5771 } else {
5772 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5772
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5773 }
5774
5775 } else if (!strcasecmp(var, "apply-candidate-acl") && !zstr(val)_zstr(val)) {
5776 if (!strcasecmp(val,"none")) {
5777 profile->cand_acl_count = 0;
5778 } else if (profile->cand_acl_count < SWITCH_MAX_CAND_ACL25) {
5779 profile->cand_acl[profile->cand_acl_count++] = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5779)
;
5780 } else {
5781 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5781
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SWITCH_MAX_CAND_ACL25);
5782 }
5783 } else if (!strcasecmp(var, "alias")) {
5784 sip_alias_node_t *node;
5785 if (zstr(val)_zstr(val)) {
5786 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5786
, ((void*)0)
, SWITCH_LOG_DEBUG, "Alias Param has no data...\n");
5787 } else {
5788 if ((node = switch_core_alloc(profile->pool, sizeof(*node))switch_core_perform_alloc(profile->pool, sizeof(*node), "sofia.c"
, (const char *)__func__, 5788)
)) {
5789 if ((node->url = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5789)
)) {
5790 node->next = profile->aliases;
5791 profile->aliases = node;
5792 }
5793 }
5794 }
5795 } else if (!strcasecmp(var, "dialplan")) {
5796 profile->dialplan = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5796)
;
5797 } else if (!strcasecmp(var, "max-calls") && !zstr(val)_zstr(val)) {
5798 profile->max_calls = atoi(val);
5799 } else if (!strcasecmp(var, "codec-prefs")) {
5800 profile->inbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5800)
;
5801 profile->outbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5801)
;
5802 } else if (!strcasecmp(var, "inbound-codec-prefs")) {
5803 profile->inbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5803)
;
5804 } else if (!strcasecmp(var, "outbound-codec-prefs")) {
5805 profile->outbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5805)
;
5806 } else if (!strcasecmp(var, "challenge-realm")) {
5807 profile->challenge_realm = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5807)
;
5808 } else if (!strcasecmp(var, "dtmf-duration") && !zstr(val)_zstr(val)) {
5809 uint32_t dur = atoi(val);
5810 if (dur >= switch_core_min_dtmf_duration(0) && dur <= switch_core_max_dtmf_duration(0)) {
5811 profile->dtmf_duration = dur;
5812 } else {
5813 profile->dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION2000;
5814 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5814
, ((void*)0)
, SWITCH_LOG_DEBUG, "Duration out of bounds, using default of %d!\n",
5815 SWITCH_DEFAULT_DTMF_DURATION2000);
5816 }
5817
5818 } else if (!strcasecmp(var, "ws-binding") && !zstr(val)_zstr(val)) {
5819 int tmp;
5820 char *p;
5821
5822 profile->ws_ip = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5822)
;
5823 if ((p = strrchr(profile->ws_ip, ':'))) {
5824 *p++ = '\0';
5825
5826 if ((tmp = atol(p)) && tmp > 0) {
5827 profile->ws_port = (switch_port_t) tmp;
5828 }
5829 }
5830
5831 } else if (!strcasecmp(var, "wss-binding") && !zstr(val)_zstr(val)) {
5832 int tmp;
5833 char *p;
5834
5835 profile->wss_ip = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5835)
;
5836 if ((p = strrchr(profile->wss_ip, ':'))) {
5837 *p++ = '\0';
5838
5839 if ((tmp = atol(p)) && tmp > 0) {
5840 profile->wss_port = (switch_port_t) tmp;
5841 }
5842 }
5843
5844 /*
5845 * handle TLS params #1
5846 */
5847 } else if (!strcasecmp(var, "tls")) {
5848 if (switch_true(val)) {
5849 sofia_set_pflag(profile, PFLAG_TLS)(profile)->pflags[PFLAG_TLS] = 1;
5850 if (profile->tls_bind_params) {
5851 if (!switch_stristr("transport=tls", profile->tls_bind_params)) {
5852 profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", profile->tls_bind_params);
5853 }
5854 } else {
5855 profile->tls_bind_params = switch_core_strdup(profile->pool, "transport=tls")switch_core_perform_strdup(profile->pool, "transport=tls",
"sofia.c", (const char *)__func__, 5855)
;
5856 }
5857 } else {
5858 sofia_clear_pflag(profile, PFLAG_TLS)(profile)->pflags[PFLAG_TLS] = 0;
5859 }
5860 } else if (!strcasecmp(var, "tls-bind-params")) {
5861 if (val && switch_stristr("transport=tls", val)) {
5862 profile->tls_bind_params = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5862)
;
5863 } else {
5864 profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", val);
5865 }
5866 } else if (!strcasecmp(var, "tls-only")) {
5867 profile->tls_only = switch_true(val);
5868 } else if (!strcasecmp(var, "tls-verify-date")) {
5869 profile->tls_verify_date = switch_true(val);
5870 } else if (!strcasecmp(var, "tls-verify-depth") && !zstr(val)_zstr(val)) {
5871 profile->tls_verify_depth = atoi(val);
5872 } else if (!strcasecmp(var, "tls-verify-policy")) {
5873 profile->tls_verify_policy = sofia_glue_str2tls_verify_policy(val);
5874 } else if (!strcasecmp(var, "tls-sip-port") && !zstr(val)_zstr(val)) {
5875 if (!strcasecmp(val, "auto")) {
5876 sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] = 1;
5877 } else {
5878 sofia_clear_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] = 0;
5879 profile->tls_sip_port = (switch_port_t) atoi(val);
5880 }
5881 } else if (!strcasecmp(var, "tls-cert-dir") && !zstr(val)_zstr(val)) {
5882 profile->tls_cert_dir = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5882)
;
5883 } else if (!strcasecmp(var, "tls-passphrase") && !zstr(val)_zstr(val)) {
5884 profile->tls_passphrase = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5884)
;
5885 } else if (!strcasecmp(var, "tls-verify-in-subjects") && !zstr(val)_zstr(val)) {
5886 profile->tls_verify_in_subjects_str = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5886)
;
5887 } else if (!strcasecmp(var, "tls-ciphers") && !zstr(val)_zstr(val)) {
5888 profile->tls_ciphers = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5888)
;
5889 } else if (!strcasecmp(var, "tls-version") && !zstr(val)_zstr(val)) {
5890 char *ps = val, *pe = val;
5891 profile->tls_version = 0;
5892 while (ps && *pe) {
5893 int n;
5894 pe = strchr(ps,',');
5895 if (!pe && !(pe = memchr(ps,0,1024))) break;
5896 n = (int)(pe-ps);
5897 if (n==5 && !strncasecmp(ps, "sslv2", n))
5898 profile->tls_version |= SOFIA_TLS_VERSION_SSLv2;
5899 if (n==5 && !strncasecmp(ps, "sslv3", n))
5900 profile->tls_version |= SOFIA_TLS_VERSION_SSLv3;
5901 if (n==6 && !strncasecmp(ps, "sslv23", n))
5902 profile->tls_version |= SOFIA_TLS_VERSION_SSLv2 | SOFIA_TLS_VERSION_SSLv3;
5903 if (n==5 && !strncasecmp(ps, "tlsv1", n))
5904 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1;
5905 if (n==7 && !strncasecmp(ps, "tlsv1.1", n))
5906 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_1;
5907 if (n==7 && !strncasecmp(ps, "tlsv1.2", n))
5908 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
5909 ps=pe+1;
5910 }
5911 } else if (!strcasecmp(var, "tls-timeout") && !zstr(val)_zstr(val)) {
5912 int v = atoi(val);
5913 profile->tls_timeout = v > 0 ? (unsigned int)v : 300;
5914 } else if (!strcasecmp(var, "timer-T1") && !zstr(val)_zstr(val)) {
5915 int v = atoi(val);
5916 if (v > 0) {
5917 profile->timer_t1 = v;
5918 } else {
5919 profile->timer_t1 = 500;
5920 }
5921 } else if (!strcasecmp(var, "timer-T1X64") && !zstr(val)_zstr(val)) {
5922 int v = atoi(val);
5923 if (v > 0) {
5924 profile->timer_t1x64 = v;
5925 } else {
5926 profile->timer_t1x64 = 32000;
5927 }
5928 } else if (!strcasecmp(var, "timer-T2") && !zstr(val)_zstr(val)) {
5929 int v = atoi(val);
5930 if (v > 0) {
5931 profile->timer_t2 = v;
5932 } else {
5933 profile->timer_t2 = 4000;
5934 }
5935 } else if (!strcasecmp(var, "timer-T4") && !zstr(val)_zstr(val)) {
5936 int v = atoi(val);
5937 if (v > 0) {
5938 profile->timer_t4 = v;
5939 } else {
5940 profile->timer_t4 = 4000;
5941 }
5942 } else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) {
5943 if (switch_true(val)) {
5944 sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)(profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] = 1;
5945 } else {
5946 sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)(profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] = 0;
5947 }
5948 } else if (!strcasecmp(var, "sip-expires-late-margin") && !zstr(val)_zstr(val)) {
5949 int32_t sip_expires_late_margin = atoi(val);
5950 if (sip_expires_late_margin >= 0) {
5951 profile->sip_expires_late_margin = sip_expires_late_margin;
5952 } else {
5953 profile->sip_expires_late_margin = 60;
5954 }
5955 } else if (!strcasecmp(var, "sip-force-expires-min") && !zstr(val)_zstr(val)) {
5956 int32_t sip_force_expires_min = atoi(val);
5957 if (sip_force_expires_min >= 0) {
5958 profile->sip_force_expires_min = sip_force_expires_min;
5959 } else {
5960 profile->sip_force_expires_min = 0;
5961 }
5962 } else if (!strcasecmp(var, "sip-force-expires-max") && !zstr(val)_zstr(val)) {
5963 int32_t sip_force_expires_max = atoi(val);
5964 if (sip_force_expires_max >= 0) {
5965 profile->sip_force_expires_max = sip_force_expires_max;
5966 } else {
5967 profile->sip_force_expires_max = 0;
5968 }
5969 } else if (!strcasecmp(var, "sip-force-expires") && !zstr(val)_zstr(val)) {
5970 int32_t sip_force_expires = atoi(val);
5971 if (sip_force_expires >= 0) {
5972 profile->sip_force_expires = sip_force_expires;
5973 } else {
5974 profile->sip_force_expires = 0;
5975 }
5976 } else if (!strcasecmp(var, "sip-expires-max-deviation") && !zstr(val)_zstr(val)) {
5977 int32_t sip_expires_max_deviation = atoi(val);
5978 if (sip_expires_max_deviation >= 0) {
5979 profile->sip_expires_max_deviation = sip_expires_max_deviation;
5980 } else {
5981 profile->sip_expires_max_deviation = 0;
5982 }
5983 } else if (!strcasecmp(var, "sip-subscription-max-deviation") && !zstr(val)_zstr(val)) {
5984 int32_t sip_subscription_max_deviation = atoi(val);
5985 if (sip_subscription_max_deviation >= 0) {
5986 profile->sip_subscription_max_deviation = sip_subscription_max_deviation;
5987 } else {
5988 profile->sip_subscription_max_deviation = 0;
5989 }
5990 } else if (!strcasecmp(var, "reuse-connections")) {
5991 switch_bool_t value = switch_true(val);
5992 if (!value) {
5993 sofia_set_pflag(profile, PFLAG_NO_CONNECTION_REUSE)(profile)->pflags[PFLAG_NO_CONNECTION_REUSE] = 1;
5994 } else {
5995 sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE)(profile)->pflags[PFLAG_NO_CONNECTION_REUSE] = 0;
5996 }
5997 } else if (!strcasecmp(var, "p-asserted-id-parse")) {
5998 if (!val) {
5999 profile->paid_type = PAID_DEFAULT;
6000 } else if (!strncasecmp(val, "default", 7)) {
6001 profile->paid_type = PAID_DEFAULT;
6002 } else if (!strncasecmp(val, "user-only", 9)) {
6003 profile->paid_type = PAID_USER;
6004 } else if (!strncasecmp(val, "user-domain", 11)) {
6005 profile->paid_type = PAID_USER_DOMAIN;
6006 } else if (!strncasecmp(val, "verbatim", 8)) {
6007 profile->paid_type = PAID_VERBATIM;
6008 } else {
6009 profile->paid_type = PAID_DEFAULT;
6010 }
6011 } else if (!strcasecmp(var, "channel-xml-fetch-on-nightmare-transfer")) {
6012 if(switch_true(val)) {
6013 sofia_set_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)(profile)->pflags[PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER
] = 1
;
6014 } else {
6015 sofia_clear_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)(profile)->pflags[PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER
] = 0
;
6016 }
6017 } else if (!strcasecmp(var, "make-every-transfer-a-nightmare")) {
6018 if(switch_true(val)) {
6019 sofia_set_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)(profile)->pflags[PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE] =
1
;
6020 } else {
6021 sofia_clear_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)(profile)->pflags[PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE] =
0
;
6022 }
6023 } else if (!strcasecmp(var, "fire-transfer-events")) {
6024 if(switch_true(val)) {
6025 sofia_set_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)(profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] = 1;
6026 } else {
6027 sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)(profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] = 0;
6028 }
6029 } else if (!strcasecmp(var, "enforce-blind-auth-result")) {
6030 if(switch_true(val)) {
6031 sofia_set_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)(profile)->pflags[PFLAG_BLIND_AUTH_ENFORCE_RESULT] = 1;
6032 } else {
6033 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)(profile)->pflags[PFLAG_BLIND_AUTH_ENFORCE_RESULT] = 0;
6034 }
6035 } else if (!strcasecmp(var, "blind-auth-reply-403")) {
6036 if(switch_true(val)) {
6037 sofia_set_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)(profile)->pflags[PFLAG_BLIND_AUTH_REPLY_403] = 1;
6038 } else {
6039 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)(profile)->pflags[PFLAG_BLIND_AUTH_REPLY_403] = 0;
6040 }
6041 } else if (!strcasecmp(var, "auth-calls-acl-only")) {
6042 if(switch_true(val)) {
6043 sofia_set_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)(profile)->pflags[PFLAG_AUTH_CALLS_ACL_ONLY] = 1;
6044 } else {
6045 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)(profile)->pflags[PFLAG_AUTH_CALLS_ACL_ONLY] = 0;
6046 }
6047 } else if (!strcasecmp(var, "use-port-for-acl-check")) {
6048 if(switch_true(val)) {
6049 sofia_set_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK)(profile)->pflags[PFLAG_USE_PORT_FOR_ACL_CHECK] = 1;
6050 } else {
6051 sofia_clear_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK)(profile)->pflags[PFLAG_USE_PORT_FOR_ACL_CHECK] = 0;
6052 }
6053 } else if (!strcasecmp(var, "apply-inbound-acl-x-token")) {
6054 profile->acl_inbound_x_token_header = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 6054)
;
6055 } else if (!strcasecmp(var, "apply-proxy-acl-x-token")) {
6056 profile->acl_proxy_x_token_header = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 6056)
;
6057 } else if (!strcasecmp(var, "proxy-hold")) {
6058 if(switch_true(val)) {
6059 sofia_set_pflag(profile, PFLAG_PROXY_HOLD)(profile)->pflags[PFLAG_PROXY_HOLD] = 1;
6060 } else {
6061 sofia_clear_pflag(profile, PFLAG_PROXY_HOLD)(profile)->pflags[PFLAG_PROXY_HOLD] = 0;
6062 }
6063 } else if (!strcasecmp(var, "proxy-info")) {
6064 if(switch_true(val)) {
6065 sofia_set_pflag(profile, PFLAG_PROXY_INFO)(profile)->pflags[PFLAG_PROXY_INFO] = 1;
6066 } else {
6067 sofia_clear_pflag(profile, PFLAG_PROXY_INFO)(profile)->pflags[PFLAG_PROXY_INFO] = 0;
6068 }
6069 } else if (!strcasecmp(var, "proxy-message")) {
6070 if(switch_true(val)) {
6071 sofia_set_pflag(profile, PFLAG_PROXY_MESSAGE)(profile)->pflags[PFLAG_PROXY_MESSAGE] = 1;
6072 } else {
6073 sofia_clear_pflag(profile, PFLAG_PROXY_MESSAGE)(profile)->pflags[PFLAG_PROXY_MESSAGE] = 0;
6074 }
6075 } else if (!strcasecmp(var, "proxy-notify-events")) {
6076 profile->proxy_notify_events = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 6076)
;
6077 } else if (!strcasecmp(var, "proxy-info-content-types")) {
6078 profile->proxy_info_content_types = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 6078)
;
6079 } else if (!strcasecmp(var, "rfc8760-auth-algorithms")) {
6080 char *algs_arr[100] = { 0 };
6081 uint8_t algs = switch_separate_string(val, ',', algs_arr, (sizeof(algs_arr) / sizeof(algs_arr[0])));
6082 if (algs && algs < SOFIA_MAX_REG_ALGS7) {
6083 sofia_auth_algs_t temp;
6084 int i, j = 0;
6085 for (i = 0; i < algs && algs_arr[i]; i++) {
6086 temp = sofia_alg_str2id(algs_arr[i], SWITCH_TRUE);
6087 if (temp != ALG_NONE) {
6088 profile->auth_algs[j] = temp;
6089 j++;
6090 }
6091 }
6092 profile->rfc8760_algs_count = j;
6093 for (i = 0; i < profile->rfc8760_algs_count; i++) {
6094 for (j = i + 1; j < profile->rfc8760_algs_count; j++) {
6095 /* when adding algs: algs must be kept in priority order in the enum */
6096 if (profile->auth_algs[i] < profile->auth_algs[j])
6097 {
6098 temp = profile->auth_algs[i];
6099 profile->auth_algs[i] = profile->auth_algs[j];
6100 profile->auth_algs[j] = temp;
6101 }
6102 }
6103 }
6104 }
6105 }
6106 }
6107
6108 if (!disable_message_auth_flag) {
6109 if (!auth_messages_value || switch_true(auth_messages_value)) {
6110 sofia_set_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 1;
6111 } else {
6112 sofia_clear_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 0;
6113 }
6114 }
6115
6116 if (!disable_subscription_auth_flag) {
6117 if (!auth_subscriptions_value || switch_true(auth_subscriptions_value)) {
6118 sofia_set_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 1;
6119 } else {
6120 sofia_clear_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 0;
6121 }
6122 }
6123
6124 if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)((profile)->flags[TFLAG_ZRTP_PASSTHRU] ? 1 : 0) && !sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION)((profile)->flags[TFLAG_LATE_NEGOTIATION] ? 1 : 0)) {
6125 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6125
, ((void*)0)
, SWITCH_LOG_WARNING, "ZRTP passthrough implictly enables inbound-late-negotiation\n");
6126 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
6127 }
6128
6129 if (sofia_test_flag(profile, TFLAG_INB_NOMEDIA)((profile)->flags[TFLAG_INB_NOMEDIA] ? 1 : 0) && !sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION)((profile)->flags[TFLAG_LATE_NEGOTIATION] ? 1 : 0)) {
6130 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6130
, ((void*)0)
, SWITCH_LOG_WARNING, "inbound-bypass-media implictly enables inbound-late-negotiation\n");
6131 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
6132 }
6133
6134 if (sofia_test_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)((profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] ? 1 : 0) && !sofia_test_pflag(profile, PFLAG_ALLOW_UPDATE)((profile)->pflags[PFLAG_ALLOW_UPDATE] ? 1 : 0)) {
6135 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6135
, ((void*)0)
, SWITCH_LOG_WARNING, "send-display-update=true is set, but we can't comply because allow-update=false\n");
6136 sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 0;
6137 }
6138 if (sofia_test_pflag(profile, PFLAG_PROXY_HOLD)((profile)->pflags[PFLAG_PROXY_HOLD] ? 1 : 0)) {
6139 if (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
6140 profile->media_options &= ~MEDIA_OPT_MEDIA_ON_HOLD;
6141 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6141
, ((void*)0)
, SWITCH_LOG_WARNING, "proxy-hold=true is set, incompatible with media-option=resume-media-on-hold\n");
6142 }
6143 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_HOLD) {
6144 profile->media_options &= ~MEDIA_OPT_BYPASS_AFTER_HOLD;
6145 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6145
, ((void*)0)
, SWITCH_LOG_WARNING, "proxy-hold=true is set, incompatible with media-option=bypass-media-after-hold\n");
6146 }
6147 }
6148
6149 if ((!profile->cng_pt) && (!sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)((profile)->media_flags[SCMF_SUPPRESS_CNG] ? 1 : 0))) {
6150 profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD13;
6151 }
6152
6153 if (!profile->sipip) {
6154 profile->sipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip)switch_core_perform_strdup(profile->pool, mod_sofia_globals
.guess_ip, "sofia.c", (const char *)__func__, 6154)
;
6155 }
6156
6157 if (!profile->rtpip[0] && !profile->rtpip6[0]) {
6158 profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip)switch_core_perform_strdup(profile->pool, mod_sofia_globals
.guess_ip, "sofia.c", (const char *)__func__, 6158)
;
6159 }
6160
6161 if (switch_nat_get_type()) {
6162 char *ip = switch_core_get_variable_dup("nat_public_addr");
6163 if (ip && !strchr(profile->sipip, ':')) {
6164 if (!profile->extrtpip) {
6165 profile->extrtpip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 6165)
;
6166 }
6167 if (!profile->extsipip) {
6168 profile->extsipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 6168)
;
6169 }
6170 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
6171 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6171
, ((void*)0)
, SWITCH_LOG_NOTICE, "NAT detected setting external ip to %s\n", ip);
6172 }
6173 switch_safe_free(ip)if (ip) {free(ip);ip=((void*)0);};
6174 }
6175
6176 if (profile->nonce_ttl < 60) {
6177 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6177
, ((void*)0)
, SWITCH_LOG_INFO, "Setting nonce TTL to 60 seconds\n");
6178 profile->nonce_ttl = 60;
6179 }
6180
6181 if (!profile->max_auth_validity) {
6182 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6182
, ((void*)0)
, SWITCH_LOG_INFO, "Setting MAX Auth Validity to 0 Attempts\n");
6183 profile->max_auth_validity = 0;
6184 }
6185
6186 if (!profile->sdp_username) {
6187 profile->sdp_username = switch_core_strdup(profile->pool, "FreeSWITCH")switch_core_perform_strdup(profile->pool, "FreeSWITCH", "sofia.c"
, (const char *)__func__, 6187)
;
6188 }
6189
6190 if (!profile->rtpip[0] && !profile->rtpip6[0]) {
6191 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6191
, ((void*)0)
, SWITCH_LOG_WARNING, "Setting ip to '127.0.0.1'\n");
6192 profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, "127.0.0.1")switch_core_perform_strdup(profile->pool, "127.0.0.1", "sofia.c"
, (const char *)__func__, 6192)
;
6193 }
6194
6195 if (!profile->sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_PORT] ? 1 : 0)) {
6196 profile->sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_PORT"5060");
6197 if (!profile->extsipport) profile->extsipport = profile->sip_port;
6198 }
6199
6200 if (!profile->dialplan) {
6201 profile->dialplan = switch_core_strdup(profile->pool, "XML")switch_core_perform_strdup(profile->pool, "XML", "sofia.c"
, (const char *)__func__, 6201)
;
6202 }
6203
6204 if (!profile->context) {
6205 profile->context = switch_core_strdup(profile->pool, "default")switch_core_perform_strdup(profile->pool, "default", "sofia.c"
, (const char *)__func__, 6205)
;
6206 }
6207
6208 if (!profile->sipdomain) {
6209 profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip)switch_core_perform_strdup(profile->pool, profile->sipip
, "sofia.c", (const char *)__func__, 6209)
;
6210 }
6211
6212 if (profile->pres_type == PRES_TYPE_PNP) {
6213 if (!profile->pnp_prov_url) {
6214 profile->pnp_prov_url = switch_core_sprintf(profile->pool, "http://%s/provision/", mod_sofia_globals.guess_ip);
6215 }
6216
6217 if (!profile->pnp_notify_profile) {
6218 profile->pnp_notify_profile = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip)switch_core_perform_strdup(profile->pool, mod_sofia_globals
.guess_ip, "sofia.c", (const char *)__func__, 6218)
;
6219 }
6220
6221 if (!profile->extsipip) {
6222 profile->extsipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip)switch_core_perform_strdup(profile->pool, mod_sofia_globals
.guess_ip, "sofia.c", (const char *)__func__, 6222)
;
6223 }
6224
6225 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6225
, ((void*)0)
, SWITCH_LOG_INFO, "we're configured to provision to [%s] on profile [%s]\n",
6226 profile->pnp_prov_url, profile->pnp_notify_profile);
6227 }
6228
6229 config_sofia_profile_urls(profile);
6230
6231 if (profile->tls_cert_dir) {
6232 if (profile->wss_ip) {
6233 char *key, *cert;
6234 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.key");
6235 if (switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS) key = NULL((void*)0);
6236 cert = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.crt");
6237 if (switch_file_exists(cert, profile->pool) != SWITCH_STATUS_SUCCESS) cert = NULL((void*)0);
6238 if ( !key || !cert) {
6239 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
6240 if ( switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS ) {
6241 switch_core_gen_certs(key);
6242 }
6243 }
6244 }
6245 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
6246 char *key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "agent.pem");
6247 char *ca = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "cafile.pem");;
6248 if (switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS) key = NULL((void*)0);
6249 if (switch_file_exists(ca, profile->pool) != SWITCH_STATUS_SUCCESS) ca = NULL((void*)0);
6250 if ( !key || !ca ) {
6251 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "tls.pem");
6252 if ( switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS ) {
6253 switch_core_gen_certs(key);
6254 }
6255 }
6256 }
6257 }
6258 }
6259
6260 if (profile) {
6261 if (profile_already_started) {
6262 switch_xml_t gateways_tag, domain_tag, domains_tag, aliases_tag, alias_tag;
6263
6264 if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)((profile)->flags[TFLAG_ZRTP_PASSTHRU] ? 1 : 0)) {
6265 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
6266 }
6267
6268 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
6269 parse_gateways(profile, gateways_tag, NULL((void*)0));
6270 }
6271
6272 status = SWITCH_STATUS_SUCCESS;
6273
6274 if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
6275 switch_event_t *xml_params;
6276 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 6276, &xml_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
6277 switch_assert(xml_params)((xml_params) ? (void) (0) : __assert_fail ("xml_params", "sofia.c"
, 6277, __extension__ __PRETTY_FUNCTION__))
;
6278 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways");
6279 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
6280
6281 for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
6282 switch_xml_t droot, x_domain_tag;
6283 const char *dname = switch_xml_attr_soft(domain_tag, "name");
6284 const char *parse = switch_xml_attr_soft(domain_tag, "parse");
6285 const char *alias = switch_xml_attr_soft(domain_tag, "alias");
6286
6287 if (!zstr(dname)_zstr(dname)) {
6288 if (!strcasecmp(dname, "all")) {
6289 switch_xml_t xml_root, x_domains;
6290 if (switch_xml_locate("directory", NULL((void*)0), NULL((void*)0), NULL((void*)0), &xml_root, &x_domains, xml_params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
6291 for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
6292 dname = switch_xml_attr_soft(x_domain_tag, "name");
6293 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
6294 }
6295 switch_xml_free(xml_root);
6296 }
6297 } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) {
6298 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
6299 switch_xml_free(droot);
6300 }
6301 }
6302 }
6303
6304 switch_event_destroy(&xml_params);
6305 }
6306
6307 if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
6308 for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
6309 char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
6310 if (!zstr(aname)_zstr(aname)) {
6311
6312 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname)switch_core_perform_strdup(profile->pool, aname, "sofia.c"
, (const char *)__func__, 6312)
, profile) == SWITCH_STATUS_SUCCESS) {
6313 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6313
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
6314 } else {
6315 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6315
, ((void*)0)
, SWITCH_LOG_WARNING, "Alias [%s] for profile [%s] (already exists)\n",
6316 aname, profile->name);
6317 }
6318 }
6319 }
6320 }
6321
6322 } else {
6323 switch_xml_t aliases_tag, alias_tag;
6324
6325 if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
6326 for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
6327 char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
6328 if (!zstr(aname)_zstr(aname)) {
6329
6330 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname)switch_core_perform_strdup(profile->pool, aname, "sofia.c"
, (const char *)__func__, 6330)
, profile) == SWITCH_STATUS_SUCCESS) {
6331 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6331
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
6332 } else {
6333 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6333
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Adding Alias [%s] for profile [%s] (name in use)\n",
6334 aname, profile->name);
6335 }
6336 }
6337 }
6338 }
6339
6340 if (profile->sipip) {
6341 switch_event_t *s_event;
6342 if (!profile->extsipport) profile->extsipport = profile->sip_port;
6343
6344 launch_sofia_profile_thread(profile);
6345 if (profile->odbc_dsn) {
6346 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6346
, ((void*)0)
, SWITCH_LOG_NOTICE, "Connecting ODBC Profile %s [%s]\n", profile->name, url);
6347 switch_yield(1000000)switch_sleep(1000000);;
6348 } else {
6349 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6349
, ((void*)0)
, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url);
6350 }
6351 if ((switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_PROFILE_START)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 6351, &s_event, SWITCH_EVENT_CUSTOM
, "sofia::profile_start")
== SWITCH_STATUS_SUCCESS)) {
6352 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
6353 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
6354 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
6355 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 6355, &s_event, ((void*)0))
;
6356 }
6357 } else {
6358 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6358
, ((void*)0)
, SWITCH_LOG_NOTICE, "Unable to start Profile %s due to no configured sip-ip\n", profile->name);
6359 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 6359)
;
6360 }
6361 profile = NULL((void*)0);
6362 }
6363 if (profile_found) {
6364 break;
6365 }
6366 }
6367 }
6368 }
6369 done:
6370
6371 if (profile_already_started) {
6372 sofia_glue_release_profile(profile_already_started)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 6372, profile_already_started)
;
6373 }
6374
6375 switch_event_destroy(&params);
6376
6377 if (xml) {
6378 switch_xml_free(xml);
6379 }
6380
6381 if (profile_name && !profile_found) {
6382 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6382
, ((void*)0)
, SWITCH_LOG_WARNING, "No Such Profile '%s'\n", profile_name);
6383 status = SWITCH_STATUS_FALSE;
6384 }
6385
6386 return status;
6387}
6388
6389const char *sofia_gateway_status_name(sofia_gateway_status_t status)
6390{
6391 static const char *status_names[] = { "DOWN", "UP", NULL((void*)0) };
6392
6393 if (status < SOFIA_GATEWAY_INVALID) {
6394 return status_names[status];
6395 } else {
6396 return "INVALID";
6397 }
6398}
6399
6400const char *sofia_sip_user_status_name(sofia_sip_user_status_t status)
6401{
6402 static const char *status_names[] = { "UNREACHABLE", "REACHABLE", NULL((void*)0) };
6403
6404 if (status < SOFIA_REG_INVALID) {
6405 return status_names[status];
6406 } else {
6407 return "INVALID";
6408 }
6409}
6410
6411struct cb_helper_sip_user_status {
6412 char *status;
6413 size_t status_len;
6414
6415 char *contact;
6416 size_t contact_len;
6417
6418 int count;
6419};
6420
6421int sofia_sip_user_status_callback(void *pArg, int argc, char **argv, char **columnNames)
6422{
6423 struct cb_helper_sip_user_status *cbt = (struct cb_helper_sip_user_status *) pArg;
6424
6425 if (argc != 3) {
6426 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6426
, ((void*)0)
, SWITCH_LOG_ERROR, "expected 3 arguments from query, instead got %d\n", argc);
6427 return 0;
6428 }
6429
6430 switch_copy_string(cbt->status, argv[0], cbt->status_len);
6431 cbt->count = (argv[1] && switch_is_number(argv[1])) ? atoi(argv[1]) : 0;
6432
6433 switch_copy_string(cbt->contact, argv[2], cbt->contact_len);
6434
6435 return 1;
6436}
6437
6438static void sofia_handle_sip_r_options(switch_core_session_t *session, int status,
6439 char const *phrase,
6440 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
6441 sofia_dispatch_event_t *de,
6442 tagi_t tags[])
6443{
6444 sofia_gateway_t *gateway = NULL((void*)0);
6445 switch_bool_t do_fire_gateway_state_event = SWITCH_FALSE;
6446
6447 if (sofia_private && !zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
6448 gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 6448
, sofia_private->gateway_name)
;
6449 sofia_private->destroy_me = 1;
6450 }
6451
6452 if (gateway) {
6453 if (status >= 200 && status < 600 && status != 408 && status != 503) {
6454 if (gateway->state == REG_STATE_FAILED) {
6455 gateway->state = REG_STATE_UNREGED;
6456 }
6457
6458 if (gateway->ping_count < 0) {
6459 gateway->ping_count = 0;
6460 }
6461
6462 if (gateway->ping_count < gateway->ping_max) {
6463 gateway->ping_count++;
6464
6465 if (gateway->ping_count >= gateway->ping_min && gateway->status != SOFIA_GATEWAY_UP) {
6466 gateway->status = SOFIA_GATEWAY_UP;
6467 gateway->uptime = switch_time_now();
6468 do_fire_gateway_state_event = SWITCH_TRUE;
6469 }
6470
6471 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6471, (const char*)(session)
, SWITCH_LOG_WARNING,
6472 "Ping succeeded %s with code %d - count %d/%d/%d, state %s\n",
6473 gateway->name, status, gateway->ping_min, gateway->ping_count, gateway->ping_max, sofia_gateway_status_name(gateway->status));
6474 }
6475 if (gateway->ping_sent) {
6476 gateway->ping_time = (float)(switch_time_now() - gateway->ping_sent) / 1000;
6477 gateway->ping_sent = 0;
6478 }
6479 } else {
6480 if (gateway->state == REG_STATE_REGED) {
6481 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6481, (const char*)(session)
, SWITCH_LOG_WARNING, "Unregister %s\n", gateway->name);
6482 gateway->state = REG_STATE_FAILED;
6483 gateway->ping_time = 0;
6484 }
6485
6486 if (gateway->ping_count > 0) {
6487 gateway->ping_count--;
6488 }
6489
6490 if (gateway->ping_count < gateway->ping_min && gateway->status != SOFIA_GATEWAY_DOWN) {
6491 gateway->status = SOFIA_GATEWAY_DOWN;
6492 do_fire_gateway_state_event = SWITCH_TRUE;
6493 gateway->ping_time = 0;
6494 }
6495
6496 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6496, (const char*)(session)
, SWITCH_LOG_WARNING,
6497 "Ping failed %s with code %d - count %d/%d/%d, state %s\n",
6498 gateway->name, status, gateway->ping_min, gateway->ping_count, gateway->ping_max, sofia_gateway_status_name(gateway->status));
6499 }
6500 if (gateway->ping_monitoring || do_fire_gateway_state_event) {
6501 sofia_reg_fire_custom_gateway_state_event(gateway, status, phrase);
6502 }
6503
6504 gateway->ping = switch_epoch_time_now(NULL((void*)0)) + gateway->ping_freq;
6505 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 6505, gateway);
;
6506 gateway->pinging = 0;
6507 } else if (sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')) {
6508 const char *call_id = strchr(sip->sip_call_id->i_id, '_') + 1;
6509 char *sql;
6510 struct cb_helper_sip_user_status sip_user_status;
6511 char ping_status[255] = "";
6512 char sip_contact[1024] = "";
6513 int sip_user_ping_min = profile->sip_user_ping_min;
6514 int sip_user_ping_max = profile->sip_user_ping_max;
6515
6516 char *sip_user = switch_mprintf("%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6517 int ping_time = 0;
6518
6519 if (sofia_private && sofia_private->ping_sent) {
6520 ping_time = (int)(switch_time_now() - sofia_private->ping_sent);
6521 }
6522
6523 sip_user_status.status = ping_status;
6524 sip_user_status.status_len = sizeof(ping_status);
6525 sip_user_status.contact = sip_contact;
6526 sip_user_status.contact_len = sizeof(sip_contact);
6527 sql = switch_mprintf("select ping_status, ping_count, contact from sip_registrations where sip_user='%q' and sip_host='%q' and call_id='%q'",
6528 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6529 sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sip_user_status_callback, &sip_user_status);
6530 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6531
6532 if (status != 200 && status != 486) {
6533 sip_user_status.count--;
6534 if (sip_user_status.count >= 0) {
6535 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6535, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' failed with code %d - count %d, state %s\n",
6536 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
6537 sql = switch_mprintf("update sip_registrations set ping_count=%d, ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6538 sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6539 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6540 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6541 }
6542 if (sip_user_status.count < sip_user_ping_min) {
6543 if (strcmp(sip_user_status.status, "Unreachable")) {
6544 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6544, (const char*)(session)
, SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Unreachable\n",
6545 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6546 sql = switch_mprintf("update sip_registrations set ping_status='Unreachable', ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6547 ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6548 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6549 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6550 sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
6551 sip->sip_to->a_url->url_host, call_id, SOFIA_REG_REACHABLE, status, phrase);
6552
6553 if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)((profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] ? 1 : 0)) {
6554 time_t now = switch_epoch_time_now(NULL((void*)0));
6555 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6555, (const char*)(session)
, SWITCH_LOG_WARNING, "Expire sip user '%s@%s' due to options failure\n",
6556 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6557
6558 sql = switch_mprintf("update sip_registrations set expires=%ld, ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6559 (long) now, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6560 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6561 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6562 }
6563 }
6564 }
6565 } else {
6566 sip_user_status.count++;
6567 if (sip_user_status.count <= sip_user_ping_max) {
6568 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6568, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' succeeded with code %d - count %d, state %s\n",
6569 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
6570 sql = switch_mprintf("update sip_registrations set ping_count=%d, ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6571 sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6572 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6573 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6574 }
6575 if (sip_user_status.count >= sip_user_ping_min) {
6576 if (strcmp(sip_user_status.status, "Reachable")) {
6577 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6577, (const char*)(session)
, SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Reachable\n",
6578 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6579 sql = switch_mprintf("update sip_registrations set ping_status='Reachable' where sip_user='%q' and sip_host='%q' and call_id='%q'",
6580 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6581 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6582 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6583 sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
6584 sip->sip_to->a_url->url_host, call_id, SOFIA_REG_UNREACHABLE, status, phrase);
6585 }
6586 }
6587 }
6588
6589 switch_safe_free(sip_user)if (sip_user) {free(sip_user);sip_user=((void*)0);};
6590
6591 }
6592}
6593
6594static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
6595 char const *phrase,
6596 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
6597 sofia_dispatch_event_t *de,
6598 tagi_t tags[])
6599{
6600 char *call_info = NULL((void*)0);
6601 if (sip && session) {
6602 switch_channel_t *channel = switch_core_session_get_channel(session);
6603 const char *uuid;
6604 switch_core_session_t *other_session;
6605 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
6606 char network_ip[80] = "";
6607 int network_port = 0;
6608 switch_caller_profile_t *caller_profile = NULL((void*)0);
6609 int has_t38 = 0;
6610
6611 switch_channel_clear_flag(channel, CF_REQ_MEDIA);
6612
6613 if (status < 200) {
6614 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 6614)
== SWITCH_STATUS_SUCCESS) {
6615 if(switch_core_session_compare(session, other_session)) {
6616 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
6617 if (sofia_test_flag(other_tech_pvt, TFLAG_3PCC)((other_tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0)) {
6618 sofia_set_flag_locked(tech_pvt, TFLAG_SKIP_EARLY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 6618, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_SKIP_EARLY] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
6619 }
6620 }
6621 switch_core_session_rwunlock(other_session);
6622 }
6623
6624 if (sofia_test_flag(tech_pvt, TFLAG_SKIP_EARLY)((tech_pvt)->flags[TFLAG_SKIP_EARLY] ? 1 : 0)) {
6625 return;
6626 }
6627 }
6628
6629 if (status >= 900) {
6630 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6630, (const char*)(session)
, SWITCH_LOG_ERROR, "%s status %d received.\n",
6631 switch_channel_get_name(channel), status);
6632 return;
6633 }
6634
6635 if (status > 299) {
6636 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_refuse")switch_channel_set_variable_var_check(channel, "sip_hangup_disposition"
, "recv_refuse", SWITCH_TRUE)
;
6637 }
6638
6639 if (status >= 400) {
6640 char status_str[5];
6641 switch_snprintf(status_str, sizeof(status_str), "%d", status);
6642 switch_channel_set_variable(channel, "sip_invite_failure_status", status_str)switch_channel_set_variable_var_check(channel, "sip_invite_failure_status"
, status_str, SWITCH_TRUE)
;
6643 switch_channel_set_variable(channel, "sip_invite_failure_phrase", phrase)switch_channel_set_variable_var_check(channel, "sip_invite_failure_phrase"
, phrase, SWITCH_TRUE)
;
6644 switch_channel_set_variable_partner(channel, "sip_invite_failure_status", status_str)switch_channel_set_variable_partner_var_check(channel, "sip_invite_failure_status"
, status_str, SWITCH_TRUE)
;
6645 switch_channel_set_variable_partner(channel, "sip_invite_failure_phrase", phrase)switch_channel_set_variable_partner_var_check(channel, "sip_invite_failure_phrase"
, phrase, SWITCH_TRUE)
;
6646 } else {
6647 switch_channel_set_variable_partner(channel, "sip_invite_failure_status", NULL)switch_channel_set_variable_partner_var_check(channel, "sip_invite_failure_status"
, ((void*)0), SWITCH_TRUE)
;
6648 switch_channel_set_variable_partner(channel, "sip_invite_failure_phrase", NULL)switch_channel_set_variable_partner_var_check(channel, "sip_invite_failure_phrase"
, ((void*)0), SWITCH_TRUE)
;
6649 }
6650
6651 if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
6652 || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
6653 || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
6654 tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
6655 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6655, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote Reason: %d\n", tech_pvt->q850_cause);
6656 }
6657
6658 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
6659
6660 switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
6661 switch_channel_set_variable(channel, "sip_reply_host", network_ip)switch_channel_set_variable_var_check(channel, "sip_reply_host"
, network_ip, SWITCH_TRUE)
;
6662 switch_channel_set_variable_printf(channel, "sip_reply_port", "%d", network_port);
6663
6664 switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip);
6665 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
6666
6667 if ((caller_profile = switch_channel_get_caller_profile(channel)) && !zstr(network_ip)_zstr(network_ip) &&
6668 (zstr(caller_profile->network_addr)_zstr(caller_profile->network_addr) || strcmp(caller_profile->network_addr, network_ip))) {
6669 caller_profile->network_addr = switch_core_strdup(caller_profile->pool, network_ip)switch_core_perform_strdup(caller_profile->pool, network_ip
, "sofia.c", (const char *)__func__, 6669)
;
6670 }
6671
6672 if (tech_pvt->mparams.last_sdp_response) {
6673 tech_pvt->mparams.prev_sdp_response = tech_pvt->mparams.last_sdp_response;
6674 }
6675 tech_pvt->mparams.last_sdp_response = NULL((void*)0);
6676
6677 if (sip->sip_payload && sip->sip_payload->pl_data) {
6678 switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE);
6679
6680 if (!zstr(tech_pvt->mparams.prev_sdp_response)_zstr(tech_pvt->mparams.prev_sdp_response) && !strcmp(tech_pvt->mparams.prev_sdp_response, sip->sip_payload->pl_data)) {
6681 tech_pvt->mparams.last_sdp_response = tech_pvt->mparams.prev_sdp_response;
6682 } else {
6683 tech_pvt->mparams.last_sdp_response = switch_core_session_strdup(session, sip->sip_payload->pl_data)switch_core_perform_session_strdup(session, sip->sip_payload
->pl_data, "sofia.c", (const char *)__func__, 6683)
;
6684 }
6685 }
6686
6687 if (status > 299 && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ)) {
6688 switch_channel_set_private(channel, "t38_options", NULL((void*)0));
6689 switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
6690 switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ);
6691 switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_FAIL);
6692 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6692, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s T38 invite failed\n", switch_channel_get_name(tech_pvt->channel));
6693 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
6694 }
6695
6696
6697 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
6698 if (channel && sip->sip_call_info) {
6699 char *p;
6700 call_info = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info);
6701
6702 if (switch_stristr("appearance", call_info)) {
6703 switch_channel_set_variable(channel, "presence_call_info_full", call_info)switch_channel_set_variable_var_check(channel, "presence_call_info_full"
, call_info, SWITCH_TRUE)
;
6704 if ((p = strchr(call_info, ';'))) {
6705 switch_channel_set_variable(channel, "presence_call_info", p + 1)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p + 1, SWITCH_TRUE)
;
6706 }
6707 }
6708 } else if ((status == 180 || status == 183 || status == 200)) {
6709 char buf[128] = "";
6710 char *sql;
6711 char *state = "active";
6712
6713 if (status != 200) {
6714 state = "progressing";
6715 }
6716
6717 if (sip->sip_from && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
6718 sip->sip_to && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
6719 sql =
6720 switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
6721 "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
6722 sip->sip_from->a_url->url_host);
6723 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
6724
6725 if (mod_sofia_globals.debug_sla > 1) {
6726 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6726
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
6727 }
6728 free(sql);
6729
6730 if (!zstr(buf)_zstr(buf)) {
6731 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
6732 "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
6733
6734 if (mod_sofia_globals.debug_sla > 1) {
6735 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6735
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
6736 }
6737
6738 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
6739
6740 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6740, (const char*)(session)
, SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
6741 sip->sip_from->a_url->url_host, buf);
6742 switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
6743 switch_channel_set_variable(channel, "presence_call_info", buf)switch_channel_set_variable_var_check(channel, "presence_call_info"
, buf, SWITCH_TRUE)
;
6744 }
6745 }
6746 }
6747 }
6748
6749 if ((status == 180 || status == 183 || status > 199)) {
6750 const char *vval;
6751
6752 sofia_set_accept_language_channel_variable(channel, sip);
6753
6754 if (status > 199) {
6755 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_RESPONSE_HEADER_PREFIX"sip_rh_");
6756 } else {
6757 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_PROGRESS_HEADER_PREFIX"sip_ph_");
6758 }
6759
6760
6761 if (!(vval = switch_channel_get_variable(channel, "sip_copy_custom_headers")switch_channel_get_variable_dup(channel, "sip_copy_custom_headers"
, SWITCH_TRUE, -1)
) || switch_true(vval)) {
6762 switch_core_session_t *other_session;
6763
6764 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 6764)
== SWITCH_STATUS_SUCCESS) {
6765 if (status > 199) {
6766 switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_RESPONSE_HEADER_PREFIX_T"~sip_rh_");
6767 } else {
6768 switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_PROGRESS_HEADER_PREFIX_T"~sip_ph_");
6769 }
6770 switch_core_session_rwunlock(other_session);
6771 }
6772 }
6773 }
6774
6775 if ((status == 180 || status == 183 || status == 200)) {
6776 const char *x_freeswitch_support;
6777
6778 switch_channel_set_flag(channel, CF_MEDIA_ACK)switch_channel_set_flag_value(channel, CF_MEDIA_ACK, 1);
6779
6780 sofia_glue_store_session_id(session, profile, sip, 1);
6781
6782 if ((x_freeswitch_support = sofia_glue_get_unknown_header(sip, "X-FS-Support"))) {
6783 tech_pvt->x_freeswitch_support_remote = switch_core_session_strdup(session, x_freeswitch_support)switch_core_perform_session_strdup(session, x_freeswitch_support
, "sofia.c", (const char *)__func__, 6783)
;
6784 }
6785
6786 if (sip->sip_user_agent && sip->sip_user_agent->g_string) {
6787 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_user_agent->g_string)switch_channel_set_variable_var_check(channel, "sip_user_agent"
, sip->sip_user_agent->g_string, SWITCH_TRUE)
;
6788 } else if (sip->sip_server && sip->sip_server->g_string) {
6789 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_server->g_string)switch_channel_set_variable_var_check(channel, "sip_user_agent"
, sip->sip_server->g_string, SWITCH_TRUE)
;
6790 }
6791
6792 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_allow");
6793
6794 sofia_update_callee_id(session, profile, sip, SWITCH_FALSE);
6795
6796 if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)((tech_pvt->profile)->media_flags[SCMF_AUTOFIX_TIMING] ?
1 : 0)
) {
6797 switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
6798 }
6799
6800 }
6801
6802 if (channel && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
6803 sip_contact_t *p_contact = sip->sip_contact;
6804 int i = 0;
6805 char var_name[80];
6806 const char *diversion_header;
6807 char *full_contact = NULL((void*)0);
6808 char *invite_contact;
6809 const char *br;
6810 const char *v;
6811
6812 if ((v = switch_channel_get_variable(channel, "outbound_redirect_fatal")switch_channel_get_variable_dup(channel, "outbound_redirect_fatal"
, SWITCH_TRUE, -1)
) && switch_true(v)) {
6813 su_home_t *home = su_home_new(sizeof(*home));
6814 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6814, __extension__ __PRETTY_FUNCTION__))
;
6815
6816 for (p_contact = sip->sip_contact; p_contact; p_contact = p_contact->m_next) {
6817 full_contact = sip_header_as_string(home, (void *) p_contact);
6818 invite_contact = sofia_glue_strip_uri(full_contact);
6819
6820 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_%d", i);
6821 switch_channel_set_variable(channel, var_name, full_contact)switch_channel_set_variable_var_check(channel, var_name, full_contact
, SWITCH_TRUE)
;
6822
6823 if (i == 0) {
6824 switch_channel_set_variable(channel, "sip_redirected_to", full_contact)switch_channel_set_variable_var_check(channel, "sip_redirected_to"
, full_contact, SWITCH_TRUE)
;
6825 }
6826
6827 if (p_contact->m_url->url_user) {
6828 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_user_%d", i);
6829 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_user)switch_channel_set_variable_var_check(channel, var_name, p_contact
->m_url->url_user, SWITCH_TRUE)
;
6830 }
6831 if (p_contact->m_url->url_host) {
6832 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_host_%d", i);
6833 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_host)switch_channel_set_variable_var_check(channel, var_name, p_contact
->m_url->url_host, SWITCH_TRUE)
;
6834 }
6835 if (p_contact->m_url->url_params) {
6836 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_params_%d", i);
6837 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_params)switch_channel_set_variable_var_check(channel, var_name, p_contact
->m_url->url_params, SWITCH_TRUE)
;
6838 }
6839
6840 free(invite_contact);
6841 i++;
6842 }
6843 su_home_unref(home);
6844 home = NULL((void*)0);
6845 switch_snprintf(var_name, sizeof(var_name), "sip:%d", status);
6846 switch_channel_set_variable(channel, SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE, var_name)switch_channel_set_variable_var_check(channel, "proto_specific_hangup_cause"
, var_name, SWITCH_TRUE)
;
6847 switch_channel_hangup(channel, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6847, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL)
;
6848 goto end;
6849 }
6850
6851 if (!p_contact) {
6852 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6852, (const char*)(session)
, SWITCH_LOG_ERROR, "Missing contact header in redirect request\n");
6853 goto end;
6854 }
6855
6856 if ((br = switch_channel_get_partner_uuid(channel))) {
6857 switch_xml_t root = NULL((void*)0), domain = NULL((void*)0);
6858 switch_core_session_t *a_session;
6859 switch_channel_t *a_channel;
6860
6861 const char *sip_redirect_profile, *sip_redirect_context, *sip_redirect_dialplan, *sip_redirect_fork;
6862
6863 if ((a_session = switch_core_session_locate(br)switch_core_session_perform_locate(br, "sofia.c", (const char
*)__func__, 6863)
) && (a_channel = switch_core_session_get_channel(a_session))) {
6864 switch_stream_handle_t stream = { 0 };
6865 char separator[2] = "|";
6866 char *redirect_dialstring;
6867 su_home_t *home = su_home_new(sizeof(*home));
6868 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6868, __extension__ __PRETTY_FUNCTION__))
;
6869
6870 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 6870, __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
;
6871
6872 if (!(sip_redirect_profile = switch_channel_get_variable(channel, "sip_redirect_profile")switch_channel_get_variable_dup(channel, "sip_redirect_profile"
, SWITCH_TRUE, -1)
)) {
6873 sip_redirect_profile = profile->name;
6874 }
6875 if (!(sip_redirect_context = switch_channel_get_variable(channel, "sip_redirect_context")switch_channel_get_variable_dup(channel, "sip_redirect_context"
, SWITCH_TRUE, -1)
)) {
6876 sip_redirect_context = "redirected";
6877 }
6878 if (!(sip_redirect_dialplan = switch_channel_get_variable(channel, "sip_redirect_dialplan")switch_channel_get_variable_dup(channel, "sip_redirect_dialplan"
, SWITCH_TRUE, -1)
)) {
6879 sip_redirect_dialplan = "XML";
6880 }
6881
6882 sip_redirect_fork = switch_channel_get_variable(channel, "sip_redirect_fork")switch_channel_get_variable_dup(channel, "sip_redirect_fork",
SWITCH_TRUE, -1)
;
6883
6884 if (switch_true(sip_redirect_fork)) {
6885 *separator = ',';
6886 }
6887
6888 for (p_contact = sip->sip_contact; p_contact; p_contact = p_contact->m_next) {
6889 full_contact = sip_header_as_string(home, (void *) p_contact);
6890 invite_contact = sofia_glue_strip_uri(full_contact);
6891
6892 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_%d", i);
6893 switch_channel_set_variable(a_channel, var_name, full_contact)switch_channel_set_variable_var_check(a_channel, var_name, full_contact
, SWITCH_TRUE)
;
6894
6895 if (i == 0) {
6896 switch_channel_set_variable(channel, "sip_redirected_to", full_contact)switch_channel_set_variable_var_check(channel, "sip_redirected_to"
, full_contact, SWITCH_TRUE)
;
6897 switch_channel_set_variable(a_channel, "sip_redirected_to", full_contact)switch_channel_set_variable_var_check(a_channel, "sip_redirected_to"
, full_contact, SWITCH_TRUE)
;
6898 }
6899
6900 if (p_contact->m_url->url_user) {
6901 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_user_%d", i);
6902 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_user)switch_channel_set_variable_var_check(channel, var_name, p_contact
->m_url->url_user, SWITCH_TRUE)
;
6903 switch_channel_set_variable(a_channel, var_name, p_contact->m_url->url_user)switch_channel_set_variable_var_check(a_channel, var_name, p_contact
->m_url->url_user, SWITCH_TRUE)
;
6904 }
6905 if (p_contact->m_url->url_host) {
6906 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_host_%d", i);
6907 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_host)switch_channel_set_variable_var_check(channel, var_name, p_contact
->m_url->url_host, SWITCH_TRUE)
;
6908 switch_channel_set_variable(a_channel, var_name, p_contact->m_url->url_host)switch_channel_set_variable_var_check(a_channel, var_name, p_contact
->m_url->url_host, SWITCH_TRUE)
;
6909 }
6910 if (p_contact->m_url->url_params) {
6911 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_params_%d", i);
6912 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_params)switch_channel_set_variable_var_check(channel, var_name, p_contact
->m_url->url_params, SWITCH_TRUE)
;
6913 switch_channel_set_variable(a_channel, var_name, p_contact->m_url->url_params)switch_channel_set_variable_var_check(a_channel, var_name, p_contact
->m_url->url_params, SWITCH_TRUE)
;
6914 }
6915
6916 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_dialstring_%d", i);
6917 switch_channel_set_variable_printf(channel, var_name, "sofia/%s/%s", sip_redirect_profile, invite_contact);
6918 switch_channel_set_variable_printf(a_channel, var_name, "sofia/%s/%s", sip_redirect_profile, invite_contact);
6919 stream.write_function(&stream, "%ssofia/%s/%s", i ? separator : "", sip_redirect_profile, invite_contact);
6920 free(invite_contact);
6921 i++;
6922 }
6923
6924 redirect_dialstring = stream.data;
6925
6926 switch_channel_set_variable_printf(channel, "sip_redirect_count", "%d", i);
6927 switch_channel_set_variable(channel, "sip_redirect_dialstring", redirect_dialstring)switch_channel_set_variable_var_check(channel, "sip_redirect_dialstring"
, redirect_dialstring, SWITCH_TRUE)
;
6928 switch_channel_set_variable(a_channel, "sip_redirect_dialstring", redirect_dialstring)switch_channel_set_variable_var_check(a_channel, "sip_redirect_dialstring"
, redirect_dialstring, SWITCH_TRUE)
;
6929
6930 p_contact = sip->sip_contact;
6931 full_contact = sip_header_as_string(home, (void *) sip->sip_contact);
6932
6933 if ((diversion_header = sofia_glue_get_unknown_header(sip, "diversion"))) {
6934 switch_channel_set_variable(channel, "sip_redirected_by", diversion_header)switch_channel_set_variable_var_check(channel, "sip_redirected_by"
, diversion_header, SWITCH_TRUE)
;
6935 switch_channel_set_variable(a_channel, "sip_redirected_by", diversion_header)switch_channel_set_variable_var_check(a_channel, "sip_redirected_by"
, diversion_header, SWITCH_TRUE)
;
6936 }
6937
6938 if (sofia_test_pflag(profile, PFLAG_MANUAL_REDIRECT)((profile)->pflags[PFLAG_MANUAL_REDIRECT] ? 1 : 0)) {
6939 if (!(v = switch_channel_get_variable(channel, "outbound_redirect_info")switch_channel_get_variable_dup(channel, "outbound_redirect_info"
, SWITCH_TRUE, -1)
)) {
6940 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6940, (const char*)(session)
, SWITCH_LOG_DEBUG, "Redirect: Transfering to %s %s %s\n",
6941 p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
6942
6943 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
6944 switch_ivr_transfer_recordings(session, a_session);
6945 }
6946
6947 switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
6948 }
6949 switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6949, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION
)
;
6950 } else if( !p_contact->m_url->url_host ) {
6951 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6951, (const char*)(session)
, SWITCH_LOG_WARNING, "Received redirect with invalid URI\n");
6952 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "REDIRECT_ERROR")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "REDIRECT_ERROR", SWITCH_TRUE)
;
6953 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6953, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
6954 } else if ((!strcmp(profile->sipip, p_contact->m_url->url_host))
6955 || (profile->extsipip && !strcmp(profile->extsipip, p_contact->m_url->url_host))
6956 || (switch_xml_locate_domain(p_contact->m_url->url_host, NULL((void*)0), &root, &domain) == SWITCH_STATUS_SUCCESS)) {
6957 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6957, (const char*)(session)
, SWITCH_LOG_DEBUG, "Redirect: Transfering to %s\n",
6958 p_contact->m_url->url_user);
6959
6960 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
6961 switch_ivr_transfer_recordings(session, a_session);
6962 }
6963
6964 switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, NULL((void*)0), NULL((void*)0));
6965 switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6965, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION
)
;
6966 switch_xml_free(root);
6967 } else {
6968 invite_contact = sofia_glue_strip_uri(full_contact);
6969 tech_pvt->redirected = switch_core_session_strdup(session, invite_contact)switch_core_perform_session_strdup(session, invite_contact, "sofia.c"
, (const char *)__func__, 6969)
;
6970 free(invite_contact);
6971 }
6972
6973 su_home_unref(home);
6974 home = NULL((void*)0);
6975
6976 free(stream.data);
6977
6978 switch_core_session_rwunlock(a_session);
6979 }
6980 } else {
6981 su_home_t *home = su_home_new(sizeof(*home));
6982 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6982, __extension__ __PRETTY_FUNCTION__))
;
6983 full_contact = sip_header_as_string(home, (void *) sip->sip_contact);
6984 invite_contact = sofia_glue_strip_uri(full_contact);
6985
6986 switch_channel_set_variable(channel, "sip_redirected_to", invite_contact)switch_channel_set_variable_var_check(channel, "sip_redirected_to"
, invite_contact, SWITCH_TRUE)
;
6987 tech_pvt->redirected = switch_core_session_strdup(session, invite_contact)switch_core_perform_session_strdup(session, invite_contact, "sofia.c"
, (const char *)__func__, 6987)
;
6988
6989 free(invite_contact);
6990 su_home_unref(home);
6991 home = NULL((void*)0);
6992 }
6993 }
6994
6995
6996 if (sip->sip_payload && sip->sip_payload->pl_data && switch_stristr("m=image", sip->sip_payload->pl_data)) {
6997 has_t38 = 1;
6998 }
6999
7000 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7001 switch_channel_clear_flag(channel, CF_T38_PASSTHRU);
7002 has_t38 = 0;
7003 }
7004
7005 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && has_t38) {
7006 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
7007 switch_core_media_udptl_mode(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
7008
7009 if ((uuid = switch_channel_get_partner_uuid(channel)) && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 7009)
)) {
7010 if (switch_core_session_compare(session, other_session)) {
7011 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7012 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
7013 switch_core_media_udptl_mode(other_tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
7014 }
7015 }
7016 switch_core_session_rwunlock(other_session);
7017 }
7018 }
7019
7020 has_t38 = 0;
7021 }
7022
7023 if (status > 199 && (switch_channel_test_flag(channel, CF_PROXY_MODE) ||
7024 switch_channel_test_flag(channel, CF_PROXY_MEDIA) ||
7025 (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && (has_t38 || status > 299)))) {
7026
7027 if (sofia_test_flag(tech_pvt, TFLAG_SENT_UPDATE)((tech_pvt)->flags[TFLAG_SENT_UPDATE] ? 1 : 0)) {
7028 sofia_clear_flag_locked(tech_pvt, TFLAG_SENT_UPDATE)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_SENT_UPDATE] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7029
7030 if ((uuid = switch_channel_get_partner_uuid(channel)) && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 7030)
)) {
7031 const char *r_sdp = NULL((void*)0);
7032 switch_core_session_message_t *msg;
7033 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7034 //switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
7035
7036 if (sip->sip_payload && sip->sip_payload->pl_data &&
7037 sip->sip_content_type && sip->sip_content_type->c_subtype && switch_stristr("sdp", sip->sip_content_type->c_subtype)) {
7038 tech_pvt->mparams.remote_sdp_str = switch_core_session_strdup(tech_pvt->session, sip->sip_payload->pl_data)switch_core_perform_session_strdup(tech_pvt->session, sip->
sip_payload->pl_data, "sofia.c", (const char *)__func__, 7038
)
;
7039 r_sdp = tech_pvt->mparams.remote_sdp_str;
7040 switch_core_media_proxy_remote_addr(session, NULL((void*)0));
7041 }
7042
7043 if (status == 415) {
7044 int new_status = 488;
7045 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7045, (const char*)(session)
, SWITCH_LOG_DEBUG, "Overriding %d %s with %d\n", status, phrase, new_status);
7046 status = new_status;
7047 }
7048
7049 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7049, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n%s\n", status, phrase, switch_str_nil(r_sdp)(r_sdp ? r_sdp : ""));
7050
7051 if (switch_core_session_compare(session, other_session)) {
7052 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7053 sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK)(other_tech_pvt)->flags[TFLAG_PASS_ACK] = 1;
7054 }
7055
7056
7057 if (status == 491 && (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) ||
7058 switch_channel_test_flag(channel, CF_PROXY_MODE))) {
7059 nua_respond(other_tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending, TAG_END()(tag_type_t)0, (tag_value_t)0);
7060 switch_core_session_rwunlock(other_session);
7061 goto end;
7062 } else if (status > 299) {
7063 switch_core_media_reset_t38(session);
7064 switch_core_media_reset_t38(other_session);
7065 } else if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) &&
7066 has_t38 && sip->sip_payload && sip->sip_payload->pl_data) {
7067 switch_t38_options_t *t38_options = switch_core_media_extract_t38_options(session, sip->sip_payload->pl_data);
7068
7069 if (!t38_options) {
7070 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7070, (const char*)(session)
, SWITCH_LOG_WARNING, "Could not parse T.38 options from sdp.\n");
7071 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "T.38 NEGOTIATION ERROR")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "T.38 NEGOTIATION ERROR", SWITCH_TRUE)
;
7072 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7072, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7073 switch_core_session_rwunlock(other_session);
7074 goto end;
7075 } else {
7076 switch_core_media_process_t38_passthru(session, other_session, t38_options);
7077 }
7078 }
7079
7080
7081 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 7081)
;
7082 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
7083 msg->from = __FILE__"sofia.c";
7084 msg->numeric_arg = status;
7085 msg->string_arg = switch_core_session_strdup(other_session, phrase)switch_core_perform_session_strdup(other_session, phrase, "sofia.c"
, (const char *)__func__, 7085)
;
7086
7087 if (status == 200 && switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && has_t38) {
7088 msg->pointer_arg = switch_core_session_strdup(other_session, "t38")switch_core_perform_session_strdup(other_session, "t38", "sofia.c"
, (const char *)__func__, 7088)
;
7089 } else if (r_sdp) {
7090 msg->pointer_arg = switch_core_session_strdup(other_session, r_sdp)switch_core_perform_session_strdup(other_session, r_sdp, "sofia.c"
, (const char *)__func__, 7090)
;
7091 msg->pointer_arg_size = strlen(r_sdp);
7092 }
7093
7094 if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) && has_t38) {
7095 if (switch_core_media_ready(session, SWITCH_MEDIA_TYPE_AUDIO) &&
7096 switch_core_media_ready(other_session, SWITCH_MEDIA_TYPE_AUDIO)) {
7097 switch_channel_clear_flag(channel, CF_NOTIMER_DURING_BRIDGE);
7098 switch_core_media_udptl_mode(session, SWITCH_MEDIA_TYPE_AUDIO);
7099 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7099, (const char*)(session)
, SWITCH_LOG_INFO, "Activating T38 Passthru\n");
7100 }
7101 }
7102
7103 switch_core_session_queue_message(other_session, msg);
7104
7105 switch_core_session_rwunlock(other_session);
7106 }
7107 goto end;
7108 }
7109 }
7110
7111 if ((status == 180 || status == 183 || status == 200)) {
7112 const char *astate = "early";
7113 url_t *from = NULL((void*)0), *to = NULL((void*)0), *contact = NULL((void*)0);
7114
7115 if (sip->sip_to) {
7116 to = sip->sip_to->a_url;
7117 }
7118 if (sip->sip_from) {
7119 from = sip->sip_from->a_url;
7120 }
7121 if (sip->sip_contact) {
7122 contact = sip->sip_contact->m_url;
7123 }
7124
7125 if (status == 200) {
7126 astate = "confirmed";
7127 }
7128
7129 if ((!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED) &&
7130 !switch_channel_test_flag(channel, CF_RING_READY)) || switch_channel_test_flag(channel, CF_RECOVERING)) {
7131 const char *from_user = "", *from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
7132 const char *user_agent = "", *call_id = "";
7133 const char *to_tag = "";
7134 const char *from_tag = "";
7135 char *sql = NULL((void*)0);
7136
7137 if (sip->sip_user_agent) {
7138 user_agent = switch_str_nil(sip->sip_user_agent->g_string)(sip->sip_user_agent->g_string ? sip->sip_user_agent
->g_string : "")
;
7139 }
7140
7141 if (sip->sip_call_id) {
7142 call_id = switch_str_nil(sip->sip_call_id->i_id)(sip->sip_call_id->i_id ? sip->sip_call_id->i_id :
"")
;
7143 }
7144
7145 if (to) {
7146 from_user = switch_str_nil(to->url_user)(to->url_user ? to->url_user : "");
7147 from_tag = switch_str_nil(sip->sip_to->a_tag)(sip->sip_to->a_tag ? sip->sip_to->a_tag : "");
7148 }
7149
7150 if (from) {
7151 from_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
7152 to_user = switch_str_nil(from->url_user)(from->url_user ? from->url_user : "");
7153 to_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
7154 to_tag = switch_str_nil(sip->sip_from->a_tag)(sip->sip_from->a_tag ? sip->sip_from->a_tag : ""
)
;
7155 }
7156
7157 if (contact) {
7158 contact_user = switch_str_nil(contact->url_user)(contact->url_user ? contact->url_user : "");
7159 contact_host = switch_str_nil(contact->url_host)(contact->url_host ? contact->url_host : "");
7160 }
7161
7162 if (profile->pres_type) {
7163 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
7164 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
7165 char *full_contact = NULL((void*)0);
7166 char *p = NULL((void*)0);
7167 time_t now;
7168
7169 if (sip->sip_contact) {
7170 full_contact = sip_header_as_string(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), (void *) sip->sip_contact);
7171 }
7172
7173 if (call_info && (p = strchr(call_info, ';'))) {
7174 p++;
7175 }
7176
7177 now = switch_epoch_time_now(NULL((void*)0));
7178
7179 sql = switch_mprintf("insert into sip_dialogs "
7180 "(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
7181 "contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
7182 "call_info,rcd,call_info_state) "
7183 "values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
7184 call_id,
7185 switch_core_session_get_uuid(session),
7186 to_user, to_host, to_tag, from_user, from_host, from_tag, contact_user,
7187 contact_host, astate, "outbound", user_agent,
7188 profile->name, mod_sofia_globals.hostname, switch_str_nil(full_contact)(full_contact ? full_contact : ""),
7189 switch_str_nil(presence_id)(presence_id ? presence_id : ""), switch_str_nil(presence_data)(presence_data ? presence_data : ""), switch_str_nil(p)(p ? p : ""), (long) now);
7190 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 7190, __extension__
__PRETTY_FUNCTION__))
;
7191
7192 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7193
7194 if ( full_contact ) {
7195 su_free(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), full_contact);
7196 }
7197 }
7198 } else if (status == 200 && (profile->pres_type)) {
7199 char *sql = NULL((void*)0);
7200 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
7201 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
7202
7203 sql = switch_mprintf("update sip_dialogs set state='%q',presence_id='%q',presence_data='%q' "
7204 "where uuid='%q';\n", astate, switch_str_nil(presence_id)(presence_id ? presence_id : ""), switch_str_nil(presence_data)(presence_data ? presence_data : ""),
7205 switch_core_session_get_uuid(session));
7206 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 7206, __extension__
__PRETTY_FUNCTION__))
;
7207 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7208 }
7209
7210 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7211 switch_channel_set_variable(channel, "dlg_req_swap_direction", "true")switch_channel_set_variable_var_check(channel, "dlg_req_swap_direction"
, "true", SWITCH_TRUE)
;
7212 }
7213
7214 extract_header_vars(profile, sip, session, nh);
7215 extract_vars(profile, sip, session);
7216 switch_core_recovery_track(session);
7217 switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING);
7218 }
7219
7220 }
7221
7222 end:
7223
7224 if (call_info) {
7225 su_free(nua_handle_home(nh)((su_home_t *)(nh)), call_info);
7226 }
7227
7228 if (!session && (status == 180 || status == 183 || status == 200)) {
7229 /* nevermind */
7230 nua_handle_bind(nh, NULL((void*)0));
7231 nua_handle_destroy(nh);
7232 }
7233}
7234
7235/* Pure black magic, if you can't understand this code you are lucky.........*/
7236void *SWITCH_THREAD_FUNC media_on_hold_thread_run(switch_thread_t *thread, void *obj)
7237{
7238 switch_core_session_t *other_session = NULL((void*)0), *session = (switch_core_session_t *) obj;
7239 const char *uuid;
7240
7241 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
7242 switch_channel_t *channel = switch_core_session_get_channel(session);
7243 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
7244
7245 if ((uuid = switch_channel_get_partner_uuid(channel)) && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 7245)
)) {
7246 if (switch_core_session_compare(session, other_session)) {
7247 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
7248 sofia_set_flag_locked(tech_pvt, TFLAG_HOLD_LOCK)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 7248, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_HOLD_LOCK] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
7249
7250 switch_yield(250000)switch_sleep(250000);;
7251 switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
7252 switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
7253
7254 if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7255 switch_ivr_3p_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE|SMF_REPLYONLY_B);
7256 } else {
7257 switch_ivr_3p_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE);
7258 }
7259
7260
7261 switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
7262 switch_core_media_clear_rtp_flag(other_session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
7263
7264
7265 switch_core_media_toggle_hold(session, 1);
7266 }
7267 switch_core_session_rwunlock(other_session);
7268 }
7269
7270 switch_core_session_rwunlock(session);
7271 }
7272
7273 return NULL((void*)0);
7274}
7275
7276static void launch_media_on_hold(switch_core_session_t *session)
7277{
7278 switch_thread_t *thread;
7279 switch_threadattr_t *thd_attr = NULL((void*)0);
7280
7281 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
7282 switch_threadattr_detach_set(thd_attr, 1);
7283 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
7284 switch_thread_create(&thread, thd_attr, media_on_hold_thread_run, session, switch_core_session_get_pool(session));
7285}
7286
7287
7288
7289static void mark_transfer_record(switch_core_session_t *session, const char *br_a, const char *br_b)
7290{
7291 switch_core_session_t *br_b_session, *br_a_session;
7292 switch_channel_t *channel;
7293 const char *uvar1, *dvar1, *uvar2, *dvar2;
7294
7295 channel = switch_core_session_get_channel(session);
7296
7297 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7298 uvar1 = "sip_from_user";
7299 dvar1 = "sip_from_host";
7300 } else {
7301 uvar1 = "sip_to_user";
7302 dvar1 = "sip_to_host";
7303 }
7304
7305
7306 if ((br_b_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 7306)
) ) {
7307 switch_channel_t *br_b_channel = switch_core_session_get_channel(br_b_session);
7308 switch_caller_profile_t *cp = switch_channel_get_caller_profile(br_b_channel);
7309
7310 if (switch_channel_direction(br_b_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7311 uvar2 = "sip_from_user";
7312 dvar2 = "sip_from_host";
7313 } else {
7314 uvar2 = "sip_to_user";
7315 dvar2 = "sip_to_host";
7316 }
7317
7318 cp->transfer_source = switch_core_sprintf(cp->pool,
7319 "%ld:%s:att_xfer:%s@%s/%s@%s",
7320 (long) switch_epoch_time_now(NULL((void*)0)),
7321 cp->uuid_str,
7322 switch_channel_get_variable(channel, uvar1)switch_channel_get_variable_dup(channel, uvar1, SWITCH_TRUE, -
1)
,
7323 switch_channel_get_variable(channel, dvar1)switch_channel_get_variable_dup(channel, dvar1, SWITCH_TRUE, -
1)
,
7324 switch_channel_get_variable(br_b_channel, uvar2)switch_channel_get_variable_dup(br_b_channel, uvar2, SWITCH_TRUE
, -1)
,
7325 switch_channel_get_variable(br_b_channel, dvar2)switch_channel_get_variable_dup(br_b_channel, dvar2, SWITCH_TRUE
, -1)
);
7326
7327 switch_channel_add_variable_var_check(br_b_channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history", cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
7328 switch_channel_set_variable(br_b_channel, SWITCH_TRANSFER_SOURCE_VARIABLE, cp->transfer_source)switch_channel_set_variable_var_check(br_b_channel, "transfer_source"
, cp->transfer_source, SWITCH_TRUE)
;
7329
7330 switch_core_session_rwunlock(br_b_session);
7331 }
7332
7333
7334
7335 if ((br_a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 7335)
) ) {
7336 switch_channel_t *br_a_channel = switch_core_session_get_channel(br_a_session);
7337 switch_caller_profile_t *cp = switch_channel_get_caller_profile(br_a_channel);
7338
7339 if (switch_channel_direction(br_a_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7340 uvar2 = "sip_from_user";
7341 dvar2 = "sip_from_host";
7342 } else {
7343 uvar2 = "sip_to_user";
7344 dvar2 = "sip_to_host";
7345 }
7346
7347 cp->transfer_source = switch_core_sprintf(cp->pool,
7348 "%ld:%s:att_xfer:%s@%s/%s@%s",
7349 (long) switch_epoch_time_now(NULL((void*)0)),
7350 cp->uuid_str,
7351 switch_channel_get_variable(channel, uvar1)switch_channel_get_variable_dup(channel, uvar1, SWITCH_TRUE, -
1)
,
7352 switch_channel_get_variable(channel, dvar1)switch_channel_get_variable_dup(channel, dvar1, SWITCH_TRUE, -
1)
,
7353 switch_channel_get_variable(br_a_channel, uvar2)switch_channel_get_variable_dup(br_a_channel, uvar2, SWITCH_TRUE
, -1)
,
7354 switch_channel_get_variable(br_a_channel, dvar2)switch_channel_get_variable_dup(br_a_channel, dvar2, SWITCH_TRUE
, -1)
);
7355
7356 switch_channel_add_variable_var_check(br_a_channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history", cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
7357 switch_channel_set_variable(br_a_channel, SWITCH_TRANSFER_SOURCE_VARIABLE, cp->transfer_source)switch_channel_set_variable_var_check(br_a_channel, "transfer_source"
, cp->transfer_source, SWITCH_TRUE)
;
7358
7359 switch_core_session_rwunlock(br_a_session);
7360 }
7361
7362
7363}
7364
7365
7366static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
7367 char const *phrase,
7368 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
7369 sofia_dispatch_event_t *de,
7370 tagi_t tags[])
7371{
7372 const char *l_sdp = NULL((void*)0), *r_sdp = NULL((void*)0);
7373 int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
7374 int ss_state = nua_callstate_init;
7375 switch_channel_t *channel = NULL((void*)0);
7376 private_object_t *tech_pvt = NULL((void*)0);
7377 const char *replaces_str = NULL((void*)0);
7378 switch_core_session_t *other_session = NULL((void*)0);
7379 switch_channel_t *other_channel = NULL((void*)0);
7380 //private_object_t *other_tech_pvt = NULL;
7381 char st[80] = "";
7382 int is_dup_sdp = 0;
7383 switch_event_t *s_event = NULL((void*)0);
7384 char *p;
7385 char *patched_sdp = NULL((void*)0);
7386 const char *session_id_header = sofia_glue_session_id_header(session, profile);
7387
7388 tl_gets(tags,
7389 NUTAG_CALLSTATE_REF(ss_state)nutag_callstate_ref, tag_int_vr(&(ss_state)),
7390 NUTAG_OFFER_RECV_REF(offer_recv)nutag_offer_recv_ref, tag_bool_vr(&(offer_recv)),
7391 NUTAG_ANSWER_RECV_REF(answer_recv)nutag_answer_recv_ref, tag_bool_vr(&(answer_recv)),
7392 NUTAG_OFFER_SENT_REF(offer_sent)nutag_offer_sent_ref, tag_bool_vr(&(offer_sent)),
7393 NUTAG_ANSWER_SENT_REF(answer_sent)nutag_answer_sent_ref, tag_bool_vr(&(answer_sent)),
7394 SIPTAG_REPLACES_STR_REF(replaces_str)siptag_replaces_str_ref, tag_str_vr(&(replaces_str)), SOATAG_LOCAL_SDP_STR_REF(l_sdp)soatag_local_sdp_str_ref, tag_str_vr(&(l_sdp)), SOATAG_REMOTE_SDP_STR_REF(r_sdp)soatag_remote_sdp_str_ref, tag_str_vr(&(r_sdp)), TAG_END()(tag_type_t)0, (tag_value_t)0);
7395
7396 if (session) {
7397 channel = switch_core_session_get_channel(session);
7398 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
7399
7400 if (!tech_pvt || !tech_pvt->nh) {
7401 goto done;
7402 }
7403
7404 if (!r_sdp && (status == 100 || status == 200)) {
7405 if (ss_state == nua_callstate_completing) {
7406 if (tech_pvt->mparams.last_sdp_response) {
7407 r_sdp = tech_pvt->mparams.last_sdp_response;
7408 }
7409 } else if (ss_state == nua_callstate_received || ss_state == nua_callstate_ready) {
7410 if (tech_pvt->mparams.last_sdp_str) {
7411 r_sdp = tech_pvt->mparams.last_sdp_str;
7412 }
7413 }
7414 }
7415
7416 if (tech_pvt->mparams.last_sdp_str) {
7417 tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
7418 }
7419
7420 if (tech_pvt->mparams.last_sdp_response) {
7421 tech_pvt->mparams.prev_sdp_response = tech_pvt->mparams.last_sdp_response;
7422 }
7423
7424 tech_pvt->mparams.last_sdp_str = NULL((void*)0);
7425 tech_pvt->mparams.last_sdp_response = NULL((void*)0);
7426
7427 if (r_sdp && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) {
7428 const char *var;
7429
7430 if ((var = switch_channel_get_variable(channel, "bypass_media_sdp_filter")switch_channel_get_variable_dup(channel, "bypass_media_sdp_filter"
, SWITCH_TRUE, -1)
)) {
7431 if ((patched_sdp = switch_core_media_process_sdp_filter(r_sdp, var, session))) {
7432 r_sdp = patched_sdp;
7433 }
7434 }
7435 }
7436
7437 if ((switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) ||
7438 (sofia_test_flag(profile, TFLAG_INB_NOMEDIA)((profile)->flags[TFLAG_INB_NOMEDIA] ? 1 : 0) || sofia_test_flag(profile, TFLAG_PROXY_MEDIA)((profile)->flags[TFLAG_PROXY_MEDIA] ? 1 : 0))) {
7439
7440 /* This marr in our code brought to you by people who can't read........ */
7441 if (profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME && r_sdp && (p = (char *) switch_stristr("g729a/8000", r_sdp))) {
7442 p += 4;
7443 *p++ = '/';
7444 *p++ = '8';
7445 *p++ = '0';
7446 *p++ = '0';
7447 *p++ = '0';
7448 *p++ = ' ';
7449 }
7450 }
7451 }
7452
7453
7454 if (ss_state == nua_callstate_terminated) {
7455
7456 if ((status == 300 || status == 301 || status == 302 || status == 305) && session) {
7457 channel = switch_core_session_get_channel(session);
7458 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
7459
7460 if (!tech_pvt || !tech_pvt->nh) {
7461 goto done;
7462 }
7463
7464
7465 if (tech_pvt->redirected) {
7466 sofia_glue_do_invite(session);
7467 goto done;
7468 }
7469 }
7470
7471 if (sofia_private) {
7472 sofia_private->destroy_me = 1;
7473 }
7474 }
7475
7476 if (session) {
7477 if ((switch_channel_test_flag(channel, CF_ANSWERED) && (status == 180 || status == 183) && !r_sdp) || (ss_state == nua_callstate_ready && status >= 300)) {
7478 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7478, (const char*)(session)
, SWITCH_LOG_DEBUG, "Channel %s skipping state [%s][%d]\n",
7479 switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
7480 goto done;
7481 } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (status == 180 || status == 183) && r_sdp) {
7482 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
7483 }
7484
7485 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7485, (const char*)(session)
, SWITCH_LOG_DEBUG, "Channel %s entering state [%s][%d]\n",
7486 switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
7487
7488 if (r_sdp) {
7489 switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp)switch_channel_set_variable_var_check(channel, "switch_r_sdp"
, r_sdp, SWITCH_TRUE)
;
7490
7491 if (!(profile->mndlb & SM_NDLB_ALLOW_NONDUP_SDP) || (!zstr(tech_pvt->mparams.remote_sdp_str)_zstr(tech_pvt->mparams.remote_sdp_str) && !strcmp(tech_pvt->mparams.remote_sdp_str, r_sdp))) {
7492 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7492, (const char*)(session)
, SWITCH_LOG_DEBUG, "Duplicate SDP\n%s\n", r_sdp);
7493 is_dup_sdp = 1;
7494 } else {
7495 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7495, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
7496 tech_pvt->mparams.remote_sdp_str = switch_core_session_strdup(session, r_sdp)switch_core_perform_session_strdup(session, r_sdp, "sofia.c",
(const char *)__func__, 7496)
;
7497 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && status < 200) {
7498 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 7498)
;
7499 }
7500 //if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
7501 // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE);
7502 //}
7503 switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
7504 sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
7505 sofia_set_flag(tech_pvt, TFLAG_NEW_SDP)(tech_pvt)->flags[TFLAG_NEW_SDP] = 1;
7506
7507 }
7508 }
7509 }
7510
7511 if (status == 988) {
7512 goto done;
7513 }
7514
7515 if (status == 183 && !r_sdp) {
7516 if ((channel && switch_true(switch_channel_get_variable(channel, "sip_ignore_183nosdp")switch_channel_get_variable_dup(channel, "sip_ignore_183nosdp"
, SWITCH_TRUE, -1)
)) || sofia_test_pflag(profile, PFLAG_IGNORE_183NOSDP)((profile)->pflags[PFLAG_IGNORE_183NOSDP] ? 1 : 0)) {
7517 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7517, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s Ignoring 183 w/o sdp\n", channel ? switch_channel_get_name(channel) : "None");
7518 goto done;
7519 }
7520 status = 180;
7521 }
7522
7523 if (status == 180 && r_sdp) {
7524 status = 183;
7525 }
7526
7527 if (channel && profile->pres_type && ss_state == nua_callstate_ready && status == 200) {
7528 const char* to_tag = "";
7529 char *sql = NULL((void*)0);
7530 to_tag = switch_str_nil(switch_channel_get_variable(channel, "sip_to_tag"))(switch_channel_get_variable_dup(channel, "sip_to_tag", SWITCH_TRUE
, -1) ? switch_channel_get_variable_dup(channel, "sip_to_tag"
, SWITCH_TRUE, -1) : "")
;
7531 sql = switch_mprintf("update sip_dialogs set sip_to_tag='%q' "
7532 "where uuid='%q' and sip_to_tag = ''", to_tag, switch_core_session_get_uuid(session));
7533
7534 if (mod_sofia_globals.debug_presence > 1) {
7535 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 7535
, ((void*)0)
, SWITCH_LOG_DEBUG, "QUERY SQL %s\n", sql);
7536 }
7537 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7538 }
7539
7540 if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
7541 const char *full_to = NULL((void*)0);
7542 const char *var;
7543 if ((var = switch_channel_get_variable(channel, "sip_auto_answer")switch_channel_get_variable_dup(channel, "sip_auto_answer", SWITCH_TRUE
, -1)
) && switch_true(var) &&
7544 !((var = switch_channel_get_variable(channel, "sip_auto_answer_suppress_notify")switch_channel_get_variable_dup(channel, "sip_auto_answer_suppress_notify"
, SWITCH_TRUE, -1)
) && switch_true(var))) {
7545 full_to = switch_str_nil(switch_channel_get_variable(channel, "sip_full_to"))(switch_channel_get_variable_dup(channel, "sip_full_to", SWITCH_TRUE
, -1) ? switch_channel_get_variable_dup(channel, "sip_full_to"
, SWITCH_TRUE, -1) : "")
;
7546
7547 nua_notify(nh,
7548 NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1),
7549 NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
7550 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
7551 TAG_IF((full_to), SIPTAG_TO_STR(full_to))!((full_to)) ? tag_skip : siptag_to_str, tag_str_v(full_to),
7552 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
7553 SIPTAG_EVENT_STR("talk")siptag_event_str, tag_str_v("talk"),
7554 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))
,
7555 TAG_END()(tag_type_t)0, (tag_value_t)0);
7556 }
7557 }
7558
7559
7560
7561 state_process:
7562
7563 switch ((enum nua_callstate) ss_state) {
7564 case nua_callstate_terminated:
7565 case nua_callstate_terminating:
7566 case nua_callstate_ready:
7567 case nua_callstate_completed:
7568 case nua_callstate_received:
7569 case nua_callstate_proceeding:
7570 case nua_callstate_completing:
7571 case nua_callstate_calling:
7572 if (!(session && channel && tech_pvt))
7573 goto done;
7574 default:
7575 break;
7576 }
7577
7578 switch ((enum nua_callstate) ss_state) {
7579 case nua_callstate_init:
7580 break;
7581 case nua_callstate_authenticating:
7582 break;
7583 case nua_callstate_calling:
7584 tech_pvt->sent_last_invite = 1;
7585 tech_pvt->sent_invites++;
7586 break;
7587 case nua_callstate_proceeding:
7588
7589 if (sofia_test_flag(tech_pvt, TFLAG_SKIP_EARLY)((tech_pvt)->flags[TFLAG_SKIP_EARLY] ? 1 : 0)) {
7590 sofia_clear_flag_locked(tech_pvt, TFLAG_SKIP_EARLY)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_SKIP_EARLY] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7591 goto done;
7592 }
7593
7594 switch (status) {
7595 case 180:
7596 switch_channel_mark_ring_ready(channel)switch_channel_perform_mark_ring_ready_value(channel, SWITCH_RING_READY_RINGING
, "sofia.c", (const char *)__func__, 7596)
;
7597 break;
7598 case 182:
7599 switch_channel_mark_ring_ready_value(channel, SWITCH_RING_READY_QUEUED)switch_channel_perform_mark_ring_ready_value(channel, SWITCH_RING_READY_QUEUED
, "sofia.c", (const char *)__func__, 7599)
;
7600 break;
7601 default:
7602 break;
7603 }
7604
7605 if (r_sdp) {
7606 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7607 char ibuf[35] = "", pbuf[35] = "";
7608 const char *ptr;
7609
7610 if ((ptr = switch_stristr("c=IN IP4", r_sdp))) {
7611 int i = 0;
7612
7613 ptr += 8;
7614
7615 while(*ptr == ' ') {
7616 ptr++;
7617 }
7618 while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
7619 ibuf[i++] = *ptr++;
7620 }
7621
7622 switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, ibuf)switch_channel_set_variable_var_check(channel, "remote_media_ip"
, ibuf, SWITCH_TRUE)
;
7623 }
7624
7625 if ((ptr = switch_stristr("m=audio", r_sdp))) {
7626 int i = 0;
7627
7628 ptr += 7;
7629
7630 while(*ptr == ' ') {
7631 ptr++;
7632 }
7633 while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
7634 pbuf[i++] = *ptr++;
7635 }
7636
7637 switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, pbuf)switch_channel_set_variable_var_check(channel, "remote_media_port"
, pbuf, SWITCH_TRUE)
;
7638 }
7639
7640 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7641 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
7642 }
7643 sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 7643, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_EARLY_MEDIA] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
7644 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 7644)
;
7645 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7646 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) || switch_channel_test_flag(channel, CF_REINVITE)) {
7647 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7648 goto done;
7649 }
7650 }
7651 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7651)
== SWITCH_STATUS_SUCCESS) {
7652 other_channel = switch_core_session_get_channel(other_session);
7653 switch_channel_pass_sdp(channel, other_channel, r_sdp);
7654
7655 //switch_channel_pre_answer(other_channel);
7656 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_PROGRESS);
7657 switch_core_session_rwunlock(other_session);
7658 }
7659 goto done;
7660 } else {
7661 if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)((tech_pvt)->flags[TFLAG_LATE_NEGOTIATION] ? 1 : 0) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7662 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "DELAYED NEGOTIATION", SWITCH_TRUE)
;
7663 } else if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7664 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
7665 switch_core_media_patch_sdp(tech_pvt->session);
7666 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7667 nua_respond(nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
7668 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
7669 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7669, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7670 } else{
7671 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 7671)
;
7672 }
7673
7674 } else {
7675 if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
7676 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "CODEC NEGOTIATION ERROR", SWITCH_TRUE)
;
7677 nua_respond(nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
7678 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))
,TAG_END()(tag_type_t)0, (tag_value_t)0);
7679 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7679, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7680 }
7681 }
7682 goto done;
7683 }
7684 }
7685 break;
7686 case nua_callstate_completing:
7687 {
7688 int send_ack = 1;
7689
7690 if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
7691 const char *wait_for_ack = switch_channel_get_variable(channel, "sip_wait_for_aleg_ack")switch_channel_get_variable_dup(channel, "sip_wait_for_aleg_ack"
, SWITCH_TRUE, -1)
;
7692
7693 if (switch_true(wait_for_ack)) {
7694 switch_core_session_t *other_session;
7695
7696 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7696)
== SWITCH_STATUS_SUCCESS) {
7697 if (switch_core_session_compare(session, other_session)) {
7698 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7699
7700 if (!sofia_test_flag(tech_pvt, TFLAG_3PCC)((tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0) && !sofia_test_flag(other_tech_pvt, TFLAG_3PCC)((other_tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0)) {
7701 sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK)(other_tech_pvt)->flags[TFLAG_PASS_ACK] = 1;
7702 send_ack = 0;
7703 }
7704 }
7705 switch_core_session_rwunlock(other_session);
7706 }
7707 }
7708 }
7709
7710 if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED)) {
7711 if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG)) {
7712 switch_core_session_t *other_session;
7713
7714 switch_channel_clear_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG);
7715
7716 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7716)
== SWITCH_STATUS_SUCCESS) {
7717 if (switch_core_session_compare(session, other_session)) {
7718 //switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
7719 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7720
7721 sofia_glue_clear_soa(other_session, SWITCH_TRUE);
7722
7723 if (sofia_use_soa(other_tech_pvt)((other_tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
7724 nua_ack(other_tech_pvt->nh,
7725 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via))!(!_zstr(other_tech_pvt->user_via)) ? tag_skip : siptag_via_str
, tag_str_v(other_tech_pvt->user_via)
,
7726 SIPTAG_CONTACT_STR(other_tech_pvt->reply_contact)siptag_contact_str, tag_str_v(other_tech_pvt->reply_contact
)
,
7727 SOATAG_USER_SDP_STR(r_sdp)soatag_user_sdp_str, tag_str_v(r_sdp),
7728 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
7729 SOATAG_RTP_SELECT(1)soatag_rtp_select, tag_int_v(1),
7730 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7731 TAG_IF(sofia_test_pflag(other_tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1))!(((other_tech_pvt->profile)->pflags[PFLAG_DISABLE_100REL
] ? 1 : 0)) ? tag_skip : nutag_include_extra_sdp, tag_bool_v(
1)
,
7732 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))
,
7733 TAG_END()(tag_type_t)0, (tag_value_t)0);
7734 } else {
7735 nua_ack(other_tech_pvt->nh,
7736 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
7737 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via))!(!_zstr(other_tech_pvt->user_via)) ? tag_skip : siptag_via_str
, tag_str_v(other_tech_pvt->user_via)
,
7738 SIPTAG_CONTACT_STR(other_tech_pvt->reply_contact)siptag_contact_str, tag_str_v(other_tech_pvt->reply_contact
)
,
7739 TAG_IF(r_sdp, SIPTAG_CONTENT_TYPE_STR("application/sdp"))!(r_sdp) ? tag_skip : siptag_content_type_str, tag_str_v("application/sdp"
)
,
7740 TAG_IF(r_sdp, SIPTAG_PAYLOAD_STR(r_sdp))!(r_sdp) ? tag_skip : siptag_payload_str, tag_str_v(r_sdp),
7741 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7742 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))
,
7743 TAG_END()(tag_type_t)0, (tag_value_t)0);
7744 }
7745
7746 nua_ack(tech_pvt->nh,
7747 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)
,
7748 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7749 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))
,
7750 TAG_END()(tag_type_t)0, (tag_value_t)0);
7751
7752 }
7753 switch_core_session_rwunlock(other_session);
7754 }
7755 } else {
7756 switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp)switch_channel_set_variable_var_check(channel, "switch_r_sdp"
, r_sdp, SWITCH_TRUE)
;
7757 }
7758
7759 switch_channel_clear_flag(channel, CF_3P_NOMEDIA_REQUESTED);
7760 goto done;
7761
7762 } else if (switch_channel_test_flag(channel, CF_3P_MEDIA_REQUESTED)) {
7763 uint8_t match = 0;
7764
7765 switch_channel_clear_flag(channel, CF_PROXY_MODE);
7766
7767 switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
7768 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
7769
7770 if (tech_pvt->mparams.num_codecs) {
7771 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
7772 }
7773
7774 if (!match) {
7775 if (switch_channel_get_state(channel) != CS_NEW) {
7776 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
7777 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))
,TAG_END()(tag_type_t)0, (tag_value_t)0);
7778 }
7779 } else {
7780 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
7781 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED", SWITCH_TRUE)
;
7782 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 7782, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7783
7784 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7785 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7785, (const char*)(session)
, SWITCH_LOG_DEBUG, "RESTABLISH MEDIA SDP:\n%s\n", tech_pvt->mparams.local_sdp_str);
7786
7787 switch_channel_set_flag(channel, CF_REQ_MEDIA)switch_channel_set_flag_value(channel, CF_REQ_MEDIA, 1);
7788 switch_channel_set_flag(channel, CF_MEDIA_ACK)switch_channel_set_flag_value(channel, CF_MEDIA_ACK, 1);
7789 switch_channel_set_flag(channel, CF_MEDIA_SET)switch_channel_set_flag_value(channel, CF_MEDIA_SET, 1);
7790
7791 switch_core_media_activate_rtp(session);
7792
7793
7794 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
7795 nua_ack(tech_pvt->nh,
7796 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)
,
7797 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7798 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
7799 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
7800 SOATAG_RTP_SELECT(1)soatag_rtp_select, tag_int_v(1),
7801 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7802 TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1))!(((tech_pvt->profile)->pflags[PFLAG_DISABLE_100REL] ? 1
: 0)) ? tag_skip : nutag_include_extra_sdp, tag_bool_v(1)
,
7803 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))
,
7804 TAG_END()(tag_type_t)0, (tag_value_t)0);
7805 } else {
7806 nua_ack(tech_pvt->nh,
7807 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
7808 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)
,
7809 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7810 TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp"))!(tech_pvt->mparams.local_sdp_str) ? tag_skip : siptag_content_type_str
, tag_str_v("application/sdp")
,
7811 TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str))!(tech_pvt->mparams.local_sdp_str) ? tag_skip : siptag_payload_str
, tag_str_v(tech_pvt->mparams.local_sdp_str)
,
7812 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7813 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))
,
7814 TAG_END()(tag_type_t)0, (tag_value_t)0);
7815 }
7816
7817 switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED);
7818 goto done;
7819 }
7820
7821 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "NO CODECS", SWITCH_TRUE)
;
7822 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7822, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7823
7824 switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED);
7825 goto done;
7826 //ss_state = nua_callstate_ready;
7827 //goto state_process;
7828 }
7829
7830 if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE)((tech_pvt)->flags[TFLAG_3PCC_INVITE] ? 1 : 0) && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
7831 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7832 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7832)
== SWITCH_STATUS_SUCCESS) {
7833 other_channel = switch_core_session_get_channel(other_session);
7834 //other_tech_pvt = switch_core_session_get_private(other_session);
7835
7836 switch_channel_pass_sdp(channel, other_channel, r_sdp);
7837 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
7838 switch_core_session_rwunlock(other_session);
7839 }
7840 goto done;
7841
7842 }
7843
7844 if (send_ack) {
7845 tech_send_ack(nh, tech_pvt, NULL((void*)0));
7846 } else {
7847 ss_state = nua_callstate_ready;
7848 goto state_process;
7849 }
7850
7851 }
7852 goto done;
7853 case nua_callstate_received:
7854 tech_pvt->recv_invites++;
7855 tech_pvt->sent_last_invite = 0;
7856
7857 if (!sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
7858 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7858)
== SWITCH_STATUS_SUCCESS) {
7859 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7860 int r = sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)((other_tech_pvt)->flags[TFLAG_REINVITED] ? 1 : 0);
7861 switch_core_session_rwunlock(other_session);
7862
7863 if (r) {
7864 /* Due to a race between simultaneous reinvites to both legs of a bridge,
7865 an earlier call to nua_invite silently failed.
7866 So we reject the incoming invite with a 491 and redo the failed outgoing invite. */
7867
7868 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7868, (const char*)(session)
, SWITCH_LOG_DEBUG,
7869 "Other leg already handling a reinvite, so responding with 491\n");
7870
7871 nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending,
7872 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
7873 sofia_glue_do_invite(session);
7874 goto done;
7875 }
7876 }
7877
7878
7879 if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
7880 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7881 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOMEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOMEDIA", SWITCH_TRUE)
;
7882 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 7882, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7883 if (switch_channel_get_state(channel) == CS_NEW) {
7884 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7884, CS_INIT)
;
7885 }
7886 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7887 goto done;
7888 } else if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
7889 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
7890 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 7890, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7891 if (switch_channel_get_state(channel) == CS_NEW) {
7892 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7892, CS_INIT)
;
7893 }
7894 } else if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)((tech_pvt)->flags[TFLAG_LATE_NEGOTIATION] ? 1 : 0)) {
7895 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "DELAYED NEGOTIATION", SWITCH_TRUE)
;
7896 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 7896, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7897 if (switch_channel_get_state(channel) == CS_NEW) {
7898 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7898, CS_INIT)
;
7899 }
7900 } else {
7901 uint8_t match = 0;
7902
7903 if (tech_pvt->mparams.num_codecs) {
7904 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
7905 }
7906
7907 if (!match) {
7908 if (switch_channel_get_state(channel) != CS_NEW) {
7909 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable, TAG_END()(tag_type_t)0, (tag_value_t)0);
7910 }
7911 } else {
7912 nua_handle_t *bnh;
7913 sip_replaces_t *replaces;
7914 su_home_t *home = NULL((void*)0);
7915 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED", SWITCH_TRUE)
;
7916 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 7916, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7917
7918 if (switch_channel_get_state(channel) == CS_NEW) {
7919 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7919, CS_INIT)
;
7920 } else {
7921 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
7922 }
7923 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7924 if (replaces_str) {
7925 home = su_home_new(sizeof(*home));
7926 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 7926, __extension__ __PRETTY_FUNCTION__))
;
7927 if ((replaces = sip_replaces_make(home, replaces_str))
7928 && (bnh = nua_handle_by_replaces(nua, replaces))) {
7929 sofia_private_t *b_private;
7930
7931 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7931, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing Replaces Attended Transfer\n");
7932 while (switch_channel_get_state(channel) < CS_EXECUTE) {
7933 switch_yield(10000)switch_sleep(10000);;
7934 }
7935
7936 if ((b_private = nua_handle_magic(bnh))) {
7937 const char *br_b = switch_channel_get_partner_uuid(channel);
7938 char *br_a = b_private->uuid;
7939
7940
7941 if (br_b) {
7942 switch_core_session_t *tmp;
7943
7944 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
) &&
7945 (tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 7945)
)) {
7946 switch_ivr_transfer_recordings(session, tmp);
7947 switch_core_session_rwunlock(tmp);
7948 }
7949
7950 switch_channel_set_variable_printf(channel, "transfer_to", "att:%s", br_b);
7951
7952 mark_transfer_record(session, br_a, br_b);
7953 switch_ivr_uuid_bridge(br_a, br_b);
7954 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "ATTENDED_TRANSFER", SWITCH_TRUE)
;
7955 sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_SIP_HOLD] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7956 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
7957 sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_HOLD_LOCK] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7958 switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7958, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
7959 } else {
7960 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "ATTENDED_TRANSFER_ERROR", SWITCH_TRUE)
;
7961 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7961, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7962 }
7963 } else {
7964 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "ATTENDED_TRANSFER_ERROR", SWITCH_TRUE)
;
7965 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7965, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7966 }
7967 nua_handle_unref_user(bnh);
7968 }
7969 su_home_unref(home);
7970 home = NULL((void*)0);
7971 }
7972
7973 goto done;
7974 }
7975
7976 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "NO CODECS", SWITCH_TRUE)
;
7977 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7977, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7978 }
7979 } else {
7980 if (sofia_test_pflag(profile, PFLAG_3PCC)((profile)->pflags[PFLAG_3PCC] ? 1 : 0)) {
7981 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7982 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7982, (const char*)(session)
, SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc=yes cannot work with bypass or proxy media, hanging up.\n");
7983 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "3PCC DISABLED", SWITCH_TRUE)
;
7984 switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7984, SWITCH_CAUSE_MANDATORY_IE_MISSING)
;
7985 } else {
7986 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOSDP", SWITCH_TRUE)
;
7987 switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
7988 switch_core_media_prepare_codecs(session, 1);
7989 switch_channel_set_state(channel, CS_HIBERNATE)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7989, CS_HIBERNATE)
;
7990 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL((void*)0), 0, NULL((void*)0), 0);
7991 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 7991, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7992
7993 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
7994 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
7995 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7996 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
7997 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
7998 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7999 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1))!(((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0)) ? tag_skip
: nutag_include_extra_sdp, tag_bool_v(1)
,
8000 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))
,
8001 TAG_END()(tag_type_t)0, (tag_value_t)0);
8002 } else {
8003 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8004 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8005 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8006 SIPTAG_CONTENT_TYPE_STR("application/sdp")siptag_content_type_str, tag_str_v("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)siptag_payload_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8007 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))
,
8008 TAG_END()(tag_type_t)0, (tag_value_t)0);
8009 }
8010 }
8011 } else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
8012 //3PCC proxy mode delays the 200 OK until the call is answered
8013 // so can be made to work with bypass media as we have time to find out what the other end thinks codec offer should be...
8014 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOSDP", SWITCH_TRUE)
;
8015 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8015, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8016 //switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
8017 //switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
8018 sofia_set_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)(tech_pvt)->flags[TFLAG_LATE_NEGOTIATION] = 1;
8019 //Moves into CS_INIT so call moves forward into the dialplan
8020 if (switch_channel_get_state(channel) == CS_NEW) {
8021 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 8021, CS_INIT)
;
8022 }
8023 } else {
8024 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8024, (const char*)(session)
, SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc not enabled, hanging up.\n");
8025 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "3PCC DISABLED", SWITCH_TRUE)
;
8026 switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8026, SWITCH_CAUSE_MANDATORY_IE_MISSING)
;
8027 }
8028 goto done;
8029 }
8030
8031 } else if (tech_pvt && sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0) && !r_sdp) {
8032 sofia_set_flag_locked(tech_pvt, TFLAG_NOSDP_REINVITE)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8032, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_NOSDP_REINVITE] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
8033 if ((switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
8034 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8034, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8035 sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA)(tech_pvt)->flags[TFLAG_ENABLE_SOA] = 0;
8036
8037 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8037)
== SWITCH_STATUS_SUCCESS) {
8038 switch_core_session_message_t *msg;
8039 if (switch_core_session_compare(session, other_session)) {
8040 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
8041 sofia_clear_flag(other_tech_pvt, TFLAG_ENABLE_SOA)(other_tech_pvt)->flags[TFLAG_ENABLE_SOA] = 0;
8042 }
8043
8044 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8044)
;
8045 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
8046 msg->from = __FILE__"sofia.c";
8047 msg->string_arg = NULL((void*)0);
8048 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8048, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing NOSDP to other leg.\n");
8049 switch_core_session_queue_message(other_session, msg);
8050 switch_core_session_rwunlock(other_session);
8051 } else {
8052 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8052, (const char*)(session)
, SWITCH_LOG_WARNING,
8053 "NOSDP Re-INVITE to a proxy mode channel that is not in a bridge.\n");
8054 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8054, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8055 }
8056 goto done;
8057 }
8058
8059 if (switch_channel_var_true(channel, "sip_unhold_nosdp")) {
8060 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, "sendrecv",
8061 zstr(tech_pvt->mparams.local_sdp_str)_zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
8062 } else {
8063 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0),
8064 zstr(tech_pvt->mparams.local_sdp_str)_zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
8065 }
8066
8067 if (zstr(tech_pvt->mparams.local_sdp_str)_zstr(tech_pvt->mparams.local_sdp_str)) {
8068 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8068, (const char*)(session)
, SWITCH_LOG_WARNING, "Cannot find a SDP\n");
8069 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8069, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8070 } else {
8071 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
8072 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8073 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8074 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8075 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8076 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8077 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1))!(((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0)) ? tag_skip
: nutag_include_extra_sdp, tag_bool_v(1)
,
8078 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))
,
8079 TAG_END()(tag_type_t)0, (tag_value_t)0);
8080 } else {
8081 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8082 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8083 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8084 SIPTAG_CONTENT_TYPE_STR("application/sdp")siptag_content_type_str, tag_str_v("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)siptag_payload_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8085 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))
,
8086 TAG_END()(tag_type_t)0, (tag_value_t)0);
8087 }
8088 }
8089
8090 goto done;
8091
8092 } else {
8093 ss_state = nua_callstate_completed;
8094 goto state_process;
8095 }
8096
8097 break;
8098 case nua_callstate_early:
8099 if (answer_recv) {
8100 uint8_t match = 0;
8101 switch_assert(tech_pvt)((tech_pvt) ? (void) (0) : __assert_fail ("tech_pvt", "sofia.c"
, 8101, __extension__ __PRETTY_FUNCTION__))
;
8102 sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8102, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_EARLY_MEDIA] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
8103 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 8103)
;
8104 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
8105
8106
8107 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8108 if (match) {
8109 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8110 goto done;
8111 }
8112
8113 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8114
8115 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8116 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8116, (const char*)(session)
, SWITCH_LOG_ERROR, "Early Media RTP Error!\n");
8117 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8117, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8118 }
8119 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8119, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
8120 } else {
8121 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8121, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8122 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8122, (const char*)(session)
, SWITCH_LOG_ERROR, "Early Media Codec Error!\n");
8123 }
8124 }
8125 break;
8126 case nua_callstate_completed:
8127 if (r_sdp) {
8128 const char *var;
8129 uint8_t match = 0, is_ok = 1, is_t38 = 0;
8130
8131 tech_pvt->mparams.hold_laps = 0;
8132
8133 if ((var = switch_channel_get_variable(channel, "sip_ignore_reinvites")switch_channel_get_variable_dup(channel, "sip_ignore_reinvites"
, SWITCH_TRUE, -1)
) && switch_true(var)) {
8134 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8134, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ignoring Re-invite\n");
8135 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
8136 goto done;
8137 }
8138
8139 if (switch_stristr("m=image", r_sdp)) {
8140 is_t38 = 1;
8141 }
8142
8143
8144 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8145 if ((sofia_test_media_flag(profile, SCMF_DISABLE_HOLD)((profile)->media_flags[SCMF_DISABLE_HOLD] ? 1 : 0)
8146 || ((var = switch_channel_get_variable(channel, "rtp_disable_hold")switch_channel_get_variable_dup(channel, "rtp_disable_hold", SWITCH_TRUE
, -1)
) && switch_true(var)))
8147 && ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) || tech_pvt->mparams.hold_laps)) {
8148 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
8149
8150 if (tech_pvt->mparams.hold_laps) {
8151 tech_pvt->mparams.hold_laps = 0;
8152 } else {
8153 tech_pvt->mparams.hold_laps = 1;
8154 }
8155
8156 goto done;
8157 }
8158
8159 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8159)
== SWITCH_STATUS_SUCCESS) {
8160 switch_core_session_message_t *msg;
8161 private_object_t *other_tech_pvt;
8162 int media_on_hold = switch_true(switch_channel_get_variable_dup(channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1));
8163
8164 switch_core_media_clear_rtp_flag(other_session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
8165
8166
8167 if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 &&
8168 ((profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) || media_on_hold)) {
8169 if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) {
8170 tech_pvt->mparams.hold_laps = 1;
8171 switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp)switch_channel_set_variable_var_check(channel, "switch_r_sdp"
, r_sdp, SWITCH_TRUE)
;
8172 switch_channel_clear_flag(channel, CF_PROXY_MODE);
8173 switch_core_media_set_local_sdp(tech_pvt->session, NULL((void*)0), SWITCH_FALSE);
8174 switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
8175
8176 if (!switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) {
8177 //if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
8178 //const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
8179
8180
8181 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
8182 if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
8183 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "CODEC NEGOTIATION ERROR", SWITCH_TRUE)
;
8184 switch_core_session_rwunlock(other_session);
8185 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8185, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8186 goto done;
8187 }
8188 //}
8189 }
8190
8191
8192 if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
8193 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
8194 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8195 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8195, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8196 switch_core_session_rwunlock(other_session);
8197 goto done;
8198 }
8199 }
8200
8201 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 1);
8202
8203 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
8204 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8205 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8206 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8207 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8208 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8209 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1))!(((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0)) ? tag_skip
: nutag_include_extra_sdp, tag_bool_v(1)
,
8210 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))
,
8211 TAG_END()(tag_type_t)0, (tag_value_t)0);
8212 } else {
8213 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8214 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8215 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8216 SIPTAG_CONTENT_TYPE_STR("application/sdp")siptag_content_type_str, tag_str_v("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)siptag_payload_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8217 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))
,
8218 TAG_END()(tag_type_t)0, (tag_value_t)0);
8219 }
8220
8221 switch_channel_set_flag(channel, CF_PROXY_MODE)switch_channel_set_flag_value(channel, CF_PROXY_MODE, 1);
8222 switch_yield(250000)switch_sleep(250000);;
8223 launch_media_on_hold(session);
8224
8225 switch_core_session_rwunlock(other_session);
8226 goto done;
8227 }
8228 }
8229
8230 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8231 sofia_media_activate_rtp(tech_pvt);
8232 switch_core_media_proxy_remote_addr(session, r_sdp);
8233
8234 if ((tech_pvt->profile->mndlb & SM_NDLB_NEVER_PATCH_REINVITE)) {
8235 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
8236 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8236, (const char*)(session)
, SWITCH_LOG_DEBUG, "NOT proxying re-invite.\n");
8237 switch_core_session_rwunlock(other_session);
8238 goto done;
8239 }
8240 }
8241
8242 other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
8243
8244 if (sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)((other_tech_pvt)->flags[TFLAG_REINVITED] ? 1 : 0)) {
8245 /* The other leg won the reinvite race */
8246 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8246, (const char*)(session)
, SWITCH_LOG_DEBUG, "Other leg already handling reinvite, so responding with 491\n");
8247 nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending,
8248 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
8249 switch_core_session_rwunlock(other_session);
8250 goto done;
8251 }
8252 sofia_set_flag(tech_pvt, TFLAG_REINVITED)(tech_pvt)->flags[TFLAG_REINVITED] = 1;
8253
8254 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8254)
;
8255 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
8256 msg->from = __FILE__"sofia.c";
8257 msg->string_arg = switch_core_session_strdup(other_session, r_sdp)switch_core_perform_session_strdup(other_session, r_sdp, "sofia.c"
, (const char *)__func__, 8257)
;
8258 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8258, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing SDP to other leg.\n%s\n", r_sdp);
8259
8260 if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt)->flags[TFLAG_SIP_HOLD] ? 1 : 0)) {
8261 if (!switch_stristr("sendonly", r_sdp) && !switch_stristr("inactive", r_sdp)) {
8262 sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_SIP_HOLD] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
8263 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
8264 switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL)switch_channel_perform_presence(tech_pvt->channel, "unknown"
, "unhold", ((void*)0), "sofia.c", (const char *)__func__, 8264
)
;
8265 }
8266 } else if (switch_stristr("sendonly", r_sdp) && !switch_stristr("inactive", r_sdp)) {
8267 const char *msg = "hold";
8268
8269 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
8270 const char *info = switch_channel_get_variable(channel, "presence_call_info")switch_channel_get_variable_dup(channel, "presence_call_info"
, SWITCH_TRUE, -1)
;
8271 if (info) {
8272 if (switch_stristr("private", info)) {
8273 msg = "hold-private";
8274 }
8275 }
8276 }
8277
8278 sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8278, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_SIP_HOLD] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
8279 switch_channel_set_flag(channel, CF_LEG_HOLDING)switch_channel_set_flag_value(channel, CF_LEG_HOLDING, 1);
8280 switch_channel_presence(tech_pvt->channel, "unknown", msg, NULL)switch_channel_perform_presence(tech_pvt->channel, "unknown"
, msg, ((void*)0), "sofia.c", (const char *)__func__, 8280)
;
8281 }
8282
8283 switch_core_session_queue_message(other_session, msg);
8284
8285 switch_core_session_rwunlock(other_session);
8286 } else {
8287 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8287, (const char*)(session)
, SWITCH_LOG_WARNING,
8288 "Re-INVITE to a no-media channel that is not in a bridge.\n");
8289 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8289, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8290 }
8291 goto done;
8292 } else {
8293 int hold_related = 0;
8294
8295 if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt)->flags[TFLAG_SIP_HOLD] ? 1 : 0)) {
8296 hold_related = 2;
8297 } else if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) {
8298 hold_related = 1;
8299 }
8300
8301 if (!is_t38 && hold_related && switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8301)
== SWITCH_STATUS_SUCCESS) {
8302 if (switch_core_session_compare(session, other_session)) {
8303 switch_core_session_message_t *msg;
8304 const char *hold_msg = "hold";
8305 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
8306
8307 if (sofia_test_pflag(profile, PFLAG_PROXY_HOLD)((profile)->pflags[PFLAG_PROXY_HOLD] ? 1 : 0)) {
8308 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8309
8310 if (tech_pvt->mparams.num_codecs){
8311 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
8312 }
8313
8314 if (!match) {
8315 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8315, (const char*)(session)
, SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
8316 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
8317 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))
,
8318 TAG_END()(tag_type_t)0, (tag_value_t)0);
8319 switch_core_session_rwunlock(other_session);
8320 goto done;
8321 }
8322
8323 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8323)
;
8324
8325 if (switch_stristr("inactive", r_sdp)) {
8326 sofia_set_flag_locked(other_tech_pvt, TFLAG_SIP_HOLD_INACTIVE)((other_tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) :
__assert_fail ("other_tech_pvt->flag_mutex != NULL", "sofia.c"
, 8326, __extension__ __PRETTY_FUNCTION__));switch_mutex_lock
(other_tech_pvt->flag_mutex);(other_tech_pvt)->flags[TFLAG_SIP_HOLD_INACTIVE
] = 1;switch_mutex_unlock(other_tech_pvt->flag_mutex);
;
8327 //switch_channel_set_variable(channel, "sofia_hold_inactive", "true");
8328 } else {
8329 sofia_clear_flag_locked(other_tech_pvt, TFLAG_SIP_HOLD_INACTIVE)switch_mutex_lock(other_tech_pvt->flag_mutex); (other_tech_pvt
)->flags[TFLAG_SIP_HOLD_INACTIVE] = 0; switch_mutex_unlock
(other_tech_pvt->flag_mutex);
;
8330 }
8331
8332 if (hold_related == 1) {
8333 msg->message_id = SWITCH_MESSAGE_INDICATE_HOLD;
8334 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
8335 const char *info = switch_channel_get_variable(channel, "presence_call_info")switch_channel_get_variable_dup(channel, "presence_call_info"
, SWITCH_TRUE, -1)
;
8336
8337 if (info) {
8338 if (switch_stristr("private", info)) {
8339 hold_msg = "hold-private";
8340 }
8341 }
8342 }
8343 sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8343, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_SIP_HOLD] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
8344 switch_channel_set_flag(channel, CF_LEG_HOLDING)switch_channel_set_flag_value(channel, CF_LEG_HOLDING, 1);
8345 switch_channel_presence(tech_pvt->channel, "unknown", hold_msg, NULL)switch_channel_perform_presence(tech_pvt->channel, "unknown"
, hold_msg, ((void*)0), "sofia.c", (const char *)__func__, 8345
)
;
8346 } else {
8347 hold_msg = "unhold";
8348 msg->message_id = SWITCH_MESSAGE_INDICATE_UNHOLD;
8349 sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_SIP_HOLD] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
8350 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
8351 switch_channel_presence(tech_pvt->channel, "unknown", hold_msg, NULL)switch_channel_perform_presence(tech_pvt->channel, "unknown"
, hold_msg, ((void*)0), "sofia.c", (const char *)__func__, 8351
)
;
8352 }
8353 msg->from = __FILE__"sofia.c";
8354 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8354, (const char*)(session)
, SWITCH_LOG_DEBUG, "Indicating %s to other leg.\n%s\n", hold_msg, r_sdp);
8355
8356 switch_core_session_queue_message(other_session, msg);
8357
8358
8359
8360 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8361 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)){
8362 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8363 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8364 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8365 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8366 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8367 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1))!(((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0)) ? tag_skip
: nutag_include_extra_sdp, tag_bool_v(1)
,
8368 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))
,
8369 TAG_END()(tag_type_t)0, (tag_value_t)0);
8370 } else {
8371 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8372 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8373 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8374 SIPTAG_CONTENT_TYPE_STR("application/sdp")siptag_content_type_str, tag_str_v("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)siptag_payload_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8375 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))
,
8376 TAG_END()(tag_type_t)0, (tag_value_t)0);
8377 }
8378 switch_core_session_rwunlock(other_session);
8379 goto done;
8380 }
8381 }
8382
8383 switch_core_session_rwunlock(other_session);
8384 }
8385
8386 if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) {
8387 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
8388 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8389 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8390 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8391 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8392 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8393 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1))!(((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0)) ? tag_skip
: nutag_include_extra_sdp, tag_bool_v(1)
,
8394 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))
,
8395 TAG_END()(tag_type_t)0, (tag_value_t)0);
8396 } else {
8397 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8398 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8399 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8400 SIPTAG_CONTENT_TYPE_STR("application/sdp")siptag_content_type_str, tag_str_v("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)siptag_payload_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8401 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))
,
8402 TAG_END()(tag_type_t)0, (tag_value_t)0);
8403 }
8404 goto done;
8405 }
8406
8407 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8408
8409 if (tech_pvt->mparams.num_codecs) {
8410 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
8411 }
8412
8413
8414 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
8415 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
8416 goto done;
8417 }
8418
8419 if (match && sofia_test_flag(tech_pvt, TFLAG_NOREPLY)((tech_pvt)->flags[TFLAG_NOREPLY] ? 1 : 0)) {
8420 sofia_clear_flag(tech_pvt, TFLAG_NOREPLY)(tech_pvt)->flags[TFLAG_NOREPLY] = 0;
8421 goto done;
8422 }
8423
8424 if (match) {
8425 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8426 goto done;
8427 }
8428
8429 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8430
8431 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8432 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8432, (const char*)(session)
, SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
8433 is_ok = 0;
8434 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8434, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8435 }
8436 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8436, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
8437 } else {
8438 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8439 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
8440 goto done;
8441 }
8442
8443 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8444 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8444, (const char*)(session)
, SWITCH_LOG_DEBUG, "Reinvite resulted in codec negotiation failure.\n");
8445 is_ok = 0;
8446 }
8447 }
8448
8449
8450 if (is_ok) {
8451
8452 if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
8453 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8454 }
8455
8456 if (!switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) {
8457 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
8458 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8459 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8460 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8461 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8462 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8463 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1))!(((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0)) ? tag_skip
: nutag_include_extra_sdp, tag_bool_v(1)
,
8464 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))
,
8465 TAG_END()(tag_type_t)0, (tag_value_t)0);
8466 } else {
8467 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8468 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8469 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8470 SIPTAG_CONTENT_TYPE_STR("application/sdp")siptag_content_type_str, tag_str_v("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)siptag_payload_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8471 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))
,
8472 TAG_END()(tag_type_t)0, (tag_value_t)0);
8473 }
8474 }
8475
8476 if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REINVITE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 8476, &s_event, SWITCH_EVENT_CUSTOM
, "sofia::reinvite")
== SWITCH_STATUS_SUCCESS) {
8477 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
8478 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 8478, &s_event, ((void*)0))
;
8479 }
8480 } else {
8481 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
8482 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))
,
8483 TAG_END()(tag_type_t)0, (tag_value_t)0);
8484 }
8485 }
8486 break;
8487 case nua_callstate_ready:
8488 if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA) &&
8489 r_sdp && (!is_dup_sdp || sofia_test_flag(tech_pvt, TFLAG_NEW_SDP)((tech_pvt)->flags[TFLAG_NEW_SDP] ? 1 : 0)) && switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) && !sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)((tech_pvt)->flags[TFLAG_NOSDP_REINVITE] ? 1 : 0)) {
8490 /* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */
8491 uint8_t match = 0;
8492
8493 sofia_clear_flag(tech_pvt, TFLAG_NEW_SDP)(tech_pvt)->flags[TFLAG_NEW_SDP] = 0;
8494 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8495
8496
8497 if (tech_pvt->mparams.num_codecs) {
8498 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8499 }
8500 if (match) {
8501 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8502 goto done;
8503 }
8504 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8505
8506 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8506, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
8507 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8508
8509 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8510 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8510, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
8511 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8511, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8512 goto done;
8513 }
8514 } else {
8515 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8516 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8516, (const char*)(session)
, SWITCH_LOG_ERROR, "Codec Error! %s\n", r_sdp);
8517 goto done;
8518
8519 }
8520 }
8521
8522 if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)((tech_pvt)->flags[TFLAG_NOSDP_REINVITE] ? 1 : 0)) {
8523 sofia_clear_flag_locked(tech_pvt, TFLAG_NOSDP_REINVITE)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_NOSDP_REINVITE] = 0; switch_mutex_unlock(tech_pvt->
flag_mutex);
;
8524 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8525 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8526 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8527 goto done;
8528 }
8529 }
8530
8531 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8531)
== SWITCH_STATUS_SUCCESS) {
8532 other_channel = switch_core_session_get_channel(other_session);
8533 switch_channel_pass_sdp(channel, other_channel, r_sdp);
8534
8535 if (sofia_test_flag(tech_pvt, TFLAG_3PCC)((tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
8536 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8536, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8537 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
8538 } else {
8539 switch_core_session_message_t *msg;
8540
8541 if (sofia_test_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)((profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] ? 1
: 0)
) {
8542 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8542)
;
8543 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
8544 msg->from = __FILE__"sofia.c";
8545 msg->string_arg = switch_core_session_strdup(other_session, r_sdp)switch_core_perform_session_strdup(other_session, r_sdp, "sofia.c"
, (const char *)__func__, 8545)
;
8546 switch_core_session_queue_message(other_session, msg);
8547 }
8548
8549 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8550 }
8551
8552 switch_core_session_rwunlock(other_session);
8553 }
8554 } else {
8555 uint8_t match = 0;
8556 int is_ok = 1;
8557
8558 if (!tech_pvt) goto done;
8559
8560 if (tech_pvt->mparams.num_codecs) {
8561 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8562 }
8563
8564 if (match) {
8565 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8566 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8567 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8567, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
8568 switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RTP ERROR")switch_channel_set_variable_var_check(tech_pvt->channel, "endpoint_disposition"
, "RTP ERROR", SWITCH_TRUE)
;
8569 is_ok = 0;
8570 }
8571 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8572 } else {
8573 switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR")switch_channel_set_variable_var_check(tech_pvt->channel, "endpoint_disposition"
, "CODEC NEGOTIATION ERROR", SWITCH_TRUE)
;
8574 is_ok = 0;
8575 }
8576
8577 if (!is_ok) {
8578 nua_respond(nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable, 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
8579 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 8579, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION
)
;
8580 }
8581 }
8582 goto done;
8583 }
8584
8585 if (channel) {
8586 switch_channel_clear_flag(channel, CF_REQ_MEDIA);
8587 }
8588 if (tech_pvt && nh == tech_pvt->nh2) {
8589 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8589, (const char*)(session)
, SWITCH_LOG_DEBUG, "Cheater Reinvite!\n");
8590 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8591 tech_pvt->nh = tech_pvt->nh2;
8592 tech_pvt->nh2 = NULL((void*)0);
8593 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) == SWITCH_STATUS_SUCCESS) {
8594 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8595 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8595, (const char*)(session)
, SWITCH_LOG_ERROR, "Cheater Reinvite RTP Error!\n");
8596 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8596, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8597 }
8598 }
8599 goto done;
8600 }
8601
8602 if (channel) {
8603 if (sofia_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)((tech_pvt)->flags[TFLAG_EARLY_MEDIA] ? 1 : 0) && !sofia_test_flag(tech_pvt, TFLAG_ANS)((tech_pvt)->flags[TFLAG_ANS] ? 1 : 0)) {
8604 sofia_set_flag_locked(tech_pvt, TFLAG_ANS)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8604, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8605 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
8606 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 8606)
;
8607
8608 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8609 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8609)
== SWITCH_STATUS_SUCCESS) {
8610 //other_channel = switch_core_session_get_channel(other_session);
8611 //switch_channel_answer(other_channel);
8612 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8613 switch_core_session_rwunlock(other_session);
8614 }
8615 }
8616 goto done;
8617 }
8618
8619 if (!r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
8620 r_sdp = (const char *) switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE)switch_channel_get_variable_dup(channel, "switch_r_sdp", SWITCH_TRUE
, -1)
;
8621 }
8622
8623 if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
8624 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8625 sofia_set_flag_locked(tech_pvt, TFLAG_ANS)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8625, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8626 sofia_set_flag_locked(tech_pvt, TFLAG_SDP)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8626, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_SDP] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8627 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 8627)
;
8628
8629 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8630 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8631 goto done;
8632 }
8633 }
8634
8635 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8635)
== SWITCH_STATUS_SUCCESS) {
8636 other_channel = switch_core_session_get_channel(other_session);
8637 switch_channel_pass_sdp(channel, other_channel, r_sdp);
8638
8639 //switch_channel_answer(other_channel);
8640 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8641
8642 switch_core_session_rwunlock(other_session);
8643 }
8644
8645 if (sofia_test_flag(tech_pvt, TFLAG_3PCC)((tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
8646 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8646, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8647 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
8648 }
8649
8650 goto done;
8651 } else {
8652 uint8_t match = 0;
8653
8654
8655 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8656
8657
8658 sofia_set_flag_locked(tech_pvt, TFLAG_ANS)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8658, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8659
8660 if (match) {
8661 switch_channel_check_zrtp(channel);
8662
8663 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) == SWITCH_STATUS_SUCCESS) {
8664 if (sofia_media_activate_rtp(tech_pvt) == SWITCH_STATUS_SUCCESS) {
8665 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 8665)
;
8666 } else {
8667 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8667, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
8668 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8668, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8669 }
8670
8671 if (sofia_test_flag(tech_pvt, TFLAG_3PCC)((tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0)) {
8672 /* Check if we are in 3PCC proxy mode, if so then set the flag to indicate we received the ack */
8673 if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
8674 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8674, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8675 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
8676 } else if (switch_channel_get_state(channel) == CS_HIBERNATE) {
8677 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8677, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8678 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 8678, CS_INIT)
;
8679 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
8680 }
8681 }
8682 goto done;
8683 }
8684 }
8685
8686 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "NO CODECS", SWITCH_TRUE)
;
8687 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8687, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
8688 }
8689 }
8690 }
8691
8692 break;
8693 case nua_callstate_terminating:
8694 if (status == 488 || switch_channel_get_state(channel) == CS_HIBERNATE) {
8695 tech_pvt->q850_cause = SWITCH_CAUSE_MANDATORY_IE_MISSING;
8696 }
8697 case nua_callstate_terminated:
8698 sofia_set_flag_locked(tech_pvt, TFLAG_BYE)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != NULL", "sofia.c", 8698, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_BYE] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8699 if (sofia_test_flag(tech_pvt, TFLAG_NOHUP)((tech_pvt)->flags[TFLAG_NOHUP] ? 1 : 0)) {
8700 sofia_clear_flag_locked(tech_pvt, TFLAG_NOHUP)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_NOHUP] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
8701 } else if (switch_channel_up(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) < CS_HANGUP)
) {
8702 int cause;
8703 if (tech_pvt->q850_cause) {
8704 cause = tech_pvt->q850_cause;
8705 } else {
8706 cause = sofia_glue_sip_cause_to_freeswitch(status);
8707 }
8708 if (status) {
8709 switch_snprintf(st, sizeof(st), "%d", status);
8710 switch_channel_set_variable(channel, "sip_term_status", st)switch_channel_set_variable_var_check(channel, "sip_term_status"
, st, SWITCH_TRUE)
;
8711 switch_snprintf(st, sizeof(st), "sip:%d", status);
8712 switch_channel_set_variable(channel, SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE, st)switch_channel_set_variable_var_check(channel, "proto_specific_hangup_cause"
, st, SWITCH_TRUE)
;
8713 if (phrase) {
8714 switch_channel_set_variable_partner(channel, "sip_hangup_phrase", phrase)switch_channel_set_variable_partner_var_check(channel, "sip_hangup_phrase"
, phrase, SWITCH_TRUE)
;
8715 }
8716 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_BYE_HEADER_PREFIX"sip_bye_h_");
8717 }
8718 switch_snprintf(st, sizeof(st), "%d", cause);
8719 switch_channel_set_variable(channel, "sip_term_cause", st)switch_channel_set_variable_var_check(channel, "sip_term_cause"
, st, SWITCH_TRUE)
;
8720 switch_channel_hangup(channel, cause)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8720, cause)
;
8721 ss_state = nua_callstate_terminated;
8722 }
8723
8724 if (ss_state == nua_callstate_terminated) {
8725 if (tech_pvt->sofia_private) {
8726 tech_pvt->sofia_private = NULL((void*)0);
8727 }
8728
8729 tech_pvt->nh = NULL((void*)0);
8730
8731 if (nh) {
8732 nua_handle_bind(nh, NULL((void*)0));
8733 nua_handle_destroy(nh);
8734 }
8735 }
8736
8737 break;
8738 }
8739
8740 done:
8741
8742 switch_safe_free(patched_sdp)if (patched_sdp) {free(patched_sdp);patched_sdp=((void*)0);};
8743
8744 if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) {
8745 sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY)(tech_pvt)->flags[TFLAG_SIMPLIFY] = 1;
8746 }
8747
8748
8749 return;
8750}
8751
8752typedef struct {
8753 char *exten;
8754 char *exten_with_params;
8755 char *event;
8756 char *reply_uuid;
8757 char *bridge_to_uuid;
8758 switch_event_t *vars;
8759 switch_memory_pool_t *pool;
8760 sofia_profile_t *profile;
8761} nightmare_xfer_helper_t;
8762
8763void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void *obj)
8764{
8765 nightmare_xfer_helper_t *nhelper = (nightmare_xfer_helper_t *) obj;
8766 switch_memory_pool_t *pool;
8767 switch_status_t status = SWITCH_STATUS_FALSE;
8768 switch_core_session_t *session, *a_session;
8769
8770 if ((a_session = switch_core_session_locate(nhelper->bridge_to_uuid)switch_core_session_perform_locate(nhelper->bridge_to_uuid
, "sofia.c", (const char *)__func__, 8770)
)) {
8771 switch_core_session_t *tsession = NULL((void*)0);
8772 switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
8773 uint32_t timeout = 60;
8774 char *tuuid_str;
8775
8776 if ((session = switch_core_session_locate(nhelper->reply_uuid)switch_core_session_perform_locate(nhelper->reply_uuid, "sofia.c"
, (const char *)__func__, 8776)
)) {
8777 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8778 switch_channel_t *channel_a = switch_core_session_get_channel(session);
8779 const char *session_id_header = sofia_glue_session_id_header(session, nhelper->profile);
8780
8781 if ((status = switch_ivr_originate(NULL((void*)0), &tsession, &cause, nhelper->exten_with_params, timeout, NULL((void*)0), NULL((void*)0), NULL((void*)0),
8782 switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL((void*)0), NULL((void*)0))) == SWITCH_STATUS_SUCCESS) {
8783 if (switch_channel_up(channel_a)(switch_channel_check_signal(channel_a, SWITCH_TRUE) || switch_channel_get_state
(channel_a) < CS_HANGUP)
) {
8784
8785 if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer")switch_channel_get_variable_dup(channel_a, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
8786 switch_ivr_transfer_recordings(session, a_session);
8787 }
8788
8789
8790 tuuid_str = switch_core_session_get_uuid(tsession);
8791 switch_channel_set_variable_printf(channel_a, "transfer_to", "att:%s", tuuid_str);
8792 mark_transfer_record(session, nhelper->bridge_to_uuid, tuuid_str);
8793 switch_ivr_uuid_bridge(nhelper->bridge_to_uuid, tuuid_str);
8794 switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER")switch_channel_set_variable_var_check(channel_a, "endpoint_disposition"
, "ATTENDED_TRANSFER", SWITCH_TRUE)
;
8795 } else {
8796 switch_channel_hangup(switch_core_session_get_channel(tsession), SWITCH_CAUSE_ORIGINATOR_CANCEL)switch_channel_perform_hangup(switch_core_session_get_channel
(tsession), "sofia.c", (const char *)__func__, 8796, SWITCH_CAUSE_ORIGINATOR_CANCEL
)
;
8797 status = SWITCH_STATUS_FALSE;
8798 }
8799 switch_core_session_rwunlock(tsession);
8800 }
8801
8802 if (status == SWITCH_STATUS_SUCCESS) {
8803 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8803, (const char*)(session)
, SWITCH_LOG_DEBUG, "The nightmare is over.....\n");
8804 } else {
8805 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8805, (const char*)(session)
, SWITCH_LOG_DEBUG, "1 .. 2 .. Freddie's commin' for you...\n");
8806 }
8807
8808 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag")siptag_content_type_str, tag_str_v("message/sipfrag"),
8809 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
8810 SIPTAG_PAYLOAD_STR(status == SWITCH_STATUS_SUCCESS ? "SIP/2.0 200 OK\r\n" :siptag_payload_str, tag_str_v(status == SWITCH_STATUS_SUCCESS
? "SIP/2.0 200 OK\r\n" : "SIP/2.0 403 Forbidden\r\n")
8811 "SIP/2.0 403 Forbidden\r\n")siptag_payload_str, tag_str_v(status == SWITCH_STATUS_SUCCESS
? "SIP/2.0 200 OK\r\n" : "SIP/2.0 403 Forbidden\r\n")
, SIPTAG_EVENT_STR(nhelper->event)siptag_event_str, tag_str_v(nhelper->event),
8812 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))
,
8813 TAG_END()(tag_type_t)0, (tag_value_t)0);
8814
8815 switch_core_session_rwunlock(session);
8816 }
8817
8818 switch_core_session_rwunlock(a_session);
8819 }
8820
8821 switch_event_destroy(&nhelper->vars);
8822
8823 pool = nhelper->pool;
8824 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia.c",
(const char *)__func__, 8824)
;
8825
8826 return NULL((void*)0);
8827}
8828
8829static void launch_nightmare_xfer(nightmare_xfer_helper_t *nhelper)
8830{
8831 switch_thread_t *thread;
8832 switch_threadattr_t *thd_attr = NULL((void*)0);
8833
8834 switch_threadattr_create(&thd_attr, nhelper->pool);
8835 switch_threadattr_detach_set(thd_attr, 1);
8836 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
8837 switch_thread_create(&thread, thd_attr, nightmare_xfer_thread_run, nhelper, nhelper->pool);
8838}
8839
8840/*---------------------------------------*/
8841
8842static switch_status_t xfer_hanguphook(switch_core_session_t *session)
8843{
8844 switch_channel_t *channel = switch_core_session_get_channel(session);
8845 switch_channel_state_t state = switch_channel_get_state(channel);
8846
8847 if (state == CS_HANGUP) {
8848 switch_core_session_t *ksession;
8849 const char *uuid = switch_channel_get_variable(channel, "att_xfer_kill_uuid")switch_channel_get_variable_dup(channel, "att_xfer_kill_uuid"
, SWITCH_TRUE, -1)
;
8850
8851 if (uuid && (ksession = switch_core_session_force_locate(uuid)switch_core_session_perform_force_locate(uuid, "sofia.c", (const
char *)__func__, 8851)
)) {
8852 switch_channel_t *kchannel = switch_core_session_get_channel(ksession);
8853
8854 switch_channel_clear_flag(kchannel, CF_XFER_ZOMBIE);
8855 switch_channel_clear_flag(kchannel, CF_TRANSFER);
8856 if (switch_channel_up(kchannel)(switch_channel_check_signal(kchannel, SWITCH_TRUE) || switch_channel_get_state
(kchannel) < CS_HANGUP)
) {
8857 switch_channel_hangup(kchannel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(kchannel, "sofia.c", (const char
*)__func__, 8857, SWITCH_CAUSE_NORMAL_CLEARING)
;
8858 }
8859
8860 switch_core_session_rwunlock(ksession);
8861 }
8862
8863 switch_core_event_hook_remove_state_change(session, xfer_hanguphook);
8864
8865 }
8866
8867 return SWITCH_STATUS_SUCCESS;
8868}
8869
8870nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces)
8871{
8872 nua_handle_t *nh = NULL((void*)0);
8873 switch_hash_index_t *hi;
8874 const void *var;
8875 void *val;
8876 sofia_profile_t *profile;
8877
8878 switch_mutex_lock(mod_sofia_globals.hash_mutex);
8879 if (mod_sofia_globals.profile_hash) {
8880 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)) {
8881 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
8882 if ((profile = (sofia_profile_t *) val)) {
8883 if (!(nh = nua_handle_by_replaces(profile->nua, replaces))) {
8884 nh = nua_handle_by_call_id(profile->nua, replaces->rp_call_id);
8885 }
8886 if (nh)
8887 break;
8888 }
8889 }
8890 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
8891 }
8892 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
8893
8894 return nh;
8895
8896}
8897
8898static switch_status_t sofia_process_proxy_refer(switch_core_session_t *session, const char *refer_to)
8899{
8900 switch_core_session_t *other_session;
8901 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8902
8903 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8903)
== SWITCH_STATUS_SUCCESS) {
8904 switch_core_session_message_t *msg;
8905
8906 tech_pvt->proxy_refer_uuid = switch_core_session_strdup(session, switch_core_session_get_uuid(other_session))switch_core_perform_session_strdup(session, switch_core_session_get_uuid
(other_session), "sofia.c", (const char *)__func__, 8906)
;
8907 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8907)
;
8908 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 8908
;
8909 msg->message_id = SWITCH_MESSAGE_INDICATE_DEFLECT;
8910 msg->string_arg = switch_core_session_strdup(other_session, refer_to)switch_core_perform_session_strdup(other_session, refer_to, "sofia.c"
, (const char *)__func__, 8910)
;
8911 msg->string_array_arg[0] = switch_core_session_strdup(other_session, switch_core_session_get_uuid(session))switch_core_perform_session_strdup(other_session, switch_core_session_get_uuid
(session), "sofia.c", (const char *)__func__, 8911)
;
8912 msg->from = __FILE__"sofia.c";
8913 switch_core_session_queue_message(other_session, msg);
8914 switch_core_session_rwunlock(other_session);
8915 return SWITCH_STATUS_SUCCESS;
8916 }
8917
8918 return SWITCH_STATUS_FALSE;
8919}
8920
8921void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
8922 sofia_dispatch_event_t *de, tagi_t tags[])
8923{
8924 /* Incoming refer */
8925 sip_from_t const *from;
8926 //sip_to_t const *to;
8927 sip_refer_to_t const *refer_to;
8928 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8929 char *etmp = NULL((void*)0), *exten = NULL((void*)0);
8930 switch_channel_t *channel_a = switch_core_session_get_channel(session);
8931 switch_channel_t *channel_b = NULL((void*)0);
8932 su_home_t *home = NULL((void*)0);
8933 char *full_ref_by = NULL((void*)0);
8934 char *full_ref_to = NULL((void*)0);
8935 nightmare_xfer_helper_t *nightmare_xfer_helper;
8936 switch_memory_pool_t *npool;
8937 switch_event_t *event = NULL((void*)0);
8938 const char *session_id_header = sofia_glue_session_id_header(session, profile);
8939
8940 if (!(profile->mflags & MFLAG_REFER)) {
8941 nua_respond(nh, SIP_403_FORBIDDEN403, sip_403_Forbidden, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
8942 goto done;
8943 }
8944
8945 if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
8946 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8946, (const char*)(session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
8947 goto done;
8948 }
8949
8950 home = su_home_new(sizeof(*home));
8951 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 8951, __extension__ __PRETTY_FUNCTION__))
;
8952
8953 if ((refer_to = sip->sip_refer_to)) {
8954 full_ref_to = sip_header_as_string(home, (void *) sip->sip_refer_to);
8955 }
8956
8957 if (full_ref_to && sofia_test_pflag(profile, PFLAG_PROXY_REFER)((profile)->pflags[PFLAG_PROXY_REFER] ? 1 : 0)) {
8958 if (sofia_process_proxy_refer(session, full_ref_to) == SWITCH_STATUS_SUCCESS) {
8959 if (tech_pvt->proxy_refer_msg) {
8960 msg_ref_destroy(tech_pvt->proxy_refer_msg);
8961 tech_pvt->proxy_refer_msg = NULL((void*)0);
8962 }
8963 tech_pvt->proxy_refer_msg = msg_ref_create(de->data->e_msg);
8964 //nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), TAG_END());
8965 goto done;
8966 }
8967 }
8968
8969 from = sip->sip_from;
8970 //to = sip->sip_to;
8971
8972 nua_respond(nh, SIP_202_ACCEPTED202, sip_202_Accepted, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), SIPTAG_EXPIRES_STR("60")siptag_expires_str, tag_str_v("60"),
8973 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
8974
8975
8976 switch_channel_set_variable(tech_pvt->channel, SOFIA_REPLACES_HEADER, NULL)switch_channel_set_variable_var_check(tech_pvt->channel, "_sofia_replaces_"
, ((void*)0), SWITCH_TRUE)
;
8977
8978 if (sip->sip_referred_by) {
8979 full_ref_by = sip_header_as_string(home, (void *) sip->sip_referred_by);
8980 }
8981
8982 if (refer_to) {
8983 char *rep = NULL((void*)0);
8984
8985 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
8986 exten = switch_core_session_sprintf(session, "%s@%s", (char *) refer_to->r_url->url_user, (char *) refer_to->r_url->url_host);
8987 } else {
8988 exten = (char *) refer_to->r_url->url_user;
8989 }
8990
8991 if (refer_to->r_url->url_params) {
8992 switch_channel_set_variable(tech_pvt->channel, "sip_refer_to_params", refer_to->r_url->url_params)switch_channel_set_variable_var_check(tech_pvt->channel, "sip_refer_to_params"
, refer_to->r_url->url_params, SWITCH_TRUE)
;
8993 }
8994
8995 switch_core_session_queue_indication(session, SWITCH_MESSAGE_REFER_EVENT);
8996 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8996, (const char*)(session)
, SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
8997
8998 switch_channel_set_variable(tech_pvt->channel, "transfer_disposition", "recv_replace")switch_channel_set_variable_var_check(tech_pvt->channel, "transfer_disposition"
, "recv_replace", SWITCH_TRUE)
;
8999
9000
9001 if (refer_to->r_url->url_headers) {
9002 rep = (char *) switch_stristr("Replaces=", refer_to->r_url->url_headers);
9003 }
9004
9005
9006 if (rep) {
9007 sip_replaces_t *replaces;
9008 nua_handle_t *bnh = NULL((void*)0);
9009
9010 const char *br_a = NULL((void*)0), *br_b = NULL((void*)0);
9011 char *buf;
9012 char *p;
9013
9014 rep = switch_core_session_strdup(session, rep + 9)switch_core_perform_session_strdup(session, rep + 9, "sofia.c"
, (const char *)__func__, 9014)
;
9015
9016 if ((buf = switch_core_session_alloc(session, strlen(rep) + 1)switch_core_perform_session_alloc(session, strlen(rep) + 1, "sofia.c"
, (const char *)__func__, 9016)
)) {
9017 rep = url_unescape(buf, (const char *) rep);
9018 if ((p = strchr(rep, ';'))) {
9019 *p = '\0';
9020 }
9021 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9021, (const char*)(session)
, SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep);
9022 } else {
9023 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9023, (const char*)(session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
9024 goto done;
9025 }
9026
9027 if ((replaces = sip_replaces_make(home, rep))) {
9028 if (!(bnh = nua_handle_by_replaces(nua, replaces))) {
9029 if (!(bnh = nua_handle_by_call_id(nua, replaces->rp_call_id))) {
9030 bnh = sofia_global_nua_handle_by_replaces(replaces);
9031 }
9032 }
9033 }
9034
9035 if (bnh && !sofia_test_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)((profile)->pflags[PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE] ?
1 : 0)
) {
9036 sofia_private_t *b_private = NULL((void*)0);
9037 private_object_t *b_tech_pvt = NULL((void*)0);
9038 switch_core_session_t *b_session = NULL((void*)0);
9039
9040
9041 switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep)switch_channel_set_variable_var_check(channel_a, "_sofia_replaces_"
, rep, SWITCH_TRUE)
;
9042 if ((b_private = nua_handle_magic(bnh))) {
9043 int deny_refer_requests = 0;
9044
9045 if (!(b_session = switch_core_session_locate(b_private->uuid)switch_core_session_perform_locate(b_private->uuid, "sofia.c"
, (const char *)__func__, 9045)
)) {
9046 goto done;
9047 }
9048 b_tech_pvt = (private_object_t *) switch_core_session_get_private(b_session)switch_core_session_get_private_class(b_session, SWITCH_PVT_PRIMARY
)
;
9049 channel_b = switch_core_session_get_channel(b_session);
9050
9051 switch_channel_set_variable(channel_a, "refer_uuid", b_private->uuid)switch_channel_set_variable_var_check(channel_a, "refer_uuid"
, b_private->uuid, SWITCH_TRUE)
;
9052 switch_channel_set_variable(channel_b, "transfer_disposition", "replaced")switch_channel_set_variable_var_check(channel_b, "transfer_disposition"
, "replaced", SWITCH_TRUE)
;
9053
9054 br_a = switch_channel_get_partner_uuid(channel_a);
9055 br_b = switch_channel_get_partner_uuid(channel_b);
9056
9057 if (!switch_ivr_uuid_exists(br_a)) {
9058 br_a = NULL((void*)0);
9059 }
9060
9061 if (!switch_ivr_uuid_exists(br_b)) {
9062 br_b = NULL((void*)0);
9063 }
9064
9065 if (channel_a && switch_true(switch_channel_get_variable(channel_a, "deny_refer_requests")switch_channel_get_variable_dup(channel_a, "deny_refer_requests"
, SWITCH_TRUE, -1)
)) {
9066 deny_refer_requests = 1;
9067 }
9068
9069 if (!deny_refer_requests && channel_b && switch_true(switch_channel_get_variable(channel_b, "deny_refer_requests")switch_channel_get_variable_dup(channel_b, "deny_refer_requests"
, SWITCH_TRUE, -1)
)) {
9070 deny_refer_requests = 1;
9071 }
9072
9073 if (!deny_refer_requests && br_a) {
9074 switch_core_session_t *a_session;
9075 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9075)
)) {
9076 switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
9077
9078 if (a_channel && switch_true(switch_channel_get_variable(a_channel, "deny_refer_requests")switch_channel_get_variable_dup(a_channel, "deny_refer_requests"
, SWITCH_TRUE, -1)
)) {
9079 deny_refer_requests = 1;
9080 }
9081 switch_core_session_rwunlock(a_session);
9082 }
9083 }
9084
9085 if (!deny_refer_requests && br_b) {
9086 switch_core_session_t *b_session;
9087 if ((b_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 9087)
)) {
9088 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
9089
9090 if (b_channel && switch_true(switch_channel_get_variable(b_channel, "deny_refer_requests")switch_channel_get_variable_dup(b_channel, "deny_refer_requests"
, SWITCH_TRUE, -1)
)) {
9091 deny_refer_requests = 1;
9092 }
9093 switch_core_session_rwunlock(b_session);
9094 }
9095 }
9096
9097 if (deny_refer_requests) {
9098 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9098, (const char*)(session)
, SWITCH_LOG_NOTICE, "Denying Attended Transfer, variable [deny_refer_requests] was set to true\n");
9099
9100 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9101 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
9102 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))
,
9103 SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n")siptag_payload_str, tag_str_v("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp), TAG_END()(tag_type_t)0, (tag_value_t)0);
9104
9105 } else if (switch_channel_test_flag(channel_b, CF_ORIGINATOR)) {
9106 switch_core_session_t *a_session;
9107
9108 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9108, (const char*)(session)
, SWITCH_LOG_NOTICE,
9109 "Attended Transfer on originating session %s\n", switch_core_session_get_uuid(b_session));
9110
9111
9112
9113 switch_channel_set_variable_printf(channel_b, "transfer_to", "satt:%s", br_a);
9114
9115 switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER")switch_channel_set_variable_var_check(channel_b, "endpoint_disposition"
, "ATTENDED_TRANSFER", SWITCH_TRUE)
;
9116
9117
9118 sofia_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD)switch_mutex_lock(b_tech_pvt->flag_mutex); (b_tech_pvt)->
flags[TFLAG_SIP_HOLD] = 0; switch_mutex_unlock(b_tech_pvt->
flag_mutex);
;
9119 switch_channel_clear_flag(channel_b, CF_LEG_HOLDING);
9120 sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_HOLD_LOCK] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
9121
9122 switch_channel_set_variable(channel_b, SWITCH_HOLDING_UUID_VARIABLE, br_a)switch_channel_set_variable_var_check(channel_b, "holding_uuid"
, br_a, SWITCH_TRUE)
;
9123 switch_channel_set_flag(channel_b, CF_XFER_ZOMBIE)switch_channel_set_flag_value(channel_b, CF_XFER_ZOMBIE, 1);
9124 switch_channel_set_flag(channel_b, CF_TRANSFER)switch_channel_set_flag_value(channel_b, CF_TRANSFER, 1);
9125
9126
9127 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9127)
)) {
9128 const char *moh = profile->hold_music;
9129 switch_core_session_t *tmpsess = NULL((void*)0);
9130 switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
9131 switch_caller_profile_t *prof = switch_channel_get_caller_profile(channel_b);
9132 const char *tmp;
9133
9134 switch_core_event_hook_add_state_change(a_session, xfer_hanguphook);
9135 switch_channel_set_variable(a_channel, "att_xfer_kill_uuid", switch_core_session_get_uuid(b_session))switch_channel_set_variable_var_check(a_channel, "att_xfer_kill_uuid"
, switch_core_session_get_uuid(b_session), SWITCH_TRUE)
;
9136 switch_channel_set_variable(a_channel, "att_xfer_destination_number", prof->destination_number)switch_channel_set_variable_var_check(a_channel, "att_xfer_destination_number"
, prof->destination_number, SWITCH_TRUE)
;
9137 switch_channel_set_variable(a_channel, "att_xfer_callee_id_name", prof->callee_id_name)switch_channel_set_variable_var_check(a_channel, "att_xfer_callee_id_name"
, prof->callee_id_name, SWITCH_TRUE)
;
9138 switch_channel_set_variable(a_channel, "att_xfer_callee_id_number", prof->callee_id_number)switch_channel_set_variable_var_check(a_channel, "att_xfer_callee_id_number"
, prof->callee_id_number, SWITCH_TRUE)
;
9139
9140 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) {
9141 switch_channel_set_flag(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
9142 }
9143
9144
9145 if ((tmp = switch_channel_get_hold_music(a_channel))) {
9146 moh = tmp;
9147 }
9148
9149 if (!zstr(moh)_zstr(moh) && !strcasecmp(moh, "silence")) {
9150 moh = NULL((void*)0);
9151 }
9152
9153 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9154 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9154, &event, SWITCH_EVENT_CUSTOM
, "sofia::replaced")
== SWITCH_STATUS_SUCCESS) {
9155 switch_channel_event_set_data(channel_b, event);
9156 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", br_a);
9157 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9157, &event, ((void*)0))
;
9158 }
9159
9160 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9160, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9161 switch_channel_event_set_data(channel_a, event);
9162 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9163 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9164 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_core_session_get_uuid(b_session));
9165 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9165, &event, ((void*)0))
;
9166 }
9167
9168 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9168, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9169 switch_channel_event_set_data(a_channel, event);
9170 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_call_id", switch_core_session_get_uuid(b_session));
9171 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9171, &event, ((void*)0))
;
9172 }
9173 }
9174
9175 if (moh) {
9176 char *xdest;
9177 xdest = switch_core_session_sprintf(a_session, "m:\":endless_playback:%s\"park", moh);
9178 switch_ivr_session_transfer(a_session, xdest, "inline", NULL((void*)0));
9179 } else {
9180 switch_ivr_session_transfer(a_session, "park", "inline", NULL((void*)0));
9181 }
9182 if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer")switch_channel_get_variable_dup(channel_a, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
9183 switch_ivr_transfer_recordings(session, a_session);
9184 }
9185 if (switch_true(switch_channel_get_variable(channel_b, "recording_follow_transfer")switch_channel_get_variable_dup(channel_b, "recording_follow_transfer"
, SWITCH_TRUE, -1)
) && (tmpsess = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9185)
)) {
9186 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9186, (const char*)(session)
, SWITCH_LOG_NOTICE,
9187 "Early transfer detected with no media, moving recording bug to other leg\n");
9188 switch_ivr_transfer_recordings(b_session, tmpsess);
9189 switch_core_session_rwunlock(tmpsess);
9190 }
9191
9192 switch_core_session_rwunlock(a_session);
9193
9194 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9195 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
, SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n")siptag_payload_str, tag_str_v("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9196 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))
,
9197 TAG_END()(tag_type_t)0, (tag_value_t)0);
9198
9199 if (b_tech_pvt && !sofia_test_flag(b_tech_pvt, TFLAG_BYE)((b_tech_pvt)->flags[TFLAG_BYE] ? 1 : 0)) {
9200 char *q850 = NULL((void*)0);
9201 const char *val = NULL((void*)0);
9202
9203 sofia_set_flag_locked(b_tech_pvt, TFLAG_BYE)((b_tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("b_tech_pvt->flag_mutex != NULL", "sofia.c", 9203, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(b_tech_pvt->flag_mutex
);(b_tech_pvt)->flags[TFLAG_BYE] = 1;switch_mutex_unlock(b_tech_pvt
->flag_mutex);
;
9204 val = switch_channel_get_variable(tech_pvt->channel, "disable_q850_reason")switch_channel_get_variable_dup(tech_pvt->channel, "disable_q850_reason"
, SWITCH_TRUE, -1)
;
9205 if (!val || switch_true(val)) {
9206 q850 = switch_core_session_sprintf(a_session, "Q.850;cause=16;text=\"normal_clearing\"");
9207 }
9208 nua_bye(b_tech_pvt->nh,
9209 SIPTAG_CONTACT(SIP_NONE)siptag_contact, siptag_contact_v(((void const *)-1L)),
9210 TAG_IF(!zstr(q850), SIPTAG_REASON_STR(q850))!(!_zstr(q850)) ? tag_skip : siptag_reason_str, tag_str_v(q850
)
,
9211 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)
,
9212 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))
,
9213 TAG_END()(tag_type_t)0, (tag_value_t)0);
9214
9215 }
9216 } else {
9217 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9218 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
9219 SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n")siptag_payload_str, tag_str_v("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9220 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))
,
9221 TAG_END()(tag_type_t)0, (tag_value_t)0);
9222 }
9223
9224 } else if (br_a && br_b) {
9225 switch_core_session_t *tmp = NULL((void*)0);
9226 switch_event_t *event = NULL((void*)0);
9227
9228 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9228, (const char*)(session)
, SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n",
9229 switch_str_nil(br_a)(br_a ? br_a : ""), switch_str_nil(br_b)(br_b ? br_b : ""));
9230
9231 if ((tmp = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 9231)
)) {
9232 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9233
9234 if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER)) {
9235 switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
9236 }
9237
9238 switch_channel_set_variable(tchannel, "transfer_disposition", "bridge")switch_channel_set_variable_var_check(tchannel, "transfer_disposition"
, "bridge", SWITCH_TRUE)
;
9239
9240 switch_channel_set_flag(tchannel, CF_ATTENDED_TRANSFER)switch_channel_set_flag_value(tchannel, CF_ATTENDED_TRANSFER,
1)
;
9241 switch_core_session_rwunlock(tmp);
9242 }
9243
9244 if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) && (tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9244)
)) {
9245 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9246 switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
9247 switch_core_session_rwunlock(tmp);
9248 }
9249
9250
9251 if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer")switch_channel_get_variable_dup(channel_a, "recording_follow_transfer"
, SWITCH_TRUE, -1)
) &&
9252 (tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9252)
)) {
9253 switch_channel_set_variable(switch_core_session_get_channel(tmp), "transfer_disposition", "bridge")switch_channel_set_variable_var_check(switch_core_session_get_channel
(tmp), "transfer_disposition", "bridge", SWITCH_TRUE)
;
9254 switch_ivr_transfer_recordings(session, tmp);
9255 switch_core_session_rwunlock(tmp);
9256 }
9257
9258
9259 if (switch_true(switch_channel_get_variable(channel_b, "recording_follow_transfer")switch_channel_get_variable_dup(channel_b, "recording_follow_transfer"
, SWITCH_TRUE, -1)
) &&
9260 (tmp = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 9260)
)) {
9261 switch_ivr_transfer_recordings(b_session, tmp);
9262 switch_core_session_rwunlock(tmp);
9263 }
9264
9265 switch_channel_set_variable_printf(channel_a, "transfer_to", "att:%s", br_b);
9266
9267 mark_transfer_record(session, br_a, br_b);
9268
9269 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9270 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9270, &event, SWITCH_EVENT_CUSTOM
, "sofia::replaced")
== SWITCH_STATUS_SUCCESS) {
9271 switch_channel_event_set_data(channel_b, event);
9272 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", br_a);
9273 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9273, &event, ((void*)0))
;
9274 }
9275
9276 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9276, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9277 switch_channel_event_set_data(channel_a, event);
9278 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9279 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9280 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_core_session_get_uuid(b_session));
9281 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9281, &event, ((void*)0))
;
9282 }
9283
9284 if ((tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9284)
)) {
9285 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9286
9287 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9287, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9288 switch_channel_event_set_data(tchannel, event);
9289 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9289, &event, ((void*)0))
;
9290 }
9291
9292 switch_core_session_rwunlock(tmp);
9293 }
9294 }
9295
9296 switch_ivr_uuid_bridge(br_a, br_b);
9297 switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER")switch_channel_set_variable_var_check(channel_b, "endpoint_disposition"
, "ATTENDED_TRANSFER", SWITCH_TRUE)
;
9298 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9299 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
, SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n")siptag_payload_str, tag_str_v("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9300 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))
,
9301 TAG_END()(tag_type_t)0, (tag_value_t)0);
9302
9303 sofia_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD)switch_mutex_lock(b_tech_pvt->flag_mutex); (b_tech_pvt)->
flags[TFLAG_SIP_HOLD] = 0; switch_mutex_unlock(b_tech_pvt->
flag_mutex);
;
9304 switch_channel_clear_flag(channel_b, CF_LEG_HOLDING);
9305 sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_HOLD_LOCK] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
9306 switch_channel_set_variable(channel_b, "park_timeout", "2:attended_transfer")switch_channel_set_variable_var_check(channel_b, "park_timeout"
, "2:attended_transfer", SWITCH_TRUE)
;
9307 switch_channel_set_state(channel_b, CS_PARK)switch_channel_perform_set_state(channel_b, "sofia.c", (const
char *)__func__, 9307, CS_PARK)
;
9308 switch_channel_wait_for_state_timeout(channel_b, CS_PARK, 5000);
9309
9310 } else {
9311 if (!br_a && !br_b) {
9312 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9312, (const char*)(session)
, SWITCH_LOG_WARNING,
9313 "Cannot transfer channels that are not in a bridge.\n");
9314 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9315 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
, SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n")siptag_payload_str, tag_str_v("SIP/2.0 403 Forbidden\r\n"),
9316 SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9317 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))
,
9318 TAG_END()(tag_type_t)0, (tag_value_t)0);
9319 } else {
9320 switch_core_session_t *t_session, *hup_session;
9321 switch_channel_t *hup_channel;
9322 switch_event_t *event = NULL((void*)0);
9323 const char *ext;
9324
9325 if (br_a && !br_b) {
9326 t_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9326)
;
9327 hup_channel = channel_b;
9328 hup_session = b_session;
9329 } else {
9330 private_object_t *h_tech_pvt = (private_object_t *) switch_core_session_get_private(b_session)switch_core_session_get_private_class(b_session, SWITCH_PVT_PRIMARY
)
;
9331 t_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 9331)
;
9332 hup_channel = channel_a;
9333 hup_session = session;
9334 sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD)switch_mutex_lock(tech_pvt->flag_mutex); (tech_pvt)->flags
[TFLAG_SIP_HOLD] = 0; switch_mutex_unlock(tech_pvt->flag_mutex
);
;
9335 switch_channel_clear_flag(tech_pvt->channel, CF_LEG_HOLDING);
9336 sofia_clear_flag_locked(h_tech_pvt, TFLAG_SIP_HOLD)switch_mutex_lock(h_tech_pvt->flag_mutex); (h_tech_pvt)->
flags[TFLAG_SIP_HOLD] = 0; switch_mutex_unlock(h_tech_pvt->
flag_mutex);
;
9337 switch_channel_clear_flag(h_tech_pvt->channel, CF_LEG_HOLDING);
9338 switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(channel_b, "sofia.c", (const char
*)__func__, 9338, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
9339 }
9340
9341 if (t_session) {
9342 switch_channel_t *t_channel = switch_core_session_get_channel(t_session);
9343 const char *idest = switch_channel_get_variable(hup_channel, "inline_destination")switch_channel_get_variable_dup(hup_channel, "inline_destination"
, SWITCH_TRUE, -1)
;
9344 ext = switch_channel_get_variable(hup_channel, "destination_number")switch_channel_get_variable_dup(hup_channel, "destination_number"
, SWITCH_TRUE, -1)
;
9345
9346 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
9347 switch_channel_set_variable(t_channel, SOFIA_SIP_HEADER_PREFIX "Referred-By", full_ref_by)switch_channel_set_variable_var_check(t_channel, "sip_h_" "Referred-By"
, full_ref_by, SWITCH_TRUE)
;
9348 }
9349
9350 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
9351 switch_channel_set_variable(t_channel, SOFIA_REFER_TO_VARIABLE, full_ref_to)switch_channel_set_variable_var_check(t_channel, "sip_refer_to"
, full_ref_to, SWITCH_TRUE)
;
9352 }
9353
9354
9355 if (switch_true(switch_channel_get_variable(hup_channel, "recording_follow_transfer")switch_channel_get_variable_dup(hup_channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
9356 switch_ivr_transfer_recordings(hup_session, t_session);
9357 }
9358
9359 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9360 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9360, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9361 switch_channel_event_set_data(channel_a, event);
9362 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", switch_core_session_get_uuid(hup_session));
9363 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", switch_core_session_get_uuid(t_session));
9364 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_channel_get_partner_uuid(t_channel));
9365 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9365, &event, ((void*)0))
;
9366 }
9367
9368 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9368, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9369 switch_channel_event_set_data(t_channel, event);
9370 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9370, &event, ((void*)0))
;
9371 }
9372 }
9373
9374 if (idest) {
9375 switch_ivr_session_transfer(t_session, idest, "inline", NULL((void*)0));
9376 } else {
9377 switch_ivr_session_transfer(t_session, ext, NULL((void*)0), NULL((void*)0));
9378 }
9379
9380 nua_notify(tech_pvt->nh,
9381 NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1),
9382 SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9383 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
9384 SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n")siptag_payload_str, tag_str_v("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9385 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))
,
9386 TAG_END()(tag_type_t)0, (tag_value_t)0);
9387 switch_core_session_rwunlock(t_session);
9388 switch_channel_hangup(hup_channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(hup_channel, "sofia.c", (const char
*)__func__, 9388, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
9389 } else {
9390 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9390, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session to transfer to not found.\n");
9391 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9392 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
9393 SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n")siptag_payload_str, tag_str_v("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9394 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))
,
9395 TAG_END()(tag_type_t)0, (tag_value_t)0);
9396 }
9397 }
9398 }
9399 switch_core_session_rwunlock(b_session);
9400 }
9401 nua_handle_unref_user(bnh);
9402 } else { /* the other channel is on a different box, we have to go find them */
9403 if (exten && (br_a = switch_channel_get_partner_uuid(channel_a))) {
9404 switch_core_session_t *a_session;
9405 switch_channel_t *channel;
9406
9407 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9407)
)) {
9408 const char *port = NULL((void*)0);
9409 const char *rep_h = NULL((void*)0);
9410
9411 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9411, (const char*)(session)
, SWITCH_LOG_DEBUG,
9412 "REFER from %s replaces %s (%s@%s) with %s on another server\n",
9413 switch_core_session_get_uuid(session), rep, exten, (char *) refer_to->r_url->url_host, br_a);
9414
9415 if (refer_to->r_url->url_port) {
9416 port = refer_to->r_url->url_port;
9417 }
9418
9419 channel = switch_core_session_get_channel(a_session);
9420
9421 exten = NULL((void*)0);
9422
9423 if (sofia_test_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)((profile)->pflags[PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER
] ? 1 : 0)
) {
9424 switch_xml_t xml_root = NULL((void*)0), xml_channel = NULL((void*)0);
9425 switch_event_t *xml_params = NULL((void*)0);
9426 const char *xml_url = NULL((void*)0), *use_profile = profile->name, *dial_prefix = NULL((void*)0), *absolute_dial_string = NULL((void*)0);
9427 switch_xml_t params = NULL((void*)0), param = NULL((void*)0);
9428
9429 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9429, &xml_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
9430 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "nightmare_xfer");
9431 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
9432 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-user", refer_to->r_url->url_user);
9433 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-host", refer_to->r_url->url_host);
9434 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-params", refer_to->r_url->url_params ? refer_to->r_url->url_params : "");
9435 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-headers", refer_to->r_url->url_headers ? refer_to->r_url->url_headers : "");
9436 if (replaces) {
9437 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "replaces-call-id", replaces->rp_call_id);
9438 }
9439 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-from-channel-id", switch_core_session_get_uuid(session));
9440 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-for-channel-id", br_a);
9441
9442 if (switch_xml_locate("channels", NULL((void*)0), NULL((void*)0), NULL((void*)0),
9443 &xml_root, &xml_channel, xml_params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
9444 if ((params = switch_xml_child(xml_channel, "params"))) {
9445 for (param = switch_xml_child(params, "param"); param; param = param->next) {
9446 const char *name = switch_xml_attr(param, "name");
9447 const char *value = switch_xml_attr(param, "value");
9448
9449 if (!(name && value)) continue;
9450
9451 if (!strcasecmp(name, "sip-url")) {
9452 xml_url = value;
9453 } else if (!strcasecmp(name, "dial-prefix")) {
9454 dial_prefix = value;
9455 } else if (!strcasecmp(name, "absolute-dial-string")) {
9456 absolute_dial_string = value;
9457 } else if (!strcasecmp(name, "sip-profile")) {
9458 use_profile = value;
9459 }
9460 }
9461 }
9462
9463 if (absolute_dial_string) {
9464 exten = switch_core_session_sprintf(session, "%s%s", dial_prefix, absolute_dial_string);
9465 } else if (xml_url) {
9466 exten = switch_core_session_sprintf(session, "%ssofia/%s/%s", dial_prefix, use_profile, xml_url);
9467 }
9468
9469 switch_xml_free(xml_root);
9470 }
9471
9472 switch_event_destroy(&xml_params);
9473 }
9474
9475
9476 if (zstr(exten)_zstr(exten)) {
9477 exten = switch_core_session_sprintf(session, "sofia/%s/sip:%s@%s%s%s",
9478 profile->name, refer_to->r_url->url_user,
9479 refer_to->r_url->url_host, port ? ":" : "", port ? port : "");
9480 }
9481
9482 switch_core_new_memory_pool(&npool)switch_core_perform_new_memory_pool(&npool, "sofia.c", (const
char *)__func__, 9482)
;
9483 nightmare_xfer_helper = switch_core_alloc(npool, sizeof(*nightmare_xfer_helper))switch_core_perform_alloc(npool, sizeof(*nightmare_xfer_helper
), "sofia.c", (const char *)__func__, 9483)
;
9484 nightmare_xfer_helper->exten = switch_core_strdup(npool, exten)switch_core_perform_strdup(npool, exten, "sofia.c", (const char
*)__func__, 9484)
;
9485
9486 if (refer_to->r_url->url_params || refer_to->r_url->url_headers) {
9487 if (refer_to->r_url->url_headers) {
9488 nightmare_xfer_helper->exten_with_params = switch_core_sprintf(npool,
9489 "{sip_invite_params=%s?%s}%s",
9490 refer_to->r_url->url_params ? refer_to->r_url->
9491 url_params : "", refer_to->r_url->url_headers, exten);
9492 } else {
9493 nightmare_xfer_helper->exten_with_params = switch_core_sprintf(npool,
9494 "{sip_invite_params=%s}%s", refer_to->r_url->url_params,
9495 exten);
9496 }
9497 } else {
9498 nightmare_xfer_helper->exten_with_params = nightmare_xfer_helper->exten;
9499 }
9500
9501 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 9501
, ((void*)0)
, SWITCH_LOG_INFO, "Nightmare transfer to '%s'\n", nightmare_xfer_helper->exten_with_params);
9502
9503 nightmare_xfer_helper->event = switch_core_strdup(npool, etmp)switch_core_perform_strdup(npool, etmp, "sofia.c", (const char
*)__func__, 9503)
;
9504 nightmare_xfer_helper->reply_uuid = switch_core_strdup(npool, switch_core_session_get_uuid(session))switch_core_perform_strdup(npool, switch_core_session_get_uuid
(session), "sofia.c", (const char *)__func__, 9504)
;
9505 nightmare_xfer_helper->bridge_to_uuid = switch_core_strdup(npool, br_a)switch_core_perform_strdup(npool, br_a, "sofia.c", (const char
*)__func__, 9505)
;
9506 nightmare_xfer_helper->pool = npool;
9507
9508 if (refer_to->r_url->url_headers) {
9509 char *h, *v, *hp;
9510 p = switch_core_session_strdup(session, refer_to->r_url->url_headers)switch_core_perform_session_strdup(session, refer_to->r_url
->url_headers, "sofia.c", (const char *)__func__, 9510)
;
9511 while (p && *p) {
9512 h = p;
9513 if ((p = strchr(p, '='))) {
9514 *p++ = '\0';
9515 v = p;
9516 if ((p = strchr(p, '&'))) {
9517 *p++ = '\0';
9518 }
9519
9520 url_unescape(h, (const char *) h);
9521 url_unescape(v, (const char *) v);
9522 if (strcasecmp("Replaces", h)) {
9523 hp = switch_core_session_sprintf(session, "%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", h);
9524 switch_channel_set_variable(channel, hp, v)switch_channel_set_variable_var_check(channel, hp, v, SWITCH_TRUE
)
;
9525 } else {
9526 // use this one instead of rep value from above to keep all parameters
9527 switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, v)switch_channel_set_variable_var_check(channel, "_sofia_replaces_"
, v, SWITCH_TRUE)
;
9528 }
9529 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9529, (const char*)(session)
, SWITCH_LOG_DEBUG, "Exporting replaces URL header [%s:%s]\n",
9530 h, v);
9531 }
9532 }
9533 }
9534
9535
9536 switch_event_create(&nightmare_xfer_helper->vars, SWITCH_EVENT_CHANNEL_DATA)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9536, &nightmare_xfer_helper->
vars, SWITCH_EVENT_CHANNEL_DATA, ((void*)0))
;
9537
9538 rep_h = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER)switch_channel_get_variable_dup(channel, "_sofia_replaces_", SWITCH_TRUE
, -1)
;
9539 if (rep_h) {
9540 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REPLACES_HEADER"_sofia_replaces_", rep_h);
9541 } else {
9542 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REPLACES_HEADER"_sofia_replaces_", rep);
9543 }
9544
9545
9546 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
9547 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "Referred-By", full_ref_by);
9548 }
9549
9550 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
9551 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REFER_TO_VARIABLE"sip_refer_to", full_ref_to);
9552 }
9553
9554 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9555 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9555, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9556 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9557 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9558 switch_channel_event_set_data(channel_a, event);
9559 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9559, &event, ((void*)0))
;
9560 }
9561
9562 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9562, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9563 switch_channel_event_set_data(channel, event);
9564 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9564, &event, ((void*)0))
;
9565 }
9566 }
9567
9568 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Refer-From", switch_core_session_get_uuid(session));
9569 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Refer-For", br_a);
9570
9571 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9571, (const char*)(session)
, SWITCH_LOG_DEBUG, "Good Luck, you'll need it......\n");
9572 nightmare_xfer_helper->profile = profile;
9573 launch_nightmare_xfer(nightmare_xfer_helper);
9574
9575 switch_core_session_rwunlock(a_session);
9576
9577 } else {
9578 goto error;
9579 }
9580
9581 } else {
9582 error:
9583 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9583, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid Transfer! [%s]\n", br_a);
9584 switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR")switch_channel_set_variable_var_check(channel_a, "endpoint_disposition"
, "ATTENDED_TRANSFER_ERROR", SWITCH_TRUE)
;
9585 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9586 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
, SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n")siptag_payload_str, tag_str_v("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9587 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))
,
9588 TAG_END()(tag_type_t)0, (tag_value_t)0);
9589 }
9590 }
9591 goto done;
9592 }
9593
9594 } else {
9595 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9595, (const char*)(session)
, SWITCH_LOG_ERROR, "Missing Refer-To\n");
9596 goto done;
9597 }
9598
9599 if (exten) {
9600 switch_channel_t *channel = switch_core_session_get_channel(session);
9601 const char *br = switch_channel_get_partner_uuid(channel);
9602 switch_core_session_t *b_session;
9603
9604 switch_channel_set_variable_printf(channel, "transfer_to", "blind:%s", br ? br : exten);
9605 switch_channel_set_variable_printf(channel, "transfer_destination", "blind:%s", exten);
9606
9607 if (!zstr(br)_zstr(br) && (b_session = switch_core_session_locate(br)switch_core_session_perform_locate(br, "sofia.c", (const char
*)__func__, 9607)
)) {
9608 const char *var;
9609 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
9610 switch_event_t *event = NULL((void*)0);
9611
9612 switch_channel_set_variable(channel, "transfer_fallback_extension", from->a_user)switch_channel_set_variable_var_check(channel, "transfer_fallback_extension"
, from->a_url->url_user, SWITCH_TRUE)
;
9613 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
9614 switch_channel_set_variable(b_channel, SOFIA_SIP_HEADER_PREFIX "Referred-By", full_ref_by)switch_channel_set_variable_var_check(b_channel, "sip_h_" "Referred-By"
, full_ref_by, SWITCH_TRUE)
;
9615 }
9616
9617 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
9618 switch_channel_set_variable(b_channel, SOFIA_REFER_TO_VARIABLE, full_ref_to)switch_channel_set_variable_var_check(b_channel, "sip_refer_to"
, full_ref_to, SWITCH_TRUE)
;
9619 }
9620
9621 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
9622 switch_ivr_transfer_recordings(session, b_session);
9623 }
9624
9625 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "BLIND_TRANSFER")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "BLIND_TRANSFER", SWITCH_TRUE)
;
9626
9627 if (((var = switch_channel_get_variable(channel, "confirm_blind_transfer")switch_channel_get_variable_dup(channel, "confirm_blind_transfer"
, SWITCH_TRUE, -1)
) && switch_true(var)) ||
9628 sofia_test_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)((profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] ? 1 : 0)) {
9629
9630 switch_channel_set_state_flag(b_channel, CF_CONFIRM_BLIND_TRANSFER);
9631 switch_channel_set_variable(channel, "sip_blind_transfer_event", etmp)switch_channel_set_variable_var_check(channel, "sip_blind_transfer_event"
, etmp, SWITCH_TRUE)
;
9632 switch_channel_set_variable(b_channel, "blind_transfer_uuid", switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(b_channel, "blind_transfer_uuid"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
9633 switch_channel_set_variable(channel, "blind_transfer_uuid", switch_core_session_get_uuid(b_session))switch_channel_set_variable_var_check(channel, "blind_transfer_uuid"
, switch_core_session_get_uuid(b_session), SWITCH_TRUE)
;
9634
9635 switch_channel_set_variable(channel, "park_timeout", "600:blind_transfer")switch_channel_set_variable_var_check(channel, "park_timeout"
, "600:blind_transfer", SWITCH_TRUE)
;
9636 switch_channel_set_state(channel, CS_PARK)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 9636, CS_PARK)
;
9637 } else {
9638 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9639 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
9640 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
9641 SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n")siptag_payload_str, tag_str_v("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9642 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))
,
9643 TAG_END()(tag_type_t)0, (tag_value_t)0);
9644 }
9645
9646 if (refer_to->r_url->url_params) {
9647 switch_channel_set_variable(b_channel, "sip_h_X-FS-Refer-Params", refer_to->r_url->url_params)switch_channel_set_variable_var_check(b_channel, "sip_h_X-FS-Refer-Params"
, refer_to->r_url->url_params, SWITCH_TRUE)
;
9648 }
9649
9650 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9651 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9651, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9652 switch_channel_event_set_data(channel_a, event);
9653 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9653, &event, ((void*)0))
;
9654 }
9655
9656 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9656, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9657 switch_channel_event_set_data(b_channel, event);
9658 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9658, &event, ((void*)0))
;
9659 }
9660 }
9661
9662 switch_ivr_session_transfer(b_session, exten, NULL((void*)0), NULL((void*)0));
9663 switch_core_session_rwunlock(b_session);
9664 } else {
9665 switch_event_t *event;
9666
9667 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9667, &event, SWITCH_EVENT_CUSTOM
, "sofia::error")
== SWITCH_STATUS_SUCCESS) {
9668 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Error-Type", "blind_transfer");
9669 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Transfer-Exten", exten);
9670 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Full-Refer-To", full_ref_to);
9671 switch_channel_event_set_data(channel, event);
9672 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9672, &event, ((void*)0))
;
9673 }
9674
9675 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9675, (const char*)(session)
, SWITCH_LOG_ERROR, "Cannot Blind Transfer 1 Legged calls\n");
9676 switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR")switch_channel_set_variable_var_check(channel_a, "endpoint_disposition"
, "ATTENDED_TRANSFER_ERROR", SWITCH_TRUE)
;
9677 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9678 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
9679 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
9680 SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n")siptag_payload_str, tag_str_v("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9681 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))
,
9682 TAG_END()(tag_type_t)0, (tag_value_t)0);
9683 }
9684 }
9685
9686 done:
9687 if (home) {
9688 su_home_unref(home);
9689 home = NULL((void*)0);
9690 }
9691
9692 switch_safe_free(etmp)if (etmp) {free(etmp);etmp=((void*)0);};
9693}
9694
9695
9696static switch_status_t create_info_event(sip_t const *sip,
9697 nua_handle_t *nh, switch_event_t **revent)
9698{
9699 sip_alert_info_t *alert_info = sip_alert_info(sip)((sip_alert_info_t *)msg_header_access((msg_pub_t*)(sip), sip_alert_info_class
))
;
9700 switch_event_t *event;
9701
9702 if (!(sip && switch_event_create(&event, SWITCH_EVENT_RECV_INFO)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9702, &event, SWITCH_EVENT_RECV_INFO
, ((void*)0))
== SWITCH_STATUS_SUCCESS)) {
9703 return SWITCH_STATUS_FALSE;
9704 }
9705
9706 if (sip->sip_content_type) {
9707 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Content-Type", sip->sip_content_type->c_type);
9708 }
9709
9710 if (sip->sip_from) {
9711 if (sip->sip_from->a_url->url_user) {
9712 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-From-User", sip->sip_from->a_url->url_user);
9713 }
9714
9715 if (sip->sip_from->a_url->url_host) {
9716 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-From-Host", sip->sip_from->a_url->url_host);
9717 }
9718 }
9719
9720 if (sip->sip_to) {
9721 if (sip->sip_to->a_url->url_user) {
9722 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-To-User", sip->sip_to->a_url->url_user);
9723 }
9724
9725 if (sip->sip_to->a_url->url_host) {
9726 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-To-Host", sip->sip_to->a_url->url_host);
9727 }
9728 }
9729
9730
9731 if (sip->sip_contact) {
9732 if (sip->sip_contact->m_url->url_user) {
9733 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Contact-User", sip->sip_contact->m_url->url_user);
9734 }
9735
9736 if (sip->sip_contact->m_url->url_host) {
9737 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Contact-Host", sip->sip_contact->m_url->url_host);
9738 }
9739 }
9740
9741
9742 if (sip->sip_call_info) {
9743 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Call-Info",
9744 sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info));
9745 }
9746
9747 if (alert_info) {
9748 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Alert-Info", sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) alert_info));
9749 }
9750
9751
9752 if (sip->sip_payload && sip->sip_payload->pl_data) {
9753 switch_event_add_body(event, "%s", sip->sip_payload->pl_data);
9754 }
9755
9756 *revent = event;
9757
9758 return SWITCH_STATUS_SUCCESS;
9759}
9760
9761switch_status_t sofia_proxy_sip_i_message(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
9762 sofia_dispatch_event_t *de, tagi_t tags[])
9763{
9764 switch_core_session_t *other_session = NULL((void*)0);
9765 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9766
9767 if (session && switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 9767)
== SWITCH_STATUS_SUCCESS) {
9768 if (switch_core_session_compare(session, other_session)) {
9769 private_object_t *other_tech_pvt = NULL((void*)0);
9770 const char *ct = NULL((void*)0);
9771 char *pl = NULL((void*)0);
9772
9773
9774 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
9775 pl = sip->sip_payload->pl_data;
9776 }
9777
9778 other_tech_pvt = (private_object_t *) switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
9779
9780 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype) {
9781 ct = sip->sip_content_type->c_type;
9782 }
9783
9784 nua_message(other_tech_pvt->nh,
9785 TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(nua_handle_get_home(other_tech_pvt->nh), ct)))!(ct) ? tag_skip : siptag_content_type_str, tag_str_v(su_strdup
(nua_handle_get_home(other_tech_pvt->nh), ct))
,
9786 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via))!(!_zstr(other_tech_pvt->user_via)) ? tag_skip : siptag_via_str
, tag_str_v(other_tech_pvt->user_via)
,
9787 TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(nua_handle_get_home(other_tech_pvt->nh), pl)))!(pl) ? tag_skip : siptag_payload_str, tag_str_v(su_strdup(nua_handle_get_home
(other_tech_pvt->nh), pl))
,
9788 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))
,
9789 TAG_END()(tag_type_t)0, (tag_value_t)0);
9790 }
9791
9792 switch_core_session_rwunlock(other_session);
9793
9794 nua_respond(nh, SIP_202_ACCEPTED202, sip_202_Accepted, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
9795 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))
,
9796 TAG_END()(tag_type_t)0, (tag_value_t)0);
9797
9798 return SWITCH_STATUS_SUCCESS;
9799 }
9800
9801 return SWITCH_STATUS_FALSE;
9802}
9803
9804switch_status_t sofia_proxy_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
9805 sofia_dispatch_event_t *de, tagi_t tags[])
9806{
9807 switch_core_session_t *other_session = NULL((void*)0);
9808 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9809
9810 if (session && switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 9810)
== SWITCH_STATUS_SUCCESS) {
9811 if (switch_core_session_compare(session, other_session)) {
9812 private_object_t *other_tech_pvt = NULL((void*)0);
9813 const char *ct = NULL((void*)0);
9814 char *pl = NULL((void*)0);
9815 switch_channel_t *channel = switch_core_session_get_channel(session);
9816
9817 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
9818 pl = sip->sip_payload->pl_data;
9819 }
9820
9821 other_tech_pvt = (private_object_t *) switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
9822
9823 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype) {
9824 ct = sip->sip_content_type->c_type;
9825 }
9826
9827 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && !strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) {
9828 if (switch_channel_test_flag(channel, CF_VIDEO)) {
9829 switch_core_media_gen_key_frame(session)switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const
char *)__func__, 9829, (const char*)(session), SWITCH_LOG_DEBUG1
, "%s Send KeyFrame\n", switch_channel_get_name(switch_core_session_get_channel
(session))); switch_core_media_codec_control(session, SWITCH_MEDIA_TYPE_VIDEO
, SWITCH_IO_WRITE, SCC_VIDEO_GEN_KEYFRAME, SCCT_NONE, ((void*
)0), SCCT_NONE, ((void*)0), ((void*)0), ((void*)0))
;
9830 switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ)switch_channel_set_flag_value(channel, CF_VIDEO_REFRESH_REQ, 1
)
;
9831 }
9832 }
9833
9834 nua_info(other_tech_pvt->nh,
9835 TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(nua_handle_get_home(other_tech_pvt->nh), ct)))!(ct) ? tag_skip : siptag_content_type_str, tag_str_v(su_strdup
(nua_handle_get_home(other_tech_pvt->nh), ct))
,
9836 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via))!(!_zstr(other_tech_pvt->user_via)) ? tag_skip : siptag_via_str
, tag_str_v(other_tech_pvt->user_via)
,
9837 TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(nua_handle_get_home(other_tech_pvt->nh), pl)))!(pl) ? tag_skip : siptag_payload_str, tag_str_v(su_strdup(nua_handle_get_home
(other_tech_pvt->nh), pl))
,
9838 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))
,
9839 TAG_END()(tag_type_t)0, (tag_value_t)0);
9840 }
9841
9842 switch_core_session_rwunlock(other_session);
9843
9844 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
9845
9846 return SWITCH_STATUS_SUCCESS;
9847 }
9848
9849 return SWITCH_STATUS_FALSE;
9850}
9851
9852
9853void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
9854 sofia_dispatch_event_t *de, tagi_t tags[])
9855{
9856 /* placeholder for string searching */
9857 const char *signal_ptr;
9858 const char *rec_header;
9859 const char *clientcode_header;
9860 switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), 0, SWITCH_DTMF_ENDPOINT };
9861 switch_event_t *event;
9862 private_object_t *tech_pvt = NULL((void*)0);
9863 switch_channel_t *channel = NULL((void*)0);
9864 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9865
9866 if (session) {
9867 tech_pvt = (private_object_t *) switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
9868 channel = switch_core_session_get_channel(session);
9869 }
9870
9871 if (sofia_test_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)((profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] ? 1 : 0)) {
9872 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
9873 sip->sip_payload && sip->sip_payload->pl_data) {
9874
9875 if (!strncasecmp(sip->sip_content_type->c_type, "freeswitch", 10)) {
9876
9877 if (!strcasecmp(sip->sip_content_type->c_subtype, "session-event")) {
9878 if (session) {
9879
9880 if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
9881 if (switch_core_session_queue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
9882 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9882, (const char*)(session)
, SWITCH_LOG_DEBUG, "queued freeswitch event for INFO\n");
9883 nua_respond(nh, SIP_200_OK200, sip_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response")siptag_content_type_str, tag_str_v("freeswitch/session-event-response"
)
,
9884 SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED")siptag_payload_str, tag_str_v("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
9885 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))
,
9886 TAG_END()(tag_type_t)0, (tag_value_t)0);
9887 } else {
9888 switch_event_destroy(&event);
9889 nua_respond(nh, SIP_200_OK200, sip_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response")siptag_content_type_str, tag_str_v("freeswitch/session-event-response"
)
,
9890 SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED")siptag_payload_str, tag_str_v("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
9891 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))
,
9892 TAG_END()(tag_type_t)0, (tag_value_t)0);
9893 }
9894 }
9895
9896 } else {
9897 nua_respond(nh, SIP_200_OK200, sip_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response")siptag_content_type_str, tag_str_v("freeswitch/session-event-response"
)
,
9898 SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION")siptag_payload_str, tag_str_v("-ERR INVALID SESSION"), NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
9899 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))
,
9900 TAG_END()(tag_type_t)0, (tag_value_t)0);
9901
9902 }
9903
9904 return;
9905
9906 } else if (!strcasecmp(sip->sip_content_type->c_subtype, "api-request")) {
9907 char *cmd = strdup(sip->sip_payload->pl_data);
9908 char *arg;
9909 switch_stream_handle_t stream = { 0 };
9910 switch_status_t status;
9911
9912 switch_assert(cmd)((cmd) ? (void) (0) : __assert_fail ("cmd", "sofia.c", 9912, __extension__
__PRETTY_FUNCTION__))
;
9913 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 9913, __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
;
9914 switch_assert(stream.data)((stream.data) ? (void) (0) : __assert_fail ("stream.data", "sofia.c"
, 9914, __extension__ __PRETTY_FUNCTION__))
;
9915
9916 if ((arg = strchr(cmd, ':'))) {
9917 *arg++ = '\0';
9918 }
9919
9920 if ((status = switch_api_execute(cmd, arg, NULL((void*)0), &stream)) == SWITCH_STATUS_SUCCESS) {
9921 nua_respond(nh, SIP_200_OK200, sip_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response")siptag_content_type_str, tag_str_v("freeswitch/api-response"),
9922 SIPTAG_PAYLOAD_STR(stream.data)siptag_payload_str, tag_str_v(stream.data), NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
9923 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))
,
9924 TAG_END()(tag_type_t)0, (tag_value_t)0);
9925 } else {
9926
9927 nua_respond(nh, SIP_200_OK200, sip_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response")siptag_content_type_str, tag_str_v("freeswitch/api-response"),
9928 SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND")siptag_payload_str, tag_str_v("-ERR INVALID COMMAND"), NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
9929 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))
,
9930 TAG_END()(tag_type_t)0, (tag_value_t)0);
9931 }
9932
9933 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
9934 switch_safe_free(cmd)if (cmd) {free(cmd);cmd=((void*)0);};
9935 return;
9936 }
9937
9938 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
9939 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))
,
9940 TAG_END()(tag_type_t)0, (tag_value_t)0);
9941
9942 return;
9943 }
9944 }
9945 }
9946
9947 if (session) {
9948 const char *vval;
9949
9950 /* Barf if we didn't get our private */
9951 assert(switch_core_session_get_private(session))((switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)) ? (void) (0) : __assert_fail ("switch_core_session_get_private(session)"
, "sofia.c", 9951, __extension__ __PRETTY_FUNCTION__))
;
9952
9953 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_INFO_HEADER_PREFIX"sip_info_h_");
9954 if (!zstr(profile->proxy_info_content_types)_zstr(profile->proxy_info_content_types) && sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
9955 (!strcasecmp(profile->proxy_info_content_types,"all") || strstr(profile->proxy_info_content_types,sip->sip_content_type->c_type))) {
9956 switch_core_session_t *other_session;
9957
9958 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 9958)
== SWITCH_STATUS_SUCCESS) {
9959 char *pl = NULL((void*)0);
9960 char *ct = NULL((void*)0);
9961 char *extra_headers = NULL((void*)0);
9962 char *unknown = NULL((void*)0);
9963 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
9964
9965 ct = switch_core_session_strdup(other_session, (char*)sip->sip_content_type->c_type)switch_core_perform_session_strdup(other_session, (char*)sip->
sip_content_type->c_type, "sofia.c", (const char *)__func__
, 9965)
;
9966 if (sip->sip_payload && sip->sip_payload->pl_data) {
9967 pl = switch_core_session_strdup(other_session,(char*)sip->sip_payload->pl_data)switch_core_perform_session_strdup(other_session, (char*)sip->
sip_payload->pl_data, "sofia.c", (const char *)__func__, 9967
)
;
9968 }
9969 unknown = sofia_glue_get_non_extra_unknown_headers(sip);
9970
9971 extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_INFO_HEADER_PREFIX"sip_info_h_");
9972
9973 nua_info(other_tech_pvt->nh,
9974 SIPTAG_CONTENT_TYPE_STR(ct)siptag_content_type_str, tag_str_v(ct),
9975 TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers))!(!_zstr(extra_headers)) ? tag_skip : siptag_header_str, tag_str_v
((extra_headers))
,
9976 TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown))!(!_zstr(unknown)) ? tag_skip : siptag_header_str, tag_str_v(
(unknown))
,
9977 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via))!(!_zstr(other_tech_pvt->user_via)) ? tag_skip : siptag_via_str
, tag_str_v(other_tech_pvt->user_via)
,
9978 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))
,
9979 TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl))!(!_zstr(pl)) ? tag_skip : siptag_payload_str, tag_str_v(pl),
9980 TAG_END()(tag_type_t)0, (tag_value_t)0);
9981 switch_safe_free(extra_headers)if (extra_headers) {free(extra_headers);extra_headers=((void*
)0);}
;
9982 switch_safe_free(unknown)if (unknown) {free(unknown);unknown=((void*)0);};
9983 switch_core_session_rwunlock(other_session);
9984 }
9985 }
9986
9987 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && !strcasecmp(sip->sip_content_type->c_type, "freeswitch/data")) {
9988 char *data = NULL((void*)0);
9989
9990 if (sip->sip_payload && sip->sip_payload->pl_data) {
9991 data = sip->sip_payload->pl_data;
9992 }
9993
9994 if ((vval = switch_channel_get_variable(channel, "sip_copy_custom_headers")switch_channel_get_variable_dup(channel, "sip_copy_custom_headers"
, SWITCH_TRUE, -1)
) && switch_true(vval)) {
9995 switch_core_session_t *nsession = NULL((void*)0);
9996
9997 switch_core_session_get_partner(session, &nsession)switch_core_session_perform_get_partner(session, &nsession
, "sofia.c", (const char *)__func__, 9997)
;
9998
9999 if (nsession) {
10000 switch_core_session_message_t *msg;
10001
10002 switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_INFO_HEADER_PREFIX_T"~sip_info_h_");
10003 msg = switch_core_session_alloc(nsession, sizeof(*msg))switch_core_perform_session_alloc(nsession, sizeof(*msg), "sofia.c"
, (const char *)__func__, 10003)
;
10004 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 10004
;
10005 msg->message_id = SWITCH_MESSAGE_INDICATE_INFO;
10006
10007 msg->string_array_arg[2] = switch_core_session_strdup(nsession, data)switch_core_perform_session_strdup(nsession, data, "sofia.c",
(const char *)__func__, 10007)
;
10008
10009 msg->from = __FILE__"sofia.c";
10010 switch_core_session_queue_message(nsession, msg);
10011
10012 switch_core_session_rwunlock(nsession);
10013 }
10014 }
10015 }
10016
10017 if (sip && sip->sip_content_type && sip->sip_content_type->c_subtype && sip->sip_content_type->c_type &&
10018 !strncasecmp(sip->sip_content_type->c_type, "message", 7) &&
10019 !strcasecmp(sip->sip_content_type->c_subtype, "update_display")) {
10020 sofia_update_callee_id(session, profile, sip, SWITCH_TRUE);
10021 goto end;
10022 }
10023
10024 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
10025 sip->sip_payload && sip->sip_payload->pl_data) {
10026 if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) {
10027
10028 if (switch_channel_test_flag(channel, CF_VIDEO)) {
10029 switch_core_media_gen_key_frame(session)switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const
char *)__func__, 10029, (const char*)(session), SWITCH_LOG_DEBUG1
, "%s Send KeyFrame\n", switch_channel_get_name(switch_core_session_get_channel
(session))); switch_core_media_codec_control(session, SWITCH_MEDIA_TYPE_VIDEO
, SWITCH_IO_WRITE, SCC_VIDEO_GEN_KEYFRAME, SCCT_NONE, ((void*
)0), SCCT_NONE, ((void*)0), ((void*)0), ((void*)0))
;
10030 switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ)switch_channel_set_flag_value(channel, CF_VIDEO_REFRESH_REQ, 1
)
;
10031 }
10032
10033 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) &&
10034 !strcasecmp(sip->sip_content_type->c_subtype, "vnd.nortelnetworks.digits")) {
10035 int tmp;
10036 if ((signal_ptr = switch_stristr("d=", sip->sip_payload->pl_data))) {
10037 signal_ptr = signal_ptr + 2;
10038
10039 while (*signal_ptr && *signal_ptr == ' ') {
10040 signal_ptr++;
10041 }
10042
10043 if (*signal_ptr && (*signal_ptr == '*' || *signal_ptr == '#' || *signal_ptr == 'A' || *signal_ptr == 'B'
10044 || *signal_ptr == 'C' || *signal_ptr == 'D')) {
10045 dtmf.digit = *signal_ptr;
10046 } else {
10047 tmp = atoi(signal_ptr);
10048 dtmf.digit = switch_rfc2833_to_char(tmp);
10049 }
10050
10051 dtmf.duration = 100;
10052 } else {
10053 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10053, (const char*)(session)
, SWITCH_LOG_DEBUG, "Bad signal\n");
10054 goto end;
10055 }
10056 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) {
10057 /* Try and find signal information in the payload */
10058 if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) {
10059 int tmp;
10060 /* move signal_ptr where we need it (right past Signal=) */
10061 signal_ptr = signal_ptr + 7;
10062
10063 /* handle broken devices with spaces after the = (cough) VegaStream (cough) */
10064 while (*signal_ptr && *signal_ptr == ' ')
10065 signal_ptr++;
10066
10067 if (*signal_ptr
10068 && (*signal_ptr == '*' || *signal_ptr == '#' || *signal_ptr == 'A' || *signal_ptr == 'B' || *signal_ptr == 'C'
10069 || *signal_ptr == 'D')) {
10070 dtmf.digit = *signal_ptr;
10071 } else {
10072 tmp = atoi(signal_ptr);
10073 dtmf.digit = switch_rfc2833_to_char(tmp);
10074 }
10075 } else {
10076 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10076, (const char*)(session)
, SWITCH_LOG_DEBUG, "Bad signal\n");
10077 goto end;
10078 }
10079
10080 if ((signal_ptr = switch_stristr("Duration=", sip->sip_payload->pl_data))) {
10081 int tmp;
10082 signal_ptr += 9;
10083
10084 /* handle broken devices with spaces after the = (cough) VegaStream (cough) */
10085 while (*signal_ptr && *signal_ptr == ' ')
10086 signal_ptr++;
10087
10088 if ((tmp = atoi(signal_ptr)) <= 0) {
10089 tmp = switch_core_default_dtmf_duration(0);
10090 }
10091 dtmf.duration = tmp * 8;
10092 }
10093 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf")) {
10094 int tmp = atoi(sip->sip_payload->pl_data);
10095 dtmf.digit = switch_rfc2833_to_char(tmp);
10096 }
10097
10098 if (dtmf.digit) {
10099 if (tech_pvt->mparams.dtmf_type == DTMF_INFO ||
10100 sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF)((tech_pvt->profile)->pflags[PFLAG_LIBERAL_DTMF] ? 1 : 0
)
|| switch_channel_test_flag(tech_pvt->channel, CF_LIBERAL_DTMF)) {
10101 /* queue it up */
10102 switch_channel_queue_dtmf(channel, &dtmf);
10103
10104 /* print debug info */
10105 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10105, (const char*)(session)
, SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit);
10106
10107 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
10108 const char *uuid;
10109 switch_core_session_t *session_b;
10110
10111 if ((uuid = switch_channel_get_partner_uuid(channel)) && (session_b = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 10111)
)) {
10112 while (switch_channel_has_dtmf(channel)) {
10113 switch_dtmf_t idtmf = { 0, 0 };
10114 if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) {
10115 switch_core_session_send_dtmf(session_b, &idtmf);
10116 }
10117 }
10118
10119 switch_core_session_rwunlock(session_b);
10120 }
10121 }
10122
10123 /* Send 200 OK response */
10124 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10125 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))
,
10126 TAG_END()(tag_type_t)0, (tag_value_t)0);
10127 } else {
10128 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10128, (const char*)(session)
, SWITCH_LOG_WARNING,
10129 "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
10130 }
10131 goto end;
10132 }
10133 }
10134
10135 if ((clientcode_header = sofia_glue_get_unknown_header(sip, "x-clientcode"))) {
10136 if (!zstr(clientcode_header)_zstr(clientcode_header)) {
10137 switch_channel_set_variable(channel, "call_clientcode", clientcode_header)switch_channel_set_variable_var_check(channel, "call_clientcode"
, clientcode_header, SWITCH_TRUE)
;
10138 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10138, (const char*)(session)
, SWITCH_LOG_NOTICE, "Setting CMC to %s\n", clientcode_header);
10139 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10140 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))
,
10141 TAG_END()(tag_type_t)0, (tag_value_t)0);
10142 }
10143 goto end;
10144 }
10145
10146 if ((rec_header = sofia_glue_get_unknown_header(sip, "record"))) {
10147 if (zstr(profile->record_template)_zstr(profile->record_template)) {
10148 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10148, (const char*)(session)
, SWITCH_LOG_WARNING, "Record attempted but no template defined.\n");
10149 nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10150 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))
,
10151 TAG_END()(tag_type_t)0, (tag_value_t)0);
10152 } else {
10153 if (!strcasecmp(rec_header, "on")) {
10154 char *file = NULL((void*)0), *tmp = NULL((void*)0);
10155
10156 if (switch_true(switch_channel_get_variable(channel, "sip_disable_recording")switch_channel_get_variable_dup(channel, "sip_disable_recording"
, SWITCH_TRUE, -1)
)) {
10157 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10157, (const char*)(session)
, SWITCH_LOG_WARNING, "Record attempted but is disabled by sip_disable_recording variable.\n");
10158 nua_respond(nh, 488, "Recording disabled for this channel", NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10159 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
10160 } else {
10161
10162 tmp = switch_mprintf("%s%s%s", profile->record_path ? profile->record_path : "${recordings_dir}",
10163 SWITCH_PATH_SEPARATOR"/", profile->record_template);
10164 file = switch_channel_expand_variables(channel, tmp)switch_channel_expand_variables_check(channel, tmp, ((void*)0
), ((void*)0), 0)
;
10165 switch_ivr_record_session(session, file, 0, NULL((void*)0));
10166 switch_channel_set_variable(channel, "sofia_record_file", file)switch_channel_set_variable_var_check(channel, "sofia_record_file"
, file, SWITCH_TRUE)
;
10167 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10167, (const char*)(session)
, SWITCH_LOG_NOTICE, "Recording %s to %s\n", switch_channel_get_name(channel),
10168 file);
10169 switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);};
10170 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10171 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))
,
10172 TAG_END()(tag_type_t)0, (tag_value_t)0);
10173 if (file != profile->record_template) {
10174 free(file);
10175 file = NULL((void*)0);
10176 }
10177 }
10178 } else {
10179 const char *file;
10180
10181 if ((file = switch_channel_get_variable(channel, "sofia_record_file")switch_channel_get_variable_dup(channel, "sofia_record_file",
SWITCH_TRUE, -1)
)) {
10182 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10182, (const char*)(session)
, SWITCH_LOG_NOTICE, "Done recording %s to %s\n",
10183 switch_channel_get_name(channel), file);
10184 switch_ivr_stop_record_session(session, file);
10185 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10186 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))
,
10187 TAG_END()(tag_type_t)0, (tag_value_t)0);
10188 } else {
10189 nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10190 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))
,
10191 TAG_END()(tag_type_t)0, (tag_value_t)0);
10192 }
10193 }
10194 }
10195 }
10196 }
10197
10198 end:
10199
10200 if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
10201 if (channel) {
10202 switch_channel_event_set_data(channel, event);
10203 }
10204 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 10204, &event, ((void*)0))
;
10205 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10205, (const char*)(session)
, SWITCH_LOG_DEBUG1, "dispatched freeswitch event for INFO\n");
10206 }
10207
10208 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10209 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))
,
10210 TAG_END()(tag_type_t)0, (tag_value_t)0);
10211
10212 return;
10213
10214}
10215
10216void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
10217 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
10218 sofia_dispatch_event_t *de,
10219 tagi_t tags[])
10220{
10221 char *call_info = NULL((void*)0);
10222 switch_channel_t *channel = NULL((void*)0);
10223 private_object_t *tech_pvt = NULL((void*)0);
10224
10225 nua_respond(nh, SIP_100_TRYING100, sip_100_Trying, TAG_END()(tag_type_t)0, (tag_value_t)0);
10226
10227 if (session) {
10228 channel = switch_core_session_get_channel(session);
10229 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
10230
10231
10232 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10233 tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data)switch_core_perform_session_strdup(session, sip->sip_payload
->pl_data, "sofia.c", (const char *)__func__, 10233)
;
10234 }
10235 }
10236
10237 if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)((profile)->pflags[PFLAG_TRACK_CALLS] ? 1 : 0)) {
10238 switch_channel_t *channel = switch_core_session_get_channel(session);
10239 private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
10240 char network_ip[80] = "";
10241 int network_port = 0;
10242 char via_space[2048];
10243 char branch[16] = "";
10244
10245 sofia_glue_store_session_id(session, profile, sip, 0);
10246
10247 sofia_clear_flag(tech_pvt, TFLAG_GOT_ACK)(tech_pvt)->flags[TFLAG_GOT_ACK] = 0;
10248
10249 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
10250 switch_stun_random_string(branch, sizeof(branch) - 1, "0123456789abcdef");
10251
10252 switch_snprintf(via_space, sizeof(via_space), "SIP/2.0/UDP %s;rport=%d;branch=%s", network_ip, network_port, branch);
10253 switch_channel_set_variable(channel, "sip_full_via", via_space)switch_channel_set_variable_var_check(channel, "sip_full_via"
, via_space, SWITCH_TRUE)
;
10254 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
10255 switch_channel_set_variable_printf(channel, "sip_recieved_port", "%d", network_port);
10256 switch_channel_set_variable_printf(channel, "sip_via_rport", "%d", network_port);
10257
10258 switch_core_recovery_track(session);
10259 }
10260
10261 if (profile && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
10262 if (channel && sip && sip->sip_call_info) {
10263 char *p;
10264 if ((call_info = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info))) {
10265 if (switch_stristr("appearance", call_info)) {
10266 switch_channel_set_variable(channel, "presence_call_info_full", call_info)switch_channel_set_variable_var_check(channel, "presence_call_info_full"
, call_info, SWITCH_TRUE)
;
10267 if ((p = strchr(call_info, ';'))) {
10268 switch_channel_set_variable(channel, "presence_call_info", p + 1)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p + 1, SWITCH_TRUE)
;
10269 }
10270 }
10271 su_free(nua_handle_home(nh)((su_home_t *)(nh)), call_info);
10272 }
10273 }
10274 }
10275
10276 if (channel) {
10277 if (tech_pvt->mparams.last_sdp_str) {
10278 tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
10279 }
10280 tech_pvt->mparams.last_sdp_str = NULL((void*)0);
10281
10282 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10283 if (!zstr(tech_pvt->mparams.prev_sdp_str)_zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) {
10284 switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data)switch_channel_set_variable_var_check(channel, "sip_reinvite_sdp"
, sip->sip_payload->pl_data, SWITCH_TRUE)
;
10285 tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data)switch_core_perform_session_strdup(session, sip->sip_payload
->pl_data, "sofia.c", (const char *)__func__, 10285)
;
10286 } else {
10287 tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str;
10288 }
10289 }
10290
10291 switch_channel_execute_on(channel, "execute_on_sip_reinvite");
10292 }
10293
10294}
10295
10296switch_status_t sofia_locate_user(char* user, switch_core_session_t *session, sip_t const *sip, switch_xml_t* x_user)
10297{
10298 char *username, *domain;
10299 switch_event_t *v_event = NULL((void*)0);
10300 switch_status_t result = SWITCH_STATUS_FALSE;
10301
10302 if (!session) {
10303 return SWITCH_STATUS_FALSE;
10304 }
10305
10306 if (zstr(user)_zstr(user)) {
10307 return SWITCH_STATUS_FALSE;
10308 }
10309
10310 if (!(username = switch_core_session_strdup(session, user)switch_core_perform_session_strdup(session, user, "sofia.c", (
const char *)__func__, 10310)
)) {
10311 return SWITCH_STATUS_FALSE;
10312 }
10313
10314 if (!(domain = strchr(username, '@'))) {
10315 return SWITCH_STATUS_FALSE;
10316 }
10317
10318 *domain++ = '\0';
10319
10320 if (switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 10320, &v_event, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
10321 sip_unknown_t *un;
10322 for (un = sip->sip_unknown; un; un = un->un_next) {
10323 switch_event_add_header_string(v_event, SWITCH_STACK_BOTTOM, un->un_name, un->un_value);
10324 };
10325 switch_channel_event_set_data(switch_core_session_get_channel(session), v_event);
10326 }
10327
10328 result = switch_xml_locate_user_merged("id", username, domain, NULL((void*)0), x_user, v_event);
10329
10330 if (v_event) {
10331 switch_event_destroy(&v_event);
10332 }
10333
10334 return result;
10335}
10336
10337void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, sofia_dispatch_event_t *de, tagi_t tags[])
10338{
10339 char key[128] = "";
10340 sip_unknown_t *un;
10341 sip_remote_party_id_t *rpid = NULL((void*)0);
10342 sip_p_asserted_identity_t *passerted = NULL((void*)0);
10343 sip_p_preferred_identity_t *ppreferred = NULL((void*)0);
10344 sip_privacy_t *privacy = NULL((void*)0);
10345 sip_alert_info_t *alert_info = NULL((void*)0);
10346 sip_call_info_t *call_info = NULL((void*)0);
10347 private_object_t *tech_pvt = NULL((void*)0);
10348 switch_channel_t *channel = NULL((void*)0);
10349 //const char *channel_name = NULL;
10350 const char *displayname = NULL((void*)0);
10351 const char *destination_number = NULL((void*)0);
10352 const char *from_user = NULL((void*)0), *from_host = NULL((void*)0);
10353 const char *referred_by_user = NULL((void*)0);//, *referred_by_host = NULL;
10354 const char *context = NULL((void*)0);
10355 const char *dialplan = NULL((void*)0);
10356 char network_ip[80] = "";
10357 char proxied_client_ip[80];
10358 switch_event_t *v_event = NULL((void*)0);
10359 switch_xml_t x_user = NULL((void*)0);
10360 uint32_t sess_count = switch_core_session_count();
10361 uint32_t sess_max = switch_core_session_limit(0);
10362 int is_auth = 0, calling_myself = 0;
10363 int network_port = 0;
10364 char *is_nat = NULL((void*)0);
10365 char *aniii = NULL((void*)0);
10366 char acl_token[512] = "";
10367 sofia_transport_t transport;
10368 const char *gw_name = NULL((void*)0);
10369 const char *gw_param_name = NULL((void*)0);
10370 char *call_info_str = NULL((void*)0);
10371 nua_handle_t *bnh = NULL((void*)0);
10372 char sip_acl_authed_by[512] = "";
10373 char sip_acl_token[512] = "";
10374 const char *dialog_from_user = "", *dialog_from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
10375 const char *user_agent = "", *call_id = "";
10376 url_t *from = NULL((void*)0), *to = NULL((void*)0), *contact = NULL((void*)0);
10377 const char *to_tag = "";
10378 const char *from_tag = "";
10379 char *sql = NULL((void*)0);
10380 char *acl_context = NULL((void*)0);
10381 const char *r_sdp = NULL((void*)0);
10382 int is_tcp = 0, is_tls = 0;
10383 const char *uparams = NULL((void*)0);
10384 char *name_params = NULL((void*)0);
10385 const char *req_uri = NULL((void*)0);
10386 char *req_user = NULL((void*)0);
10387 switch_time_t sip_invite_time;
10388 const char *session_id_header;
10389
10390 sofia_glue_store_session_id(session, profile, sip, 0);
10391 session_id_header = sofia_glue_session_id_header(session, profile);
10392
10393 if (sip && sip->sip_contact && sip->sip_contact->m_url->url_params) {
1
Assuming 'sip' is non-null
2
Assuming the condition is true
3
Assuming the condition is true
4
Taking true branch
10394 uparams = sip->sip_contact->m_url->url_params;
10395 } else {
10396 uparams = NULL((void*)0);
10397 }
10398
10399
10400 if (uparams) {
5
Taking true branch
10401 if (switch_stristr("transport=tcp", uparams)) {
6
Assuming the condition is false
7
Taking false branch
10402 is_tcp = 1;
10403 } else if (switch_stristr("transport=tls", uparams)) {
8
Assuming the condition is false
9
Taking false branch
10404 is_tls = 1;
10405 }
10406 }
10407
10408 profile->ib_calls++;
10409
10410 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10
Assuming the condition is false
10411 r_sdp = sip->sip_payload->pl_data;
10412 }
10413
10414 if (!session || (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0))) {
11
Assuming 'session' is non-null
12
Assuming 'sess_count' is < 'sess_max'
13
Taking false branch
10415 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300")siptag_retry_after_str, tag_str_v("300"),
10416 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
10417 goto fail;
10418 }
10419
10420 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
10421
10422 sip_invite_time = switch_micro_time_now();
10423
10424 if (!sip || !sip->sip_request || !sip->sip_request->rq_method_name) {
14
Assuming the condition is false
15
Assuming the condition is false
16
Taking false branch
10425 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10425
, ((void*)0)
, SWITCH_LOG_ERROR, "Received an invalid packet!\n");
10426 nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE503, sip_503_Service_unavailable,
10427 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
10428 goto fail;
10429 }
10430
10431 if (!(sip->sip_contact)) {
17
Taking false branch
10432 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10432
, ((void*)0)
, SWITCH_LOG_ERROR, "NO CONTACT!\n");
10433 nua_respond(nh, 400, "Missing Contact Header",
10434 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
10435 goto fail;
10436 }
10437
10438
10439 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
10440
10441 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10441, (const char*)(tech_pvt->session)
, SWITCH_LOG_INFO, "%s receiving invite from %s:%d version: %s call-id: %s\n",
10442 switch_channel_get_name(tech_pvt->channel), network_ip, network_port, switch_version_full_human(), sip->sip_call_id ? switch_str_nil(sip->sip_call_id->i_id)(sip->sip_call_id->i_id ? sip->sip_call_id->i_id :
"")
: "");
18
Assuming the condition is false
19
'?' condition is false
10443
10444
10445 if (sip->sip_via && sip->sip_via->v_protocol && switch_stristr("sip/2.0/ws", sip->sip_via->v_protocol)) {
20
Assuming the condition is false
10446 is_nat = "websockets";
10447 }
10448
10449
10450 if (r_sdp) {
21
Taking false branch
10451 switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
10452 }
10453
10454
10455 if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)((profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] ? 1 : 0
)
||
10456 (sofia_test_pflag(profile, PFLAG_TLS_ALWAYS_NAT)((profile)->pflags[PFLAG_TLS_ALWAYS_NAT] ? 1 : 0) && (is_tcp || is_tls)) ||
10457 (!is_tcp && !is_tls && (zstr(network_ip)_zstr(network_ip) || !switch_check_network_list_ip(network_ip, profile->local_network)switch_check_network_list_ip_token(network_ip, profile->local_network
, ((void*)0))
) &&
22
Assuming the condition is false
10458 profile->server_rport_level >= 2 && sip->sip_user_agent &&
10459 sip->sip_user_agent->g_string &&
10460 (!strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7) || !strncasecmp(sip->sip_user_agent->g_string, "KIRK Wireless Server", 20)))
10461 ) {
10462 if (sip->sip_via) {
10463 const char *port = sip->sip_via->v_port;
10464 const char *host = sip->sip_via->v_host;
10465
10466 if (host && sip->sip_via->v_received) {
10467 is_nat = "via received";
10468 } else if (host && strcmp(network_ip, host)) {
10469 is_nat = "via host";
10470 } else if (port && atoi(port) != network_port) {
10471 is_nat = "via port";
10472 }
10473 }
10474 }
10475
10476 if (!is_nat && profile->nat_acl_count) {
23
Assuming the condition is false
24
Taking false branch
10477 uint32_t x = 0;
10478 int contact_private_ip = 1;
10479 int network_private_ip = 0;
10480 char *last_acl = NULL((void*)0);
10481 const char *contact_host = NULL((void*)0);
10482
10483 if (sip->sip_via && sip->sip_via->v_host) {
10484 contact_host = sip->sip_via->v_host;
10485 } else if (sip->sip_contact) {
10486 contact_host = sip->sip_contact->m_url->url_host;
10487 }
10488
10489 if (!zstr(contact_host)_zstr(contact_host)) {
10490 /* NAT mode double check logic and examples.
10491
10492 Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point
10493 is most likely behind nat with us so we need to veto that decision to turn on nat processing.
10494
10495 Example 2: the contact_host is 192.168.1.100 and the network_ip is 192.0.2.100 which is a public internet ip
10496 the remote endpoint is likely behind a remote nat traversing the public internet.
10497
10498 This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net
10499 in cases where we don't really need to be doing this.
10500
10501 Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind
10502 remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process.
10503
10504 */
10505
10506 for (x = 0; x < profile->nat_acl_count; x++) {
10507 last_acl = profile->nat_acl[x];
10508 if ((contact_private_ip = switch_check_network_list_ip(contact_host, last_acl)switch_check_network_list_ip_token(contact_host, last_acl, ((
void*)0))
)) {
10509 break;
10510 }
10511 }
10512 if (contact_private_ip) {
10513 for (x = 0; x < profile->nat_acl_count; x++) {
10514 if ((network_private_ip = switch_check_network_list_ip(network_ip, profile->nat_acl[x])switch_check_network_list_ip_token(network_ip, profile->nat_acl
[x], ((void*)0))
)) {
10515 break;
10516 }
10517 }
10518 }
10519
10520 if (contact_private_ip && !network_private_ip) {
10521 is_nat = last_acl;
10522 }
10523 }
10524 }
10525
10526 if (profile->acl_count) {
25
Assuming the condition is false
26
Taking false branch
10527 uint32_t x = 0;
10528 int ok = 1;
10529 char *last_acl = NULL((void*)0);
10530 const char *token = NULL((void*)0);
10531 int acl_port = sofia_test_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK)((profile)->pflags[PFLAG_USE_PORT_FOR_ACL_CHECK] ? 1 : 0) ? network_port : 0;
10532
10533 for (x = 0; x < profile->acl_count; x++) {
10534 last_acl = profile->acl[x];
10535 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10535
, ((void*)0)
, SWITCH_LOG_DEBUG, "verifying acl \"%s\" for ip/port %s:%i.\n",
10536 switch_str_nil(last_acl)(last_acl ? last_acl : ""), network_ip, acl_port);
10537 if ((ok = switch_check_network_list_ip_port_token(network_ip, acl_port, last_acl, &token))) {
10538
10539 if (profile->acl_pass_context[x]) {
10540 acl_context = profile->acl_pass_context[x];
10541 }
10542 if(!token && profile->acl_inbound_x_token_header) {
10543 const char * x_auth_token = sofia_glue_get_unknown_header(sip, profile->acl_inbound_x_token_header);
10544 if (!zstr(x_auth_token)_zstr(x_auth_token)) {
10545 token = x_auth_token;
10546 }
10547 }
10548
10549 break;
10550 }
10551
10552 if (profile->acl_fail_context[x]) {
10553 acl_context = profile->acl_fail_context[x];
10554 } else {
10555 acl_context = NULL((void*)0);
10556 }
10557 }
10558
10559 if (ok) {
10560 if (token) {
10561 switch_set_string(acl_token, token)switch_copy_string(acl_token, token, sizeof(acl_token));
10562 }
10563 if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
10564 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10564
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
10565 network_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""), acl_token);
10566 switch_set_string(sip_acl_authed_by, last_acl)switch_copy_string(sip_acl_authed_by, last_acl, sizeof(sip_acl_authed_by
))
;
10567 switch_set_string(sip_acl_token, acl_token)switch_copy_string(sip_acl_token, acl_token, sizeof(sip_acl_token
))
;
10568 is_auth = 1;
10569 }
10570 } else {
10571 int network_ip_is_proxy = 0;
10572 const char* x_auth_ip = network_ip;
10573 /* Check if network_ip is a proxy allowed to send us calls */
10574 if (profile->proxy_acl_count) {
10575 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10575
, ((void*)0)
, SWITCH_LOG_DEBUG, "%d acls to check for proxy\n", profile->proxy_acl_count);
10576 for (x = 0; x < profile->proxy_acl_count; x++) {
10577 last_acl = profile->proxy_acl[x];
10578 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10578
, ((void*)0)
, SWITCH_LOG_DEBUG, "checking %s against acl %s\n", network_ip, last_acl);
10579 if (switch_check_network_list_ip_port_token(network_ip, network_port, last_acl, &token)) {
10580 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10580
, ((void*)0)
, SWITCH_LOG_INFO, "%s is a proxy according to the %s acl\n", network_ip, last_acl);
10581 network_ip_is_proxy = 1;
10582 break;
10583 }
10584 }
10585 }
10586
10587 /*
10588 * if network_ip is a proxy allowed to send calls, check for auth
10589 * ip header and see if it matches against the inbound acl
10590 */
10591 if (network_ip_is_proxy) {
10592 const char * x_auth_port = sofia_glue_get_unknown_header(sip, "X-AUTH-PORT");
10593 int x_auth_port_i = sofia_test_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK)((profile)->pflags[PFLAG_USE_PORT_FOR_ACL_CHECK] ? 1 : 0) ? zstr(x_auth_port)_zstr(x_auth_port) ? 0 : atoi(x_auth_port) : 0;
10594
10595 /*
10596 * if network_ip is a proxy allowed to send calls,
10597 * authorize call if proxy provided matched token header
10598 */
10599 if (profile->acl_proxy_x_token_header) {
10600 const char * x_auth_token = sofia_glue_get_unknown_header(sip, profile->acl_proxy_x_token_header);
10601 if (!zstr(x_auth_token)_zstr(x_auth_token)) {
10602 token = x_auth_token;
10603 switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
10604 ok = 1;
10605 }
10606 }
10607
10608 if (!ok && (x_auth_ip = sofia_glue_get_unknown_header(sip, "X-AUTH-IP")) && !zstr(x_auth_ip)_zstr(x_auth_ip)) {
10609 for (x = 0; x < profile->acl_count; x++) {
10610 last_acl = profile->acl[x];
10611 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10611
, ((void*)0)
, SWITCH_LOG_DEBUG, "verifying acl \"%s\" from proxy for ip/port %s:%i.\n",
10612 switch_str_nil(last_acl)(last_acl ? last_acl : ""), x_auth_ip, x_auth_port_i);
10613 if ((ok = switch_check_network_list_ip_port_token(x_auth_ip, x_auth_port_i, last_acl, &token))) {
10614
10615 switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
10616
10617 if (profile->acl_pass_context[x]) {
10618 acl_context = profile->acl_pass_context[x];
10619 }
10620
10621 break;
10622 }
10623
10624 if (profile->acl_fail_context[x]) {
10625 acl_context = profile->acl_fail_context[x];
10626 } else {
10627 acl_context = NULL((void*)0);
10628 }
10629 }
10630 } else {
10631 x_auth_ip = network_ip;
10632 }
10633 }
10634
10635 if (ok) {
10636 if (token) {
10637 switch_set_string(acl_token, token)switch_copy_string(acl_token, token, sizeof(acl_token));
10638 }
10639 if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
10640 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10640
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
10641 x_auth_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""), acl_token);
10642 switch_set_string(sip_acl_authed_by, last_acl)switch_copy_string(sip_acl_authed_by, last_acl, sizeof(sip_acl_authed_by
))
;
10643 switch_set_string(sip_acl_token, acl_token)switch_copy_string(sip_acl_token, acl_token, sizeof(sip_acl_token
))
;
10644 is_auth = 1;
10645 }
10646 } else {
10647 if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
10648 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10648
, ((void*)0)
, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", x_auth_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""));
10649 if (!acl_context) {
10650 nua_respond(nh, SIP_403_FORBIDDEN403, sip_403_Forbidden,
10651 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
10652 goto fail;
10653 } else {
10654 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10654
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
10655 x_auth_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""));
10656 }
10657 }
10658 }
10659 }
10660 }
10661
10662
10663 if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0) && sofia_test_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)((profile)->pflags[PFLAG_AUTH_CALLS_ACL_ONLY] ? 1 : 0)) {
10664 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10664
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP/Port %s %i Rejected by acls and auth-calls-acl-only flag is set, rejecting call\n",
10665 network_ip, network_port);
10666 nua_respond(nh, SIP_403_FORBIDDEN403, sip_403_Forbidden,
10667 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
10668 goto fail;
10669 }
10670
10671 if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0) && sofia_test_pflag(profile, PFLAG_BLIND_AUTH)((profile)->pflags[PFLAG_BLIND_AUTH] ? 1 : 0)) {
10672 char *user = NULL((void*)0);
10673 switch_status_t blind_result = SWITCH_STATUS_FALSE;
10674
10675 if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
10676 calling_myself++;
10677 }
10678
10679 if (sip->sip_from) {
10680 user = switch_core_session_sprintf(session, "%s@%s", sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host);
10681 blind_result = sofia_locate_user(user, session, sip, &x_user);
10682 }
10683 if (!sofia_test_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)((profile)->pflags[PFLAG_BLIND_AUTH_ENFORCE_RESULT] ? 1 : 0
)
|| blind_result == SWITCH_STATUS_SUCCESS) {
10684 is_auth++;
10685 } else if (sofia_test_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)((profile)->pflags[PFLAG_BLIND_AUTH_REPLY_403] ? 1 : 0)) {
10686 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10686
, ((void*)0)
, SWITCH_LOG_DEBUG, "blind auth enforce 403 enabled and couldn't find user %s, rejecting call\n", user);
10687 nua_respond(nh, SIP_403_FORBIDDEN403, sip_403_Forbidden, TAG_END()(tag_type_t)0, (tag_value_t)0);
10688 goto fail;
10689 }
10690 }
10691
10692 if (sip->sip_from && sip->sip_from->a_url) {
27
Assuming the condition is false
10693 tech_pvt->from_user = switch_core_session_strdup(session, sip->sip_from->a_url->url_user)switch_core_perform_session_strdup(session, sip->sip_from->
a_url->url_user, "sofia.c", (const char *)__func__, 10693)
;
10694 }
10695 tech_pvt->mparams.remote_ip = switch_core_session_strdup(session, network_ip)switch_core_perform_session_strdup(session, network_ip, "sofia.c"
, (const char *)__func__, 10695)
;
10696 tech_pvt->mparams.remote_port = network_port;
10697
10698 if (!is_auth &&
30
Taking false branch
10699 (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)
10700 || (!sofia_test_pflag(profile, PFLAG_BLIND_AUTH)((profile)->pflags[PFLAG_BLIND_AUTH] ? 1 : 0) && (sip->sip_proxy_authorization || sip->sip_authorization)))) {
28
Assuming the condition is false
29
Assuming the condition is false
10701 if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
10702 calling_myself++;
10703 } else {
10704 switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 10704, &v_event, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
10705
10706 if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, sizeof(key), &v_event, NULL, NULL, &x_user)sofia_reg_handle_register_token(nua, profile, nh, sip, de, REG_INVITE
, key, sizeof(key), &v_event, ((void*)0), ((void*)0), &
x_user, ((void*)0))
) {
10707 if (v_event) {
10708 switch_event_destroy(&v_event);
10709 }
10710 if (x_user) {
10711 switch_xml_free(x_user);
10712 }
10713
10714 if (sip->sip_authorization || sip->sip_proxy_authorization) {
10715 goto fail;
10716 }
10717
10718 return;
10719 }
10720 }
10721 is_auth++;
10722 }
10723
10724 channel = tech_pvt->channel = switch_core_session_get_channel(session);
10725
10726 switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
31
Assuming the condition is false
32
'?' condition is false
10727 switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip);
10728 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
10729 switch_channel_set_variable_printf(channel, "sip_invite_stamp", "%" SWITCH_TIME_T_FMT"ld", sip_invite_time);
10730
10731 if (*acl_token) {
33
Taking false branch
10732 if (x_user) {
10733 switch_xml_free(x_user);
10734 x_user = NULL((void*)0);
10735 }
10736 switch_channel_set_variable(channel, "acl_token", acl_token)switch_channel_set_variable_var_check(channel, "acl_token", acl_token
, SWITCH_TRUE)
;
10737 if (sofia_locate_user(acl_token, session, sip, &x_user) == SWITCH_STATUS_SUCCESS) {
10738 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10738, (const char*)(session)
, SWITCH_LOG_DEBUG, "Authenticating user %s\n", acl_token);
10739 } else {
10740 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10740, (const char*)(session)
, SWITCH_LOG_WARNING, "Error Authenticating user %s\n", acl_token);
10741 if (sofia_test_pflag(profile, PFLAG_AUTH_REQUIRE_USER)((profile)->pflags[PFLAG_AUTH_REQUIRE_USER] ? 1 : 0)) {
10742 nua_respond(nh, SIP_480_TEMPORARILY_UNAVAILABLE480, sip_480_Temporarily_unavailable, TAG_END()(tag_type_t)0, (tag_value_t)0);
10743 if (v_event) {
10744 switch_event_destroy(&v_event);
10745 }
10746 goto fail;
10747 }
10748 }
10749 }
10750
10751 if (sip->sip_via) {
34
Taking false branch
10752 char tmp[35] = "";
10753 const char *ipv6 = strchr(tech_pvt->mparams.remote_ip, ':');
10754
10755 transport = sofia_glue_via2transport(sip->sip_via);
10756
10757
10758 tech_pvt->record_route =
10759 switch_core_session_sprintf(session,
10760 "sip:%s%s%s:%d;transport=%s",
10761 ipv6 ? "[" : "", tech_pvt->mparams.remote_ip, ipv6 ? "]" : "",
10762 tech_pvt->mparams.remote_port, sofia_glue_transport2str(transport));
10763
10764 switch_channel_set_variable(channel, "sip_received_ip", tech_pvt->mparams.remote_ip)switch_channel_set_variable_var_check(channel, "sip_received_ip"
, tech_pvt->mparams.remote_ip, SWITCH_TRUE)
;
10765 snprintf(tmp, sizeof(tmp), "%d", tech_pvt->mparams.remote_port);
10766 switch_channel_set_variable(channel, "sip_received_port", tmp)switch_channel_set_variable_var_check(channel, "sip_received_port"
, tmp, SWITCH_TRUE)
;
10767 switch_channel_set_variable(channel, "sip_via_protocol", sofia_glue_transport2str(sofia_glue_via2transport(sip->sip_via)))switch_channel_set_variable_var_check(channel, "sip_via_protocol"
, sofia_glue_transport2str(sofia_glue_via2transport(sip->sip_via
)), SWITCH_TRUE)
;
10768 }
10769
10770 if (*key != '\0') {
35
Taking false branch
10771 tech_pvt->key = switch_core_session_strdup(session, key)switch_core_perform_session_strdup(session, key, "sofia.c", (
const char *)__func__, 10771)
;
10772 }
10773
10774
10775 if (is_auth) {
36
Taking false branch
10776 switch_channel_set_variable(channel, "sip_authorized", "true")switch_channel_set_variable_var_check(channel, "sip_authorized"
, "true", SWITCH_TRUE)
;
10777
10778 if (!zstr(sip_acl_authed_by)_zstr(sip_acl_authed_by)) {
10779 switch_channel_set_variable(channel, "sip_acl_authed_by", sip_acl_authed_by)switch_channel_set_variable_var_check(channel, "sip_acl_authed_by"
, sip_acl_authed_by, SWITCH_TRUE)
;
10780 }
10781
10782 if (!zstr(sip_acl_token)_zstr(sip_acl_token)) {
10783 switch_channel_set_variable(channel, "sip_acl_token", sip_acl_token)switch_channel_set_variable_var_check(channel, "sip_acl_token"
, sip_acl_token, SWITCH_TRUE)
;
10784 }
10785
10786 }
10787
10788 if (calling_myself) {
37
Taking false branch
10789 switch_channel_set_variable(channel, "sip_looped_call", "true")switch_channel_set_variable_var_check(channel, "sip_looped_call"
, "true", SWITCH_TRUE)
;
10790 }
10791
10792 tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
10793 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), MODNAME"mod_sofia", NULL((void*)0), NULL((void*)0));
10794 switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
10795
10796 if (x_user) {
38
Taking false branch
10797 const char *ruser = NULL((void*)0), *rdomain = NULL((void*)0), *user = switch_xml_attr(x_user, "id"), *domain = switch_xml_attr(x_user, "domain-name");
10798
10799 if (v_event) {
10800 switch_event_header_t *hp;
10801
10802 for (hp = v_event->headers; hp; hp = hp->next) {
10803 switch_channel_set_variable(channel, hp->name, hp->value)switch_channel_set_variable_var_check(channel, hp->name, hp
->value, SWITCH_TRUE)
;
10804 }
10805
10806 ruser = switch_event_get_header(v_event, "user_name")switch_event_get_header_idx(v_event, "user_name", -1);
10807 rdomain = switch_event_get_header(v_event, "domain_name")switch_event_get_header_idx(v_event, "domain_name", -1);
10808
10809 switch_channel_set_variable(channel, "requested_user_name", ruser)switch_channel_set_variable_var_check(channel, "requested_user_name"
, ruser, SWITCH_TRUE)
;
10810 switch_channel_set_variable(channel, "requested_domain_name", rdomain)switch_channel_set_variable_var_check(channel, "requested_domain_name"
, rdomain, SWITCH_TRUE)
;
10811 }
10812
10813 if (!user) user = ruser;
10814 if (!domain) domain = rdomain;
10815
10816 switch_ivr_set_user_xml(session, NULL((void*)0), user, domain, x_user);
10817 switch_xml_free(x_user);
10818 x_user = NULL((void*)0);
10819 }
10820
10821 if (v_event) {
39
Taking false branch
10822 switch_event_destroy(&v_event);
10823 }
10824
10825 if (sip->sip_from) {
40
Taking false branch
10826 from_user = sip->sip_from->a_url->url_user;
10827 from_host = sip->sip_from->a_url->url_host;
10828 //channel_name = url_set_chanvars(session, sip->sip_from->a_url, sip_from);
10829
10830 if (sip->sip_from->a_url->url_params) {
10831 aniii = switch_find_parameter(sip->sip_from->a_url->url_params, "isup-oli", switch_core_session_get_pool(session));
10832 }
10833
10834 if (!zstr(from_user)_zstr(from_user)) {
10835 if (*from_user == '+') {
10836 switch_channel_set_variable(channel, "sip_from_user_stripped", (const char *) (from_user + 1))switch_channel_set_variable_var_check(channel, "sip_from_user_stripped"
, (const char *) (from_user + 1), SWITCH_TRUE)
;
10837 } else {
10838 switch_channel_set_variable(channel, "sip_from_user_stripped", from_user)switch_channel_set_variable_var_check(channel, "sip_from_user_stripped"
, from_user, SWITCH_TRUE)
;
10839 }
10840 }
10841
10842 switch_channel_set_variable(channel, "sip_from_comment", sip->sip_from->a_comment)switch_channel_set_variable_var_check(channel, "sip_from_comment"
, sip->sip_from->a_comment, SWITCH_TRUE)
;
10843
10844 if (sip->sip_from->a_params) {
10845 set_variable_sip_param(channel, "from", sip->sip_from->a_params);
10846 }
10847
10848 switch_channel_set_variable(channel, "sofia_profile_name", profile->name)switch_channel_set_variable_var_check(channel, "sofia_profile_name"
, profile->name, SWITCH_TRUE)
;
10849 switch_channel_set_variable(channel, "sofia_profile_url", profile->url)switch_channel_set_variable_var_check(channel, "sofia_profile_url"
, profile->url, SWITCH_TRUE)
;
10850 switch_channel_set_variable(channel, "recovery_profile_name", profile->name)switch_channel_set_variable_var_check(channel, "recovery_profile_name"
, profile->name, SWITCH_TRUE)
;
10851 switch_channel_set_variable(channel, "sofia_profile_domain_name", profile->domain_name)switch_channel_set_variable_var_check(channel, "sofia_profile_domain_name"
, profile->domain_name, SWITCH_TRUE)
;
10852
10853 if (!zstr(sip->sip_from->a_display)_zstr(sip->sip_from->a_display)) {
10854 displayname = sip->sip_from->a_display;
10855 } else {
10856 displayname = zstr(from_user)_zstr(from_user) ? "unknown" : from_user;
10857 }
10858 }
10859
10860 if ((rpid = sip_remote_party_id(sip)((sip_remote_party_id_t *)msg_header_access((msg_pub_t*)(sip)
, sip_remote_party_id_class))
)) {
41
Assuming 'rpid' is null
42
Taking false branch
10861 if (rpid->rpid_url->url_user) {
10862 char *full_rpid_header = sip_header_as_string(nua_handle_get_home(nh), (void *) rpid);
10863 from_user = rpid->rpid_url->url_user;
10864 if (!zstr(full_rpid_header)_zstr(full_rpid_header)) {
10865 switch_channel_set_variable(channel, "sip_Remote-Party-ID", full_rpid_header)switch_channel_set_variable_var_check(channel, "sip_Remote-Party-ID"
, full_rpid_header, SWITCH_TRUE)
;
10866 }
10867
10868 }
10869 if (!zstr(rpid->rpid_display)_zstr(rpid->rpid_display)) {
10870 displayname = rpid->rpid_display;
10871 }
10872 switch_channel_set_variable(channel, "sip_cid_type", "rpid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "rpid", SWITCH_TRUE)
;
10873 tech_pvt->cid_type = CID_TYPE_RPID;
10874 }
10875
10876 if ((passerted = sip_p_asserted_identity(sip)((sip_p_asserted_identity_t *)msg_header_access((msg_pub_t*)(
sip), sip_p_asserted_identity_class))
)) {
43
Assuming 'passerted' is null
44
Taking false branch
10877 if (passerted->paid_url->url_user) {
10878 char *full_paid_header = sip_header_as_string(nua_handle_get_home(nh), (void *) passerted);
10879 //char *full_paid_header = (char *)(passerted->paid_common->h_data);
10880 from_user = passerted->paid_url->url_user;
10881 if (!zstr(full_paid_header)_zstr(full_paid_header)) {
10882 if (profile->paid_type == PAID_DEFAULT || profile->paid_type == PAID_USER) {
10883 switch_channel_set_variable(channel, "sip_P-Asserted-Identity", from_user)switch_channel_set_variable_var_check(channel, "sip_P-Asserted-Identity"
, from_user, SWITCH_TRUE)
;
10884 } else if (profile->paid_type == PAID_USER_DOMAIN) {
10885 switch_channel_set_variable(channel, "sip_P-Asserted-Identity",switch_channel_set_variable_var_check(channel, "sip_P-Asserted-Identity"
, switch_core_session_sprintf(session, "%s@%s", passerted->
paid_url->url_user, passerted->paid_url->url_host), SWITCH_TRUE
)
10886 switch_core_session_sprintf(session, "%s@%s", passerted->paid_url->url_user, passerted->paid_url->url_host))switch_channel_set_variable_var_check(channel, "sip_P-Asserted-Identity"
, switch_core_session_sprintf(session, "%s@%s", passerted->
paid_url->url_user, passerted->paid_url->url_host), SWITCH_TRUE
)
;
10887 } else if (profile->paid_type == PAID_VERBATIM) {
10888 switch_channel_set_variable(channel, "sip_P-Asserted-Identity", full_paid_header)switch_channel_set_variable_var_check(channel, "sip_P-Asserted-Identity"
, full_paid_header, SWITCH_TRUE)
;
10889 }
10890 }
10891 }
10892 if (!zstr(passerted->paid_display)_zstr(passerted->paid_display)) {
10893 displayname = passerted->paid_display;
10894 }
10895 switch_channel_set_variable(channel, "sip_cid_type", "pid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "pid", SWITCH_TRUE)
;
10896 tech_pvt->cid_type = CID_TYPE_PID;
10897 }
10898
10899 if ((ppreferred = sip_p_preferred_identity(sip)((sip_p_preferred_identity_t *)msg_header_access((msg_pub_t*)
(sip), sip_p_preferred_identity_class))
)) {
45
Assuming 'ppreferred' is null
46
Taking false branch
10900 if (ppreferred->ppid_url->url_user) {
10901 char *full_ppid_header = sip_header_as_string(nua_handle_get_home(nh), (void *) ppreferred);
10902 from_user = ppreferred->ppid_url->url_user;
10903 if (!zstr(full_ppid_header)_zstr(full_ppid_header)) {
10904 switch_channel_set_variable(channel, "sip_P-Preferred-Identity", full_ppid_header)switch_channel_set_variable_var_check(channel, "sip_P-Preferred-Identity"
, full_ppid_header, SWITCH_TRUE)
;
10905 }
10906
10907 }
10908 if (!zstr(ppreferred->ppid_display)_zstr(ppreferred->ppid_display)) {
10909 displayname = ppreferred->ppid_display;
10910 }
10911 switch_channel_set_variable(channel, "sip_cid_type", "pid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "pid", SWITCH_TRUE)
;
10912 tech_pvt->cid_type = CID_TYPE_PID;
10913 }
10914
10915 if (from_user) {
47
Taking false branch
10916 check_decode(from_user, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 10916, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(from_user
)) { int d = 0; char *p; if (strchr(from_user, '%')) { char *
tmp = switch_core_perform_session_strdup(session, from_user, "sofia.c"
, (const char *)__func__, 10916); switch_url_decode(tmp); from_user
= tmp; d++; } if ((p = strchr(from_user, '"'))) { if (!d) { char
*tmp = switch_core_perform_session_strdup(session, from_user
, "sofia.c", (const char *)__func__, 10916); from_user = tmp;
} if ((p = strchr(from_user, '"'))) { from_user = p+1; } if (
(p = strrchr(from_user, '"'))) { *p = '\0'; } } } break; } while
(0)
;
10917
10918 if ((name_params = strchr(from_user, ';'))) {
10919 *name_params++ = '\0';
10920 switch_channel_set_variable(channel, "sip_name_params", name_params)switch_channel_set_variable_var_check(channel, "sip_name_params"
, name_params, SWITCH_TRUE)
;
10921 }
10922 }
10923
10924 extract_header_vars(profile, sip, session, nh);
48
Calling 'extract_header_vars'
10925 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_allow");
10926
10927 req_uri = url_set_chanvars(session, sip->sip_request->rq_url, sip_req)_url_set_chanvars(session, sip->sip_request->rq_url, "sip_req"
"_user", "sip_req" "_host", "sip_req" "_port", "sip_req" "_uri"
, "sip_req" "_params")
;
10928 if (sip->sip_request->rq_url->url_user) {
10929
10930 req_user = switch_core_session_strdup(session, sip->sip_request->rq_url->url_user)switch_core_perform_session_strdup(session, sip->sip_request
->rq_url->url_user, "sofia.c", (const char *)__func__, 10930
)
;
10931 if (profile->parse_invite_tel_params) {
10932 if (strchr(req_user, ';')) {
10933 int argc1, x1 = 0;
10934 char *argv1[32] = { 0 };
10935
10936 if ((argc1 = switch_separate_string(req_user, ';', argv1, (sizeof(argv1) / sizeof(argv1[0]))))) {
10937 for (x1 = 0; x1 < argc1; x1++) {
10938 if (x1 == 0) {
10939 switch_channel_set_variable(channel, "sip_req_user", argv1[0])switch_channel_set_variable_var_check(channel, "sip_req_user"
, argv1[0], SWITCH_TRUE)
;
10940 } else {
10941 int argc2 = 0;
10942 char *argv2[2] = { 0 };
10943 if ((argc2 = switch_separate_string(argv1[x1], '=', argv2, (sizeof(argv2) / sizeof(argv2[0])))) == 2) {
10944 char *var_name = NULL((void*)0);
10945 var_name = switch_mprintf("sip_invite_%s", argv2[0]);
10946 switch_channel_set_variable(channel, var_name, argv2[1])switch_channel_set_variable_var_check(channel, var_name, argv2
[1], SWITCH_TRUE)
;
10947 switch_safe_free( var_name )if (var_name) {free(var_name);var_name=((void*)0);};
10948 } else {
10949 char *var_name = NULL((void*)0);
10950 var_name = switch_mprintf("sip_invite_%s", argv1[x1]);
10951 switch_channel_set_variable(channel, var_name, "true")switch_channel_set_variable_var_check(channel, var_name, "true"
, SWITCH_TRUE)
;
10952 switch_safe_free( var_name )if (var_name) {free(var_name);var_name=((void*)0);};
10953 }
10954 }
10955 }
10956 }
10957 }
10958 }
10959 }
10960
10961 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
10962 destination_number = req_uri;
10963 } else {
10964 destination_number = req_user;
10965 }
10966 if (sip->sip_request->rq_url->url_params && (sofia_glue_find_parameter(sip->sip_request->rq_url->url_params, "intercom=true"))) {
10967 switch_channel_set_variable(channel, "sip_auto_answer_detected", "true")switch_channel_set_variable_var_check(channel, "sip_auto_answer_detected"
, "true", SWITCH_TRUE)
;
10968 }
10969
10970 if (!destination_number && sip->sip_to) {
10971 destination_number = sip->sip_to->a_url->url_user;
10972 }
10973
10974 /* The human network, OH THE HUMANITY!!! lets send invites with no number! */
10975 if (!destination_number && sip->sip_from) {
10976 destination_number = sip->sip_from->a_url->url_user;
10977 }
10978
10979 if (destination_number) {
10980 check_decode(destination_number, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 10980, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(destination_number
)) { int d = 0; char *p; if (strchr(destination_number, '%'))
{ char *tmp = switch_core_perform_session_strdup(session, destination_number
, "sofia.c", (const char *)__func__, 10980); switch_url_decode
(tmp); destination_number = tmp; d++; } if ((p = strchr(destination_number
, '"'))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, destination_number, "sofia.c", (const char *)__func__
, 10980); destination_number = tmp; } if ((p = strchr(destination_number
, '"'))) { destination_number = p+1; } if ((p = strrchr(destination_number
, '"'))) { *p = '\0'; } } } break; } while (0)
;
10981 } else {
10982 destination_number = "service";
10983 }
10984
10985 if (sip->sip_to) {
10986 const char *host, *user;
10987 int port, check_nat = 0;
10988 url_t *transport_url;
10989
10990 if (sip->sip_record_route) {
10991 transport_url = sip->sip_record_route->r_url;
10992 } else {
10993 transport_url = sip->sip_contact->m_url;
10994 }
10995
10996 transport = sofia_glue_url2transport(transport_url);
10997 tech_pvt->transport = transport;
10998
10999 url_set_chanvars(session, sip->sip_to->a_url, sip_to)_url_set_chanvars(session, sip->sip_to->a_url, "sip_to"
"_user", "sip_to" "_host", "sip_to" "_port", "sip_to" "_uri"
, "sip_to" "_params")
;
11000 if (switch_channel_get_variable(channel, "sip_to_uri")switch_channel_get_variable_dup(channel, "sip_to_uri", SWITCH_TRUE
, -1)
) {
11001 const char *ipv6;
11002 const char *tmp, *at, *url = NULL((void*)0);
11003 const char *tmp_user = switch_channel_get_variable(channel, "sip_to_user")switch_channel_get_variable_dup(channel, "sip_to_user", SWITCH_TRUE
, -1)
;
11004
11005 user = switch_core_session_url_encode(session, tmp_user);
11006 host = switch_channel_get_variable(channel, "sip_to_host")switch_channel_get_variable_dup(channel, "sip_to_host", SWITCH_TRUE
, -1)
;
11007
11008 switch_channel_set_variable(channel, "sip_to_comment", sip->sip_to->a_comment)switch_channel_set_variable_var_check(channel, "sip_to_comment"
, sip->sip_to->a_comment, SWITCH_TRUE)
;
11009
11010 if (sip->sip_to->a_params) {
11011 set_variable_sip_param(channel, "to", sip->sip_to->a_params);
11012 }
11013
11014 if (sip->sip_contact->m_url->url_port) {
11015 port = atoi(sip->sip_contact->m_url->url_port);
11016 } else {
11017 port = sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->extsipport;
11018 }
11019
11020 ipv6 = strchr(host, ':');
11021 tech_pvt->to_uri =
11022 switch_core_session_sprintf(session,
11023 "sip:%s@%s%s%s:%d;transport=%s",
11024 user, ipv6 ? "[" : "", host, ipv6 ? "]" : "", port, sofia_glue_transport2str(transport));
11025
11026 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
11027 check_nat = 1;
11028 }
11029 url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport);
11030
11031 if (!url) {
11032 if (check_nat) {
11033 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11033, (const char*)(session)
, SWITCH_LOG_WARNING, "Nat detected but no external address configured.\n");
11034 }
11035 url = profile->url;
11036 }
11037
11038 if (!url) {
11039 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 11039, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
11040 }
11041
11042 tmp = sofia_overcome_sip_uri_weakness(session, url, transport, SWITCH_TRUE, NULL((void*)0), NULL((void*)0));
11043
11044 if ((at = strchr(tmp, '@'))) {
11045 url = switch_core_session_sprintf(session, "sip:%s%s", user, at);
11046 }
11047
11048 if (url) {
11049 const char *brackets = NULL((void*)0);
11050 const char *proto = NULL((void*)0);
11051
11052 brackets = strchr(url, '>');
11053 proto = switch_stristr("transport=", url);
11054 tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s%s%s%s%s",
11055 brackets ? "" : "<", url,
11056 proto ? "" : ";transport=",
11057 proto ? "" : sofia_glue_transport2str(transport), brackets ? "" : ">");
11058 } else {
11059 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 11059, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
11060 }
11061
11062 } else {
11063 const char *url = NULL((void*)0);
11064 url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport);
11065
11066 if (url) {
11067 const char *brackets = NULL((void*)0);
11068 const char *proto = NULL((void*)0);
11069
11070 brackets = strchr(url, '>');
11071 proto = switch_stristr("transport=", url);
11072 tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s%s%s%s%s",
11073 brackets ? "" : "<", url,
11074 proto ? "" : ";transport=",
11075 proto ? "" : sofia_glue_transport2str(transport), brackets ? "" : ">");
11076 } else {
11077 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 11077, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
11078 }
11079 }
11080 }
11081
11082 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
11083 tech_pvt->user_via = sofia_glue_create_external_via(session, profile, tech_pvt->transport);
11084 nua_set_hparams(nh, SIPTAG_VIA_STR(tech_pvt->user_via)siptag_via_str, tag_str_v(tech_pvt->user_via), TAG_END()(tag_type_t)0, (tag_value_t)0);
11085 }
11086
11087 url_set_chanvars(session, sip->sip_contact->m_url, sip_contact)_url_set_chanvars(session, sip->sip_contact->m_url, "sip_contact"
"_user", "sip_contact" "_host", "sip_contact" "_port", "sip_contact"
"_uri", "sip_contact" "_params")
;
11088
11089 if (sip->sip_referred_by) {
11090 referred_by_user = sip->sip_referred_by->b_url->url_user;
11091 //referred_by_host = sip->sip_referred_by->b_url->url_host;
11092 //channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by);
11093
11094 check_decode(referred_by_user, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 11094, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(referred_by_user
)) { int d = 0; char *p; if (strchr(referred_by_user, '%')) {
char *tmp = switch_core_perform_session_strdup(session, referred_by_user
, "sofia.c", (const char *)__func__, 11094); switch_url_decode
(tmp); referred_by_user = tmp; d++; } if ((p = strchr(referred_by_user
, '"'))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, referred_by_user, "sofia.c", (const char *)__func__
, 11094); referred_by_user = tmp; } if ((p = strchr(referred_by_user
, '"'))) { referred_by_user = p+1; } if ((p = strrchr(referred_by_user
, '"'))) { *p = '\0'; } } } break; } while (0)
;
11095
11096 if (!zstr(referred_by_user)_zstr(referred_by_user)) {
11097 if (*referred_by_user == '+') {
11098 switch_channel_set_variable(channel, "sip_referred_by_user_stripped", (const char *) (referred_by_user + 1))switch_channel_set_variable_var_check(channel, "sip_referred_by_user_stripped"
, (const char *) (referred_by_user + 1), SWITCH_TRUE)
;
11099 } else {
11100 switch_channel_set_variable(channel, "sip_referred_by_user_stripped", referred_by_user)switch_channel_set_variable_var_check(channel, "sip_referred_by_user_stripped"
, referred_by_user, SWITCH_TRUE)
;
11101 }
11102 }
11103
11104 switch_channel_set_variable(channel, "sip_referred_by_cid", sip->sip_referred_by->b_cid)switch_channel_set_variable_var_check(channel, "sip_referred_by_cid"
, sip->sip_referred_by->b_cid, SWITCH_TRUE)
;
11105
11106 if (sip->sip_referred_by->b_params) {
11107 set_variable_sip_param(channel, "referred_by", sip->sip_referred_by->b_params);
11108 }
11109 }
11110
11111 //sofia_glue_set_name(tech_pvt, channel_name);
11112 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
11113
11114 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "INBOUND CALL")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "INBOUND CALL", SWITCH_TRUE)
;
11115
11116 if (sofia_test_flag(tech_pvt, TFLAG_INB_NOMEDIA)((tech_pvt)->flags[TFLAG_INB_NOMEDIA] ? 1 : 0)) {
11117 switch_channel_set_flag(channel, CF_PROXY_MODE)switch_channel_set_flag_value(channel, CF_PROXY_MODE, 1);
11118 }
11119
11120 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_HOLD) {
11121 switch_channel_set_flag(channel, CF_BYPASS_MEDIA_AFTER_HOLD)switch_channel_set_flag_value(channel, CF_BYPASS_MEDIA_AFTER_HOLD
, 1)
;
11122 }
11123
11124 if (sofia_test_flag(tech_pvt, TFLAG_PROXY_MEDIA)((tech_pvt)->flags[TFLAG_PROXY_MEDIA] ? 1 : 0)) {
11125 switch_channel_set_flag(channel, CF_PROXY_MEDIA)switch_channel_set_flag_value(channel, CF_PROXY_MEDIA, 1);
11126 }
11127
11128 if (sofia_test_flag(tech_pvt, TFLAG_ZRTP_PASSTHRU)((tech_pvt)->flags[TFLAG_ZRTP_PASSTHRU] ? 1 : 0)) {
11129 switch_channel_set_flag(channel, CF_ZRTP_PASSTHRU_REQ)switch_channel_set_flag_value(channel, CF_ZRTP_PASSTHRU_REQ, 1
)
;
11130 }
11131
11132 if (sip->sip_subject && sip->sip_subject->g_string) {
11133 switch_channel_set_variable(channel, "sip_subject", sip->sip_subject->g_string)switch_channel_set_variable_var_check(channel, "sip_subject",
sip->sip_subject->g_string, SWITCH_TRUE)
;
11134 }
11135
11136 if (sip->sip_user_agent && !zstr(sip->sip_user_agent->g_string)_zstr(sip->sip_user_agent->g_string)) {
11137 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_user_agent->g_string)switch_channel_set_variable_var_check(channel, "sip_user_agent"
, sip->sip_user_agent->g_string, SWITCH_TRUE)
;
11138 }
11139
11140 sofia_set_accept_language_channel_variable(channel, sip);
11141
11142 if (sip->sip_via) {
11143 if (sip->sip_via->v_host) {
11144 switch_channel_set_variable(channel, "sip_via_host", sip->sip_via->v_host)switch_channel_set_variable_var_check(channel, "sip_via_host"
, sip->sip_via->v_host, SWITCH_TRUE)
;
11145 }
11146 if (sip->sip_via->v_port) {
11147 switch_channel_set_variable(channel, "sip_via_port", sip->sip_via->v_port)switch_channel_set_variable_var_check(channel, "sip_via_port"
, sip->sip_via->v_port, SWITCH_TRUE)
;
11148 }
11149 if (sip->sip_via->v_rport) {
11150 switch_channel_set_variable(channel, "sip_via_rport", sip->sip_via->v_rport)switch_channel_set_variable_var_check(channel, "sip_via_rport"
, sip->sip_via->v_rport, SWITCH_TRUE)
;
11151 }
11152 }
11153
11154
11155 if (sip->sip_multipart) {
11156 msg_multipart_t *mp;
11157
11158 for (mp = sip->sip_multipart; mp; mp = mp->mp_next) {
11159 if (mp->mp_payload && mp->mp_payload->pl_data && mp->mp_content_type && mp->mp_content_type->c_type) {
11160 char *val = switch_core_session_sprintf(session, "%s:%s", mp->mp_content_type->c_type, mp->mp_payload->pl_data);
11161 switch_channel_add_variable_var_check(channel, "sip_multipart", val, SWITCH_FALSE, SWITCH_STACK_PUSH);
11162 }
11163 }
11164 }
11165
11166 if (sip->sip_max_forwards) {
11167 char max_forwards[32];
11168 switch_snprintf(max_forwards, sizeof(max_forwards), "%lu", sip->sip_max_forwards->mf_count);
11169 switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards)switch_channel_set_variable_var_check(channel, "max_forwards"
, max_forwards, SWITCH_TRUE)
;
11170 }
11171
11172 if (acl_context) context = acl_context;
11173
11174 if (!context) {
11175 context = switch_channel_get_variable(channel, "user_context")switch_channel_get_variable_dup(channel, "user_context", SWITCH_TRUE
, -1)
;
11176 }
11177
11178 if (!context) {
11179 if (profile->context && !strcasecmp(profile->context, "_domain_")) {
11180 context = from_host;
11181 } else {
11182 context = profile->context;
11183 }
11184 }
11185
11186 if (!(dialplan = switch_channel_get_variable(channel, "inbound_dialplan")switch_channel_get_variable_dup(channel, "inbound_dialplan", SWITCH_TRUE
, -1)
)) {
11187 dialplan = profile->dialplan;
11188 }
11189
11190 if ((alert_info = sip_alert_info(sip)((sip_alert_info_t *)msg_header_access((msg_pub_t*)(sip), sip_alert_info_class
))
)) {
11191 char *tmp = sip_header_as_string(nua_handle_get_home(nh), (void *) alert_info);
11192 switch_channel_set_variable(channel, "alert_info", tmp)switch_channel_set_variable_var_check(channel, "alert_info", tmp
, SWITCH_TRUE)
;
11193 su_free(nua_handle_get_home(nh), tmp);
11194 }
11195
11196 if ((call_info = sip_call_info(sip)((sip_call_info_t *)msg_header_access((msg_pub_t*)(sip), sip_call_info_class
))
)) {
11197 call_info_str = sip_header_as_string(nua_handle_get_home(nh), (void *) call_info);
11198
11199 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
&& switch_stristr("appearance", call_info_str)) {
11200 char *p;
11201
11202 switch_channel_set_variable(channel, "presence_call_info_full", call_info_str)switch_channel_set_variable_var_check(channel, "presence_call_info_full"
, call_info_str, SWITCH_TRUE)
;
11203 if ((p = strchr(call_info_str, ';'))) {
11204 p++;
11205 switch_channel_set_variable(channel, "presence_call_info", p)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p, SWITCH_TRUE)
;
11206 }
11207 }
11208
11209 if (call_info->ci_params && (msg_params_find(call_info->ci_params, "answer-after=0"))) {
11210 switch_channel_set_variable(channel, "sip_auto_answer_detected", "true")switch_channel_set_variable_var_check(channel, "sip_auto_answer_detected"
, "true", SWITCH_TRUE)
;
11211 }
11212
11213 switch_channel_set_variable(channel, "sip_call_info", call_info_str)switch_channel_set_variable_var_check(channel, "sip_call_info"
, call_info_str, SWITCH_TRUE)
;
11214
11215 call_info = call_info->ci_next;
11216
11217 while (call_info) {
11218 call_info_str = sip_header_as_string(nua_handle_get_home(nh), (void *) call_info);
11219 switch_channel_add_variable_var_check(channel, "sip_call_info", call_info_str, SWITCH_FALSE, SWITCH_STACK_PUSH);
11220 call_info = call_info->ci_next;
11221 }
11222
11223 call_info = sip_call_info(sip)((sip_call_info_t *)msg_header_access((msg_pub_t*)(sip), sip_call_info_class
))
;
11224
11225 } else if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
11226 char buf[128] = "";
11227 char *sql;
11228 char *state = "progressing";
11229
11230 if (sip->sip_from && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
11231 sip->sip_to && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
11232 sql =
11233 switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
11234 "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
11235 sip->sip_from->a_url->url_host);
11236 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
11237
11238 if (mod_sofia_globals.debug_sla > 1) {
11239 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 11239
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
11240 }
11241 free(sql);
11242
11243 if (!zstr(buf)_zstr(buf)) {
11244 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
11245 "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
11246
11247 if (mod_sofia_globals.debug_sla > 1) {
11248 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 11248
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
11249 }
11250
11251 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11252
11253
11254 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11254, (const char*)(session)
, SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
11255 sip->sip_from->a_url->url_host, buf);
11256
11257 switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
11258 switch_channel_set_variable(channel, "presence_call_info", buf)switch_channel_set_variable_var_check(channel, "presence_call_info"
, buf, SWITCH_TRUE)
;
11259 call_info_str = switch_core_session_sprintf(session, "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
11260 }
11261 }
11262 }
11263
11264
11265 if (profile->pres_type) {
11266 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
11267 if (zstr(presence_id)_zstr(presence_id) && sip->sip_from && sip->sip_from->a_url) {
11268 const char *user = switch_str_nil(sip->sip_from->a_url->url_user)(sip->sip_from->a_url->url_user ? sip->sip_from->
a_url->url_user : "")
;
11269 const char *host = switch_str_nil(sip->sip_from->a_url->url_host)(sip->sip_from->a_url->url_host ? sip->sip_from->
a_url->url_host : "")
;
11270 char *tmp = switch_mprintf("%s@%s", user, host);
11271 switch_assert(tmp)((tmp) ? (void) (0) : __assert_fail ("tmp", "sofia.c", 11271,
__extension__ __PRETTY_FUNCTION__))
;
11272 switch_channel_set_variable(channel, "presence_id", tmp)switch_channel_set_variable_var_check(channel, "presence_id",
tmp, SWITCH_TRUE)
;
11273 free(tmp);
11274 }
11275 }
11276
11277
11278 if (sip->sip_request->rq_url->url_params) {
11279 gw_param_name = switch_find_parameter(sip->sip_request->rq_url->url_params, "gw", switch_core_session_get_pool(session));
11280 }
11281
11282 if (strstr(destination_number, "gw+")) {
11283 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
11284 char *tmp;
11285 gw_name = switch_core_session_strdup(session, destination_number + 3)switch_core_perform_session_strdup(session, destination_number
+ 3, "sofia.c", (const char *)__func__, 11285)
;
11286 if ((tmp = strchr(gw_name, '@'))) {
11287 *tmp = '\0';
11288 }
11289 } else {
11290 gw_name = destination_number + 3;
11291 }
11292 }
11293
11294 if (gw_name || gw_param_name) {
11295 sofia_gateway_t *gateway = NULL((void*)0);
11296 char *extension = NULL((void*)0);
11297
11298 if (gw_name && ((gateway = sofia_reg_find_gateway(gw_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 11298
, gw_name)
))) {
11299 gw_param_name = NULL((void*)0);
11300 extension = gateway->extension;
11301 }
11302
11303 if (!gateway && gw_param_name) {
11304 if ((gateway = sofia_reg_find_gateway(gw_param_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 11304
, gw_param_name)
)) {
11305 extension = gateway->real_extension;
11306 }
11307 }
11308
11309 if (gateway) {
11310 context = switch_core_session_strdup(session, gateway->register_context)switch_core_perform_session_strdup(session, gateway->register_context
, "sofia.c", (const char *)__func__, 11310)
;
11311 switch_channel_set_variable(channel, "sip_gateway", gateway->name)switch_channel_set_variable_var_check(channel, "sip_gateway",
gateway->name, SWITCH_TRUE)
;
11312
11313 if (!zstr(extension)_zstr(extension)) {
11314 if (!strcasecmp(extension, "auto_to_user") && sip->sip_to) {
11315 destination_number = sip->sip_to->a_url->url_user;
11316 } else if (!strcasecmp(extension, "auto")) {
11317 if (gw_name && sip->sip_to) {
11318 destination_number = sip->sip_to->a_url->url_user;
11319 }
11320 } else {
11321 destination_number = switch_core_session_strdup(session, extension)switch_core_perform_session_strdup(session, extension, "sofia.c"
, (const char *)__func__, 11321)
;
11322 }
11323 } else if (!gw_param_name && sip->sip_to) {
11324 destination_number = sip->sip_to->a_url->url_user;
11325 }
11326
11327 gateway->ib_calls++;
11328
11329 if (gateway->ib_vars) {
11330 switch_event_header_t *hp;
11331 for (hp = gateway->ib_vars->headers; hp; hp = hp->next) {
11332 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11332, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n",
11333 switch_channel_get_name(channel), hp->name, hp->value);
11334 switch_channel_set_variable(channel, hp->name, hp->value)switch_channel_set_variable_var_check(channel, hp->name, hp
->value, SWITCH_TRUE)
;
11335 }
11336 }
11337
11338 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 11338, gateway);
;
11339 }
11340 }
11341
11342 if (call_info_str) {
11343 char *sql;
11344 char cid[512] = "";
11345 char *str;
11346 char *p = NULL((void*)0);
11347 const char *user = NULL((void*)0), *host = NULL((void*)0), *from_user = NULL((void*)0), *from_host = NULL((void*)0);
11348
11349 if (sip->sip_to) {
11350 user = sip->sip_to->a_url->url_user;
11351 host = sip->sip_to->a_url->url_host;
11352 }
11353
11354 if (sip->sip_from) {
11355 from_user = sip->sip_from->a_url->url_user;
11356 from_host = sip->sip_from->a_url->url_host;
11357 }
11358
11359 if (!user) user = from_user;
11360 if (!host) user = from_host;
11361
11362 if (user && host && from_user && !strcmp(user, from_user)) {
11363 if ((p = strchr(call_info_str, ';'))) {
11364 p++;
11365 }
11366
11367 sql = switch_mprintf(
11368 "select call_id from sip_dialogs where (call_info='%q' or call_info='%q;appearance-state=held') and "
11369 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') and call_id is not null",
11370 switch_str_nil(p)(p ? p : ""), switch_str_nil(p)(p ? p : ""), user, host, user, host);
11371
11372 if ((str = sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, cid, sizeof(cid)))) {
11373 bnh = nua_handle_by_call_id(nua, str);
11374 }
11375
11376 if (mod_sofia_globals.debug_sla > 1) {
11377 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 11377
, ((void*)0)
, SWITCH_LOG_ERROR, "PICK SQL %s [%s] [%s] %d\n", sql, str, cid, !!bnh);
11378 }
11379
11380 free(sql);
11381 }
11382 }
11383
11384
11385 check_decode(displayname, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 11385, __extension__ __PRETTY_FUNCTION__)); if (!_zstr(displayname
)) { int d = 0; char *p; if (strchr(displayname, '%')) { char
*tmp = switch_core_perform_session_strdup(session, displayname
, "sofia.c", (const char *)__func__, 11385); switch_url_decode
(tmp); displayname = tmp; d++; } if ((p = strchr(displayname,
'"'))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, displayname, "sofia.c", (const char *)__func__, 11385
); displayname = tmp; } if ((p = strchr(displayname, '"'))) {
displayname = p+1; } if ((p = strrchr(displayname, '"'))) { *
p = '\0'; } } } break; } while (0)
;
11386
11387 profile_dup_clean(from_user, tech_pvt->caller_profile->username, tech_pvt->caller_profile->pool)if (!_zstr(from_user)) { tech_pvt->caller_profile->username
= switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, from_user, "sofia.c", (
const char *)__func__, 11387)));} else { tech_pvt->caller_profile
->username = ""; }
;
11388 profile_dup_clean(dialplan, tech_pvt->caller_profile->dialplan, tech_pvt->caller_profile->pool)if (!_zstr(dialplan)) { tech_pvt->caller_profile->dialplan
= switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, dialplan, "sofia.c", (
const char *)__func__, 11388)));} else { tech_pvt->caller_profile
->dialplan = ""; }
;
11389 profile_dup_clean(displayname, tech_pvt->caller_profile->caller_id_name, tech_pvt->caller_profile->pool)if (!_zstr(displayname)) { tech_pvt->caller_profile->caller_id_name
= switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, displayname, "sofia.c"
, (const char *)__func__, 11389)));} else { tech_pvt->caller_profile
->caller_id_name = ""; }
;
11390 profile_dup_clean(from_user, tech_pvt->caller_profile->caller_id_number, tech_pvt->caller_profile->pool)if (!_zstr(from_user)) { tech_pvt->caller_profile->caller_id_number
= switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, from_user, "sofia.c", (
const char *)__func__, 11390)));} else { tech_pvt->caller_profile
->caller_id_number = ""; }
;
11391 profile_dup_clean(displayname, tech_pvt->caller_profile->orig_caller_id_name, tech_pvt->caller_profile->pool)if (!_zstr(displayname)) { tech_pvt->caller_profile->orig_caller_id_name
= switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, displayname, "sofia.c"
, (const char *)__func__, 11391)));} else { tech_pvt->caller_profile
->orig_caller_id_name = ""; }
;
11392 profile_dup_clean(from_user, tech_pvt->caller_profile->orig_caller_id_number, tech_pvt->caller_profile->pool)if (!_zstr(from_user)) { tech_pvt->caller_profile->orig_caller_id_number
= switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, from_user, "sofia.c", (
const char *)__func__, 11392)));} else { tech_pvt->caller_profile
->orig_caller_id_number = ""; }
;
11393 profile_dup_clean(network_ip, tech_pvt->caller_profile->network_addr, tech_pvt->caller_profile->pool)if (!_zstr(network_ip)) { tech_pvt->caller_profile->network_addr
= switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, network_ip, "sofia.c",
(const char *)__func__, 11393)));} else { tech_pvt->caller_profile
->network_addr = ""; }
;
11394 profile_dup_clean(from_user, tech_pvt->caller_profile->ani, tech_pvt->caller_profile->pool)if (!_zstr(from_user)) { tech_pvt->caller_profile->ani =
switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, from_user, "sofia.c", (
const char *)__func__, 11394)));} else { tech_pvt->caller_profile
->ani = ""; }
;
11395 profile_dup_clean(aniii, tech_pvt->caller_profile->aniii, tech_pvt->caller_profile->pool)if (!_zstr(aniii)) { tech_pvt->caller_profile->aniii = switch_var_clean_string
(switch_clean_string(switch_core_perform_strdup(tech_pvt->
caller_profile->pool, aniii, "sofia.c", (const char *)__func__
, 11395)));} else { tech_pvt->caller_profile->aniii = ""
; }
;
11396 profile_dup_clean(context, tech_pvt->caller_profile->context, tech_pvt->caller_profile->pool)if (!_zstr(context)) { tech_pvt->caller_profile->context
= switch_var_clean_string(switch_clean_string(switch_core_perform_strdup
(tech_pvt->caller_profile->pool, context, "sofia.c", (const
char *)__func__, 11396)));} else { tech_pvt->caller_profile
->context = ""; }
;
11397 profile_dup_clean(destination_number, tech_pvt->caller_profile->destination_number, tech_pvt->caller_profile->pool)if (!_zstr(destination_number)) { tech_pvt->caller_profile
->destination_number = switch_var_clean_string(switch_clean_string
(switch_core_perform_strdup(tech_pvt->caller_profile->pool
, destination_number, "sofia.c", (const char *)__func__, 11397
)));} else { tech_pvt->caller_profile->destination_number
= ""; }
;
11398
11399 if (!bnh && sip->sip_replaces) {
11400 if (!(bnh = nua_handle_by_replaces(nua, sip->sip_replaces))) {
11401 if (!(bnh = nua_handle_by_call_id(nua, sip->sip_replaces->rp_call_id))) {
11402 bnh = sofia_global_nua_handle_by_replaces(sip->sip_replaces);
11403 }
11404 }
11405 }
11406
11407 if (sip->sip_replaces) {
11408 msg_common_t *rp_common = sip->sip_replaces->rp_common;
11409 switch_channel_set_variable(channel, "sip_replaces_call_id", sip->sip_replaces->rp_call_id)switch_channel_set_variable_var_check(channel, "sip_replaces_call_id"
, sip->sip_replaces->rp_call_id, SWITCH_TRUE)
;
11410 if (rp_common->h_class->hc_params) {
11411 int i, n;
11412 msg_param_t const *params = * (msg_param_t const **) ((char *)rp_common + rp_common->h_class->hc_params);
11413 for (i = 0; params && params[i]; i++) {
11414 msg_param_t param = params[i];
11415 if (strchr(param, '=')) {
11416 n = strcspn(param, "=");
11417 switch_channel_set_variable_name_printf(channel, param + n + 1, "sip_replaces_%.*s", n, param);
11418 } else {
11419 switch_channel_set_variable_name_printf(channel, "true", "sip_replaces_%s", param);
11420 }
11421 }
11422 }
11423 }
11424
11425 if (bnh) {
11426 sofia_private_t *b_private = NULL((void*)0);
11427 if ((b_private = nua_handle_magic(bnh))) {
11428 switch_core_session_t *b_session = NULL((void*)0);
11429 if ((b_session = switch_core_session_locate(b_private->uuid)switch_core_session_perform_locate(b_private->uuid, "sofia.c"
, (const char *)__func__, 11429)
)) {
11430 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
11431 sofia_handle_sip_i_invite_replaces(session, channel, b_channel, b_private->uuid, tech_pvt, call_info, profile, is_nat, sip);
11432 switch_core_session_rwunlock(b_session);
11433 }
11434 }
11435 nua_handle_unref_user(bnh);
11436 } else if (sip->sip_replaces && sip->sip_replaces->rp_call_id) {
11437 switch_core_session_t *b_session = NULL((void*)0);
11438 if ((b_session = switch_core_session_locate((char*) sip->sip_replaces->rp_call_id)switch_core_session_perform_locate((char*) sip->sip_replaces
->rp_call_id, "sofia.c", (const char *)__func__, 11438)
)) {
11439 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
11440 sofia_handle_sip_i_invite_replaces(session, channel, b_channel, (char*) sip->sip_replaces->rp_call_id, tech_pvt, call_info, profile, is_nat, sip);
11441 switch_core_session_rwunlock(b_session);
11442 }
11443 }
11444
11445 if (tech_pvt->caller_profile) {
11446
11447 int first_history_info = 1;
11448
11449 if (rpid) {
11450 if (rpid->rpid_privacy) {
11451 if (!strcasecmp(rpid->rpid_privacy, "yes")) {
11452 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NAME
| SWITCH_CPF_HIDE_NUMBER)
;
11453 } else if (!strcasecmp(rpid->rpid_privacy, "full")) {
11454 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NAME
| SWITCH_CPF_HIDE_NUMBER)
;
11455 } else if (!strcasecmp(rpid->rpid_privacy, "name")) {
11456 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NAME
)
;
11457 } else if (!strcasecmp(rpid->rpid_privacy, "number")) {
11458 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NUMBER
)
;
11459 } else {
11460 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_HIDE_NAME
)
;
11461 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_HIDE_NUMBER
)
;
11462 }
11463 }
11464
11465 if (rpid->rpid_screen && !strcasecmp(rpid->rpid_screen, "no")) {
11466 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_SCREEN
)
;
11467 }
11468 }
11469
11470 if ((privacy = sip_privacy(sip)((sip_privacy_t *)msg_header_access((msg_pub_t*)(sip), sip_privacy_class
))
)) {
11471 char *full_priv_header = sip_header_as_string(nua_handle_get_home(nh), (void *) privacy);
11472 if (!zstr(full_priv_header)_zstr(full_priv_header)) {
11473 switch_channel_set_variable(channel, "sip_Privacy", full_priv_header)switch_channel_set_variable_var_check(channel, "sip_Privacy",
full_priv_header, SWITCH_TRUE)
;
11474 }
11475 if (msg_params_find(privacy->priv_values, "id")) {
11476 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NAME
| SWITCH_CPF_HIDE_NUMBER)
;
11477 }
11478 }
11479
11480 if (sip->sip_identity && sip->sip_identity->id_value) {
11481 switch_channel_set_variable(channel, "sip_h_identity", sip->sip_identity->id_value)switch_channel_set_variable_var_check(channel, "sip_h_identity"
, sip->sip_identity->id_value, SWITCH_TRUE)
;
11482 }
11483 if (sip->sip_date && sip->sip_date->d_time > 0) {
11484 // This INVITE has a SIP Date header.
11485 // sofia-sip stores the Date header value in sip_date->d_time as seconds since January 1, 1900 0:00:00.
11486 // Unix epoch time is seconds since January 1, 1970 0:00:00, making d_time larger by 2208988800.
11487 // Convert to Unix epoch time and save it.
11488 switch_channel_set_variable_printf(channel, "sip_date_epoch_time", "%ld", sip->sip_date->d_time - 2208988800);
11489 }
11490
11491 /* Loop thru unknown Headers Here so we can do something with them */
11492 for (un = sip->sip_unknown; un; un = un->un_next) {
11493 if (!strncasecmp(un->un_name, "Accept-Language", 15)) {
11494 if (!zstr(un->un_value)_zstr(un->un_value)) {
11495 char *tmp_name;
11496 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name))) {
11497 switch_channel_set_variable(channel, tmp_name, un->un_value)switch_channel_set_variable_var_check(channel, tmp_name, un->
un_value, SWITCH_TRUE)
;
11498 free(tmp_name);
11499 }
11500 }
11501 } else if (!strncasecmp(un->un_name, "Diversion", 9)) {
11502 /* Basic Diversion Support for Diversion Indication in SIP */
11503 /* draft-levy-sip-diversion-08 */
11504 if (!zstr(un->un_value)_zstr(un->un_value)) {
11505 char *tmp_name;
11506 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name))) {
11507 switch_channel_set_variable(channel, tmp_name, un->un_value)switch_channel_set_variable_var_check(channel, tmp_name, un->
un_value, SWITCH_TRUE)
;
11508 free(tmp_name);
11509 }
11510 }
11511 } else if (!strncasecmp(un->un_name, "History-Info", 12)) {
11512 if (first_history_info) {
11513 /* If the header exists first time, make sure to remove old info and re-set the variable */
11514 switch_channel_set_variable(channel, "sip_history_info", un->un_value)switch_channel_set_variable_var_check(channel, "sip_history_info"
, un->un_value, SWITCH_TRUE)
;
11515 first_history_info = 0;
11516 } else {
11517 /* Append the History-Info into one long string */
11518 const char *history_var = switch_channel_get_variable(channel, "sip_history_info")switch_channel_get_variable_dup(channel, "sip_history_info", SWITCH_TRUE
, -1)
;
11519 if (!zstr(history_var)_zstr(history_var)) {
11520 char *tmp_str;
11521 if ((tmp_str = switch_mprintf("%s, %s", history_var, un->un_value))) {
11522 switch_channel_set_variable(channel, "sip_history_info", tmp_str)switch_channel_set_variable_var_check(channel, "sip_history_info"
, tmp_str, SWITCH_TRUE)
;
11523 free(tmp_str);
11524 } else {
11525 switch_channel_set_variable(channel, "sip_history_info", un->un_value)switch_channel_set_variable_var_check(channel, "sip_history_info"
, un->un_value, SWITCH_TRUE)
;
11526 }
11527 } else {
11528 switch_channel_set_variable(channel, "sip_history_info", un->un_value)switch_channel_set_variable_var_check(channel, "sip_history_info"
, un->un_value, SWITCH_TRUE)
;
11529 }
11530 }
11531 } else if (!strcasecmp(un->un_name, "X-FS-Channel-Name") && !zstr(un->un_value)_zstr(un->un_value)) {
11532 switch_channel_set_name(channel, un->un_value);
11533 switch_channel_set_variable(channel, "push_channel_name", "true")switch_channel_set_variable_var_check(channel, "push_channel_name"
, "true", SWITCH_TRUE)
;
11534 } else if (!strcasecmp(un->un_name, "X-FS-Support")) {
11535 tech_pvt->x_freeswitch_support_remote = switch_core_session_strdup(session, un->un_value)switch_core_perform_session_strdup(session, un->un_value, "sofia.c"
, (const char *)__func__, 11535)
;
11536 } else if (!strcasecmp(un->un_name, "Geolocation")) {
11537 switch_channel_set_variable(channel, "sip_geolocation", un->un_value)switch_channel_set_variable_var_check(channel, "sip_geolocation"
, un->un_value, SWITCH_TRUE)
;
11538 } else if (!strcasecmp(un->un_name, "Geolocation-Error")) {
11539 switch_channel_set_variable(channel, "sip_geolocation_error", un->un_value)switch_channel_set_variable_var_check(channel, "sip_geolocation_error"
, un->un_value, SWITCH_TRUE)
;
11540 } else if (!strcasecmp(un->un_name, "userLocation")) {
11541 switch_channel_set_variable(channel, "sip_user_location", un->un_value)switch_channel_set_variable_var_check(channel, "sip_user_location"
, un->un_value, SWITCH_TRUE)
;
11542 } else if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2) || !strcasecmp(un->un_name, "User-to-User") || !strncasecmp(un->un_name, "On", 2) || !strncasecmp(un->un_name, "K-", 2)) {
11543 if (!zstr(un->un_value)_zstr(un->un_value)) {
11544 char new_name[512] = "";
11545 int reps = 0;
11546 for (;;) {
11547 char postfix[25] = "";
11548 if (reps > 0) {
11549 switch_snprintf(postfix, sizeof(postfix), "-%d", reps);
11550 }
11551 reps++;
11552 switch_snprintf(new_name, sizeof(new_name), "%s%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name, postfix);
11553
11554 if (switch_channel_get_variable(channel, new_name)switch_channel_get_variable_dup(channel, new_name, SWITCH_TRUE
, -1)
) {
11555 continue;
11556 }
11557
11558 switch_channel_set_variable(channel, new_name, un->un_value)switch_channel_set_variable_var_check(channel, new_name, un->
un_value, SWITCH_TRUE)
;
11559 break;
11560 }
11561 }
11562 }
11563 }
11564
11565 }
11566
11567 tech_pvt->sofia_private = sofia_private;
11568 tech_pvt->nh = nh;
11569
11570 if (profile->pres_type && sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)((profile)->pflags[PFLAG_IN_DIALOG_CHAT] ? 1 : 0)) {
11571 sofia_presence_set_chat_hash(tech_pvt, sip);
11572 }
11573
11574 if (sofia_test_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)((profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] ? 1 : 0
)
) {
11575 sofia_parse_all_invite_headers(sip, session, nh);
11576 }
11577
11578 if (sip->sip_to) {
11579 to = sip->sip_to->a_url;
11580 }
11581 if (sip->sip_from) {
11582 from = sip->sip_from->a_url;
11583 }
11584 contact = sip->sip_contact->m_url;
11585
11586 if (sip->sip_user_agent) {
11587 user_agent = switch_str_nil(sip->sip_user_agent->g_string)(sip->sip_user_agent->g_string ? sip->sip_user_agent
->g_string : "")
;
11588 }
11589
11590 if (sip->sip_call_id) {
11591 call_id = switch_str_nil(sip->sip_call_id->i_id)(sip->sip_call_id->i_id ? sip->sip_call_id->i_id :
"")
;
11592 }
11593
11594 if (to) {
11595 to_user = switch_str_nil(to->url_user)(to->url_user ? to->url_user : "");
11596 to_host = switch_str_nil(to->url_host)(to->url_host ? to->url_host : "");
11597 to_tag = switch_str_nil(sip->sip_to->a_tag)(sip->sip_to->a_tag ? sip->sip_to->a_tag : "");
11598 }
11599
11600 if (from) {
11601 dialog_from_user = switch_str_nil(from->url_user)(from->url_user ? from->url_user : "");
11602 dialog_from_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
11603 from_tag = switch_str_nil(sip->sip_from->a_tag)(sip->sip_from->a_tag ? sip->sip_from->a_tag : ""
)
;
11604 }
11605
11606 contact_user = switch_str_nil(contact->url_user)(contact->url_user ? contact->url_user : "");
11607 contact_host = switch_str_nil(contact->url_host)(contact->url_host ? contact->url_host : "");
11608
11609 if (profile->pres_type) {
11610 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
11611 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
11612 char *full_contact = "";
11613 char *p = NULL((void*)0);
11614 time_t now;
11615
11616 full_contact = sip_header_as_string(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), (void *) sip->sip_contact);
11617
11618 if (call_info_str && switch_stristr("appearance", call_info_str)) {
11619 switch_channel_set_variable(channel, "presence_call_info_full", call_info_str)switch_channel_set_variable_var_check(channel, "presence_call_info_full"
, call_info_str, SWITCH_TRUE)
;
11620 if ((p = strchr(call_info_str, ';'))) {
11621 p++;
11622 switch_channel_set_variable(channel, "presence_call_info", p)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p, SWITCH_TRUE)
;
11623 }
11624 }
11625
11626 now = switch_epoch_time_now(NULL((void*)0));
11627
11628 sql = switch_mprintf("insert into sip_dialogs "
11629 "(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
11630 "contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
11631 "call_info,rcd,call_info_state) "
11632 "values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
11633 call_id,
11634 tech_pvt->sofia_private->uuid,
11635 to_user, to_host, to_tag, dialog_from_user, dialog_from_host, from_tag,
11636 contact_user, contact_host, "confirmed", "inbound", user_agent,
11637 profile->name, mod_sofia_globals.hostname, switch_str_nil(full_contact)(full_contact ? full_contact : ""),
11638 switch_str_nil(presence_id)(presence_id ? presence_id : ""), switch_str_nil(presence_data)(presence_data ? presence_data : ""), switch_str_nil(p)(p ? p : ""), now);
11639
11640 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 11640,
__extension__ __PRETTY_FUNCTION__))
;
11641
11642 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11643
11644 if ( full_contact ) {
11645 su_free(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), full_contact);
11646 }
11647 }
11648
11649 if (is_nat) {
11650 sofia_set_flag(tech_pvt, TFLAG_NAT)(tech_pvt)->flags[TFLAG_NAT] = 1;
11651 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11651, (const char*)(session)
, SWITCH_LOG_DEBUG, "Setting NAT mode based on %s\n", is_nat);
11652 switch_channel_set_variable(channel, "sip_nat_detected", "true")switch_channel_set_variable_var_check(channel, "sip_nat_detected"
, "true", SWITCH_TRUE)
;
11653 }
11654
11655 return;
11656
11657 fail:
11658 profile->ib_failed_calls++;
11659
11660 return;
11661
11662}
11663
11664void sofia_handle_sip_i_invite_replaces(switch_core_session_t *session, switch_channel_t *channel, switch_channel_t *b_channel, char* uuid, private_object_t *tech_pvt, sip_call_info_t *call_info, sofia_profile_t *profile, char *is_nat, sip_t const *sip)
11665{
11666 const char *bridge_uuid;
11667 switch_caller_profile_t *orig_cp, *cp;
11668 //const char *sent_name, *sent_number;
11669 orig_cp = switch_channel_get_caller_profile(b_channel);
11670
11671 if (orig_cp) {
11672 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, orig_cp->callee_id_name, "sofia.c", (const char *)__func__
, 11672)
;
11673 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, orig_cp->callee_id_number, "sofia.c", (const char *)__func__
, 11673)
;
11674
11675 if (!call_info) {
11676 tech_pvt->caller_profile->caller_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, orig_cp->caller_id_name, "sofia.c", (const char *)__func__
, 11676)
;
11677 tech_pvt->caller_profile->caller_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, orig_cp->caller_id_number, "sofia.c", (const char *)__func__
, 11677)
;
11678 }
11679
11680 cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool, orig_cp);
11681 switch_channel_set_originator_caller_profile(channel, cp);
11682 }
11683
11684#if 0
11685 sent_name = switch_channel_get_variable(b_channel, "last_sent_callee_id_name")switch_channel_get_variable_dup(b_channel, "last_sent_callee_id_name"
, SWITCH_TRUE, -1)
;
11686 sent_number = switch_channel_get_variable(b_channel, "last_sent_callee_id_number")switch_channel_get_variable_dup(b_channel, "last_sent_callee_id_number"
, SWITCH_TRUE, -1)
;
11687
11688 if (!zstr(sent_name)_zstr(sent_name) && !zstr(sent_number)_zstr(sent_number)) {
11689 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, sent_name)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, sent_name, "sofia.c", (const char *)__func__, 11689)
;
11690 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, sent_number)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, sent_number, "sofia.c", (const char *)__func__, 11690)
;
11691 } else {
11692 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
11693 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, orig_cp->callee_id_name, "sofia.c", (const char *)__func__
, 11693)
;
11694 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, orig_cp->callee_id_number, "sofia.c", (const char *)__func__
, 11694)
;
11695 } else {
11696 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, orig_cp->caller_id_name, "sofia.c", (const char *)__func__
, 11696)
;
11697 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, orig_cp->caller_id_number, "sofia.c", (const char *)__func__
, 11697)
;
11698 }
11699 }
11700#endif
11701
11702 if (is_nat) {
11703 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11703, (const char*)(session)
, SWITCH_LOG_CRIT, "Setting NAT mode based on %s\n", is_nat);
11704 }
11705
11706 tech_pvt->caller_profile->dialplan = "inline";
11707
11708 bridge_uuid = switch_channel_get_partner_uuid(b_channel);
11709 if (bridge_uuid) {
11710 switch_core_session_t *bridge_session = NULL((void*)0);
11711 if ((bridge_session = switch_core_session_locate(bridge_uuid)switch_core_session_perform_locate(bridge_uuid, "sofia.c", (const
char *)__func__, 11711)
)) {
11712 switch_core_session_rwunlock(bridge_session);
11713 } else {
11714 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11714, (const char*)(session)
, SWITCH_LOG_WARNING, "could not locate partner_uuid %s, resetting\n", bridge_uuid);
11715 bridge_uuid = NULL((void*)0);
11716 }
11717 }
11718
11719 if (call_info) {
11720 switch_event_t *event = NULL((void*)0);
11721
11722 if (!zstr(bridge_uuid)_zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) {
11723 const char *b_call_id = switch_channel_get_variable(b_channel, "sip_call_id")switch_channel_get_variable_dup(b_channel, "sip_call_id", SWITCH_TRUE
, -1)
;
11724
11725 if (b_call_id) {
11726 char *sql = switch_mprintf("update sip_dialogs set call_info_state='idle' where call_id='%q'", b_call_id);
11727 if (mod_sofia_globals.debug_sla > 1) {
11728 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11728, (const char*)(session)
, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
11729 }
11730 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11731
11732 switch_channel_presence(b_channel, "unknown", "idle", NULL)switch_channel_perform_presence(b_channel, "unknown", "idle",
((void*)0), "sofia.c", (const char *)__func__, 11732)
;
11733 }
11734 switch_channel_set_flag(tech_pvt->channel, CF_SLA_INTERCEPT)switch_channel_set_flag_value(tech_pvt->channel, CF_SLA_INTERCEPT
, 1)
;
11735 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
11736 "answer,intercept:%s", bridge_uuid);
11737
11738 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)
11739 && sip && sip->sip_call_id
11740 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 11740, &event, SWITCH_EVENT_CUSTOM
, "sofia::replaced")
== SWITCH_STATUS_SUCCESS) {
11741 switch_channel_event_set_data(b_channel, event);
11742 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", sip->sip_call_id->i_id);
11743 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 11743, &event, ((void*)0))
;
11744 }
11745 } else {
11746 switch_caller_profile_t *bcp = switch_channel_get_caller_profile(b_channel);
11747
11748 if (switch_channel_test_flag(b_channel, CF_BRIDGE_ORIGINATOR)) {
11749 switch_channel_set_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR)switch_channel_set_flag_value(tech_pvt->channel, CF_BRIDGE_ORIGINATOR
, 1)
;
11750 }
11751
11752 if (!zstr(bcp->callee_id_name)_zstr(bcp->callee_id_name)) {
11753 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->callee_id_name)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, bcp->callee_id_name, "sofia.c", (const char *)__func__, 11753
)
;
11754 }
11755
11756 if (!zstr(bcp->callee_id_number)_zstr(bcp->callee_id_number)) {
11757 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->callee_id_number)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, bcp->callee_id_number, "sofia.c", (const char *)__func__
, 11757)
;
11758 }
11759
11760
11761 if (!zstr(bcp->caller_id_name)_zstr(bcp->caller_id_name)) {
11762 tech_pvt->caller_profile->caller_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->caller_id_name)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, bcp->caller_id_name, "sofia.c", (const char *)__func__, 11762
)
;
11763 }
11764
11765 if (!zstr(bcp->caller_id_number)_zstr(bcp->caller_id_number)) {
11766 tech_pvt->caller_profile->caller_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->caller_id_number)switch_core_perform_strdup(tech_pvt->caller_profile->pool
, bcp->caller_id_number, "sofia.c", (const char *)__func__
, 11766)
;
11767 }
11768
11769 if (bcp->originatee_caller_profile) {
11770 switch_caller_profile_t *cp;
11771
11772 cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool,
11773 bcp->originatee_caller_profile);
11774
11775 switch_channel_set_originatee_caller_profile(tech_pvt->channel, cp);
11776 }
11777
11778 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
11779 "answer,sofia_sla:%s", uuid);
11780 }
11781 } else {
11782 char const *nightmare_xfer_uuid = NULL((void*)0);
11783 switch_event_t *event = NULL((void*)0);
11784 if (switch_channel_var_true(channel, "sip_replaces_a-leg")) {
11785 switch_channel_mark_hold(b_channel, SWITCH_FALSE);
11786 if (sip) {
11787 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", sip->sip_replaces->rp_call_id);
11788 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11788, (const char*)(session)
, SWITCH_LOG_DEBUG, "call %s picked up on a-leg\n", sip->sip_replaces->rp_call_id);
11789 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)
11790 && sip->sip_call_id
11791 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 11791, &event, SWITCH_EVENT_CUSTOM
, "sofia::intercepted")
== SWITCH_STATUS_SUCCESS) {
11792 switch_channel_event_set_data(b_channel, event);
11793 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id);
11794 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 11794, &event, ((void*)0))
;
11795 }
11796 }
11797 } else {
11798 if (sip) {
11799 if ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-For"))) {
11800 switch_channel_set_variable(b_channel, "transfer_refer_for", nightmare_xfer_uuid)switch_channel_set_variable_var_check(b_channel, "transfer_refer_for"
, nightmare_xfer_uuid, SWITCH_TRUE)
;
11801 }
11802 if ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-From"))) {
11803 switch_channel_set_variable(b_channel, "transfer_refer_from", nightmare_xfer_uuid)switch_channel_set_variable_var_check(b_channel, "transfer_refer_from"
, nightmare_xfer_uuid, SWITCH_TRUE)
;
11804 }
11805 }
11806
11807 if (!zstr(bridge_uuid)_zstr(bridge_uuid)) {
11808 if (sip && sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id && switch_channel_test_flag(b_channel, CF_BRIDGED) &&
11809 switch_true(switch_find_parameter(*(sip->sip_replaces->rp_params), "early-only", switch_core_session_get_pool(session)))) {
11810 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11810, (const char*)(session)
, SWITCH_LOG_DEBUG, "call %s intercept rejected\n", bridge_uuid);
11811 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "hangup:CALL_REJECTED");
11812 } else {
11813 switch_channel_mark_hold(b_channel, SWITCH_FALSE);
11814 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid);
11815 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11815, (const char*)(session)
, SWITCH_LOG_DEBUG, "call %s intercepted\n", bridge_uuid);
11816 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)
11817 && sip && sip->sip_call_id
11818 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 11818, &event, SWITCH_EVENT_CUSTOM
, "sofia::intercepted")
== SWITCH_STATUS_SUCCESS) {
11819 switch_channel_event_set_data(b_channel, event);
11820 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id);
11821 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 11821, &event, ((void*)0))
;
11822 }
11823 }
11824 } else {
11825 const char *b_app = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_VARIABLE)switch_channel_get_variable_dup(b_channel, "current_application"
, SWITCH_TRUE, -1)
;
11826 const char *b_data = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE)switch_channel_get_variable_dup(b_channel, "current_application_data"
, SWITCH_TRUE, -1)
;
11827 if (b_data && b_app) {
11828 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s:%s", b_app, b_data);
11829 } else if (b_app) {
11830 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s", b_app);
11831 }
11832 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)
11833 && sip && sip->sip_call_id
11834 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 11834, &event, SWITCH_EVENT_CUSTOM
, "sofia::replaced")
== SWITCH_STATUS_SUCCESS) {
11835 switch_channel_event_set_data(b_channel, event);
11836 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", sip->sip_call_id->i_id);
11837 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 11837, &event, ((void*)0))
;
11838 }
11839 switch_channel_hangup(b_channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(b_channel, "sofia.c", (const char
*)__func__, 11839, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
11840 }
11841 }
11842 }
11843
11844}
11845
11846void sofia_handle_sip_i_options(int status,
11847 char const *phrase,
11848 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
11849 sofia_dispatch_event_t *de,
11850 tagi_t tags[])
11851{
11852 uint32_t sess_count = switch_core_session_count();
11853 uint32_t sess_max = switch_core_session_limit(0);
11854
11855 if (sofia_test_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)((profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] ? 1 :
0)
&&
11856 (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0) || !switch_core_ready_inbound())) {
11857 nua_respond(nh, 503, "Maximum Calls In Progress", NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), SIPTAG_RETRY_AFTER_STR("300")siptag_retry_after_str, tag_str_v("300"), TAG_END()(tag_type_t)0, (tag_value_t)0);
11858 } else {
11859 switch_assert(sip)((sip) ? (void) (0) : __assert_fail ("sip", "sofia.c", 11859,
__extension__ __PRETTY_FUNCTION__))
;
11860 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
11861 TAG_IF(sip->sip_record_route, SIPTAG_RECORD_ROUTE(sip->sip_record_route))!(sip->sip_record_route) ? tag_skip : siptag_record_route,
siptag_record_route_v(sip->sip_record_route)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
11862 }
11863
11864}
11865
11866/*
11867 * This subroutine will take the a_params of a sip_addr_s structure and spin through them.
11868 * Each param will be used to create a channel variable.
11869 * In the SIP RFC's, this data is called generic-param.
11870 * Note that the tag-param is also included in the a_params list.
11871 *
11872 * From: "John Doe" <sip:5551212@1.2.3.4>;tag=ed23266b52cbb17eo2;ref=101;mbid=201
11873 *
11874 * For example, the header above will produce an a_params list with three entries
11875 * tag=ed23266b52cbb17eo2
11876 * ref=101
11877 * mbid=201
11878 *
11879 * The a_params list is parsed and the lvalue is used to create the channel variable name while the
11880 * rvalue is used to create the channel variable value.
11881 *
11882 * If no equal (=) sign is found during parsing, a channel variable name is created with the param and
11883 * the value is set to NULL.
11884 *
11885 * Pointers are used for copying the sip_header_name for performance reasons. There are no calls to
11886 * any string functions and no memory is allocated/dealocated. The only limiter is the size of the
11887 * sip_header_name array.
11888*/
11889static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params)
11890{
11891 char sip_header_name[128] = "";
11892 char var1[] = "sip_";
11893 char *cp, *sh, *sh_end, *sh_save;
11894
11895 /* Build the static part of the sip_header_name variable from */
11896 /* the header_type. If the header type is "referred_by" then */
11897 /* sip_header_name = "sip_referred_by_". */
11898 sh = sip_header_name;
11899 sh_end = sh + sizeof(sip_header_name) - 1;
11900 for (cp = var1; *cp; cp++, sh++) {
11901 *sh = *cp;
11902 }
11903 *sh = '\0';
11904
11905 /* Copy the header_type to the sip_header_name. Before copying */
11906 /* each character, check that we aren't going to overflow the */
11907 /* the sip_header_name buffer. We have to account for the */
11908 /* trailing underscore and NULL that will be added to the end. */
11909 for (cp = header_type; (*cp && (sh < (sh_end - 1))); cp++, sh++) {
11910 *sh = *cp;
11911 }
11912 *sh++ = '_';
11913 *sh = '\0';
11914
11915 /* sh now points to the NULL at the end of the partially built */
11916 /* sip_header_name variable. This is also the start of the */
11917 /* variable part of the sip_header_name built from the lvalue */
11918 /* of the params data. */
11919 sh_save = sh;
11920
11921 while (params && params[0]) {
11922
11923 /* Copy the params data to the sip_header_name variable until */
11924 /* the end of the params string is reached, an '=' is detected */
11925 /* or until the sip_header_name buffer has been exhausted. */
11926 for (cp = (char *) (*params); ((*cp != '=') && *cp && (sh < sh_end)); cp++, sh++) {
11927 *sh = *cp;
11928 }
11929
11930 /* cp now points to either the end of the params data or the */
11931 /* equal (=) sign separating the lvalue and rvalue. */
11932 if (*cp == '=')
11933 cp++;
11934 *sh = '\0';
11935 switch_channel_set_variable(channel, sip_header_name, cp)switch_channel_set_variable_var_check(channel, sip_header_name
, cp, SWITCH_TRUE)
;
11936
11937 /* Bump pointer to next param in the list. Also reset the */
11938 /* sip_header_name pointer to the beginning of the dynamic area */
11939 params++;
11940 sh = sh_save;
11941 }
11942}
11943
11944/* For Emacs:
11945 * Local Variables:
11946 * mode:c
11947 * indent-tabs-mode:t
11948 * tab-width:4
11949 * c-basic-offset:4
11950 * End:
11951 * For VIM:
11952 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
11953 */