Bug Summary

File:mod/endpoints/mod_sofia/sofia.c
Warning:line 2454, column 8
Potential leak of memory pointed to by 'uuid'

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-200843-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 == '"') {
210 t++;
211
212 if (end_of(t)*(*t == '\0' ? t : t + strlen(t) - 1) == '"') {
213 r = strdup(t);
214 switch_assert(r)((r) ? (void) (0) : __assert_fail ("r", "sofia.c", 214, __extension__
__PRETTY_FUNCTION__))
;
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) {
229 if (sip->sip_route) {
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) {
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) {
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) {
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) {
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) {
340 char *p = strip_quotes(sip->sip_to->a_display);
341
342 if (p) {
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);
347
348 if ((full = sip_header_as_string(nua_handle_get_home(nh), (void *) sip->sip_to))) {
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) {
1
Control jumps to 'case nua_i_terminated:' at line 2426
2426 case nua_i_terminated:
2427 if ((status == 401 || status == 407 || status == 403) && sofia_private) {
2
Assuming 'status' is equal to 401
3
Assuming 'sofia_private' is non-null
4
Taking true branch
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)
)) {
5
Assuming 'session' is not null
6
Taking true branch
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)) {
7
Assuming the condition is true
8
Assuming the condition is true
9
Taking true branch
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) {
10
Taking false branch
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)) {
11
Taking true branch
2444 char *uuid = strdup(switch_core_session_get_uuid(session));
12
Memory is allocated
2445 tech_pvt->sofia_private = NULL((void*)0);
2446 tech_pvt->nh = NULL((void*)0);
2447 sofia_set_flag(tech_pvt, TFLAG_BYE)(tech_pvt)->flags[TFLAG_BYE] = 1;
2448 switch_mutex_lock(profile->flag_mutex);
2449
2450 if (switch_core_hash_insert_auto_free(profile->chat_hash, tech_pvt->call_id, uuid) != SWITCH_STATUS_SUCCESS) {
13
Assuming the condition is false
14
Taking false branch
2451 switch_safe_free(uuid)if (uuid) {free(uuid);uuid=((void*)0);};
2452 }
2453
2454 switch_mutex_unlock(profile->flag_mutex);
15
Potential leak of memory pointed to by 'uuid'
2455 nua_handle_destroy(nh);
2456 } else {
2457 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 2457, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
2458 }
2459 }
2460 end++;
2461 }
2462
2463 switch_core_session_rwunlock(session);
2464
2465 if (end) {
2466 goto end;
2467 }
2468 }
2469 }
2470 break;
2471 case nua_i_invite:
2472 case nua_i_register:
2473 case nua_i_options:
2474 case nua_i_notify:
2475 case nua_i_info:
2476
2477
2478 if (event == nua_i_invite) {
2479 if (sip->sip_session_expires && profile->minimum_session_expires) {
2480 if (sip->sip_session_expires->x_delta < profile->minimum_session_expires) {
2481 char buf[64] = "";
2482 switch_snprintf(buf, sizeof(buf), "Min-SE: %d", profile->minimum_session_expires);
2483 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);
2484 goto end;
2485 }
2486 }
2487 }
2488
2489 if (!sofia_private) {
2490 if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0) || !switch_core_ready_inbound()) {
2491 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);
2492 goto end;
2493 }
2494
2495
2496 if (switch_queue_size(mod_sofia_globals.msg_queue) > (unsigned int)critical) {
2497 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);
2498 goto end;
2499 }
2500
2501 if (sofia_test_pflag(profile, PFLAG_STANDBY)((profile)->pflags[PFLAG_STANDBY] ? 1 : 0)) {
2502 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);
2503 goto end;
2504 }
2505 }
2506
2507 break;
2508
2509 default:
2510 break;
2511
2512 }
2513
2514 switch_mutex_lock(profile->flag_mutex);
2515 profile->queued_events++;
2516 switch_mutex_unlock(profile->flag_mutex);
2517
2518 de = su_alloc(nua_handle_get_home(nh), sizeof(*de));
2519 memset(de, 0, sizeof(*de));
2520 nua_save_event(nua, de->event);
2521 de->nh = nh ? nua_handle_ref(nh) : NULL((void*)0);
2522 de->data = nua_event_data(de->event);
2523 de->sip = sip_object(de->data->e_msg);
2524 de->profile = profile;
2525 de->nua = (nua_t *)su_home_ref(nua_get_home(nua));
2526
2527 if (event == nua_i_invite && !sofia_private) {
2528 switch_core_session_t *session;
2529 private_object_t *tech_pvt = NULL((void*)0);
2530
2531 if (!(sofia_private = su_alloc(nua_handle_get_home(nh), sizeof(*sofia_private)))) {
2532 abort();
2533 }
2534
2535 memset(sofia_private, 0, sizeof(*sofia_private));
2536 sofia_private->is_call++;
2537 sofia_private->is_static++;
2538 nua_handle_bind(nh, sofia_private);
2539
2540
2541 if (sip->sip_call_id && sip->sip_call_id->i_id) {
2542 char *uuid = NULL((void*)0), *tmp;
2543
2544 switch_mutex_lock(profile->flag_mutex);
2545 if ((tmp = (char *) switch_core_hash_find(profile->chat_hash, sip->sip_call_id->i_id))) {
2546 uuid = strdup(tmp);
2547 switch_core_hash_delete(profile->chat_hash, sip->sip_call_id->i_id);
2548 }
2549 switch_mutex_unlock(profile->flag_mutex);
2550
2551 if (uuid) {
2552 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 2552)
)) {
2553 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
2554 switch_copy_string(sofia_private->uuid_str, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid_str));
2555 sofia_private->uuid = sofia_private->uuid_str;
2556 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2556
, ((void*)0)
, SWITCH_LOG_DEBUG, "Re-attaching to session %s\n", sofia_private->uuid);
2557 de->init_session = session;
2558 sofia_clear_flag(tech_pvt, TFLAG_BYE)(tech_pvt)->flags[TFLAG_BYE] = 0;
2559 tech_pvt->sofia_private = NULL((void*)0);
2560 tech_pvt->nh = NULL((void*)0);
2561 switch_core_session_queue_signal_data(session, de);
2562 switch_core_session_rwunlock(session);
2563 session = NULL((void*)0);
2564 free(uuid);
2565 uuid = NULL((void*)0);
2566 goto end;
2567 } else {
2568 free(uuid);
2569 uuid = NULL((void*)0);
2570 sip = NULL((void*)0);
2571 }
2572 }
2573 }
2574
2575 if (!sip || !sip->sip_call_id || zstr(sip->sip_call_id->i_id)_zstr(sip->sip_call_id->i_id)) {
2576 nua_respond(nh, 503, "INVALID INVITE", TAG_END()(tag_type_t)0, (tag_value_t)0);
2577 nua_destroy_event(de->event);
2578 su_free(nua_handle_get_home(nh), de);
2579
2580 switch_mutex_lock(profile->flag_mutex);
2581 profile->queued_events--;
2582 switch_mutex_unlock(profile->flag_mutex);
2583
2584 nua_handle_unref_user(nh);
2585 nua_unref_user(nua);
2586
2587 goto end;
2588 }
2589
2590 if (sofia_test_pflag(profile, PFLAG_CALLID_AS_UUID)((profile)->pflags[PFLAG_CALLID_AS_UUID] ? 1 : 0)) {
2591 session = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL((void*)0), sip->sip_call_id->i_id);
2592 } else {
2593 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))
;
2594 }
2595
2596 if (session) {
2597 const char *channel_name = NULL((void*)0);
2598 tech_pvt = sofia_glue_new_pvt(session);
2599
2600 if (sip->sip_from) {
2601 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")
;
2602 }
2603 if (!channel_name && sip->sip_contact) {
2604 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")
;
2605 }
2606 if (sip->sip_referred_by) {
2607 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"
)
;
2608 }
2609
2610 sofia_glue_attach_private(session, profile, tech_pvt, channel_name);
2611
2612 set_call_id(tech_pvt, sip);
2613 } else {
2614 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);
2615 nua_destroy_event(de->event);
2616 su_free(nua_handle_get_home(nh), de);
2617
2618 switch_mutex_lock(profile->flag_mutex);
2619 profile->queued_events--;
2620 switch_mutex_unlock(profile->flag_mutex);
2621
2622 nua_handle_unref_user(nh);
2623 nua_unref_user(nua);
2624
2625 goto end;
2626 }
2627
2628
2629 if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
2630 char *uuid;
2631
2632 if (!switch_core_session_running(session) && !switch_core_session_started(session)) {
2633 nua_handle_bind(nh, NULL((void*)0));
2634 sofia_private_free(sofia_private)if (sofia_private && ! sofia_private->is_static) {
free(sofia_private);} sofia_private = ((void*)0);
;
2635 switch_core_session_destroy(&session)switch_core_session_perform_destroy(&session, "sofia.c", (
const char *)__func__, 2635)
;
2636 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);
2637 }
2638 switch_mutex_lock(profile->flag_mutex);
2639 if ((uuid = switch_core_hash_find(profile->chat_hash, tech_pvt->call_id))) {
2640 free(uuid);
2641 uuid = NULL((void*)0);
2642 switch_core_hash_delete(profile->chat_hash, tech_pvt->call_id);
2643 }
2644 switch_mutex_unlock(profile->flag_mutex);
2645
2646 goto end;
2647 }
2648
2649 switch_copy_string(sofia_private->uuid_str, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid_str));
2650 sofia_private->uuid = sofia_private->uuid_str;
2651
2652 de->init_session = session;
2653 switch_core_session_queue_signal_data(session, de);
2654 goto end;
2655 }
2656
2657 if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
2658 switch_core_session_t *session;
2659
2660 if ((session = switch_core_session_locate(sofia_private->uuid)switch_core_session_perform_locate(sofia_private->uuid, "sofia.c"
, (const char *)__func__, 2660)
)) {
2661 switch_core_session_queue_signal_data(session, de);
2662 switch_core_session_rwunlock(session);
2663 goto end;
2664 }
2665 }
2666
2667 sofia_queue_message(de);
2668
2669 end:
2670 //switch_cond_next();
2671
2672 return;
2673}
2674
2675
2676void event_handler(switch_event_t *event)
2677{
2678 char *subclass, *sql;
2679 char *class;
2680 switch_event_t *pevent;
2681
2682 /* Get Original Event Name */
2683 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) : "")
;
2684 if (!strcasecmp(class, "PRESENCE_IN")) {
2685 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2685
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nGot Presence IN event via MultiCast\n");
2686 if (switch_event_create(&pevent, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2686, &pevent, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2687 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) : "")
);
2688 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) :
"")
);
2689 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) : "")
);
2690 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) : "")
);
2691 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) : "")
);
2692 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) : "")
);
2693 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) : "")
);
2694 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) : "")
);
2695 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) : "")
);
2696 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) : "")
);
2697 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) : "")
);
2698 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) :
"")
);
2699 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) : "")
);
2700 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) : "")
);
2701 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) : "")
);
2702 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) : "")
);
2703 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) : "")
);
2704 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) : "")
);
2705 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) : "")
);
2706 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) : "")
);
2707 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) : "")
);
2708 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) : "")
);
2709 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) : "")
);
2710 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) : "")
);
2711 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) : "")
);
2712 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) : "")
);
2713 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) : "")
);
2714
2715 /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
2716 sofia_presence_event_handler(pevent);
2717 return;
2718 } else {
2719 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2719
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nCannot inject PRESENCE_IN event\n");
2720 return;
2721 }
2722 } else if (!strcasecmp(class, "MESSAGE_WAITING")) {
2723 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2723
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nGot MWI event via MultiCast\n");
2724 if (switch_event_create(&pevent, SWITCH_EVENT_MESSAGE_WAITING)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2724, &pevent, SWITCH_EVENT_MESSAGE_WAITING
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2725 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) : "")
);
2726 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) : "")
);
2727 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) : "")
);
2728 /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
2729 sofia_presence_event_handler(pevent);
2730 return;
2731 } else {
2732 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2732
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nCannot inject MWI event\n");
2733 return;
2734 }
2735 } 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")) {
2736 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) :
"")
;
2737 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) : "")
;
2738 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) : "")
;
2739 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) : "")
;
2740 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) : "")
;
2741
2742 sofia_profile_t *profile = NULL((void*)0);
2743
2744 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2744
, profile_name)
)) {
2745 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2745
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2746 return;
2747 }
2748
2749 if (sofia_test_pflag(profile, PFLAG_MULTIREG)((profile)->pflags[PFLAG_MULTIREG] ? 1 : 0)) {
2750 sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
2751 } else {
2752 sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", from_user, from_host);
2753 }
2754
2755 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2756 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2756
, ((void*)0)
, SWITCH_LOG_DEBUG, "Expired propagated registration for %s@%s->%s\n", from_user, from_host, contact_str);
2757
2758 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2758, profile)
;
2759 } 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")) {
2760 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) : "")
;
2761 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) : "")
;
2762 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) : "")
;
2763 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) : "")
;
2764 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) : "")
;
2765 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) : "")
;
2766 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) : "")
;
2767 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) : "")
;
2768 long expires = (long) switch_epoch_time_now(NULL((void*)0));
2769 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) :
"")
;
2770 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) : "")
;
2771 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) : "")
;
2772 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) : "")
;
2773 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) :
"")
;
2774 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) : "")
;
2775 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) : "")
;
2776 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) : "")
;
2777 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) : "")
;
2778 char *fixed_contact_str = NULL((void*)0);
2779
2780 sofia_profile_t *profile = NULL((void*)0);
2781 char guess_ip4[256];
2782
2783 char *mwi_account = NULL((void*)0);
2784 char *dup_mwi_account = NULL((void*)0);
2785 char *mwi_user = NULL((void*)0);
2786 char *mwi_host = NULL((void*)0);
2787
2788 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) :
"")
)) {
2789 dup_mwi_account = strdup(mwi_account);
2790 switch_assert(dup_mwi_account != NULL)((dup_mwi_account != ((void*)0)) ? (void) (0) : __assert_fail
("dup_mwi_account != ((void*)0)", "sofia.c", 2790, __extension__
__PRETTY_FUNCTION__))
;
2791 switch_split_user_domain(dup_mwi_account, &mwi_user, &mwi_host);
2792 }
2793
2794 if (!mwi_user) {
2795 mwi_user = (char *) from_user;
2796 }
2797 if (!mwi_host) {
2798 mwi_host = (char *) from_host;
2799 }
2800
2801 if (exp_str) {
2802 expires += atol(exp_str);
2803 }
2804
2805 if (!rpid) {
2806 rpid = "unknown";
2807 }
2808
2809 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2809
, profile_name)
)) {
2810 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2810
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2811 goto end;
2812 }
2813 if (sofia_test_pflag(profile, PFLAG_MULTIREG)((profile)->pflags[PFLAG_MULTIREG] ? 1 : 0)) {
2814 sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
2815 } else {
2816 sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", from_user, from_host);
2817 }
2818
2819 if (mod_sofia_globals.rewrite_multicasted_fs_path && contact_str) {
2820 const char *needle = ";fs_path=";
2821 char *sptr, *eptr = NULL((void*)0);
2822 /* allocate enough room for worst-case scenario, depends on rewrite_multicased_fs_path setting */
2823 size_t len;
2824 switch (mod_sofia_globals.rewrite_multicasted_fs_path) {
2825 case 1:
2826 len = strlen(contact_str) + strlen(to_host) + 14;
2827 break;
2828 case 2:
2829 len = strlen(contact_str) + strlen(orig_server_host) + 14;
2830 break;
2831 case 3:
2832 len = strlen(contact_str) + strlen(orig_hostname) + 14;
2833 break;
2834 default:
2835 len = strlen(contact_str) + strlen(to_host) + 14;
2836 break;
2837 }
2838
2839 fixed_contact_str = malloc(len);
2840 switch_assert(fixed_contact_str)((fixed_contact_str) ? (void) (0) : __assert_fail ("fixed_contact_str"
, "sofia.c", 2840, __extension__ __PRETTY_FUNCTION__))
;
2841 switch_copy_string(fixed_contact_str, contact_str, len);
2842
2843 if ((sptr = strstr(fixed_contact_str, needle))) {
2844 char *origsptr = strstr(contact_str, needle);
2845 eptr = strchr(++origsptr, ';');
2846 } else {
2847 sptr = strchr(fixed_contact_str, '\0') - 1;
2848 }
2849
2850 switch (mod_sofia_globals.rewrite_multicasted_fs_path) {
2851 case 1:
2852 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", to_host, eptr ? eptr : ">");
2853 break;
2854 case 2:
2855 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", orig_server_host, eptr ? eptr : ">");
2856 break;
2857 case 3:
2858 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", orig_hostname, eptr ? eptr : ">");
2859 break;
2860 default:
2861 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", to_host, eptr ? eptr : ">");
2862 break;
2863 }
2864
2865 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2865
, ((void*)0)
, SWITCH_LOG_DEBUG, "Rewrote contact string from '%s' to '%s'\n", contact_str, fixed_contact_str);
2866 contact_str = fixed_contact_str;
2867 }
2868
2869
2870 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2871
2872 switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL((void*)0), AF_INET2);
2873 sql = switch_mprintf("insert into sip_registrations "
2874 "(call_id, sip_user, sip_host, presence_hosts, contact, status, rpid, expires,"
2875 "user_agent, server_user, server_host, profile_name, hostname, network_ip, network_port, sip_username, sip_realm,"
2876 "mwi_user, mwi_host, orig_server_host, orig_hostname, ping_status, ping_count) "
2877 "values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)",
2878 call_id, from_user, from_host, presence_hosts, contact_str, rpid, expires, user_agent, to_user, guess_ip4,
2879 profile_name, mod_sofia_globals.hostname, network_ip, network_port, username, realm, mwi_user, mwi_host,
2880 orig_server_host, orig_hostname, "Reachable", 0);
2881
2882 if (sql) {
2883 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2884 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2884
, ((void*)0)
, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str);
2885 }
2886
2887
2888 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2888, profile)
;
2889 end:
2890 switch_safe_free(fixed_contact_str)if (fixed_contact_str) {free(fixed_contact_str);fixed_contact_str
=((void*)0);}
;
2891 switch_safe_free(dup_mwi_account)if (dup_mwi_account) {free(dup_mwi_account);dup_mwi_account=(
(void*)0);}
;
2892 } 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")) {
2893 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) :
"")
;
2894 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) : "")
;
2895 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) : "")
;
2896 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) : "")
;
2897 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) :
"")
;
2898 sofia_profile_t *profile = NULL((void*)0);
2899
2900 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2900
, profile_name)
)) {
2901 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2901
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2902 } else {
2903 if (!strcmp(ping_status, "REACHABLE")) {
2904 sql = switch_mprintf("update sip_registrations set ping_status='%q' where sip_user='%q' and sip_host='%q' and call_id='%q'",
2905 "Reachable", from_user, from_host, call_id);
2906 } else {
2907 sql = switch_mprintf("update sip_registrations set ping_status='%q' where sip_user='%q' and sip_host='%q' and call_id='%q'",
2908 "Unreachable", from_user, from_host, call_id);
2909 }
2910 if (sql) {
2911 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2912 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2912
, ((void*)0)
, SWITCH_LOG_DEBUG, "Propagating sip_user_state for %s@%s. Ping-Status: %s\n", from_user, from_host, ping_status);
2913 }
2914
2915 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2915, profile)
;
2916 }
2917 }
2918}
2919
2920static void sofia_perform_profile_start_failure(sofia_profile_t *profile, char *profile_name, char *file, int line)
2921{
2922 int arg = 0;
2923 switch_event_t *s_event;
2924
2925 if (profile) {
2926 if (!strcasecmp(profile->shutdown_type, "true")) {
2927 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2927
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Shutting down!\n", profile->name);
2928 switch_core_session_ctl(SCSC_SHUTDOWN, &arg);
2929 } else if (!strcasecmp(profile->shutdown_type, "elegant")) {
2930 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2930
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Waiting for calls to finish, then shutting down!\n",
2931 profile->name);
2932 switch_core_session_ctl(SCSC_SHUTDOWN_ELEGANT, &arg);
2933 } else if (!strcasecmp(profile->shutdown_type, "asap")) {
2934 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2934
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Shutting down ASAP!\n", profile->name);
2935 switch_core_session_ctl(SCSC_SHUTDOWN_ASAP, &arg);
2936 } else if (!strcasecmp(profile->shutdown_type, "reincarnate-now")) {
2937 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2937
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Asking for reincarnation now!\n", profile->name);
2938 switch_core_session_ctl(SCSC_REINCARNATE_NOW, &arg);
2939 }
2940 }
2941
2942 if ((switch_event_create(&s_event, SWITCH_EVENT_FAILURE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2942, &s_event, SWITCH_EVENT_FAILURE
, ((void*)0))
== SWITCH_STATUS_SUCCESS)) {
2943 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
2944 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile_name);
2945 if (profile) {
2946 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
2947 }
2948 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "failure_message", "Profile failed to start.");
2949 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "file", file);
2950 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "line", "%d", line);
2951
2952 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 2952, &s_event, ((void*)0))
;
2953 }
2954}
2955
2956/* not a static function so that it's still visible on stacktraces */
2957void watchdog_triggered_abort(void) {
2958 abort();
2959}
2960
2961#define sofia_profile_start_failure(p, xp)sofia_perform_profile_start_failure(p, xp, "sofia.c", 2961) sofia_perform_profile_start_failure(p, xp, __FILE__"sofia.c", __LINE__2961)
2962
2963
2964#define SQLLEN1024 * 1024 1024 * 1024
2965void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread, void *obj)
2966{
2967 sofia_profile_t *profile = (sofia_profile_t *) obj;
2968 uint32_t ireg_loops = profile->ireg_seconds; /* Number of loop iterations done when we haven't checked for registrations */
2969 uint32_t iping_loops = profile->iping_freq; /* Number of loop iterations done when we haven't checked for ping expires */
2970 uint32_t gateway_loops = GATEWAY_SECONDS1; /* Number of loop iterations done when we haven't checked for gateways */
2971 void *pop;
2972 int tick = 0, x = 0;
2973
2974 sofia_set_pflag_locked(profile, PFLAG_WORKER_RUNNING)((profile->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("profile->flag_mutex != NULL", "sofia.c", 2974, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(profile->flag_mutex
);(profile)->pflags[PFLAG_WORKER_RUNNING] = 1;switch_mutex_unlock
(profile->flag_mutex);
;
2975
2976 while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0))) {
2977
2978 if (tick) {
2979 if (profile->watchdog_enabled) {
2980 uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0;
2981
2982 if (profile->step_timeout) {
2983 step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000);
2984
2985 if (step_diff > profile->step_timeout) {
2986 step_fail = 1;
2987 }
2988 }
2989
2990 if (profile->event_timeout) {
2991 event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000);
2992
2993 if (event_diff > profile->event_timeout) {
2994 event_fail = 1;
2995 }
2996 }
2997
2998 if (step_fail && profile->event_timeout && !event_fail) {
2999 step_fail = 0;
3000 }
3001
3002 if (event_fail || step_fail) {
3003 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3003
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED BY WATCHDOG!\n"
3004 "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name);
3005 switch_yield(2000000)switch_sleep(2000000);;
3006 watchdog_triggered_abort();
3007 }
3008 }
3009
3010
3011 if (!sofia_test_pflag(profile, PFLAG_STANDBY)((profile)->pflags[PFLAG_STANDBY] ? 1 : 0)) {
3012 if (++ireg_loops >= (uint32_t)profile->ireg_seconds) {
3013 time_t now = switch_epoch_time_now(NULL((void*)0));
3014 sofia_reg_check_expire(profile, now, 0);
3015 ireg_loops = 0;
3016 }
3017
3018 if(++iping_loops >= (uint32_t)profile->iping_freq) {
3019 time_t now = switch_epoch_time_now(NULL((void*)0));
3020 sofia_reg_check_ping_expire(profile, now, profile->iping_seconds);
3021 iping_loops = 0;
3022 }
3023
3024 if (++gateway_loops >= GATEWAY_SECONDS1) {
3025 sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3026 sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3027 gateway_loops = 0;
3028 }
3029 }
3030
3031 tick = 0;
3032 }
3033
3034 if (switch_queue_pop_timeout(mod_sofia_globals.general_event_queue, &pop, 100000) == SWITCH_STATUS_SUCCESS) {
3035
3036 do {
3037 switch_event_t *event = (switch_event_t *) pop;
3038 general_event_handler(event);
3039 switch_event_destroy(&event);
3040
3041 pop = NULL((void*)0);
3042 switch_queue_trypop(mod_sofia_globals.general_event_queue, &pop);
3043 } while (pop);
3044
3045 }
3046
3047 sofia_glue_fire_events(profile);
3048
3049 if (++x == 10) {
3050 tick = 1;
3051 x = 0;
3052 }
3053
3054 }
3055
3056 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
);
;
3057
3058 return NULL((void*)0);
3059}
3060
3061switch_thread_t *launch_sofia_worker_thread(sofia_profile_t *profile)
3062{
3063 switch_thread_t *thread = NULL((void*)0);
3064 switch_threadattr_t *thd_attr = NULL((void*)0);
3065 int x = 0;
3066 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);
3067 switch_event_t *params = NULL((void*)0);
3068 char *cf = "sofia.conf";
3069
3070 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3070
, ((void*)0)
, SWITCH_LOG_DEBUG, "Launching worker thread for %s\n", profile->name);
3071
3072 /* Parse gateways */
3073 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3073, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
3074 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "sofia.c", 3074
, __extension__ __PRETTY_FUNCTION__))
;
3075 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile->name);
3076
3077 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
3078 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3078
, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
3079 goto end;
3080 }
3081
3082 if ((xprofiles = switch_xml_child(cfg, "profiles"))) {
3083 if ((xprofile = switch_xml_find_child(xprofiles, "profile", "name", profile->name))) {
3084
3085 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
3086 parse_gateways(profile, gateways_tag, NULL((void*)0));
3087 }
3088
3089 if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
3090 switch_event_t *xml_params;
3091 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3091, &xml_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
3092 switch_assert(xml_params)((xml_params) ? (void) (0) : __assert_fail ("xml_params", "sofia.c"
, 3092, __extension__ __PRETTY_FUNCTION__))
;
3093 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways");
3094 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
3095
3096 for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
3097 switch_xml_t droot, x_domain_tag;
3098 const char *dname = switch_xml_attr_soft(domain_tag, "name");
3099 const char *parse = switch_xml_attr_soft(domain_tag, "parse");
3100 const char *alias = switch_xml_attr_soft(domain_tag, "alias");
3101
3102 if (!zstr(dname)_zstr(dname)) {
3103 if (!strcasecmp(dname, "all")) {
3104 switch_xml_t xml_root, x_domains;
3105 if (switch_xml_locate("directory", NULL((void*)0), NULL((void*)0), NULL((void*)0), &xml_root, &x_domains, xml_params, SWITCH_FALSE) ==
3106 SWITCH_STATUS_SUCCESS) {
3107 for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
3108 dname = switch_xml_attr_soft(x_domain_tag, "name");
3109 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
3110 }
3111 switch_xml_free(xml_root);
3112 }
3113 } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) {
3114 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
3115 switch_xml_free(droot);
3116 }
3117 }
3118 }
3119
3120 switch_event_destroy(&xml_params);
3121 }
3122
3123 }
3124 }
3125
3126 switch_threadattr_create(&thd_attr, profile->pool);
3127 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
3128 //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
3129 switch_thread_create(&thread, thd_attr, sofia_profile_worker_thread_run, profile, profile->pool);
3130
3131 while (!sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)((profile)->pflags[PFLAG_WORKER_RUNNING] ? 1 : 0)) {
3132 switch_yield(100000)switch_sleep(100000);;
3133 if (++x >= 100) {
3134 break;
3135 }
3136 }
3137
3138 end:
3139 switch_event_destroy(&params);
3140
3141 if (xml) {
3142 switch_xml_free(xml);
3143 }
3144
3145 return thread;
3146}
3147
3148void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj)
3149{
3150 sofia_profile_t *profile = (sofia_profile_t *) obj;
3151 //switch_memory_pool_t *pool;
3152 sip_alias_node_t *node;
3153 switch_event_t *s_event;
3154 int use_100rel = !sofia_test_pflag(profile, PFLAG_DISABLE_100REL)((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0);
3155 int use_timer = !sofia_test_pflag(profile, PFLAG_DISABLE_TIMER)((profile)->pflags[PFLAG_DISABLE_TIMER] ? 1 : 0);
3156 int use_rfc_5626 = sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626)((profile)->pflags[PFLAG_ENABLE_RFC5626] ? 1 : 0);
3157 const char *supported = NULL((void*)0);
3158 int sanity, attempts = 0;
3159 switch_thread_t *worker_thread;
3160 switch_status_t st;
3161 char qname [128] = "";
3162
3163#if defined(HAVE_OPENSSL1)
3164 char *key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
3165 char *cert = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
3166 char *chain = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
3167 SSL_CTX *ssl_ctx;
3168 const SSL_METHOD *ssl_method = SSLv23_server_methodTLS_server_method();
3169#endif
3170
3171 switch_bool_t ssl_error = SWITCH_FALSE;
3172
3173 switch_mutex_lock(mod_sofia_globals.mutex);
3174 mod_sofia_globals.threads++;
3175 switch_mutex_unlock(mod_sofia_globals.mutex);
3176
3177 profile->s_root = su_root_create(NULL((void*)0));
3178 //profile->home = su_home_new(sizeof(*profile->home));
3179
3180 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3180
, ((void*)0)
, SWITCH_LOG_DEBUG, "Creating agent for %s\n", profile->name);
3181
3182 if (!sofia_glue_init_sql(profile)) {
3183 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3183
, ((void*)0)
, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name);
3184 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 3184)
;
3185 goto db_fail;
3186 }
3187
3188 supported = switch_core_sprintf(profile->pool, "%s%s%spath, replaces", use_100rel ? "100rel, " : "", use_timer ? "timer, " : "", use_rfc_5626 ? "outbound, " : "");
3189
3190 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0) && switch_nat_get_type()) {
3191 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) {
3192 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3192
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3193 }
3194 if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_TCP, NULL((void*)0), SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
3195 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3195
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3196 }
3197 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)
3198 && switch_nat_add_mapping(profile->tls_sip_port, SWITCH_NAT_TCP, NULL((void*)0), SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
3199 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3199
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
3200 }
3201 }
3202
3203 /* 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 */
3204 if ( (profile->tls_verify_policy & TPTLS_VERIFY_SUBJECTS_IN) && profile->tls_verify_in_subjects_str && ! profile->tls_verify_in_subjects) {
3205 profile->tls_verify_in_subjects = su_strlst_dup_split((su_home_t *)profile->nua, profile->tls_verify_in_subjects_str, "|");
3206 }
3207
3208#if defined(HAVE_OPENSSL1)
3209 ssl_ctx = SSL_CTX_new((SSL_METHOD *)ssl_method);
3210 switch_assert(ssl_ctx)((ssl_ctx) ? (void) (0) : __assert_fail ("ssl_ctx", "sofia.c"
, 3210, __extension__ __PRETTY_FUNCTION__))
;
3211
3212 /* Disable SSLv2 */
3213 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv20x0);
3214 /* Disable SSLv3 */
3215 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv30x02000000U);
3216 /* Disable TLSv1 */
3217 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv10x04000000U);
3218 /* Disable Compression CRIME (Compression Ratio Info-leak Made Easy) */
3219 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_COMPRESSION0x00020000U);
3220
3221 if (!SSL_CTX_use_certificate_chain_file(ssl_ctx, chain)) {
3222 ssl_error = SWITCH_TRUE;
3223 }
3224
3225 if (!ssl_error && !SSL_CTX_use_certificate_file(ssl_ctx, cert, SSL_FILETYPE_PEM1)) {
3226 ssl_error = SWITCH_TRUE;
3227 }
3228
3229 if (!ssl_error && !SSL_CTX_use_PrivateKey_file(ssl_ctx, key, SSL_FILETYPE_PEM1)) {
3230 ssl_error = SWITCH_TRUE;
3231 }
3232
3233 if (!ssl_error && !SSL_CTX_check_private_key(ssl_ctx)) {
3234 ssl_error = SWITCH_TRUE;
3235 }
3236
3237 if (ssl_error) {
3238 attempts = profile->bind_attempts;
3239 }
3240
3241 SSL_CTX_free(ssl_ctx);
3242#endif
3243
3244 do {
3245 profile->nua = nua_create(profile->s_root, /* Event loop */
3246 sofia_event_callback, /* Callback for processing events */
3247 profile, /* Additional data to pass to callback */
3248 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
)
,
3249 NTATAG_USER_VIA(1)ntatag_user_via, tag_bool_v((1)),
3250 TPTAG_PONG2PING(1)tptag_pong2ping, tag_bool_v((1)),
3251 NTATAG_TCP_RPORT(0)ntatag_tcp_rport, tag_bool_v((0)),
3252 NTATAG_TLS_RPORT(0)ntatag_tls_rport, tag_bool_v((0)),
3253 NUTAG_RETRY_AFTER_ENABLE(0)nutag_retry_after_enable, tag_bool_v(0),
3254 NUTAG_AUTO_INVITE_100(0)nutag_auto_invite_100, tag_bool_v(0),
3255 TAG_IF(!strchr(profile->sipip, ':'),!(!strchr(profile->sipip, ':')) ? tag_skip : soatag_af, tag_int_v
((SOA_AF_IP4_ONLY))
3256 SOATAG_AF(SOA_AF_IP4_ONLY))!(!strchr(profile->sipip, ':')) ? tag_skip : soatag_af, tag_int_v
((SOA_AF_IP4_ONLY))
,
3257 TAG_IF(strchr(profile->sipip, ':'),!(strchr(profile->sipip, ':')) ? tag_skip : soatag_af, tag_int_v
((SOA_AF_IP6_ONLY))
3258 SOATAG_AF(SOA_AF_IP6_ONLY))!(strchr(profile->sipip, ':')) ? tag_skip : soatag_af, tag_int_v
((SOA_AF_IP6_ONLY))
,
3259 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)
3260 NUTAG_SIPS_URL(profile->tls_bindurl))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : nutag_sips_url
, urltag_url_v(profile->tls_bindurl)
,
3261 TAG_IF(profile->ws_bindurl,!(profile->ws_bindurl) ? tag_skip : nutag_ws_url, urltag_url_v
(profile->ws_bindurl)
3262 NUTAG_WS_URL(profile->ws_bindurl))!(profile->ws_bindurl) ? tag_skip : nutag_ws_url, urltag_url_v
(profile->ws_bindurl)
,
3263 TAG_IF(profile->wss_bindurl,!(profile->wss_bindurl) ? tag_skip : nutag_wss_url, urltag_url_v
(profile->wss_bindurl)
3264 NUTAG_WSS_URL(profile->wss_bindurl))!(profile->wss_bindurl) ? tag_skip : nutag_wss_url, urltag_url_v
(profile->wss_bindurl)
,
3265 TAG_IF(profile->tls_cert_dir,!(profile->tls_cert_dir) ? tag_skip : nutag_certificate_dir
, tag_str_v(profile->tls_cert_dir)
3266 NUTAG_CERTIFICATE_DIR(profile->tls_cert_dir))!(profile->tls_cert_dir) ? tag_skip : nutag_certificate_dir
, tag_str_v(profile->tls_cert_dir)
,
3267 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)
3268 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)
,
3269 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))
3270 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))
,
3271 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))
3272 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))
,
3273 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))
3274 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))
,
3275 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))
3276 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))
,
3277 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))
3278 TPTAG_TLS_CIPHERS(profile->tls_ciphers))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_ciphers
, tag_str_v((profile->tls_ciphers))
,
3279 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))
3280 TPTAG_TLS_VERSION(profile->tls_version))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_version
, tag_uint_v((profile->tls_version))
,
3281 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))
3282 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))
,
3283 TAG_IF(!strchr(profile->sipip, ':'),!(!strchr(profile->sipip, ':')) ? tag_skip : ntatag_udp_mtu
, tag_uint_v((65535))
3284 NTATAG_UDP_MTU(65535))!(!strchr(profile->sipip, ':')) ? tag_skip : ntatag_udp_mtu
, tag_uint_v((65535))
,
3285 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))
3286 NTATAG_USE_SRV(0))!(((profile)->pflags[PFLAG_DISABLE_SRV] ? 1 : 0)) ? tag_skip
: ntatag_use_srv, tag_bool_v((0))
,
3287 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))
3288 NTATAG_USE_NAPTR(0))!(((profile)->pflags[PFLAG_DISABLE_NAPTR] ? 1 : 0)) ? tag_skip
: ntatag_use_naptr, tag_bool_v((0))
,
3289 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))
3290 TPTAG_PINGPONG(profile->tcp_pingpong))!(((profile)->pflags[PFLAG_TCP_PINGPONG] ? 1 : 0)) ? tag_skip
: tptag_pingpong, tag_uint_v((profile->tcp_pingpong))
,
3291 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))
3292 TPTAG_PINGPONG(profile->tcp_ping2pong))!(((profile)->pflags[PFLAG_TCP_PING2PONG] ? 1 : 0)) ? tag_skip
: tptag_pingpong, tag_uint_v((profile->tcp_ping2pong))
,
3293 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))
3294 NTATAG_SRV_503(0))!(((profile)->pflags[PFLAG_DISABLE_SRV503] ? 1 : 0)) ? tag_skip
: ntatag_srv_503, tag_bool_v((0))
,
3295 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))
3296 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))
,
3297 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))
3298 TPTAG_KEEPALIVE(profile->tcp_keepalive))!(((profile)->pflags[PFLAG_TCP_KEEPALIVE] ? 1 : 0)) ? tag_skip
: tptag_keepalive, tag_uint_v((profile->tcp_keepalive))
,
3299 NTATAG_DEFAULT_PROXY(profile->outbound_proxy)ntatag_default_proxy, urltag_url_v((profile->outbound_proxy
))
,
3300 NTATAG_SERVER_RPORT(profile->server_rport_level)ntatag_server_rport, tag_int_v((profile->server_rport_level
))
,
3301 NTATAG_CLIENT_RPORT(profile->client_rport_level)ntatag_client_rport, tag_bool_v((profile->client_rport_level
))
,
3302 TPTAG_LOG(sofia_test_flag(profile, TFLAG_TPORT_LOG))tptag_log, tag_bool_v((((profile)->flags[TFLAG_TPORT_LOG] ?
1 : 0)))
,
3303 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)))
,
3304 TAG_IF(sofia_test_pflag(profile, PFLAG_SIPCOMPACT),!(((profile)->pflags[PFLAG_SIPCOMPACT] ? 1 : 0)) ? tag_skip
: ntatag_sipflags, tag_uint_v((MSG_FLG_COMPACT))
3305 NTATAG_SIPFLAGS(MSG_DO_COMPACT))!(((profile)->pflags[PFLAG_SIPCOMPACT] ? 1 : 0)) ? tag_skip
: ntatag_sipflags, tag_uint_v((MSG_FLG_COMPACT))
,
3306 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))
,
3307 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))
,
3308 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))
,
3309 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))
,
3310 SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed")siptag_accept_str, tag_str_v("application/sdp, multipart/mixed"
)
,
3311 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))
3312 TPTAG_REUSE(0))!(((profile)->pflags[PFLAG_NO_CONNECTION_REUSE] ? 1 : 0)) ?
tag_skip : tptag_reuse, tag_bool_v((0))
,
3313 TAG_END()(tag_type_t)0, (tag_value_t)0); /* Last tag should always finish the sequence */
3314
3315 if (!ssl_error && !profile->nua) {
3316 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3316
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s) ATTEMPT %d (RETRY IN %d SEC)\n",
3317 profile->name, profile->bindurl, attempts + 1, profile->bind_attempt_interval);
3318 if (attempts < profile->bind_attempts) {
3319 switch_yield(1000000 * profile->bind_attempt_interval)switch_sleep(1000000 * profile->bind_attempt_interval);;
3320 }
3321 }
3322
3323 } while (!profile->nua && attempts++ < profile->bind_attempts);
3324
3325 if (!profile->nua) {
3326 if (!ssl_error) {
3327 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3327
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s)\n"
3328 "The likely causes for this are:\n" "1) Another application is already listening on the specified address.\n"
3329 "2) The IP the profile is attempting to bind to is not local to this system.\n", profile->name, profile->bindurl);
3330 } else {
3331 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3331
, ((void*)0)
, SWITCH_LOG_ERROR,
3332 "Error Creating SIP UA for profile: %s (%s). Bad WSS.PEM certificate.\n", profile->name, profile->bindurl);
3333 }
3334
3335 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 3335)
;
3336 goto nua_fail;
3337 }
3338
3339 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3339
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created agent for %s\n", profile->name);
3340
3341 nua_set_params(profile->nua,
3342 SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO")siptag_allow_str, tag_str_v("INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO"
)
,
3343 SIPTAG_USER_AGENT(SIP_NONE)siptag_user_agent, siptag_user_agent_v(((void const *)-1L)),
3344 NUTAG_AUTOANSWER(0)nutag_autoanswer, tag_bool_v(0),
3345 NUTAG_AUTOACK(0)nutag_autoack, tag_bool_v(0),
3346 NUTAG_AUTOALERT(0)nutag_autoalert, tag_bool_v(0),
3347 NUTAG_ENABLEMESSENGER(1)nutag_enablemessenger, tag_bool_v(1),
3348 NTATAG_EXTRA_100(0)ntatag_extra_100, tag_bool_v((0)),
3349 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")
,
3350 TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER"))!((profile->mflags & MFLAG_REGISTER)) ? tag_skip : nutag_allow
, tag_str_v("REGISTER")
,
3351 TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER"))!((profile->mflags & MFLAG_REFER)) ? tag_skip : nutag_allow
, tag_str_v("REFER")
,
3352 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")
,
3353 NUTAG_ALLOW("INFO")nutag_allow, tag_str_v("INFO"),
3354 NUTAG_ALLOW("NOTIFY")nutag_allow, tag_str_v("NOTIFY"),
3355 NUTAG_ALLOW_EVENTS("talk")nutag_allow_events, tag_str_v("talk"),
3356 NUTAG_ALLOW_EVENTS("hold")nutag_allow_events, tag_str_v("hold"),
3357 NUTAG_ALLOW_EVENTS("conference")nutag_allow_events, tag_str_v("conference"),
3358 NUTAG_APPL_METHOD("OPTIONS")nutag_appl_method, tag_str_v("OPTIONS"),
3359 NUTAG_APPL_METHOD("INVITE")nutag_appl_method, tag_str_v("INVITE"),
3360 NUTAG_APPL_METHOD("REFER")nutag_appl_method, tag_str_v("REFER"),
3361 NUTAG_APPL_METHOD("REGISTER")nutag_appl_method, tag_str_v("REGISTER"),
3362 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"),
3363#ifdef MANUAL_BYE1
3364 NUTAG_APPL_METHOD("BYE")nutag_appl_method, tag_str_v("BYE"),
3365#endif
3366 NUTAG_APPL_METHOD("MESSAGE")nutag_appl_method, tag_str_v("MESSAGE"),
3367
3368 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
))
,
3369 NUTAG_SESSION_TIMER(profile->session_timeout)nutag_session_timer, tag_uint_v((profile->session_timeout)
)
,
3370 NTATAG_MAX_PROCEEDING(profile->max_proceeding)ntatag_max_proceeding, tag_usize_v((profile->max_proceeding
))
,
3371 TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"PUBLISH")
,
3372 TAG_IF(profile->pres_type, NUTAG_ALLOW("SUBSCRIBE"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"SUBSCRIBE")
,
3373 TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1))!(profile->pres_type) ? tag_skip : nutag_enablemessage, tag_bool_v
(1)
,
3374 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("presence")
,
3375 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")
,
3376 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"
)
,
3377 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"
)
,
3378 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("call-info"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("call-info")
,
3379 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"
)
,
3380 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")
,
3381 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence.winfo"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("presence.winfo")
,
3382 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("message-summary"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("message-summary")
,
3383 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")
,
3384 NUTAG_ALLOW_EVENTS("refer")nutag_allow_events, tag_str_v("refer"), SIPTAG_SUPPORTED_STR(supported)siptag_supported_str, tag_str_v(supported),
3385 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)
,
3386 TAG_END()(tag_type_t)0, (tag_value_t)0);
3387
3388 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3388
, ((void*)0)
, SWITCH_LOG_DEBUG, "Set params for %s\n", profile->name);
3389
3390 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)) {
3391 sip_via_t *vias = nta_agent_via(nua_get_agent(profile->nua));
3392 sip_via_t *via = NULL((void*)0);
3393
3394 for (via = vias; via; via = via->v_next) {
3395 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")) {
3396 profile->sip_port = (switch_port_t)atoi(via->v_port);
3397 if (!profile->extsipport) profile->extsipport = profile->sip_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\n", profile->sip_port, profile->name);
3399 }
3400
3401 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")) {
3402 profile->tls_sip_port = (switch_port_t)atoi(via->v_port);
3403 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3403
, ((void*)0)
, SWITCH_LOG_DEBUG, "Found auto sip port %d for %s (TLS)\n", profile->tls_sip_port, profile->name);
3404 }
3405
3406 }
3407
3408 config_sofia_profile_urls(profile);
3409 }
3410
3411 for (node = profile->aliases; node; node = node->next) {
3412 node->nua = nua_create(profile->s_root, /* Event loop */
3413 sofia_event_callback, /* Callback for processing events */
3414 profile, /* Additional data to pass to callback */
3415 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 */
3416
3417 nua_set_params(node->nua,
3418 SIPTAG_USER_AGENT(SIP_NONE)siptag_user_agent, siptag_user_agent_v(((void const *)-1L)),
3419 NUTAG_APPL_METHOD("OPTIONS")nutag_appl_method, tag_str_v("OPTIONS"),
3420 NUTAG_APPL_METHOD("REFER")nutag_appl_method, tag_str_v("REFER"),
3421 NUTAG_APPL_METHOD("SUBSCRIBE")nutag_appl_method, tag_str_v("SUBSCRIBE"),
3422 NUTAG_AUTOANSWER(0)nutag_autoanswer, tag_bool_v(0),
3423 NUTAG_AUTOACK(0)nutag_autoack, tag_bool_v(0),
3424 NUTAG_AUTOALERT(0)nutag_autoalert, tag_bool_v(0),
3425 TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER"))!((profile->mflags & MFLAG_REGISTER)) ? tag_skip : nutag_allow
, tag_str_v("REGISTER")
,
3426 TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER"))!((profile->mflags & MFLAG_REFER)) ? tag_skip : nutag_allow
, tag_str_v("REFER")
,
3427 NUTAG_ALLOW("INFO")nutag_allow, tag_str_v("INFO"),
3428 TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"PUBLISH")
,
3429 TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1))!(profile->pres_type) ? tag_skip : nutag_enablemessage, tag_bool_v
(1)
,
3430 SIPTAG_SUPPORTED_STR(supported)siptag_supported_str, tag_str_v(supported),
3431 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)
,
3432 TAG_END()(tag_type_t)0, (tag_value_t)0);
3433 }
3434
3435 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3435
, ((void*)0)
, SWITCH_LOG_DEBUG, "Activated db for %s\n", profile->name);
3436
3437 switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
3438 switch_mutex_init(&profile->dbh_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
3439 switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
3440 switch_queue_create(&profile->event_queue, SOFIA_QUEUE_SIZE50000, profile->pool);
3441
3442
3443 switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name);
3444 switch_sql_queue_manager_init_name(qname,
3445 &profile->qm,
3446 2,
3447 profile->odbc_dsn ? profile->odbc_dsn : profile->dbname,
3448 SWITCH_MAX_TRANS2000,
3449 profile->pre_trans_execute,
3450 profile->post_trans_execute,
3451 profile->inner_pre_trans_execute,
3452 profile->inner_post_trans_execute);
3453 switch_sql_queue_manager_start(profile->qm);
3454
3455 if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3455, &s_event, SWITCH_EVENT_PUBLISH
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
3456 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s",
3457 (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? ",_sips._tcp" : "");
3458
3459 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
3460 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
3461 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
3462 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
3463
3464 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
3465 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "tls_port", "%d", profile->tls_sip_port);
3466 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_tls_uri", profile->tls_url);
3467 }
3468 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 3468, &s_event, ((void*)0))
;
3469 }
3470
3471 sofia_glue_add_profile(profile->name, profile);
3472
3473 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3473
, ((void*)0)
, SWITCH_LOG_DEBUG, "Starting thread for %s\n", profile->name);
3474
3475 profile->started = switch_epoch_time_now(NULL((void*)0));
3476
3477 sofia_set_pflag_locked(profile, PFLAG_RUNNING)((profile->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("profile->flag_mutex != NULL", "sofia.c", 3477, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(profile->flag_mutex
);(profile)->pflags[PFLAG_RUNNING] = 1;switch_mutex_unlock
(profile->flag_mutex);
;
3478 worker_thread = launch_sofia_worker_thread(profile);
3479
3480 switch_yield(1000000)switch_sleep(1000000);;
3481
3482
3483 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)) {
3484 su_root_step(profile->s_root, 1000);
3485 profile->last_root_step = switch_time_now();
3486 }
3487
3488 sofia_clear_pflag_locked(profile, PFLAG_RUNNING)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_RUNNING] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3489 sofia_reg_close_handles(profile);
3490
3491 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)
;
3492 sanity = 10;
3493 while (profile->inuse) {
3494 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3494
, ((void*)0)
, SWITCH_LOG_CRIT, "Waiting for %d session(s)\n", profile->inuse);
3495 su_root_step(profile->s_root, 1000);
3496 if (!--sanity) {
3497 break;
3498 } else if (sanity == 5) {
3499 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)
;
3500 }
3501 }
3502
3503 /* Gateway cleanup start */
3504 /* Mark all gateways as deleted and set REG_STATE_UNREGISTER state on REG gateways */
3505 sofia_glue_del_every_gateway(profile);
3506 /* First call will unregister and set state to DOWN so a gateway is ready for deletion */
3507 sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3508 sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3509 /*
3510 * The gateway life cycle requires a gateway to go though different states before it's destroyed.
3511 * Normally sofia_reg_check_gateway() is called periodically
3512 * but it's not the case on profile shutdown.
3513 *
3514 * All REG gateways should be DOWN now and can be finally deleted.
3515 * Calling sofia_reg_check_gateway() second time.
3516 */
3517 sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3518 sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
3519 /* Gateway cleanup end */
3520
3521 sofia_glue_fire_events(profile);
3522
3523 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3523
, ((void*)0)
, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
3524
3525 if (worker_thread) {
3526 switch_thread_join(&st, worker_thread);
3527 }
3528 else {
3529 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3529
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n");
3530 }
3531
3532 sofia_reg_unregister(profile);
3533 nua_shutdown(profile->nua);
3534
3535 sanity = 100;
3536 while (!sofia_test_pflag(profile, PFLAG_SHUTDOWN)((profile)->pflags[PFLAG_SHUTDOWN] ? 1 : 0) || profile->queued_events > 0) {
3537 su_root_step(profile->s_root, 1000);
3538 if (!--sanity) {
3539 break;
3540 }
3541 }
3542
3543 sofia_clear_pflag_locked(profile, PFLAG_RUNNING)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_RUNNING] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3544 sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_SHUTDOWN] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3545
3546 sanity = 4;
3547 while (profile->inuse) {
3548 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)
;
3549 switch_yield(5000000)switch_sleep(5000000);;
3550 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3550
, ((void*)0)
, SWITCH_LOG_CRIT, "Waiting for %d session(s)\n", profile->inuse);
3551 if (!--sanity) {
3552 break;
3553 }
3554 }
3555 nua_destroy(profile->nua);
3556
3557 switch_mutex_lock(profile->ireg_mutex);
3558 switch_mutex_unlock(profile->ireg_mutex);
3559
3560 switch_mutex_lock(profile->flag_mutex);
3561 switch_mutex_unlock(profile->flag_mutex);
3562
3563 switch_sql_queue_manager_destroy(&profile->qm);
3564
3565 if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3565, &s_event, SWITCH_EVENT_UNPUBLISH
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
3566 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s",
3567 (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? ",_sips._tcp" : "");
3568
3569 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
3570 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
3571 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
3572 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
3573
3574 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
3575 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "tls_port", "%d", profile->tls_sip_port);
3576 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_tls_uri", profile->tls_url);
3577 }
3578 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 3578, &s_event, ((void*)0))
;
3579 }
3580
3581 nua_fail:
3582 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0) && switch_nat_get_type()) {
3583 if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_UDP) == SWITCH_STATUS_SUCCESS) {
3584 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3584
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3585 }
3586 if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_TCP) == SWITCH_STATUS_SUCCESS) {
3587 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3587
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3588 }
3589 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) {
3590 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3590
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
3591 }
3592 }
3593
3594 db_fail:
3595 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3595
, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name);
3596 switch_thread_rwlock_wrlock(profile->rwlock);
3597
3598 //su_home_unref(profile->home);
3599 su_root_destroy(profile->s_root);
3600 //pool = profile->pool;
3601
3602 sofia_glue_del_profile(profile);
3603 switch_core_hash_destroy(&profile->chat_hash);
3604 switch_core_hash_destroy(&profile->reg_nh_hash);
3605 switch_core_hash_destroy(&profile->mwi_debounce_hash);
3606
3607 switch_thread_rwlock_unlock(profile->rwlock);
3608 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3608
, ((void*)0)
, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name);
3609
3610 if (sofia_test_pflag(profile, PFLAG_RESPAWN)((profile)->pflags[PFLAG_RESPAWN] ? 1 : 0)) {
3611 config_sofia(SOFIA_CONFIG_RESPAWN, profile->name);
3612 }
3613
3614 sofia_profile_destroy(profile);
3615
3616 switch_mutex_lock(mod_sofia_globals.mutex);
3617 mod_sofia_globals.threads--;
3618 switch_mutex_unlock(mod_sofia_globals.mutex);
3619
3620 return NULL((void*)0);
3621}
3622
3623void sofia_profile_destroy(sofia_profile_t *profile)
3624{
3625 if (!profile->inuse) {
3626 switch_memory_pool_t *pool = profile->pool;
3627 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia.c",
(const char *)__func__, 3627)
;
3628 } else {
3629 sofia_set_pflag(profile, PFLAG_DESTROY)(profile)->pflags[PFLAG_DESTROY] = 1;
3630 }
3631}
3632
3633void launch_sofia_profile_thread(sofia_profile_t *profile)
3634{
3635 //switch_thread_t *thread;
3636 switch_threadattr_t *thd_attr = NULL((void*)0);
3637
3638 switch_threadattr_create(&thd_attr, profile->pool);
3639 switch_threadattr_detach_set(thd_attr, 1);
3640 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
3641 switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
3642 switch_thread_create(&profile->thread, thd_attr, sofia_profile_thread_run, profile, profile->pool);
3643}
3644
3645static void logger(void *logarg, char const *fmt, va_list ap)
3646{
3647 if (!fmt) return;
3648
3649 switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEANSWITCH_CHANNEL_ID_LOG_CLEAN, "sofia.c", (const char *)__func__
, 3649, ((void*)0)
, mod_sofia_globals.tracelevel, fmt, ap);
3650}
3651
3652static su_log_t *sofia_get_logger(const char *name)
3653{
3654 if (!strcasecmp(name, "tport")) {
3655 return tport_log;
3656 } else if (!strcasecmp(name, "iptsec")) {
3657 return iptsec_log;
3658 } else if (!strcasecmp(name, "nea")) {
3659 return nea_log;
3660 } else if (!strcasecmp(name, "nta")) {
3661 return nta_log;
3662 } else if (!strcasecmp(name, "nth_client")) {
3663 return nth_client_log;
3664 } else if (!strcasecmp(name, "nth_server")) {
3665 return nth_server_log;
3666 } else if (!strcasecmp(name, "nua")) {
3667 return nua_log;
3668 } else if (!strcasecmp(name, "soa")) {
3669 return soa_log;
3670 } else if (!strcasecmp(name, "sresolv")) {
3671 return sresolv_log;
3672#ifdef HAVE_SOFIA_STUN
3673 } else if (!strcasecmp(name, "stun")) {
3674 return stun_log;
3675#endif
3676 } else if (!strcasecmp(name, "default")) {
3677 return su_log_default;
3678 } else {
3679 return NULL((void*)0);
3680 }
3681}
3682
3683switch_status_t sofia_set_loglevel(const char *name, int level)
3684{
3685 su_log_t *log = NULL((void*)0);
3686
3687 if (level < 0 || level > 9) {
3688 return SWITCH_STATUS_FALSE;
3689 }
3690
3691 if (!strcasecmp(name, "all")) {
3692 su_log_set_level(su_log_default, level);
3693 su_log_set_level(tport_log, level);
3694 su_log_set_level(iptsec_log, level);
3695 su_log_set_level(nea_log, level);
3696 su_log_set_level(nta_log, level);
3697 su_log_set_level(nth_client_log, level);
3698 su_log_set_level(nth_server_log, level);
3699 su_log_set_level(nua_log, level);
3700 su_log_set_level(soa_log, level);
3701 su_log_set_level(sresolv_log, level);
3702#ifdef HAVE_SOFIA_STUN
3703 su_log_set_level(stun_log, level);
3704#endif
3705 return SWITCH_STATUS_SUCCESS;
3706 }
3707
3708 if (!(log = sofia_get_logger(name))) {
3709 return SWITCH_STATUS_FALSE;
3710 }
3711
3712 su_log_set_level(log, level);
3713
3714 return SWITCH_STATUS_SUCCESS;
3715}
3716
3717int sofia_get_loglevel(const char *name)
3718{
3719 su_log_t *log = NULL((void*)0);
3720
3721 if ((log = sofia_get_logger(name))) {
3722 return log->log_level;
3723 } else {
3724 return -1;
3725 }
3726}
3727
3728static void parse_gateway_subscriptions(sofia_profile_t *profile, sofia_gateway_t *gateway, switch_xml_t gw_subs_tag)
3729{
3730 switch_xml_t subscription_tag, param;
3731
3732 for (subscription_tag = switch_xml_child(gw_subs_tag, "subscription"); subscription_tag; subscription_tag = subscription_tag->next) {
3733 sofia_gateway_subscription_t *gw_sub;
3734
3735 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__, 3735)
)) {
3736 char *expire_seconds = "3600", *retry_seconds = "30", *content_type = "NO_CONTENT_TYPE";
3737 uint32_t username_in_request = 0;
3738 char *event = (char *) switch_xml_attr_soft(subscription_tag, "event");
3739 gw_sub->event = switch_core_strdup(gateway->pool, event)switch_core_perform_strdup(gateway->pool, event, "sofia.c"
, (const char *)__func__, 3739)
;
3740 gw_sub->gateway = gateway;
3741 gw_sub->next = NULL((void*)0);
3742
3743 for (param = switch_xml_child(subscription_tag, "param"); param; param = param->next) {
3744 char *var = (char *) switch_xml_attr_soft(param, "name");
3745 char *val = (char *) switch_xml_attr_soft(param, "value");
3746 if (!strcmp(var, "expire-seconds")) {
3747 expire_seconds = val;
3748 } else if (!strcmp(var, "retry-seconds")) {
3749 retry_seconds = val;
3750 } else if (!strcmp(var, "content-type")) {
3751 content_type = val;
3752 } else if (!strcmp(var, "username-in-request")) {
3753 username_in_request = switch_true(val);
3754 }
3755 }
3756
3757 gw_sub->retry_seconds = atoi(retry_seconds);
3758 if (gw_sub->retry_seconds < 10) {
3759 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3759
, ((void*)0)
, SWITCH_LOG_WARNING, "INVALID: retry_seconds correcting the value to 30\n");
3760 gw_sub->retry_seconds = 30;
3761 }
3762
3763 gw_sub->expires_str = switch_core_strdup(gateway->pool, expire_seconds)switch_core_perform_strdup(gateway->pool, expire_seconds, "sofia.c"
, (const char *)__func__, 3763)
;
3764
3765 if ((gw_sub->freq = atoi(gw_sub->expires_str)) < 5) {
3766 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3766
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid Freq: %d. Setting Register-Frequency to 3600\n", gw_sub->freq);
3767 gw_sub->freq = 3600;
3768 }
3769
3770 if(username_in_request) {
3771 gw_sub->request_uri = gateway->register_to;
3772 } else {
3773 gw_sub->request_uri = gateway->register_url;
3774 }
3775
3776 gw_sub->freq -= 2;
3777 gw_sub->content_type = switch_core_strdup(gateway->pool, content_type)switch_core_perform_strdup(gateway->pool, content_type, "sofia.c"
, (const char *)__func__, 3777)
;
3778 gw_sub->next = gateway->subscriptions;
3779 }
3780 gateway->subscriptions = gw_sub;
3781 }
3782}
3783
3784static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag, const char *gwname)
3785{
3786 switch_xml_t gateway_tag, param = NULL((void*)0), x_params, gw_subs_tag;
3787 sofia_gateway_t *gp;
3788
3789 for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
3790 char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
3791 sofia_gateway_t *gateway;
3792 char *pkey = switch_mprintf("%s::%s", profile->name, name);
3793
3794 if (zstr(name)_zstr(name) || switch_regex_match(name, "^[\\w\\.\\-\\_]+$") != SWITCH_STATUS_SUCCESS) {
3795 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3795
, ((void*)0)
, SWITCH_LOG_ERROR, "Ignoring invalid name '%s'\n", name ? name : "NULL");
3796 free(pkey);
3797 goto skip;
3798 }
3799
3800 if (gwname && strcmp(gwname, name)) {
3801 free(pkey);
3802 goto skip;
3803 }
3804
3805 switch_mutex_lock(mod_sofia_globals.hash_mutex);
3806 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) {
3807 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3807
, ((void*)0)
, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", name);
3808 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
3809 free(pkey);
3810 goto skip;
3811 }
3812 free(pkey);
3813 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
3814
3815 if ((gateway = switch_core_alloc(profile->pool, sizeof(*gateway))switch_core_perform_alloc(profile->pool, sizeof(*gateway),
"sofia.c", (const char *)__func__, 3815)
)) {
3816 const char *sipip, *format;
3817 switch_uuid_t uuid;
3818 uint32_t ping_freq = 0, extension_in_contact = 0, contact_in_ping = 0, ping_monitoring = 0, distinct_to = 0, rfc_5626 = 0;
3819 int ping_max = 1, ping_min = 1;
3820 char *register_str = "true", *scheme = "Digest",
3821 *realm = NULL((void*)0),
3822 *username = NULL((void*)0),
3823 *auth_username = NULL((void*)0),
3824 *password = NULL((void*)0),
3825 *caller_id_in_from = "false",
3826 *extension = NULL((void*)0),
3827 *proxy = NULL((void*)0),
3828 *options_user_agent = NULL((void*)0),
3829 *context = profile->context,
3830 *expire_seconds = "3600",
3831 *retry_seconds = "30",
3832 *fail_908_retry_seconds = NULL((void*)0),
3833 *timeout_seconds = "60",
3834 *from_user = "", *from_domain = NULL((void*)0), *outbound_proxy = NULL((void*)0), *register_proxy = NULL((void*)0), *contact_host = NULL((void*)0),
3835 *contact_params = "", *params = NULL((void*)0), *register_transport = NULL((void*)0),
3836 *reg_id = NULL((void*)0), *str_rfc_5626 = "";
3837
3838 if (!context) {
3839 context = "default";
3840 }
3841
3842 switch_uuid_get(&uuid);
3843 switch_uuid_format(gateway->uuid_str, &uuid);
3844
3845 gateway->register_transport = SOFIA_TRANSPORT_UDP;
3846 gateway->pool = profile->pool;
3847 gateway->profile = profile;
3848 gateway->name = switch_core_strdup(gateway->pool, name)switch_core_perform_strdup(gateway->pool, name, "sofia.c",
(const char *)__func__, 3848)
;
3849 gateway->freq = 0;
3850 gateway->next = NULL((void*)0);
3851 gateway->ping = 0;
3852 gateway->ping_freq = 0;
3853 gateway->ping_max = 0;
3854 gateway->ping_min = 0;
3855 gateway->ping_sent = 0;
3856 gateway->ping_time = 0;
3857 gateway->ping_count = 0;
3858 gateway->ping_monitoring = SWITCH_FALSE;
3859 gateway->ib_calls = 0;
3860 gateway->ob_calls = 0;
3861 gateway->ib_failed_calls = 0;
3862 gateway->ob_failed_calls = 0;
3863 gateway->destination_prefix = "";
3864
3865 if ((x_params = switch_xml_child(gateway_tag, "variables"))) {
3866 param = switch_xml_child(x_params, "variable");
3867 } else {
3868 param = switch_xml_child(gateway_tag, "variable");
3869 }
3870
3871
3872 for (; param; param = param->next) {
3873 const char *var = switch_xml_attr(param, "name");
3874 const char *val = switch_xml_attr(param, "value");
3875 const char *direction = switch_xml_attr(param, "direction");
3876 int in = 0, out = 0;
3877
3878 if (var && val) {
3879 if (direction) {
3880 if (!strcasecmp(direction, "inbound")) {
3881 in = 1;
3882 } else if (!strcasecmp(direction, "outbound")) {
3883 out = 1;
3884 }
3885 } else {
3886 in = out = 1;
3887 }
3888
3889 if (in) {
3890 if (!gateway->ib_vars) {
3891 switch_event_create_plain(&gateway->ib_vars, SWITCH_EVENT_GENERAL);
3892 }
3893 switch_event_add_header_string(gateway->ib_vars, SWITCH_STACK_BOTTOM, var, val);
3894 }
3895
3896 if (out) {
3897 if (!gateway->ob_vars) {
3898 switch_event_create_plain(&gateway->ob_vars, SWITCH_EVENT_GENERAL);
3899 }
3900 switch_event_add_header_string(gateway->ob_vars, SWITCH_STACK_BOTTOM, var, val);
3901 }
3902 }
3903 }
3904
3905 if ((x_params = switch_xml_child(gateway_tag, "params"))) {
3906 param = switch_xml_child(x_params, "param");
3907 } else {
3908 param = switch_xml_child(gateway_tag, "param");
3909 }
3910
3911 for (; param; param = param->next) {
3912 char *var = (char *) switch_xml_attr_soft(param, "name");
3913 char *val = (char *) switch_xml_attr_soft(param, "value");
3914
3915 if (!strcmp(var, "register")) {
3916 register_str = val;
3917 } else if (!strcmp(var, "scheme")) {
3918 scheme = val;
3919 } else if (!strcmp(var, "realm")) {
3920 realm = val;
3921 } else if (!strcmp(var, "username")) {
3922 username = val;
3923 } else if (!strcmp(var, "extension-in-contact")) {
3924 extension_in_contact = switch_true(val);
3925 } else if (!strcmp(var, "auth-username")) {
3926 auth_username = val;
3927 } else if (!strcmp(var, "password")) {
3928 password = val;
3929 } else if (!strcmp(var, "caller-id-in-from")) {
3930 caller_id_in_from = val;
3931 } else if (!strcmp(var, "extension")) {
3932 extension = val;
3933 } else if (!strcmp(var, "contact-in-ping")) {
3934 contact_in_ping = switch_true(val);
3935 } else if (!strcmp(var, "ping")) {
3936 ping_freq = atoi(val);
3937 } else if (!strcmp(var, "ping-max")) {
3938 ping_max = atoi(val);
3939 } else if (!strcmp(var, "ping-min")) {
3940 ping_min = atoi(val);
3941 } else if (!strcmp(var, "ping-user-agent")) {
3942 options_user_agent = val;
3943 } else if (!strcmp(var, "ping-monitoring")) { // if true then every gw ping result will fire a gateway status event
3944 ping_monitoring = switch_true(val);
3945 } else if (!strcmp(var, "proxy")) {
3946 proxy = val;
3947 } else if (!strcmp(var, "context")) {
3948 context = val;
3949 } else if (!strcmp(var, "expire-seconds")) {
3950 expire_seconds = val;
3951 } else if (!strcmp(var, "908-retry-seconds")) {
3952 fail_908_retry_seconds = val;
3953 } else if (!strcmp(var, "retry-seconds")) {
3954 retry_seconds = val;
3955 } else if (!strcmp(var, "timeout-seconds")) {
3956 timeout_seconds = val;
3957 } else if (!strcmp(var, "retry_seconds")) { // support typo for back compat
3958 retry_seconds = val;
3959 } else if (!strcmp(var, "from-user")) {
3960 from_user = val;
3961 } else if (!strcmp(var, "from-domain")) {
3962 from_domain = val;
3963 } else if (!strcmp(var, "contact-host")) {
3964 contact_host = val;
3965 } else if (!strcmp(var, "register-proxy")) {
3966 register_proxy = val;
3967 gateway->register_proxy_host_cfg = sofia_glue_get_host_from_cfg(register_proxy, gateway->pool);
3968 } else if (!strcmp(var, "outbound-proxy")) {
3969 outbound_proxy = val;
3970 gateway->outbound_proxy_host_cfg = sofia_glue_get_host_from_cfg(outbound_proxy, gateway->pool);
3971 } else if (!strcmp(var, "distinct-to")) {
3972 distinct_to = switch_true(val);
3973 } else if (!strcmp(var, "destination-prefix")) {
3974 if (!zstr(val)_zstr(val)) {
3975 gateway->destination_prefix = switch_core_strdup(gateway->pool, val)switch_core_perform_strdup(gateway->pool, val, "sofia.c", (
const char *)__func__, 3975)
;
3976 }
3977 } else if (!strcmp(var, "rfc-5626")) {
3978 rfc_5626 = switch_true(val);
3979 } else if (!strcmp(var, "reg-id")) {
3980 reg_id = val;
3981 } else if (!strcmp(var, "contact-params")) {
3982 contact_params = val;
3983 } else if (!strcmp(var, "register-transport")) {
3984 sofia_transport_t transport = sofia_glue_str2transport(val);
3985
3986 if (transport == SOFIA_TRANSPORT_UNKNOWN || (!sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) && sofia_glue_transport_has_tls(transport))) {
3987 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3987
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: unsupported transport\n");
3988 goto skip;
3989 }
3990
3991 gateway->register_transport = transport;
3992 } else if (!strcmp(var, "gw-auth-acl")) {
3993 if (!zstr(val)_zstr(val)) {
3994 gateway->gw_auth_acl = switch_core_strdup(gateway->pool, val)switch_core_perform_strdup(gateway->pool, val, "sofia.c", (
const char *)__func__, 3994)
;
3995 }
3996 }
3997 }
3998
3999 /* RFC 5626 enable in the GW profile and the UA profile */
4000 if (rfc_5626 && sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626)((profile)->pflags[PFLAG_ENABLE_RFC5626] ? 1 : 0)) {
4001 char str_guid[su_guid_strlen + 1];
4002 su_guid_t guid[1];
4003 su_guid_generate(guid);
4004 su_guid_sprintf(str_guid, su_guid_strlen + 1, guid);
4005 str_rfc_5626 = switch_core_sprintf(gateway->pool, ";reg-id=%s;+sip.instance=\"<urn:uuid:%s>\"",reg_id,str_guid);
4006 }
4007
4008 if (zstr(realm)_zstr(realm)) {
4009 if (zstr(proxy)_zstr(proxy)) {
4010 realm = name;
4011 } else {
4012 realm = proxy;
4013 }
4014 }
4015
4016 if (switch_true(register_str)) {
4017 if (zstr(username)_zstr(username)) {
4018 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4018
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: username param is REQUIRED!\n");
4019 goto skip;
4020 }
4021
4022 if (zstr(password)_zstr(password)) {
4023 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4023
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: password param is REQUIRED!\n");
4024 goto skip;
4025 }
4026 } else {
4027 if (zstr(username)_zstr(username)) {
4028 username = "FreeSWITCH";
4029 }
4030
4031 if (zstr(password)_zstr(password)) {
4032 password = "";
4033 }
4034 }
4035
4036 if (zstr(from_user)_zstr(from_user)) {
4037 from_user = username;
4038 }
4039
4040 if (zstr(proxy)_zstr(proxy)) {
4041 proxy = realm;
4042 }
4043
4044 gateway->proxy_host_cfg = sofia_glue_get_host_from_cfg(proxy, gateway->pool);
4045
4046 if (!switch_true(register_str)) {
4047 gateway->state = REG_STATE_NOREG;
4048 gateway->status = SOFIA_GATEWAY_UP;
4049 gateway->uptime = switch_time_now();
4050 }
4051
4052 if (zstr(auth_username)_zstr(auth_username)) {
4053 auth_username = username;
4054 }
4055
4056 if (!zstr(register_proxy)_zstr(register_proxy)) {
4057 if (strncasecmp(register_proxy, "sip:", 4) && strncasecmp(register_proxy, "sips:", 5)) {
4058 gateway->register_sticky_proxy = switch_core_sprintf(gateway->pool, "sip:%s", register_proxy);
4059 } else {
4060 gateway->register_sticky_proxy = switch_core_strdup(gateway->pool, register_proxy)switch_core_perform_strdup(gateway->pool, register_proxy, "sofia.c"
, (const char *)__func__, 4060)
;
4061 }
4062 }
4063
4064 if (!zstr(outbound_proxy)_zstr(outbound_proxy)) {
4065 if (strncasecmp(outbound_proxy, "sip:", 4) && strncasecmp(outbound_proxy, "sips:", 5)) {
4066 gateway->outbound_sticky_proxy = switch_core_sprintf(gateway->pool, "sip:%s", outbound_proxy);
4067 } else {
4068 gateway->outbound_sticky_proxy = switch_core_strdup(gateway->pool, outbound_proxy)switch_core_perform_strdup(gateway->pool, outbound_proxy, "sofia.c"
, (const char *)__func__, 4068)
;
4069 }
4070 }
4071
4072 gateway->retry_seconds = atoi(retry_seconds);
4073
4074 if (fail_908_retry_seconds) {
4075 gateway->fail_908_retry_seconds = atoi(fail_908_retry_seconds);
4076 }
4077
4078 if (gateway->retry_seconds < 5) {
4079 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4079
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid retry-seconds of %d on gateway %s, using the value of 30 instead.\n",
4080 gateway->retry_seconds, name);
4081 gateway->retry_seconds = 30;
4082 }
4083
4084 gateway->reg_timeout_seconds = atoi(timeout_seconds);
4085
4086 if (gateway->reg_timeout_seconds < 5) {
4087 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4087
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid timeout-seconds of %d on gateway %s, using the value of 60 instead.\n",
4088 gateway->reg_timeout_seconds, name);
4089 gateway->reg_timeout_seconds = 60;
4090 }
4091
4092
4093 gateway->register_scheme = switch_core_strdup(gateway->pool, scheme)switch_core_perform_strdup(gateway->pool, scheme, "sofia.c"
, (const char *)__func__, 4093)
;
4094 gateway->register_context = switch_core_strdup(gateway->pool, context)switch_core_perform_strdup(gateway->pool, context, "sofia.c"
, (const char *)__func__, 4094)
;
4095 gateway->register_realm = switch_core_strdup(gateway->pool, realm)switch_core_perform_strdup(gateway->pool, realm, "sofia.c"
, (const char *)__func__, 4095)
;
4096 gateway->register_username = switch_core_strdup(gateway->pool, username)switch_core_perform_strdup(gateway->pool, username, "sofia.c"
, (const char *)__func__, 4096)
;
4097 gateway->auth_username = switch_core_strdup(gateway->pool, auth_username)switch_core_perform_strdup(gateway->pool, auth_username, "sofia.c"
, (const char *)__func__, 4097)
;
4098 gateway->register_password = switch_core_strdup(gateway->pool, password)switch_core_perform_strdup(gateway->pool, password, "sofia.c"
, (const char *)__func__, 4098)
;
4099 gateway->distinct_to = distinct_to;
4100 gateway->options_user_agent = options_user_agent;
4101
4102 if (switch_true(caller_id_in_from)) {
4103 sofia_set_flag(gateway, REG_FLAG_CALLERID)(gateway)->flags[REG_FLAG_CALLERID] = 1;
4104 }
4105
4106 register_transport = (char *) sofia_glue_transport2str(gateway->register_transport);
4107
4108 if (! zstr(contact_params)_zstr(contact_params)) {
4109 if (*contact_params == ';') {
4110 params = switch_core_sprintf(gateway->pool, "%s;transport=%s;gw=%s", contact_params, register_transport, gateway->name);
4111 } else {
4112 params = switch_core_sprintf(gateway->pool, ";%s;transport=%s;gw=%s", contact_params, register_transport, gateway->name);
4113 }
4114 } else {
4115 params = switch_core_sprintf(gateway->pool, ";transport=%s;gw=%s", register_transport, gateway->name);
4116 }
4117
4118 if (!zstr(from_domain)_zstr(from_domain)) {
4119 gateway->from_domain = switch_core_strdup(gateway->pool, from_domain)switch_core_perform_strdup(gateway->pool, from_domain, "sofia.c"
, (const char *)__func__, 4119)
;
4120 }
4121
4122 if (!zstr(register_transport)_zstr(register_transport) && !switch_stristr("transport=", proxy)) {
4123 gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", proxy, register_transport);
4124 } else {
4125 gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
4126 }
4127
4128 gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s>",
4129 from_user, !zstr(from_domain)_zstr(from_domain) ? from_domain : proxy);
4130
4131 if (ping_freq) {
4132 if (ping_freq >= 5) {
4133 gateway->ping_freq = ping_freq;
4134 gateway->ping_max = ping_max;
4135 gateway->ping_min = ping_min;
4136 gateway->ping_monitoring = ping_monitoring;
4137 gateway->ping = switch_epoch_time_now(NULL((void*)0)) + ping_freq;
4138 gateway->options_to_uri = switch_core_sprintf(gateway->pool, "<sip:%s>",
4139 !zstr(from_domain)_zstr(from_domain) ? from_domain : proxy);
4140 gateway->options_from_uri = gateway->options_to_uri;
4141 if (contact_in_ping) {
4142 gateway->contact_in_ping = contact_in_ping;
4143 }
4144 } else {
4145 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4145
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: invalid ping!\n");
4146 }
4147 }
4148
4149 if (contact_host) {
4150 if (!strcmp(contact_host, "sip-ip")) {
4151 sipip = profile->sipip;
4152 } else {
4153 sipip = contact_host;
4154 }
4155 } else if (profile->extsipip) {
4156 sipip = profile->extsipip;
4157 } else {
4158 sipip = profile->sipip;
4159 }
4160
4161 if (zstr(extension)_zstr(extension)) {
4162 extension = username;
4163 } else {
4164 gateway->real_extension = switch_core_strdup(gateway->pool, extension)switch_core_perform_strdup(gateway->pool, extension, "sofia.c"
, (const char *)__func__, 4164)
;
4165 }
4166
4167 gateway->extension = switch_core_strdup(gateway->pool, extension)switch_core_perform_strdup(gateway->pool, extension, "sofia.c"
, (const char *)__func__, 4167)
;
4168
4169 if (!strncasecmp(proxy, "sip:", 4)) {
4170 gateway->register_proxy = switch_core_strdup(gateway->pool, proxy)switch_core_perform_strdup(gateway->pool, proxy, "sofia.c"
, (const char *)__func__, 4170)
;
4171 gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy + 4);
4172 } else {
4173 gateway->register_proxy = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
4174 gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy);
4175 }
4176
4177 /* This checks to make sure we provide the right contact on register for targets behind nat with us. */
4178 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
4179 char *register_host = NULL((void*)0);
4180
4181 register_host = sofia_glue_get_register_host(gateway->register_proxy);
4182
4183 if (register_host && switch_is_lan_addr(register_host)) {
4184 sipip = profile->sipip;
4185 }
4186
4187 switch_safe_free(register_host)if (register_host) {free(register_host);register_host=((void*
)0);}
;
4188 }
4189
4190 if (extension_in_contact) {
4191 if (rfc_5626) {
4192 format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d>%s" : "<sip:%s@%s:%d%s>%s";
4193 gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
4194 sipip,
4195 sofia_glue_transport_has_tls(gateway->register_transport) ?
4196 profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
4197
4198 } else {
4199 format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d%s>" : "<sip:%s@%s:%d%s>";
4200 gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
4201 sipip,
4202 sofia_glue_transport_has_tls(gateway->register_transport) ?
4203 profile->tls_sip_port : profile->extsipport, params);
4204 }
4205 } else {
4206 if (rfc_5626) {
4207 format = strchr(sipip, ':') ? "<sip:gw+%s@[%s]:%d%s>%s" : "<sip:gw+%s@%s:%d%s>%s";
4208 gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
4209 sipip,
4210 sofia_glue_transport_has_tls(gateway->register_transport) ?
4211 profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
4212
4213 } else {
4214 format = strchr(sipip, ':') ? "<sip:gw+%s@[%s]:%d%s>" : "<sip:gw+%s@%s:%d%s>";
4215 gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
4216 sipip,
4217 sofia_glue_transport_has_tls(gateway->register_transport) ?
4218 profile->tls_sip_port : profile->extsipport, params);
4219
4220 }
4221 }
4222
4223 gateway->expires_str = switch_core_strdup(gateway->pool, expire_seconds)switch_core_perform_strdup(gateway->pool, expire_seconds, "sofia.c"
, (const char *)__func__, 4223)
;
4224
4225 if ((gateway->freq = atoi(gateway->expires_str)) < 5) {
4226 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4226
, ((void*)0)
, SWITCH_LOG_WARNING,
4227 "Invalid register-frequency of %d on gateway %s, using the value of 3600 instead\n", gateway->freq, name);
4228 gateway->freq = 3600;
4229 }
4230
4231 if ((gw_subs_tag = switch_xml_child(gateway_tag, "subscriptions"))) {
4232 parse_gateway_subscriptions(profile, gateway, gw_subs_tag);
4233 }
4234
4235 sofia_reg_add_gateway(profile, gateway->name, gateway);
4236
4237 }
4238
4239 skip:
4240 switch_assert(gateway_tag)((gateway_tag) ? (void) (0) : __assert_fail ("gateway_tag", "sofia.c"
, 4240, __extension__ __PRETTY_FUNCTION__))
;
4241 }
4242}
4243
4244static void parse_domain_tag(sofia_profile_t *profile, switch_xml_t x_domain_tag, const char *dname, const char *parse, const char *alias)
4245{
4246 if (switch_true(alias)) {
4247 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, dname)switch_core_perform_strdup(profile->pool, dname, "sofia.c"
, (const char *)__func__, 4247)
, profile) == SWITCH_STATUS_SUCCESS) {
4248 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4248
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", dname, profile->name);
4249 } else {
4250 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4250
, ((void*)0)
, SWITCH_LOG_DEBUG1, "Alias [%s] for profile [%s] (already exists)\n", dname, profile->name);
4251 }
4252 }
4253
4254 if (switch_true(parse)) {
4255 switch_xml_t gts, gt, uts, ut, gateways_tag;
4256 /* Backwards Compatibility */
4257 for (ut = switch_xml_child(x_domain_tag, "user"); ut; ut = ut->next) {
4258 if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
4259 parse_gateways(profile, gateways_tag, NULL((void*)0));
4260 }
4261 }
4262 /* New Method with <groups> tags and users are now inside a <users> tag */
4263 for (gts = switch_xml_child(x_domain_tag, "groups"); gts; gts = gts->next) {
4264 for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
4265 for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
4266 for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
4267 if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
4268 parse_gateways(profile, gateways_tag, NULL((void*)0));
4269 }
4270 }
4271 }
4272 }
4273 }
4274 }
4275}
4276
4277static void config_sofia_profile_urls(sofia_profile_t * profile)
4278{
4279
4280 if (profile->extsipip) {
4281 char *ipv6 = strchr(profile->extsipip, ':');
4282 profile->public_url = switch_core_sprintf(profile->pool,
4283 "sip:%s@%s%s%s:%d",
4284 profile->contact_user,
4285 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
4286 }
4287
4288 if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
4289 char *ipv6 = strchr(profile->extsipip, ':');
4290 profile->url = switch_core_sprintf(profile->pool,
4291 "sip:%s@%s%s%s:%d",
4292 profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
4293 profile->bindurl = switch_core_sprintf(profile->pool, "%s;maddr=%s", profile->url, profile->sipip);
4294 } else {
4295 char *ipv6 = strchr(profile->sipip, ':');
4296 profile->url = switch_core_sprintf(profile->pool,
4297 "sip:%s@%s%s%s:%d",
4298 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->sip_port);
4299 profile->bindurl = profile->url;
4300 }
4301
4302 profile->tcp_contact = switch_core_sprintf(profile->pool, "<%s;transport=tcp>", profile->url);
4303
4304 if (profile->public_url) {
4305 profile->tcp_public_contact = switch_core_sprintf(profile->pool, "<%s;transport=tcp>", profile->public_url);
4306 }
4307
4308 if (profile->bind_params) {
4309 char *bindurl;
4310 if (!switch_stristr("transport=", profile->bind_params)) {
4311 profile->bind_params = switch_core_sprintf(profile->pool, "%s;transport=udp,tcp", profile->bind_params);
4312 }
4313 bindurl = switch_core_sprintf(profile->pool, "%s;%s", profile->bindurl, profile->bind_params);
4314 profile->bindurl = bindurl;
4315 } else {
4316 char *bindurl = switch_core_sprintf(profile->pool, "%s;transport=udp,tcp", profile->bindurl);
4317 profile->bindurl = bindurl;
4318 }
4319
4320
4321 if ( profile->ws_port ) {
4322 char *ip = !zstr(profile->ws_ip)_zstr(profile->ws_ip) ? profile->ws_ip : profile->sipip;
4323 switch_port_t port = profile->ws_port;
4324 char *ipv6 = strchr(ip, ':');
4325 profile->ws_bindurl =
4326 switch_core_sprintf(profile->pool,
4327 "sip:%s@%s%s%s:%d;transport=ws",
4328 profile->contact_user, ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
4329 }
4330
4331 if ( profile->wss_port ) {
4332 char *ip = !zstr(profile->wss_ip)_zstr(profile->wss_ip) ? profile->wss_ip : profile->sipip;
4333 switch_port_t port = profile->wss_port;
4334 char *ipv6 = strchr(ip, ':');
4335 profile->wss_bindurl =
4336 switch_core_sprintf(profile->pool,
4337 "sips:%s@%s%s%s:%d;transport=wss",
4338 profile->contact_user, ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
4339 }
4340
4341 /*
4342 * handle TLS params #2
4343 */
4344 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
4345 if (!profile->tls_sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] ? 1 : 0)) {
4346 profile->tls_sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_TLS_PORT"5061");
4347 }
4348
4349 if (profile->extsipip) {
4350 char *ipv6 = strchr(profile->extsipip, ':');
4351 profile->tls_public_url = switch_core_sprintf(profile->pool,
4352 "sip:%s@%s%s%s:%d",
4353 profile->contact_user,
4354 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port);
4355 }
4356
4357 if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
4358 char *ipv6 = strchr(profile->extsipip, ':');
4359 profile->tls_url =
4360 switch_core_sprintf(profile->pool,
4361 "sip:%s@%s%s%s:%d",
4362 profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port);
4363 profile->tls_bindurl =
4364 switch_core_sprintf(profile->pool,
4365 "sips:%s@%s%s%s:%d;maddr=%s",
4366 profile->contact_user,
4367 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port, profile->sipip);
4368 } else {
4369 char *ipv6 = strchr(profile->sipip, ':');
4370 profile->tls_url =
4371 switch_core_sprintf(profile->pool,
4372 "sip:%s@%s%s%s:%d",
4373 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->tls_sip_port);
4374 profile->tls_bindurl =
4375 switch_core_sprintf(profile->pool,
4376 "sips:%s@%s%s%s:%d",
4377 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->tls_sip_port);
4378 }
4379
4380 if (profile->tls_bind_params) {
4381 char *tls_bindurl = profile->tls_bindurl;
4382 profile->tls_bindurl = switch_core_sprintf(profile->pool, "%s;%s", tls_bindurl, profile->tls_bind_params);
4383 }
4384
4385 profile->tls_contact = switch_core_sprintf(profile->pool, "<%s;transport=tls>", profile->tls_url);
4386 if (profile->tls_public_url) {
4387 profile->tls_public_contact = switch_core_sprintf(profile->pool, "<%s;transport=tls>", profile->tls_public_url);
4388 }
4389
4390
4391 }
4392}
4393
4394#ifdef SOFIA_CUSTOM_TIME
4395/* appears to not be granular enough */
4396static void sofia_time(su_time_t *tv)
4397{
4398 switch_time_t now;
4399
4400 if (tv) {
4401 now = switch_micro_time_now();
4402 tv->tv_sec = ((uint32_t) (now / 1000000)) + 2208988800UL;
4403 tv->tv_usec = (uint32_t) (now % 1000000);
4404 }
4405
4406}
4407#endif
4408
4409switch_status_t sofia_init(void)
4410{
4411 su_init();
4412 if (sip_update_default_mclass(sip_extend_mclass(NULL((void*)0))) < 0) {
4413 su_deinit();
4414 sip_cloned_parser_destroy();
4415 return SWITCH_STATUS_GENERR;
4416 }
4417
4418#ifdef SOFIA_TIME
4419 su_set_time_func(sofia_time);
4420#endif
4421
4422 /* Redirect loggers in sofia */
4423 su_log_redirect(su_log_default, logger, NULL((void*)0));
4424 su_log_redirect(tport_log, logger, NULL((void*)0));
4425 su_log_redirect(iptsec_log, logger, NULL((void*)0));
4426 su_log_redirect(nea_log, logger, NULL((void*)0));
4427 su_log_redirect(nta_log, logger, NULL((void*)0));
4428 su_log_redirect(nth_client_log, logger, NULL((void*)0));
4429 su_log_redirect(nth_server_log, logger, NULL((void*)0));
4430 su_log_redirect(nua_log, logger, NULL((void*)0));
4431 su_log_redirect(soa_log, logger, NULL((void*)0));
4432 su_log_redirect(sresolv_log, logger, NULL((void*)0));
4433#ifdef HAVE_SOFIA_STUN
4434 su_log_redirect(stun_log, logger, NULL((void*)0));
4435#endif
4436
4437 return SWITCH_STATUS_SUCCESS;
4438}
4439
4440switch_status_t config_gateway(const char *profile_name, const char *gateway_name)
4441{
4442 switch_xml_t cfg, xml = NULL((void*)0), xprofiles, xprofile, gateways_tag;
4443 switch_status_t status = SWITCH_STATUS_SUCCESS;
4444 sofia_profile_t *profile = NULL((void*)0);
4445 switch_event_t *params = NULL((void*)0);
4446 const char *cf = "sofia.conf";
4447
4448 if (zstr(profile_name)_zstr(profile_name) || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 4448
, profile_name)
)) {
4449 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4449
, ((void*)0)
, SWITCH_LOG_WARNING, "Profile [%s] does not exist.\n", profile_name);
4450 status = SWITCH_STATUS_FALSE;
4451 return status;
4452 }
4453
4454 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 4454, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
4455 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "sofia.c", 4455
, __extension__ __PRETTY_FUNCTION__))
;
4456 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile_name);
4457 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true");
4458 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "gateway", gateway_name);
4459
4460 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4461 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4461
, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", gateway_name);
4462 status = SWITCH_STATUS_FALSE;
4463 goto done;
4464 }
4465
4466 if ((xprofiles = switch_xml_child(cfg, "profiles"))) {
4467 if ((xprofile = switch_xml_find_child(xprofiles, "profile", "name", profile->name))) {
4468 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
4469 parse_gateways(profile, gateways_tag, strcmp(gateway_name, "_all_") ? gateway_name : NULL((void*)0));
4470 }
4471 }
4472 }
4473
4474 status = SWITCH_STATUS_SUCCESS;
4475
4476done:
4477
4478 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 4478, profile)
;
4479 if (xml) switch_xml_free(xml);
4480
4481 switch_event_destroy(&params);
4482
4483 return status;
4484}
4485
4486switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
4487{
4488 char *cf = "sofia.conf";
4489 switch_xml_t cfg, xml = NULL((void*)0), xprofile, param, settings, profiles;
4490 switch_status_t status = SWITCH_STATUS_SUCCESS;
4491 sofia_profile_t *profile = NULL((void*)0);
4492 char url[512] = "";
4493 int profile_found = 0;
4494 switch_event_t *params = NULL((void*)0);
4495 sofia_profile_t *profile_already_started = NULL((void*)0);
4496
4497 if (!zstr(profile_name)_zstr(profile_name) && (profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 4497
, profile_name)
)) {
4498 if (reload == SOFIA_CONFIG_RESCAN) {
4499 profile_already_started = profile;
4500 } else {
4501 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4501
, ((void*)0)
, SWITCH_LOG_WARNING, "Profile [%s] Already exists.\n", switch_str_nil(profile_name)(profile_name ? profile_name : ""));
4502 status = SWITCH_STATUS_FALSE;
4503 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 4503, profile)
;
4504 return status;
4505 }
4506 }
4507
4508 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 4508, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
4509 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "sofia.c", 4509
, __extension__ __PRETTY_FUNCTION__))
;
4510 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile_name);
4511 if (reload == SOFIA_CONFIG_RESCAN) {
4512 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true");
4513 }
4514
4515 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4516 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4516
, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
4517 status = SWITCH_STATUS_FALSE;
4518 goto done;
4519 }
4520
4521 mod_sofia_globals.auto_restart = SWITCH_TRUE;
4522 mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = SWITCH_FALSE; /* handle backwards compatilibity - by default use new behavior */
4523 mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
4524
4525 if ((settings = switch_xml_child(cfg, "global_settings"))) {
4526 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
4527 char *var = (char *) switch_xml_attr_soft(param, "name");
4528 char *val = (char *) switch_xml_attr_soft(param, "value");
4529 if (!strcasecmp(var, "log-level")) {
4530 su_log_set_level(NULL((void*)0), atoi(val));
4531 } else if (!strcasecmp(var, "abort-on-empty-external-ip")) {
4532 mod_sofia_globals.abort_on_empty_external_ip = switch_true(val);
4533 } else if (!strcasecmp(var, "tracelevel")) {
4534 mod_sofia_globals.tracelevel = switch_log_str2level(val);
4535 } else if (!strcasecmp(var, "debug-presence")) {
4536 mod_sofia_globals.debug_presence = atoi(val);
4537 } else if (!strcasecmp(var, "debug-sla")) {
4538 mod_sofia_globals.debug_sla = atoi(val);
4539 } else if (!strcasecmp(var, "max-reg-threads") && val) {
4540 int x = atoi(val);
4541
4542 if (x > 0) {
4543 mod_sofia_globals.max_reg_threads = x;
4544 }
4545
4546 } else if (!strcasecmp(var, "auto-restart")) {
4547 mod_sofia_globals.auto_restart = switch_true(val);
4548 } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
4549 mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
4550 if (switch_true(val)) {
4551 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4551
, ((void*)0)
, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
4552 "deprecated and will be removed - let FS devs know if you think it should stay\n");
4553 }
4554 } else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
4555 if(val && (!strcasecmp(val, "to_host") || !strcasecmp(val, "1")) ) {
4556 /* old behaviour */
4557 mod_sofia_globals.rewrite_multicasted_fs_path = 1;
4558 } else if (val && !strcasecmp(val, "original_server_host")) {
4559 mod_sofia_globals.rewrite_multicasted_fs_path = 2;
4560 } else if (val && !strcasecmp(val, "original_hostname")) {
4561 mod_sofia_globals.rewrite_multicasted_fs_path = 3;
4562 } else {
4563 mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
4564 }
4565 } else if (!strcasecmp(var, "capture-server")) {
4566 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__, 4566)
;
4567 } else if (!strcasecmp(var, "stir-shaken-as-key")) {
4568 /* The private key to authenticate SIP Identity when sip_identity_attest is set */
4569 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__, 4569)
;
4570 } else if (!strcasecmp(var, "stir-shaken-as-url")) {
4571 /* The x5u URL to advertise when sip_identity_attest is set */
4572 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__, 4572)
;
4573 } else if (!strcasecmp(var, "stir-shaken-vs-ca-dir")) {
4574 /* The dir that contains the trusted CA root certs. */
4575 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__, 4575)
;
4576 } else if (!strcasecmp(var, "stir-shaken-vs-cert-path-check")) {
4577 mod_sofia_globals.stir_shaken_vs_cert_path_check = switch_true(val);
4578 } else if (!strcasecmp(var, "stir-shaken-vs-require-date")) {
4579 mod_sofia_globals.stir_shaken_vs_require_date = switch_true(val);
4580 }
4581 }
4582 }
4583
4584 if ((profiles = switch_xml_child(cfg, "profiles"))) {
4585 for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
4586 char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name");
4587 char *xprofiledomain = (char *) switch_xml_attr(xprofile, "domain");
4588 if (!(settings = switch_xml_child(xprofile, "settings"))) {
4589 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4589
, ((void*)0)
, SWITCH_LOG_ERROR, "No Settings, check the new config!\n");
4590 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4590)
;
4591 } else {
4592 switch_memory_pool_t *pool = NULL((void*)0);
4593 char *auth_messages_value = NULL((void*)0);
4594 char *auth_subscriptions_value = NULL((void*)0);
4595 uint8_t disable_message_auth_flag = 0;
4596 uint8_t disable_subscription_auth_flag = 0;
4597
4598 if (!xprofilename) {
4599 xprofilename = "unnamed";
4600 }
4601
4602 if (profile_name) {
4603 if (strcasecmp(profile_name, xprofilename)) {
4604 continue;
4605 } else {
4606 profile_found = 1;
4607 }
4608 }
4609
4610 if (!profile_already_started) {
4611
4612 /* Setup the pool */
4613 if ((status = switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "sofia.c", (const
char *)__func__, 4613)
) != SWITCH_STATUS_SUCCESS) {
4614 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4614
, ((void*)0)
, SWITCH_LOG_CRIT, "Memory Error!\n");
4615 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4615)
;
4616 goto done;
4617 }
4618
4619 if (!(profile = (sofia_profile_t *) switch_core_alloc(pool, sizeof(*profile))switch_core_perform_alloc(pool, sizeof(*profile), "sofia.c", (
const char *)__func__, 4619)
)) {
4620 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4620
, ((void*)0)
, SWITCH_LOG_ERROR, "Memory Error!\n");
4621 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4621)
;
4622 goto done;
4623 }
4624
4625 profile->tls_verify_policy = TPTLS_VERIFY_NONE;
4626 sofia_set_pflag(profile, PFLAG_AUTO_INVITE_100)(profile)->pflags[PFLAG_AUTO_INVITE_100] = 1;
4627 /* lib default */
4628 profile->tls_verify_depth = 2;
4629
4630
4631 switch_mutex_init(&profile->gw_mutex, SWITCH_MUTEX_NESTED0x1, pool);
4632
4633 profile->trans_timeout = 100;
4634
4635 profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
4636
4637 profile->pool = pool;
4638
4639 profile->user_agent = switch_core_sprintf(profile->pool, "FreeSWITCH-mod_sofia/%s", switch_version_full());
4640
4641 profile->sip_user_ping_max = 3;
4642 profile->sip_user_ping_min = 1;
4643
4644 profile->name = switch_core_strdup(profile->pool, xprofilename)switch_core_perform_strdup(profile->pool, xprofilename, "sofia.c"
, (const char *)__func__, 4644)
;
4645 switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
4646
4647 if (xprofiledomain) {
4648 profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain)switch_core_perform_strdup(profile->pool, xprofiledomain, "sofia.c"
, (const char *)__func__, 4648)
;
4649 }
4650
4651 profile->dbname = switch_core_strdup(profile->pool, url)switch_core_perform_strdup(profile->pool, url, "sofia.c", (
const char *)__func__, 4651)
;
4652 switch_core_hash_init(&profile->chat_hash)switch_core_hash_init_case(&profile->chat_hash, SWITCH_TRUE
)
;
4653 switch_core_hash_init(&profile->reg_nh_hash)switch_core_hash_init_case(&profile->reg_nh_hash, SWITCH_TRUE
)
;
4654 switch_core_hash_init(&profile->mwi_debounce_hash)switch_core_hash_init_case(&profile->mwi_debounce_hash
, SWITCH_TRUE)
;
4655 switch_thread_rwlock_create(&profile->rwlock, profile->pool);
4656 switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
4657 profile->dtmf_duration = 100;
4658 profile->rtp_digit_delay = 40;
4659 profile->sip_force_expires = 0;
4660 profile->sip_force_expires_min = 0;
4661 profile->sip_force_expires_max = 0;
4662 profile->sip_expires_max_deviation = 0;
4663 profile->sip_expires_late_margin = 60;
4664 profile->sip_subscription_max_deviation = 0;
4665 profile->tls_ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
4666 profile->tls_version = SOFIA_TLS_VERSION_TLSv1;
4667 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_1;
4668 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
4669 profile->tls_timeout = 300;
4670 profile->mflags = MFLAG_REFER | MFLAG_REGISTER;
4671 profile->server_rport_level = 1;
4672 profile->client_rport_level = 1;
4673 profile->tls_cert_dir = SWITCH_GLOBAL_dirs.certs_dir;
4674 sofia_set_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 1;
4675 sofia_set_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 1;
4676 profile->auto_restart = 1;
4677 sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 1;
4678 sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE)(profile)->media_flags[SCMF_RTP_AUTOFLUSH_DURING_BRIDGE] =
1
;
4679 profile->contact_user = SOFIA_DEFAULT_CONTACT_USER"mod_sofia";
4680 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
4681 sofia_set_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 1;
4682 sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 1;
4683 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
1
;
4684 //sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
4685
4686 sofia_clear_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)(profile)->pflags[PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER
] = 0
;
4687 sofia_clear_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)(profile)->pflags[PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE] =
0
;
4688 sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)(profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] = 0;
4689 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)(profile)->pflags[PFLAG_BLIND_AUTH_ENFORCE_RESULT] = 0;
4690 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)(profile)->pflags[PFLAG_BLIND_AUTH_REPLY_403] = 0;
4691 sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER)(profile)->pflags[PFLAG_AUTH_REQUIRE_USER] = 0;
4692 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)(profile)->pflags[PFLAG_AUTH_CALLS_ACL_ONLY] = 0;
4693 sofia_clear_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK)(profile)->pflags[PFLAG_USE_PORT_FOR_ACL_CHECK] = 0;
4694 profile->shutdown_type = "false";
4695 profile->local_network = "localnet.auto";
4696 sofia_set_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 1;
4697 sofia_set_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 1;
4698 profile->mndlb |= SM_NDLB_ALLOW_NONDUP_SDP;
4699 profile->te = 101;
4700 profile->ireg_seconds = IREG_SECONDS30;
4701 profile->iping_seconds = IPING_SECONDS30;
4702 profile->iping_freq = IPING_FREQUENCY1;
4703 profile->paid_type = PAID_DEFAULT;
4704 profile->bind_attempts = 2;
4705 profile->bind_attempt_interval = 5;
4706 profile->dtmf_type = DTMF_2833;
4707 profile->tls_verify_policy = TPTLS_VERIFY_NONE;
4708 /* lib default */
4709 profile->tls_verify_depth = 2;
4710 profile->tls_verify_date = SWITCH_TRUE;
4711 } else {
4712
4713 /* you could change profile->foo here if it was a minor change like context or dialplan ... */
4714 profile->acl_count = 0;
4715 profile->nat_acl_count = 0;
4716 profile->reg_acl_count = 0;
4717 profile->proxy_acl_count = 0;
4718 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
4719 profile->ib_calls = 0;
4720 profile->ob_calls = 0;
4721 profile->ib_failed_calls = 0;
4722 profile->ob_failed_calls = 0;
4723 profile->shutdown_type = "false";
4724 profile->rtpip_index = 0;
4725 profile->rtpip_index6 = 0;
4726
4727 if (xprofiledomain) {
4728 profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain)switch_core_perform_strdup(profile->pool, xprofiledomain, "sofia.c"
, (const char *)__func__, 4728)
;
4729 }
4730 }
4731
4732 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
4733 char *var = (char *) switch_xml_attr_soft(param, "name");
4734 char *val = (char *) switch_xml_attr_soft(param, "value");
4735 int found = 1; // Used to break up long if/elseif chain (MSVC2015 fails (parser stack overflow) otherwise)
4736
4737 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4737
, ((void*)0)
, SWITCH_LOG_DEBUG, "%s [%s]\n", var, val);
4738
4739 if (!strcasecmp(var, "debug") && val) {
4740 profile->debug = atoi(val);
4741 } else if (!strcasecmp(var, "parse-invite-tel-params")) {
4742 profile->parse_invite_tel_params = switch_true(val);
4743 } else if (!strcasecmp(var, "keepalive-method") && !zstr(val)_zstr(val)) {
4744 if (!strcasecmp(val, "info")) {
4745 profile->keepalive = KA_INFO;
4746 } else {
4747 profile->keepalive = KA_MESSAGE;
4748 }
4749 } else if (!strcasecmp(var, "bind-attempts") && val) {
4750 int ba = atoi(val) - 1;
4751
4752 if (ba >= 0) {
4753 profile->bind_attempts = ba;
4754 }
4755 } else if (!strcasecmp(var, "bind-attempt-interval") && val) {
4756 int bai = atoi(val);
4757
4758 if (bai >= 0) {
4759 profile->bind_attempt_interval = bai;
4760 }
4761 } else if (!strcasecmp(var, "shutdown-on-fail")) {
4762 profile->shutdown_type = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4762)
;
4763 } else if (!strcasecmp(var, "sip-trace")) {
4764 if (switch_true(val)) {
4765 sofia_set_flag(profile, TFLAG_TPORT_LOG)(profile)->flags[TFLAG_TPORT_LOG] = 1;
4766 } else {
4767 sofia_clear_flag(profile, TFLAG_TPORT_LOG)(profile)->flags[TFLAG_TPORT_LOG] = 0;
4768 }
4769 } else if (!strcasecmp(var, "sip-capture")) {
4770 if (switch_true(val)) {
4771 sofia_set_flag(profile, TFLAG_CAPTURE)(profile)->flags[TFLAG_CAPTURE] = 1;
4772 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);
4773 } else {
4774 sofia_clear_flag(profile, TFLAG_CAPTURE)(profile)->flags[TFLAG_CAPTURE] = 0;
4775 }
4776 } else if (!strcasecmp(var, "socket-tcp-keepalive") && !zstr(val)_zstr(val)) {
4777 profile->socket_tcp_keepalive = atoi(val);
4778 sofia_set_pflag(profile, PFLAG_SOCKET_TCP_KEEPALIVE)(profile)->pflags[PFLAG_SOCKET_TCP_KEEPALIVE] = 1;
4779 } else if (!strcasecmp(var, "tcp-keepalive") && !zstr(val)_zstr(val)) {
4780 profile->tcp_keepalive = atoi(val);
4781 sofia_set_pflag(profile, PFLAG_TCP_KEEPALIVE)(profile)->pflags[PFLAG_TCP_KEEPALIVE] = 1;
4782 } else if (!strcasecmp(var, "tcp-pingpong") && !zstr(val)_zstr(val)) {
4783 profile->tcp_pingpong = atoi(val);
4784 sofia_set_pflag(profile, PFLAG_TCP_PINGPONG)(profile)->pflags[PFLAG_TCP_PINGPONG] = 1;
4785 } else if (!strcasecmp(var, "tcp-ping2pong") && !zstr(val)_zstr(val)) {
4786 profile->tcp_ping2pong = atoi(val);
4787 sofia_set_pflag(profile, PFLAG_TCP_PING2PONG)(profile)->pflags[PFLAG_TCP_PING2PONG] = 1;
4788 } else if ((!strcasecmp(var, "proxy-refer-replaces") || !strcasecmp(var, "proxy-refer")) && !zstr(val)_zstr(val)) {
4789 if (switch_true(val)) {
4790 sofia_set_pflag(profile, PFLAG_PROXY_REFER)(profile)->pflags[PFLAG_PROXY_REFER] = 1;
4791 } else {
4792 sofia_clear_pflag(profile, PFLAG_PROXY_REFER)(profile)->pflags[PFLAG_PROXY_REFER] = 0;
4793 }
4794 } else if (!strcasecmp(var, "sip-messages-respond-200-ok") && !zstr(val)_zstr(val)) {
4795 if (switch_true(val)) {
4796 sofia_set_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK)(profile)->pflags[PFLAG_MESSAGES_RESPOND_200_OK] = 1;
4797 } else {
4798 sofia_clear_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK)(profile)->pflags[PFLAG_MESSAGES_RESPOND_200_OK] = 0;
4799 }
4800 } else if (!strcasecmp(var, "sip-subscribe-respond-200-ok") && !zstr(val)_zstr(val)) {
4801 if (switch_true(val)) {
4802 sofia_set_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK)(profile)->pflags[PFLAG_SUBSCRIBE_RESPOND_200_OK] = 1;
4803 } else {
4804 sofia_clear_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK)(profile)->pflags[PFLAG_SUBSCRIBE_RESPOND_200_OK] = 0;
4805 }
4806 } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)_zstr(val)) {
4807 profile->odbc_dsn = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4807)
;
4808 } else if (!strcasecmp(var, "db-pre-trans-execute") && !zstr(val)_zstr(val)) {
4809 profile->pre_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4809)
;
4810 } else if (!strcasecmp(var, "db-post-trans-execute") && !zstr(val)_zstr(val)) {
4811 profile->post_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4811)
;
4812 } else if (!strcasecmp(var, "db-inner-pre-trans-execute") && !zstr(val)_zstr(val)) {
4813 profile->inner_pre_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4813)
;
4814 } else if (!strcasecmp(var, "db-inner-post-trans-execute") && !zstr(val)_zstr(val)) {
4815 profile->inner_post_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4815)
;
4816 } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) {
4817 if (switch_true(val)) {
4818 sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)(profile)->pflags[PFLAG_FORWARD_MWI_NOTIFY] = 1;
4819 } else {
4820 sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)(profile)->pflags[PFLAG_FORWARD_MWI_NOTIFY] = 0;
4821 }
4822 } else if (!strcasecmp(var, "NDLB-proxy-never-patch-reinvites")) {
4823 if (switch_true(val)) {
4824 profile->mndlb |= SM_NDLB_NEVER_PATCH_REINVITE;
4825 } else {
4826 profile->mndlb &= ~SM_NDLB_NEVER_PATCH_REINVITE;
4827 }
4828 } else if (!strcasecmp(var, "registration-thread-frequency") && !zstr(val)_zstr(val)) {
4829 profile->ireg_seconds = atoi(val);
4830 if (profile->ireg_seconds < 0) {
4831 profile->ireg_seconds = IREG_SECONDS30;
4832 }
4833 } else if (!strcasecmp(var, "ping-mean-interval") && !zstr(val)_zstr(val)) {
4834 profile->iping_seconds = atoi(val);
4835 if (profile->iping_seconds < 0) {
4836 profile->iping_seconds = IPING_SECONDS30;
4837 }
4838 } else if (!strcasecmp(var, "ping-thread-frequency") && !zstr(val)_zstr(val)) {
4839 profile->iping_freq = atoi(val);
4840 if (profile->iping_freq < 0) {
4841 profile->iping_freq = IPING_FREQUENCY1;
4842 }
4843 } else if (!strcasecmp(var, "user-agent-string")) {
4844 profile->user_agent = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4844)
;
4845 } else if (!strcasecmp(var, "auto-restart")) {
4846 profile->auto_restart = switch_true(val);
4847 } else if (!strcasecmp(var, "log-auth-failures")) {
4848 if (switch_true(val)) {
4849 sofia_set_pflag(profile, PFLAG_LOG_AUTH_FAIL)(profile)->pflags[PFLAG_LOG_AUTH_FAIL] = 1;
4850 } else {
4851 sofia_clear_pflag(profile, PFLAG_LOG_AUTH_FAIL)(profile)->pflags[PFLAG_LOG_AUTH_FAIL] = 0;
4852 }
4853 } else if (!strcasecmp(var, "confirm-blind-transfer")) {
4854 if (switch_true(val)) {
4855 sofia_set_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)(profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] = 1;
4856 } else {
4857 sofia_clear_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)(profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] = 0;
4858 }
4859 } else if (!strcasecmp(var, "allow-update")) {
4860 if (switch_true(val)) {
4861 sofia_set_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 1;
4862 } else {
4863 sofia_clear_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 0;
4864 }
4865 } else if (!strcasecmp(var, "send-display-update")) {
4866 if (switch_true(val)) {
4867 sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 1;
4868 } else {
4869 sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 0;
4870 }
4871 } else if (!strcasecmp(var, "mwi-use-reg-callid")) {
4872 if (switch_true(val)) {
4873 sofia_set_pflag(profile, PFLAG_MWI_USE_REG_CALLID)(profile)->pflags[PFLAG_MWI_USE_REG_CALLID] = 1;
4874 } else {
4875 sofia_clear_pflag(profile, PFLAG_MWI_USE_REG_CALLID)(profile)->pflags[PFLAG_MWI_USE_REG_CALLID] = 0;
4876 }
4877 } else if (!strcasecmp(var, "tcp-unreg-on-socket-close")) {
4878 if (switch_true(val)) {
4879 sofia_set_pflag(profile, PFLAG_TCP_UNREG_ON_SOCKET_CLOSE)(profile)->pflags[PFLAG_TCP_UNREG_ON_SOCKET_CLOSE] = 1;
4880 } else {
4881 sofia_clear_pflag(profile, PFLAG_TCP_UNREG_ON_SOCKET_CLOSE)(profile)->pflags[PFLAG_TCP_UNREG_ON_SOCKET_CLOSE] = 0;
4882 }
4883 } else if (!strcasecmp(var, "tcp-always-nat")) {
4884 if (switch_true(val)) {
4885 sofia_set_pflag(profile, PFLAG_TCP_ALWAYS_NAT)(profile)->pflags[PFLAG_TCP_ALWAYS_NAT] = 1;
4886 } else {
4887 sofia_clear_pflag(profile, PFLAG_TCP_ALWAYS_NAT)(profile)->pflags[PFLAG_TCP_ALWAYS_NAT] = 0;
4888 }
4889 } else if (!strcasecmp(var, "tls-always-nat")) {
4890 if (switch_true(val)) {
4891 sofia_set_pflag(profile, PFLAG_TLS_ALWAYS_NAT)(profile)->pflags[PFLAG_TLS_ALWAYS_NAT] = 1;
4892 } else {
4893 sofia_clear_pflag(profile, PFLAG_TLS_ALWAYS_NAT)(profile)->pflags[PFLAG_TLS_ALWAYS_NAT] = 0;
4894 }
4895 } else if (!strcasecmp(var, "presence-proto-lookup")) {
4896 if (switch_true(val)) {
4897 sofia_set_pflag(profile, PFLAG_PRESENCE_MAP)(profile)->pflags[PFLAG_PRESENCE_MAP] = 1;
4898 } else {
4899 sofia_clear_pflag(profile, PFLAG_PRESENCE_MAP)(profile)->pflags[PFLAG_PRESENCE_MAP] = 0;
4900 }
4901 } else if (!strcasecmp(var, "profile-standby")) {
4902 if (switch_true(val)) {
4903 sofia_set_pflag(profile, PFLAG_STANDBY)(profile)->pflags[PFLAG_STANDBY] = 1;
4904 } else {
4905 sofia_clear_pflag(profile, PFLAG_STANDBY)(profile)->pflags[PFLAG_STANDBY] = 0;
4906 }
4907 } else if (!strcasecmp(var, "liberal-dtmf")) {
4908 if (switch_true(val)) {
4909 sofia_set_pflag(profile, PFLAG_LIBERAL_DTMF)(profile)->pflags[PFLAG_LIBERAL_DTMF] = 1;
4910 } else {
4911 sofia_clear_pflag(profile, PFLAG_LIBERAL_DTMF)(profile)->pflags[PFLAG_LIBERAL_DTMF] = 0;
4912 }
4913 } else if (!strcasecmp(var, "rtp-digit-delay") && !zstr(val)_zstr(val)) {
4914 int delay = atoi(val);
4915 if (delay < 0) {
4916 delay = 0;
4917 }
4918 profile->rtp_digit_delay = (uint32_t) delay;
4919 } else if (!strcasecmp(var, "watchdog-enabled")) {
4920 profile->watchdog_enabled = switch_true(val);
4921 } else if (!strcasecmp(var, "watchdog-step-timeout") && !zstr(val)_zstr(val)) {
4922 profile->step_timeout = atoi(val);
4923 } else if (!strcasecmp(var, "watchdog-event-timeout") && !zstr(val)_zstr(val)) {
4924 profile->event_timeout = atoi(val);
4925 } else if (!strcasecmp(var, "in-dialog-chat")) {
4926 if (switch_true(val)) {
4927 sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT)(profile)->pflags[PFLAG_IN_DIALOG_CHAT] = 1;
4928 } else {
4929 sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT)(profile)->pflags[PFLAG_IN_DIALOG_CHAT] = 0;
4930 }
4931 } else if (!strcasecmp(var, "enable-chat")) {
4932 if (switch_true(val)) {
4933 sofia_set_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 1;
4934 } else {
4935 sofia_clear_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 0;
4936 }
4937 } else if (!strcasecmp(var, "fire-bye-response-events")) {
4938 if (switch_true(val)) {
4939 sofia_set_pflag(profile, PFLAG_FIRE_BYE_RESPONSE_EVENTS)(profile)->pflags[PFLAG_FIRE_BYE_RESPONSE_EVENTS] = 1;
4940 } else {
4941 sofia_clear_pflag(profile, PFLAG_FIRE_BYE_RESPONSE_EVENTS)(profile)->pflags[PFLAG_FIRE_BYE_RESPONSE_EVENTS] = 0;
4942 }
4943 } else if (!strcasecmp(var, "fire-message-events")) {
4944 if (switch_true(val)) {
4945 sofia_set_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)(profile)->pflags[PFLAG_FIRE_MESSAGE_EVENTS] = 1;
4946 } else {
4947 sofia_clear_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)(profile)->pflags[PFLAG_FIRE_MESSAGE_EVENTS] = 0;
4948 }
4949 } else if (!strcasecmp(var, "t38-passthru")) {
4950 if (switch_true(val)) {
4951 sofia_set_pflag(profile, PFLAG_T38_PASSTHRU)(profile)->pflags[PFLAG_T38_PASSTHRU] = 1;
4952 } else {
4953 sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU)(profile)->pflags[PFLAG_T38_PASSTHRU] = 0;
4954 }
4955 } else if (!strcasecmp(var, "presence-disable-early")) {
4956 if (switch_true(val)) {
4957 sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY)(profile)->pflags[PFLAG_PRESENCE_DISABLE_EARLY] = 1;
4958 } else {
4959 sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY)(profile)->pflags[PFLAG_PRESENCE_DISABLE_EARLY] = 0;
4960 }
4961 } else if (!strcasecmp(var, "ignore-183nosdp")) {
4962 if (switch_true(val)) {
4963 sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP)(profile)->pflags[PFLAG_IGNORE_183NOSDP] = 1;
4964 } else {
4965 sofia_clear_pflag(profile, PFLAG_IGNORE_183NOSDP)(profile)->pflags[PFLAG_IGNORE_183NOSDP] = 0;
4966 }
4967 } else if (!strcasecmp(var, "presence-probe-on-register")) {
4968 if (switch_true(val)) {
4969 sofia_set_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_PROBE_ON_REGISTER] = 1;
4970 } else {
4971 sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_PROBE_ON_REGISTER] = 0;
4972 }
4973 } else if (!strcasecmp(var, "send-presence-on-register")) {
4974 if (val && (switch_true(val) || !strcasecmp(val, "all"))) {
4975 sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 1;
4976 } else if (val && !strcasecmp(val, "first-only")) {
4977 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 0;
4978 sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_FIRST_REGISTER] = 1;
4979 } else {
4980 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 0;
4981 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_FIRST_REGISTER] = 0;
4982 }
4983 } else if (!strcasecmp(var, "cid-in-1xx")) {
4984 if (switch_true(val)) {
4985 sofia_set_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 1;
4986 } else {
4987 sofia_clear_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 0;
4988 }
4989 } else if (!strcasecmp(var, "disable-hold")) {
4990 if (switch_true(val)) {
4991 sofia_set_media_flag(profile, SCMF_DISABLE_HOLD)(profile)->media_flags[SCMF_DISABLE_HOLD] = 1;
4992 } else {
4993 sofia_clear_media_flag(profile, SCMF_DISABLE_HOLD)(profile)->media_flags[SCMF_DISABLE_HOLD] = 0;
4994 }
4995 } else if (!strcasecmp(var, "auto-jitterbuffer-msec") && !zstr(val)_zstr(val)) {
4996 int msec = atoi(val);
4997 if (msec > 19) {
4998 profile->jb_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4998)
;
4999 }
5000 } else if (!strcasecmp(var, "dtmf-type")) {
5001 if (val && !strcasecmp(val, "rfc2833")) {
5002 profile->dtmf_type = DTMF_2833;
5003 } else if (val && !strcasecmp(val, "info")) {
5004 profile->dtmf_type = DTMF_INFO;
5005 } else {
5006 profile->dtmf_type = DTMF_NONE;
5007 }
5008 } else if (!strcasecmp(var, "NDLB-force-rport")) {
5009 if (val && !strcasecmp(val, "safe")) {
5010 profile->server_rport_level = 3;
5011 profile->client_rport_level = 1;
5012 } else if (val && !strcasecmp(val, "disabled")) {
5013 profile->server_rport_level = 0;
5014 profile->client_rport_level = 0;
5015 } else if (val && !strcasecmp(val, "client-only")) {
5016 profile->client_rport_level = 1;
5017 } else if (val && !strcasecmp(val, "server-only")) {
5018 profile->client_rport_level = 0;
5019 profile->server_rport_level = 1;
5020 } else if (switch_true(val)) {
5021 profile->server_rport_level = 2;
5022 profile->client_rport_level = 1;
5023 }
5024 } else if (!strcasecmp(var, "auto-rtp-bugs")) {
5025 switch_core_media_parse_rtp_bugs(&profile->auto_rtp_bugs, val);
5026 } else if (!strcasecmp(var, "manual-rtp-bugs")) {
5027 switch_core_media_parse_rtp_bugs(&profile->manual_rtp_bugs, val);
5028 } else if (!strcasecmp(var, "manual-video-rtp-bugs")) {
5029 switch_core_media_parse_rtp_bugs(&profile->manual_video_rtp_bugs, val);
5030 } else if (!strcasecmp(var, "dbname")) {
5031 profile->dbname = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5031)
;
5032 } else if (!strcasecmp(var, "presence-hosts")) {
5033 profile->presence_hosts = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5033)
;
5034 } else if (!strcasecmp(var, "caller-id-type")) {
5035 profile->cid_type = sofia_cid_name2type(val);
5036 } else if (!strcasecmp(var, "record-template")) {
5037 profile->record_template = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5037)
;
5038 } else if (!strcasecmp(var, "record-path")) {
5039 profile->record_path = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5039)
;
5040 } else if (!strcasecmp(var, "inbound-no-media") || !strcasecmp(var, "inbound-bypass-media")) {
5041 if (switch_true(val)) {
5042 sofia_set_flag(profile, TFLAG_INB_NOMEDIA)(profile)->flags[TFLAG_INB_NOMEDIA] = 1;
5043 } else {
5044 sofia_clear_flag(profile, TFLAG_INB_NOMEDIA)(profile)->flags[TFLAG_INB_NOMEDIA] = 0;
5045 }
5046 } else if (!strcasecmp(var, "inbound-late-negotiation")) {
5047 if (switch_true(val)) {
5048 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
5049 } else {
5050 sofia_clear_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 0;
5051 }
5052 } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) {
5053 if (switch_true(val)) {
5054 sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)(profile)->pflags[PFLAG_RTP_NOTIMER_DURING_BRIDGE] = 1;
5055 } else {
5056 sofia_clear_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)(profile)->pflags[PFLAG_RTP_NOTIMER_DURING_BRIDGE] = 0;
5057 }
5058 } else if (!strcasecmp(var, "manual-redirect")) {
5059 if (switch_true(val)) {
5060 sofia_set_pflag(profile, PFLAG_MANUAL_REDIRECT)(profile)->pflags[PFLAG_MANUAL_REDIRECT] = 1;
5061 } else {
5062 sofia_clear_pflag(profile, PFLAG_MANUAL_REDIRECT)(profile)->pflags[PFLAG_MANUAL_REDIRECT] = 0;
5063 }
5064 } else if (!strcasecmp(var, "inbound-proxy-media")) {
5065 if (switch_true(val)) {
5066 sofia_set_flag(profile, TFLAG_PROXY_MEDIA)(profile)->flags[TFLAG_PROXY_MEDIA] = 1;
5067 } else {
5068 sofia_clear_flag(profile, TFLAG_PROXY_MEDIA)(profile)->flags[TFLAG_PROXY_MEDIA] = 0;
5069 }
5070 } else if (!strcasecmp(var, "inbound-zrtp-passthru")) {
5071 if (switch_true(val)) {
5072 sofia_set_flag(profile, TFLAG_ZRTP_PASSTHRU)(profile)->flags[TFLAG_ZRTP_PASSTHRU] = 1;
5073 } else {
5074 sofia_clear_flag(profile, TFLAG_ZRTP_PASSTHRU)(profile)->flags[TFLAG_ZRTP_PASSTHRU] = 0;
5075 }
5076 } else if (!strcasecmp(var, "force-subscription-expires") && !zstr(val)_zstr(val)) {
5077 int tmp = atoi(val);
5078 if (tmp > 0) {
5079 profile->force_subscription_expires = tmp;
5080 }
5081 } else if (!strcasecmp(var, "force-publish-expires") && !zstr(val)_zstr(val)) {
5082 int tmp = atoi(val);
5083 if (tmp > 0) {
5084 profile->force_publish_expires = tmp;
5085 }
5086 } else if (!strcasecmp(var, "send-message-query-on-register")) {
5087 if (switch_true(val)) {
5088 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 1;
5089 } else if (val && !strcasecmp(val, "first-only")) {
5090 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 0;
5091 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
1
;
5092 } else {
5093 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 0;
5094 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
0
;
5095 }
5096 } else if (!strcasecmp(var, "inbound-reg-in-new-thread") && val) {
5097 if (switch_true(val)) {
5098 sofia_set_pflag(profile, PFLAG_THREAD_PER_REG)(profile)->pflags[PFLAG_THREAD_PER_REG] = 1;
5099 } else {
5100 sofia_clear_pflag(profile, PFLAG_THREAD_PER_REG)(profile)->pflags[PFLAG_THREAD_PER_REG] = 0;
5101 }
5102 } else if (!strcasecmp(var, "inbound-use-callid-as-uuid")) {
5103 if (switch_true(val)) {
5104 sofia_set_pflag(profile, PFLAG_CALLID_AS_UUID)(profile)->pflags[PFLAG_CALLID_AS_UUID] = 1;
5105 } else {
5106 sofia_clear_pflag(profile, PFLAG_CALLID_AS_UUID)(profile)->pflags[PFLAG_CALLID_AS_UUID] = 0;
5107 }
5108 } else if (!strcasecmp(var, "outbound-use-uuid-as-callid")) {
5109 if (switch_true(val)) {
5110 sofia_set_pflag(profile, PFLAG_UUID_AS_CALLID)(profile)->pflags[PFLAG_UUID_AS_CALLID] = 1;
5111 } else {
5112 sofia_clear_pflag(profile, PFLAG_UUID_AS_CALLID)(profile)->pflags[PFLAG_UUID_AS_CALLID] = 0;
5113 }
5114 } else if (!strcasecmp(var, "track-calls")) {
5115 if (switch_true(val)) {
5116 sofia_set_pflag(profile, PFLAG_TRACK_CALLS)(profile)->pflags[PFLAG_TRACK_CALLS] = 1;
5117 }
5118 } else if (!strcasecmp(var, "NDLB-received-in-nat-reg-contact")) {
5119 if (switch_true(val)) {
5120 sofia_set_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)(profile)->pflags[PFLAG_RECIEVED_IN_NAT_REG_CONTACT] = 1;
5121 } else {
5122 sofia_clear_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)(profile)->pflags[PFLAG_RECIEVED_IN_NAT_REG_CONTACT] = 0;
5123 }
5124 } else if (!strcasecmp(var, "aggressive-nat-detection")) {
5125 if (switch_true(val)) {
5126 sofia_set_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)(profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] = 1;
5127 } else {
5128 sofia_clear_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)(profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] = 0;
5129 }
5130 } else if (!strcasecmp(var, "disable-rtp-auto-adjust")) {
5131 if (switch_true(val)) {
5132 sofia_set_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ)(profile)->media_flags[SCMF_DISABLE_RTP_AUTOADJ] = 1;
5133 } else {
5134 sofia_clear_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ)(profile)->media_flags[SCMF_DISABLE_RTP_AUTOADJ] = 0;
5135 }
5136 } else if (!strcasecmp(var, "NDLB-support-asterisk-missing-srtp-auth")) {
5137 if (switch_true(val)) {
5138 profile->mndlb |= SM_NDLB_DISABLE_SRTP_AUTH;
5139 } else {
5140 profile->mndlb &= ~SM_NDLB_DISABLE_SRTP_AUTH;
5141 }
5142 } else if (!strcasecmp(var, "user-agent-filter")) {
5143 profile->user_agent_filter = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5143)
;
5144 } else if (!strcasecmp(var, "max-registrations-per-extension") && !zstr(val)_zstr(val)) {
5145 profile->max_registrations_perext = atoi(val);
5146 } else if (!strcasecmp(var, "rfc2833-pt") && !zstr(val)_zstr(val)) {
5147 profile->te = (switch_payload_t) atoi(val);
5148 } 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)) {
5149 profile->cng_pt = (switch_payload_t) atoi(val);
5150 } else if (!strcasecmp(var, "sip-port") && !zstr(val)_zstr(val)) {
5151 if (!strcasecmp(val, "auto")) {
5152 sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_PORT] = 1;
5153 } else {
5154 profile->sip_port = (switch_port_t) atoi(val);
5155 if (!profile->extsipport) profile->extsipport = profile->sip_port;
5156 }
5157 } else if (!strcasecmp(var, "vad") && !zstr(val)_zstr(val)) {
5158 if (!strcasecmp(val, "in")) {
5159 profile->vflags |= VAD_IN;
5160 } else if (!strcasecmp(val, "out")) {
5161 profile->vflags |= VAD_OUT;
5162 } else if (!strcasecmp(val, "both")) {
5163 profile->vflags |= VAD_OUT | VAD_IN;
5164 } else if (strcasecmp(val, "none")) {
5165 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5165
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid option %s for VAD\n", val);
5166 }
5167 } else if (!strcasecmp(var, "ext-rtp-ip")) {
5168 if (!zstr(val)_zstr(val)) {
5169 char *ip = mod_sofia_globals.guess_ip;
5170
5171 if (!strcmp(val, "0.0.0.0")) {
5172 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5172
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n",
5173 mod_sofia_globals.guess_ip);
5174 } else if (!strcasecmp(val, "auto-nat")) {
5175 ip = NULL((void*)0);
5176 } else {
5177 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5178 sofia_clear_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 0;
5179 }
5180 if (ip) {
5181 if (!strncasecmp(ip, "autonat:", 8)) {
5182 profile->extrtpip = switch_core_strdup(profile->pool, ip + 8)switch_core_perform_strdup(profile->pool, ip + 8, "sofia.c"
, (const char *)__func__, 5182)
;
5183 if (zstr(profile->extsipip)_zstr(profile->extsipip)) {
5184 profile->extsipip = switch_core_strdup(profile->pool, profile->extrtpip)switch_core_perform_strdup(profile->pool, profile->extrtpip
, "sofia.c", (const char *)__func__, 5184)
;
5185 }
5186 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
5187 } else {
5188 profile->extrtpip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5188)
;
5189 }
5190 }
5191 } else {
5192 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5192
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid ext-rtp-ip\n");
5193 if (mod_sofia_globals.abort_on_empty_external_ip) {
5194 switch_goto_status(SWITCH_STATUS_GENERR, done)status = SWITCH_STATUS_GENERR; goto done;
5195 }
5196 }
5197 } else if (!strcasecmp(var, "rtp-ip")) {
5198 char *ip = mod_sofia_globals.guess_ip;
5199 char buf[64];
5200
5201 if (zstr(val)_zstr(val)) {
5202 ip = mod_sofia_globals.guess_ip;
5203 } else if (!strcmp(val, "0.0.0.0")) {
5204 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5204
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
5205 } else if (!strncasecmp(val, "interface:", 10)) {
5206 char *ifname = val+10;
5207 int family = AF_UNSPEC0;
5208 if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC0; }
5209 if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET2; }
5210 if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET610; }
5211 if (switch_find_interface_ip(buf, sizeof(buf), NULL((void*)0), ifname, family) == SWITCH_STATUS_SUCCESS) {
5212 ip = buf;
5213 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5213
, ((void*)0)
, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for rtp-ip\n", ip, val+10);
5214 } else {
5215 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5215
, ((void*)0)
, SWITCH_LOG_ERROR, "Unknown IP for interface %s for rtp-ip\n", val+10);
5216 }
5217 } else {
5218 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5219 }
5220
5221 if (strchr(ip, ':')) {
5222 if (profile->rtpip_index6 < MAX_RTPIP50) {
5223 profile->rtpip6[profile->rtpip_index6++] = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5223)
;
5224 } else {
5225 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5225
, ((void*)0)
, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
5226 }
5227 } else {
5228 if (profile->rtpip_index < MAX_RTPIP50) {
5229 profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5229)
;
5230 } else {
5231 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5231
, ((void*)0)
, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
5232 }
5233 }
5234 } else if (!strcasecmp(var, "sip-ip") && val) {
5235 char *ip = mod_sofia_globals.guess_ip;
5236 char buf[64];
5237
5238 if (!strcmp(val, "0.0.0.0")) {
5239 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5239
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
5240 } else if (!strncasecmp(val, "interface:", 10)) {
5241 char *ifname = val+10;
5242 int family = AF_UNSPEC0;
5243 if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC0; }
5244 if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET2; }
5245 if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET610; }
5246 if (switch_find_interface_ip(buf, sizeof(buf), NULL((void*)0), ifname, family) == SWITCH_STATUS_SUCCESS) {
5247 ip = buf;
5248 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5248
, ((void*)0)
, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for sip-ip\n", ip, val+10);
5249 } else {
5250 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5250
, ((void*)0)
, SWITCH_LOG_ERROR, "Unknown IP for interface %s for sip-ip\n", val+10);
5251 }
5252 } else {
5253 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5254 }
5255 profile->sipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5255)
;
5256 } else if (!strcasecmp(var, "ext-sip-port") && val) {
5257 int tmp = atoi(val);
5258 if (tmp > 0) profile->extsipport = (switch_port_t)tmp;
5259 } else if (!strcasecmp(var, "ext-sip-ip")) {
5260 if (!zstr(val)_zstr(val)) {
5261 char *ip = mod_sofia_globals.guess_ip;
5262 char stun_ip[50] = "";
5263 char *myip = stun_ip;
5264
5265 switch_copy_string(stun_ip, ip, sizeof(stun_ip));
5266
5267 if (!strcasecmp(val, "0.0.0.0")) {
5268 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5268
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n",
5269 mod_sofia_globals.guess_ip);
5270 } else if (!strcasecmp(val, "auto-nat")) {
5271 ip = NULL((void*)0);
5272 } else if (strcasecmp(val, "auto")) {
5273 if (sofia_glue_ext_address_lookup(profile, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
5274 ip = myip;
5275 sofia_clear_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 0;
5276 } else {
5277 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5277
, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to get external ip.\n");
5278 }
5279 }
5280 if (ip) {
5281 if (!strncasecmp(ip, "autonat:", 8)) {
5282 profile->extsipip = switch_core_strdup(profile->pool, ip + 8)switch_core_perform_strdup(profile->pool, ip + 8, "sofia.c"
, (const char *)__func__, 5282)
;
5283 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
5284 } else {
5285 profile->extsipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5285)
;
5286 }
5287 }
5288 } else {
5289 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5289
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid ext-sip-ip\n");
5290 switch_goto_status(SWITCH_STATUS_GENERR, done)status = SWITCH_STATUS_GENERR; goto done;
5291 }
5292 } else if (!strcasecmp(var, "local-network-acl")) {
5293 if (val && !strcasecmp(val, "none")) {
5294 profile->local_network = NULL((void*)0);
5295 } else {
5296 profile->local_network = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5296)
;
5297 }
5298 } else if (!strcasecmp(var, "force-register-domain")) {
5299 profile->reg_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5299)
;
5300 } else if (!strcasecmp(var, "force-register-db-domain")) {
5301 profile->reg_db_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5301)
;
5302 } else if (!strcasecmp(var, "force-subscription-domain")) {
5303 profile->sub_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5303)
;
5304 } else if (!strcasecmp(var, "bind-params")) {
5305 profile->bind_params = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5305)
;
5306 } else if (!strcasecmp(var, "sip-domain")) {
5307 profile->sipdomain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5307)
;
5308 } else if (!strcasecmp(var, "rtp-timer-name")) {
5309 profile->timer_name = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5309)
;
5310 } else if (!strcasecmp(var, "hold-music")) {
5311 profile->hold_music = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5311)
;
5312 } else if (!strcasecmp(var, "outbound-proxy") && val) {
5313 if (strncasecmp(val, "sip:", 4) && strncasecmp(val, "sips:", 5)) {
5314 profile->outbound_proxy = switch_core_sprintf(profile->pool, "sip:%s", val);
5315 } else {
5316 profile->outbound_proxy = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5316)
;
5317 }
5318 } else if (!strcasecmp(var, "rtcp-audio-interval-msec")) {
5319 profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5319)
;
5320 } else if (!strcasecmp(var, "rtcp-video-interval-msec")) {
5321 profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5321)
;
5322 } else if (!strcasecmp(var, "session-timeout") && !zstr(val)_zstr(val)) {
5323 int v_session_timeout = atoi(val);
5324 if (v_session_timeout >= 0) {
5325 profile->session_timeout = v_session_timeout;
5326 }
5327 } else if (!strcasecmp(var, "max-proceeding") && !zstr(val)_zstr(val)) {
5328 int v_max_proceeding = atoi(val);
5329 if (v_max_proceeding >= 0) {
5330 profile->max_proceeding = v_max_proceeding;
5331 }
5332 } else if (!strcasecmp(var, "rtp-timeout-sec") && !zstr(val)_zstr(val)) {
5333 int v = atoi(val);
5334 if (v >= 0) {
5335 profile->rtp_timeout_sec = v;
5336 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5336
, ((void*)0)
, SWITCH_LOG_WARNING,
5337 "rtp-timeout-sec deprecated use media_timeout variable.\n");
5338 }
5339 } else if (!strcasecmp(var, "rtp-hold-timeout-sec") && !zstr(val)_zstr(val)) {
5340 int v = atoi(val);
5341 if (v >= 0) {
5342 profile->rtp_hold_timeout_sec = v;
5343 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5343
, ((void*)0)
, SWITCH_LOG_WARNING,
5344 "rtp-hold-timeout-sec deprecated use media_hold_timeout variable.\n");
5345 }
5346 } else if (!strcasecmp(var, "disable-transfer")) {
5347 if (switch_true(val)) {
5348 profile->mflags &= ~MFLAG_REFER;
5349 } else {
5350 profile->mflags |= MFLAG_REFER;
5351 }
5352 } else if (!strcasecmp(var, "disable-register")) {
5353 if (switch_true(val)) {
5354 profile->mflags &= ~MFLAG_REGISTER;
5355 } else {
5356 profile->mflags |= MFLAG_REGISTER;
5357 }
5358 } else if (!strcasecmp(var, "media-option") && !zstr(val)_zstr(val)) {
5359 if (!strcasecmp(val, "resume-media-on-hold")) {
5360 profile->media_options |= MEDIA_OPT_MEDIA_ON_HOLD;
5361 } else if (!strcasecmp(val, "bypass-media-after-att-xfer")) {
5362 profile->media_options |= MEDIA_OPT_BYPASS_AFTER_ATT_XFER;
5363 } else if (!strcasecmp(val, "bypass-media-after-hold")) {
5364 if (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
5365 profile->media_options |= MEDIA_OPT_BYPASS_AFTER_HOLD;
5366 } else {
5367 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5367
, ((void*)0)
, SWITCH_LOG_ERROR,
5368 "bypass-media-after-hold can be set only with resume-media-on-hold media-option\n");
5369 }
5370 } else if (!strcasecmp(val, "none")) {
5371 profile->media_options = 0;
5372 }
5373 } else if (!strcasecmp(var, "pnp-provision-url")) {
5374 profile->pnp_prov_url = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5374)
;
5375 } else if (!strcasecmp(var, "manage-presence")) {
5376 if (val && !strcasecmp(val, "passive")) {
5377 profile->pres_type = PRES_TYPE_PASSIVE;
5378
5379 } else if (val && !strcasecmp(val, "pnp")) {
5380 profile->pres_type = PRES_TYPE_PNP;
5381 } else if (switch_true(val)) {
5382 profile->pres_type = PRES_TYPE_FULL;
5383 } else {
5384 profile->pres_type = 0;
5385 }
5386 } else if (!strcasecmp(var, "presence-hold-state")) {
5387 if (val && !strcasecmp(val, "confirmed")) {
5388 profile->pres_held_type = PRES_HELD_CONFIRMED;
5389 } else if (val && !strcasecmp(val, "terminated")) {
5390 profile->pres_held_type = PRES_HELD_TERMINATED;
5391 } else {
5392 profile->pres_held_type = 0;
5393 }
5394 } else if (!strcasecmp(var, "presence-privacy")) {
5395 if (switch_true(val)) {
5396 sofia_set_pflag(profile, PFLAG_PRESENCE_PRIVACY)(profile)->pflags[PFLAG_PRESENCE_PRIVACY] = 1;
5397 } else {
5398 sofia_clear_pflag(profile, PFLAG_PRESENCE_PRIVACY)(profile)->pflags[PFLAG_PRESENCE_PRIVACY] = 0;
5399 }
5400 } else if (!strcasecmp(var, "update-refresher")) {
5401 if (switch_true(val)) {
5402 sofia_set_pflag(profile, PFLAG_UPDATE_REFRESHER)(profile)->pflags[PFLAG_UPDATE_REFRESHER] = 1;
5403 } else {
5404 sofia_clear_pflag(profile, PFLAG_UPDATE_REFRESHER)(profile)->pflags[PFLAG_UPDATE_REFRESHER] = 0;
5405 }
5406 } else if (!strcasecmp(var, "rfc-7989")) {
5407 if (switch_true(val)) {
5408 sofia_set_pflag(profile, PFLAG_RFC7989_SESSION_ID)(profile)->pflags[PFLAG_RFC7989_SESSION_ID] = 1;
5409 } else {
5410 sofia_clear_pflag(profile, PFLAG_RFC7989_SESSION_ID)(profile)->pflags[PFLAG_RFC7989_SESSION_ID] = 0;
5411 }
5412 } else if (!strcasecmp(var, "rfc-7989-filter")) {
5413 profile->rfc7989_filter = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5413)
;
5414 } else if (!strcasecmp(var, "rfc-7989-force-old")) {
5415 if (switch_true(val)) {
5416 sofia_set_pflag(profile, PFLAG_RFC7989_FORCE_OLD)(profile)->pflags[PFLAG_RFC7989_FORCE_OLD] = 1;
5417 } else {
5418 sofia_clear_pflag(profile, PFLAG_RFC7989_FORCE_OLD)(profile)->pflags[PFLAG_RFC7989_FORCE_OLD] = 0;
5419 }
5420 } else if (!strcasecmp(var, "manage-shared-appearance")) {
5421 if (switch_true(val)) {
5422 sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 1;
5423 profile->pres_type = PRES_TYPE_FULL;
5424 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
5425
5426 } else if (val && !strcasecmp(val, "sylantro")) {
5427 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5427
, ((void*)0)
, SWITCH_LOG_ERROR,
5428 "Sylantro support has been removed.\n"
5429 "It was incomplete anyway, and we fully support the broadsoft SCA shared line spec.");
5430 sofia_clear_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 0;
5431 } else {
5432 sofia_clear_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 0;
5433 }
5434 } else if (!strcasecmp(var, "disable-srv")) {
5435 if (switch_true(val)) {
5436 sofia_set_pflag(profile, PFLAG_DISABLE_SRV)(profile)->pflags[PFLAG_DISABLE_SRV] = 1;
5437 } else {
5438 sofia_clear_pflag(profile, PFLAG_DISABLE_SRV)(profile)->pflags[PFLAG_DISABLE_SRV] = 0;
5439 }
5440 } else if (!strcasecmp(var, "disable-naptr")) {
5441 if (switch_true(val)) {
5442 sofia_set_pflag(profile, PFLAG_DISABLE_NAPTR)(profile)->pflags[PFLAG_DISABLE_NAPTR] = 1;
5443 } else {
5444 sofia_clear_pflag(profile, PFLAG_DISABLE_NAPTR)(profile)->pflags[PFLAG_DISABLE_NAPTR] = 0;
5445 }
5446 } else if (!strcasecmp(var, "disable-srv503")) {
5447 if (switch_true(val)) {
5448 sofia_set_pflag(profile, PFLAG_DISABLE_SRV503)(profile)->pflags[PFLAG_DISABLE_SRV503] = 1;
5449 } else {
5450 sofia_clear_pflag(profile, PFLAG_DISABLE_SRV503)(profile)->pflags[PFLAG_DISABLE_SRV503] = 0;
5451 }
5452 } else if (!strcasecmp(var, "unregister-on-options-fail")) {
5453 if (switch_true(val)) {
5454 sofia_set_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)(profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] = 1;
5455 } else {
5456 sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)(profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] = 0;
5457 }
5458 } else if (!strcasecmp(var, "sip-user-ping-max") && !zstr(val)_zstr(val)) {
5459 profile->sip_user_ping_max = atoi(val);
5460 } else if (!strcasecmp(var, "sip-user-ping-min") && !zstr(val)_zstr(val)) {
5461 profile->sip_user_ping_min = atoi(val);
5462 } else if (!strcasecmp(var, "require-secure-rtp")) {
5463 if (switch_true(val)) {
5464 sofia_set_pflag(profile, PFLAG_SECURE)(profile)->pflags[PFLAG_SECURE] = 1;
5465 } else {
5466 sofia_clear_pflag(profile, PFLAG_SECURE)(profile)->pflags[PFLAG_SECURE] = 0;
5467 }
5468 } else if (!strcasecmp(var, "auto-invite-100")) {
5469 if (switch_true(val)) {
5470 sofia_set_pflag(profile, PFLAG_AUTO_INVITE_100)(profile)->pflags[PFLAG_AUTO_INVITE_100] = 1;
5471 } else {
5472 sofia_clear_pflag(profile, PFLAG_AUTO_INVITE_100)(profile)->pflags[PFLAG_AUTO_INVITE_100] = 0;
5473 }
5474 } else {
5475 found = 0;
5476 }
5477 if (found) continue;
5478
5479 if (!strcasecmp(var, "multiple-registrations")) {
5480 if (val && !strcasecmp(val, "call-id")) {
5481 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
5482 } else if (val && (!strcasecmp(val, "contact") || switch_true(val))) {
5483 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
5484 sofia_set_pflag(profile, PFLAG_MULTIREG_CONTACT)(profile)->pflags[PFLAG_MULTIREG_CONTACT] = 1;
5485 } else if (!switch_true(val)) {
5486 sofia_clear_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 0;
5487 sofia_clear_pflag(profile, PFLAG_MULTIREG_CONTACT)(profile)->pflags[PFLAG_MULTIREG_CONTACT] = 0;
5488 }
5489 } else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) {
5490 if (switch_true(val)) {
5491 sofia_set_media_flag(profile, SCMF_SUPPRESS_CNG)(profile)->media_flags[SCMF_SUPPRESS_CNG] = 1;
5492 profile->cng_pt = 0;
5493 } else {
5494 sofia_clear_media_flag(profile, SCMF_SUPPRESS_CNG)(profile)->media_flags[SCMF_SUPPRESS_CNG] = 0;
5495 }
5496 } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
5497 if (switch_true(val)) {
5498 profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH;
5499 } else {
5500 profile->ndlb &= ~PFLAG_NDLB_BROKEN_AUTH_HASH;
5501 }
5502 } else if (!strcasecmp(var, "NDLB-sendrecv-in-session")) {
5503 if (switch_true(val)) {
5504 profile->mndlb |= SM_NDLB_SENDRECV_IN_SESSION;
5505 } else {
5506 profile->mndlb &= ~SM_NDLB_SENDRECV_IN_SESSION;
5507 }
5508 } else if (!strcasecmp(var, "NDLB-allow-bad-iananame")) {
5509 if (switch_true(val)) {
5510 profile->ndlb |= SM_NDLB_ALLOW_BAD_IANANAME;
5511 } else {
5512 profile->ndlb &= ~SM_NDLB_ALLOW_BAD_IANANAME;
5513 }
5514 } else if (!strcasecmp(var, "NDLB-expires-in-register-response")) {
5515 if (switch_true(val)) {
5516 profile->ndlb |= PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE;
5517 } else {
5518 profile->ndlb &= ~PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE;
5519 }
5520 } else if (!strcasecmp(var, "NDLB-allow-crypto-in-avp")) {
5521 if (switch_true(val)) {
5522 profile->mndlb |= SM_NDLB_ALLOW_CRYPTO_IN_AVP;
5523 } else {
5524 profile->mndlb &= ~SM_NDLB_ALLOW_CRYPTO_IN_AVP;
5525 }
5526 } else if (!strcasecmp(var, "NDLB-allow-nondup-sdp")) {
5527 if (switch_true(val)) {
5528 profile->mndlb |= SM_NDLB_ALLOW_NONDUP_SDP;
5529 } else {
5530 profile->mndlb &= ~SM_NDLB_ALLOW_NONDUP_SDP;
5531 }
5532 } else if (!strcasecmp(var, "pass-rfc2833")) {
5533 if (switch_true(val)) {
5534 sofia_set_pflag(profile, PFLAG_PASS_RFC2833)(profile)->pflags[PFLAG_PASS_RFC2833] = 1;
5535 } else {
5536 sofia_clear_pflag(profile, PFLAG_PASS_RFC2833)(profile)->pflags[PFLAG_PASS_RFC2833] = 0;
5537 }
5538 } else if (!strcasecmp(var, "rtp-autofix-timing")) {
5539 if (switch_true(val)) {
5540 sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 1;
5541 } else {
5542 sofia_clear_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 0;
5543 }
5544 } else if (!strcasecmp(var, "contact-user")) {
5545 profile->contact_user = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5545)
;
5546 } else if (!strcasecmp(var, "nat-options-ping")) {
5547 if (val && !strcasecmp(val, "udp-only")) {
5548 sofia_set_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_UDP_NAT_OPTIONS_PING] = 1;
5549 } else if (switch_true(val)) {
5550 sofia_set_pflag(profile, PFLAG_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_NAT_OPTIONS_PING] = 1;
5551 } else {
5552 sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_NAT_OPTIONS_PING] = 0;
5553 sofia_clear_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_UDP_NAT_OPTIONS_PING] = 0;
5554 }
5555 } else if (!strcasecmp(var, "all-reg-options-ping")) {
5556 if (switch_true(val)) {
5557 sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)(profile)->pflags[PFLAG_ALL_REG_OPTIONS_PING] = 1;
5558 } else {
5559 sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)(profile)->pflags[PFLAG_ALL_REG_OPTIONS_PING] = 0;
5560 }
5561 } else if (!strcasecmp(var, "inbound-codec-negotiation")) {
5562 if (val && !strcasecmp(val, "greedy")) {
5563 sofia_set_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 1;
5564 } else if (val && !strcasecmp(val, "scrooge")) {
5565 sofia_set_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 1;
5566 sofia_set_media_flag(profile, SCMF_CODEC_SCROOGE)(profile)->media_flags[SCMF_CODEC_SCROOGE] = 1;
5567 } else {
5568 sofia_clear_media_flag(profile, SCMF_CODEC_SCROOGE)(profile)->media_flags[SCMF_CODEC_SCROOGE] = 0;
5569 sofia_clear_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 0;
5570 }
5571 } else if (!strcasecmp(var, "disable-transcoding")) {
5572 if (switch_true(val)) {
5573 sofia_set_media_flag(profile, SCMF_DISABLE_TRANSCODING)(profile)->media_flags[SCMF_DISABLE_TRANSCODING] = 1;
5574 } else {
5575 sofia_clear_media_flag(profile, SCMF_DISABLE_TRANSCODING)(profile)->media_flags[SCMF_DISABLE_TRANSCODING] = 0;
5576 }
5577 } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) {
5578 if (switch_true(val)) {
5579 sofia_set_media_flag(profile, SCMF_REWRITE_TIMESTAMPS)(profile)->media_flags[SCMF_REWRITE_TIMESTAMPS] = 1;
5580 } else {
5581 sofia_clear_media_flag(profile, SCMF_REWRITE_TIMESTAMPS)(profile)->media_flags[SCMF_REWRITE_TIMESTAMPS] = 0;
5582 }
5583 } else if (!strcasecmp(var, "auth-calls")) {
5584 if (switch_true(val)) {
5585 sofia_set_pflag(profile, PFLAG_AUTH_CALLS)(profile)->pflags[PFLAG_AUTH_CALLS] = 1;
5586 } else {
5587 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS)(profile)->pflags[PFLAG_AUTH_CALLS] = 0;
5588 }
5589 } else if (!strcasecmp(var, "auth-messages")) {
5590 auth_messages_value = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5590)
;
5591 } else if (!strcasecmp(var, "disable-auth-messages")) {
5592 if (switch_true(val)) {
5593 sofia_clear_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 0;
5594 } else {
5595 sofia_set_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 1;
5596 }
5597
5598 disable_message_auth_flag = 1;
5599 } else if (!strcasecmp(var, "auth-subscriptions")) {
5600 auth_subscriptions_value = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5600)
;
5601 } else if (!strcasecmp(var, "disable-auth-subscriptions")) {
5602 if (switch_true(val)) {
5603 sofia_clear_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 0;
5604 } else {
5605 sofia_set_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 1;
5606 }
5607
5608 disable_subscription_auth_flag = 1;
5609 } else if (!strcasecmp(var, "extended-info-parsing")) {
5610 if (switch_true(val)) {
5611 sofia_set_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)(profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] = 1;
5612 } else {
5613 sofia_clear_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)(profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] = 0;
5614 }
5615 } else if (!strcasecmp(var, "nonce-ttl") && !zstr(val)_zstr(val)) {
5616 profile->nonce_ttl = atoi(val);
5617 } else if (!strcasecmp(var, "max-auth-validity") && !zstr(val)_zstr(val)) {
5618 profile->max_auth_validity = atoi(val);
5619 } else if (!strcasecmp(var, "auth-require-user")) {
5620 if (switch_true(val)) {
5621 sofia_set_pflag(profile, PFLAG_AUTH_REQUIRE_USER)(profile)->pflags[PFLAG_AUTH_REQUIRE_USER] = 1;
5622 } else {
5623 sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER)(profile)->pflags[PFLAG_AUTH_REQUIRE_USER] = 0;
5624 }
5625 } else if (!strcasecmp(var, "accept-blind-reg")) {
5626 if (switch_true(val)) {
5627 sofia_set_pflag(profile, PFLAG_BLIND_REG)(profile)->pflags[PFLAG_BLIND_REG] = 1;
5628 } else {
5629 sofia_clear_pflag(profile, PFLAG_BLIND_REG)(profile)->pflags[PFLAG_BLIND_REG] = 0;
5630 }
5631 } else if (!strcasecmp(var, "3pcc-reinvite-bridged-on-ack")) {
5632 if (switch_true(val)) {
5633 sofia_set_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)(profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] = 1;
5634 } else {
5635 sofia_clear_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)(profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] = 0;
5636 }
5637 } else if (!strcasecmp(var, "enable-3pcc")) {
5638 if (switch_true(val)) {
5639 sofia_set_pflag(profile, PFLAG_3PCC)(profile)->pflags[PFLAG_3PCC] = 1;
5640 } else if (!strcasecmp(val, "proxy")) {
5641 sofia_set_pflag(profile, PFLAG_3PCC_PROXY)(profile)->pflags[PFLAG_3PCC_PROXY] = 1;
5642 }
5643 } else if (!strcasecmp(var, "accept-blind-auth")) {
5644 if (switch_true(val)) {
5645 sofia_set_pflag(profile, PFLAG_BLIND_AUTH)(profile)->pflags[PFLAG_BLIND_AUTH] = 1;
5646 } else {
5647 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH)(profile)->pflags[PFLAG_BLIND_AUTH] = 0;
5648 }
5649 } else if (!strcasecmp(var, "auth-all-packets")) {
5650 if (switch_true(val)) {
5651 sofia_set_pflag(profile, PFLAG_AUTH_ALL)(profile)->pflags[PFLAG_AUTH_ALL] = 1;
5652 } else {
5653 sofia_clear_pflag(profile, PFLAG_AUTH_ALL)(profile)->pflags[PFLAG_AUTH_ALL] = 0;
5654 }
5655 } else if (!strcasecmp(var, "full-id-in-dialplan")) {
5656 if (switch_true(val)) {
5657 sofia_set_pflag(profile, PFLAG_FULL_ID)(profile)->pflags[PFLAG_FULL_ID] = 1;
5658 } else {
5659 sofia_clear_pflag(profile, PFLAG_FULL_ID)(profile)->pflags[PFLAG_FULL_ID] = 0;
5660 }
5661 } else if (!strcasecmp(var, "inbound-reg-force-matching-username")) {
5662 if (switch_true(val)) {
5663 sofia_set_pflag(profile, PFLAG_CHECKUSER)(profile)->pflags[PFLAG_CHECKUSER] = 1;
5664 } else {
5665 sofia_clear_pflag(profile, PFLAG_CHECKUSER)(profile)->pflags[PFLAG_CHECKUSER] = 0;
5666 }
5667 } else if (!strcasecmp(var, "enable-timer")) {
5668 if (!switch_true(val)) {
5669 sofia_set_pflag(profile, PFLAG_DISABLE_TIMER)(profile)->pflags[PFLAG_DISABLE_TIMER] = 1;
5670 } else {
5671 sofia_clear_pflag(profile, PFLAG_DISABLE_TIMER)(profile)->pflags[PFLAG_DISABLE_TIMER] = 0;
5672 }
5673 } else if (!strcasecmp(var, "enable-rfc-5626")) {
5674 if (switch_true(val)) {
5675 sofia_set_pflag(profile, PFLAG_ENABLE_RFC5626)(profile)->pflags[PFLAG_ENABLE_RFC5626] = 1;
5676 } else {
5677 sofia_clear_pflag(profile, PFLAG_ENABLE_RFC5626)(profile)->pflags[PFLAG_ENABLE_RFC5626] = 0;
5678 }
5679 } else if (!strcasecmp(var, "minimum-session-expires") && !zstr(val)_zstr(val)) {
5680 profile->minimum_session_expires = atoi(val);
5681 /* per RFC 4028: minimum_session_expires must be > 90 */
5682 if (profile->minimum_session_expires < 90) {
5683 profile->minimum_session_expires = 90;
5684 }
5685 } else if (!strcasecmp(var, "enable-100rel")) {
5686 if (switch_true(val)) {
5687 sofia_clear_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 0;
5688 } else {
5689 sofia_set_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 1;
5690 }
5691 } else if (!strcasecmp(var, "enable-compact-headers")) {
5692 if (switch_true(val)) {
5693 sofia_set_pflag(profile, PFLAG_SIPCOMPACT)(profile)->pflags[PFLAG_SIPCOMPACT] = 1;
5694 } else {
5695 sofia_clear_pflag(profile, PFLAG_SIPCOMPACT)(profile)->pflags[PFLAG_SIPCOMPACT] = 0;
5696 }
5697 } else if (!strcasecmp(var, "pass-callee-id")) {
5698 if (switch_true(val)) {
5699 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
5700 } else {
5701 sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 0;
5702 }
5703 } else if (!strcasecmp(var, "enable-soa")) {
5704 if (switch_true(val)) {
5705 sofia_set_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 1;
5706 } else {
5707 sofia_clear_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 0;
5708 }
5709 } else if (!strcasecmp(var, "parse-all-invite-headers")) {
5710 if (switch_true(val)) {
5711 sofia_set_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)(profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] = 1;
5712 } else {
5713 sofia_clear_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)(profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] = 0;
5714 }
5715 } else if (!strcasecmp(var, "bitpacking")) {
5716 if (val && !strcasecmp(val, "aal2")) {
5717 profile->codec_flags = SWITCH_CODEC_FLAG_AAL2;
5718 } else {
5719 profile->codec_flags = 0;
5720 }
5721 } else if (!strcasecmp(var, "username")) {
5722 profile->sdp_username = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5722)
;
5723 } else if (!strcasecmp(var, "context")) {
5724 profile->context = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5724)
;
5725 } else if (!strcasecmp(var, "apply-nat-acl") && !zstr(val)_zstr(val)) {
5726 if (!strcasecmp(val,"none")) {
5727 profile->nat_acl_count = 0;
5728 } else if (profile->nat_acl_count < SOFIA_MAX_ACL100) {
5729 if (!profile->extsipip && profile->sipip && switch_check_network_list_ip(profile->sipip, val)switch_check_network_list_ip_token(profile->sipip, val, ((
void*)0))
) {
5730 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5730
, ((void*)0)
, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val);
5731 } else {
5732 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__, 5732)
;
5733 }
5734 } else {
5735 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5735
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5736 }
5737 } else if (!strcasecmp(var, "apply-inbound-acl") && !zstr(val)_zstr(val)) {
5738 if (!strcasecmp(val,"none")) {
5739 profile->acl_count = 0;
5740 } else if (profile->acl_count < SOFIA_MAX_ACL100) {
5741 char *list, *pass = NULL((void*)0), *fail = NULL((void*)0);
5742
5743 list = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5743)
;
5744
5745 if ((pass = strchr(list, ':'))) {
5746 *pass++ = '\0';
5747 if ((fail = strchr(pass, ':'))) {
5748 *fail++ = '\0';
5749 }
5750
5751 if (zstr(pass)_zstr(pass)) pass = NULL((void*)0);
5752 if (zstr(fail)_zstr(fail)) fail = NULL((void*)0);
5753
5754 profile->acl_pass_context[profile->acl_count] = pass;
5755 profile->acl_fail_context[profile->acl_count] = fail;
5756 }
5757
5758 profile->acl[profile->acl_count++] = list;
5759
5760 } else {
5761 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5761
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5762 }
5763 } else if (!strcasecmp(var, "apply-proxy-acl") && !zstr(val)_zstr(val)) {
5764 if (!strcasecmp(val,"none")) {
5765 profile->proxy_acl_count = 0;
5766 } else if (profile->proxy_acl_count < SOFIA_MAX_ACL100) {
5767 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__, 5767)
;
5768 } else {
5769 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5769
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5770 }
5771 } else if (!strcasecmp(var, "apply-register-acl") && !zstr(val)_zstr(val)) {
5772 if (!strcasecmp(val,"none")) {
5773 profile->reg_acl_count = 0;
5774 } else if (profile->reg_acl_count < SOFIA_MAX_ACL100) {
5775 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__, 5775)
;
5776 } else {
5777 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5777
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5778 }
5779
5780 } else if (!strcasecmp(var, "apply-candidate-acl") && !zstr(val)_zstr(val)) {
5781 if (!strcasecmp(val,"none")) {
5782 profile->cand_acl_count = 0;
5783 } else if (profile->cand_acl_count < SWITCH_MAX_CAND_ACL25) {
5784 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__, 5784)
;
5785 } else {
5786 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5786
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SWITCH_MAX_CAND_ACL25);
5787 }
5788 } else if (!strcasecmp(var, "alias")) {
5789 sip_alias_node_t *node;
5790 if (zstr(val)_zstr(val)) {
5791 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5791
, ((void*)0)
, SWITCH_LOG_DEBUG, "Alias Param has no data...\n");
5792 } else {
5793 if ((node = switch_core_alloc(profile->pool, sizeof(*node))switch_core_perform_alloc(profile->pool, sizeof(*node), "sofia.c"
, (const char *)__func__, 5793)
)) {
5794 if ((node->url = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5794)
)) {
5795 node->next = profile->aliases;
5796 profile->aliases = node;
5797 }
5798 }
5799 }
5800 } else if (!strcasecmp(var, "dialplan")) {
5801 profile->dialplan = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5801)
;
5802 } else if (!strcasecmp(var, "max-calls") && !zstr(val)_zstr(val)) {
5803 profile->max_calls = atoi(val);
5804 } else if (!strcasecmp(var, "codec-prefs")) {
5805 profile->inbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5805)
;
5806 profile->outbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5806)
;
5807 } else if (!strcasecmp(var, "inbound-codec-prefs")) {
5808 profile->inbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5808)
;
5809 } else if (!strcasecmp(var, "outbound-codec-prefs")) {
5810 profile->outbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5810)
;
5811 } else if (!strcasecmp(var, "challenge-realm")) {
5812 profile->challenge_realm = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5812)
;
5813 } else if (!strcasecmp(var, "dtmf-duration") && !zstr(val)_zstr(val)) {
5814 uint32_t dur = atoi(val);
5815 if (dur >= switch_core_min_dtmf_duration(0) && dur <= switch_core_max_dtmf_duration(0)) {
5816 profile->dtmf_duration = dur;
5817 } else {
5818 profile->dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION2000;
5819 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5819
, ((void*)0)
, SWITCH_LOG_DEBUG, "Duration out of bounds, using default of %d!\n",
5820 SWITCH_DEFAULT_DTMF_DURATION2000);
5821 }
5822
5823 } else if (!strcasecmp(var, "ws-binding") && !zstr(val)_zstr(val)) {
5824 int tmp;
5825 char *p;
5826
5827 profile->ws_ip = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5827)
;
5828 if ((p = strrchr(profile->ws_ip, ':'))) {
5829 *p++ = '\0';
5830
5831 if ((tmp = atol(p)) && tmp > 0) {
5832 profile->ws_port = (switch_port_t) tmp;
5833 }
5834 }
5835
5836 } else if (!strcasecmp(var, "wss-binding") && !zstr(val)_zstr(val)) {
5837 int tmp;
5838 char *p;
5839
5840 profile->wss_ip = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5840)
;
5841 if ((p = strrchr(profile->wss_ip, ':'))) {
5842 *p++ = '\0';
5843
5844 if ((tmp = atol(p)) && tmp > 0) {
5845 profile->wss_port = (switch_port_t) tmp;
5846 }
5847 }
5848
5849 /*
5850 * handle TLS params #1
5851 */
5852 } else if (!strcasecmp(var, "tls")) {
5853 if (switch_true(val)) {
5854 sofia_set_pflag(profile, PFLAG_TLS)(profile)->pflags[PFLAG_TLS] = 1;
5855 if (profile->tls_bind_params) {
5856 if (!switch_stristr("transport=tls", profile->tls_bind_params)) {
5857 profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", profile->tls_bind_params);
5858 }
5859 } else {
5860 profile->tls_bind_params = switch_core_strdup(profile->pool, "transport=tls")switch_core_perform_strdup(profile->pool, "transport=tls",
"sofia.c", (const char *)__func__, 5860)
;
5861 }
5862 } else {
5863 sofia_clear_pflag(profile, PFLAG_TLS)(profile)->pflags[PFLAG_TLS] = 0;
5864 }
5865 } else if (!strcasecmp(var, "tls-bind-params")) {
5866 if (val && switch_stristr("transport=tls", val)) {
5867 profile->tls_bind_params = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5867)
;
5868 } else {
5869 profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", val);
5870 }
5871 } else if (!strcasecmp(var, "tls-only")) {
5872 profile->tls_only = switch_true(val);
5873 } else if (!strcasecmp(var, "tls-verify-date")) {
5874 profile->tls_verify_date = switch_true(val);
5875 } else if (!strcasecmp(var, "tls-verify-depth") && !zstr(val)_zstr(val)) {
5876 profile->tls_verify_depth = atoi(val);
5877 } else if (!strcasecmp(var, "tls-verify-policy")) {
5878 profile->tls_verify_policy = sofia_glue_str2tls_verify_policy(val);
5879 } else if (!strcasecmp(var, "tls-sip-port") && !zstr(val)_zstr(val)) {
5880 if (!strcasecmp(val, "auto")) {
5881 sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] = 1;
5882 } else {
5883 sofia_clear_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] = 0;
5884 profile->tls_sip_port = (switch_port_t) atoi(val);
5885 }
5886 } else if (!strcasecmp(var, "tls-cert-dir") && !zstr(val)_zstr(val)) {
5887 profile->tls_cert_dir = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5887)
;
5888 } else if (!strcasecmp(var, "tls-passphrase") && !zstr(val)_zstr(val)) {
5889 profile->tls_passphrase = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5889)
;
5890 } else if (!strcasecmp(var, "tls-verify-in-subjects") && !zstr(val)_zstr(val)) {
5891 profile->tls_verify_in_subjects_str = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5891)
;
5892 } else if (!strcasecmp(var, "tls-ciphers") && !zstr(val)_zstr(val)) {
5893 profile->tls_ciphers = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5893)
;
5894 } else if (!strcasecmp(var, "tls-version") && !zstr(val)_zstr(val)) {
5895 char *ps = val, *pe = val;
5896 profile->tls_version = 0;
5897 while (ps && *pe) {
5898 int n;
5899 pe = strchr(ps,',');
5900 if (!pe && !(pe = memchr(ps,0,1024))) break;
5901 n = (int)(pe-ps);
5902 if (n==5 && !strncasecmp(ps, "sslv2", n))
5903 profile->tls_version |= SOFIA_TLS_VERSION_SSLv2;
5904 if (n==5 && !strncasecmp(ps, "sslv3", n))
5905 profile->tls_version |= SOFIA_TLS_VERSION_SSLv3;
5906 if (n==6 && !strncasecmp(ps, "sslv23", n))
5907 profile->tls_version |= SOFIA_TLS_VERSION_SSLv2 | SOFIA_TLS_VERSION_SSLv3;
5908 if (n==5 && !strncasecmp(ps, "tlsv1", n))
5909 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1;
5910 if (n==7 && !strncasecmp(ps, "tlsv1.1", n))
5911 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_1;
5912 if (n==7 && !strncasecmp(ps, "tlsv1.2", n))
5913 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
5914 ps=pe+1;
5915 }
5916 } else if (!strcasecmp(var, "tls-timeout") && !zstr(val)_zstr(val)) {
5917 int v = atoi(val);
5918 profile->tls_timeout = v > 0 ? (unsigned int)v : 300;
5919 } else if (!strcasecmp(var, "timer-T1") && !zstr(val)_zstr(val)) {
5920 int v = atoi(val);
5921 if (v > 0) {
5922 profile->timer_t1 = v;
5923 } else {
5924 profile->timer_t1 = 500;
5925 }
5926 } else if (!strcasecmp(var, "timer-T1X64") && !zstr(val)_zstr(val)) {
5927 int v = atoi(val);
5928 if (v > 0) {
5929 profile->timer_t1x64 = v;
5930 } else {
5931 profile->timer_t1x64 = 32000;
5932 }
5933 } else if (!strcasecmp(var, "timer-T2") && !zstr(val)_zstr(val)) {
5934 int v = atoi(val);
5935 if (v > 0) {
5936 profile->timer_t2 = v;
5937 } else {
5938 profile->timer_t2 = 4000;
5939 }
5940 } else if (!strcasecmp(var, "timer-T4") && !zstr(val)_zstr(val)) {
5941 int v = atoi(val);
5942 if (v > 0) {
5943 profile->timer_t4 = v;
5944 } else {
5945 profile->timer_t4 = 4000;
5946 }
5947 } else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) {
5948 if (switch_true(val)) {
5949 sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)(profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] = 1;
5950 } else {
5951 sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)(profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] = 0;
5952 }
5953 } else if (!strcasecmp(var, "sip-expires-late-margin") && !zstr(val)_zstr(val)) {
5954 int32_t sip_expires_late_margin = atoi(val);
5955 if (sip_expires_late_margin >= 0) {
5956 profile->sip_expires_late_margin = sip_expires_late_margin;
5957 } else {
5958 profile->sip_expires_late_margin = 60;
5959 }
5960 } else if (!strcasecmp(var, "sip-force-expires-min") && !zstr(val)_zstr(val)) {
5961 int32_t sip_force_expires_min = atoi(val);
5962 if (sip_force_expires_min >= 0) {
5963 profile->sip_force_expires_min = sip_force_expires_min;
5964 } else {
5965 profile->sip_force_expires_min = 0;
5966 }
5967 } else if (!strcasecmp(var, "sip-force-expires-max") && !zstr(val)_zstr(val)) {
5968 int32_t sip_force_expires_max = atoi(val);
5969 if (sip_force_expires_max >= 0) {
5970 profile->sip_force_expires_max = sip_force_expires_max;
5971 } else {
5972 profile->sip_force_expires_max = 0;
5973 }
5974 } else if (!strcasecmp(var, "sip-force-expires") && !zstr(val)_zstr(val)) {
5975 int32_t sip_force_expires = atoi(val);
5976 if (sip_force_expires >= 0) {
5977 profile->sip_force_expires = sip_force_expires;
5978 } else {
5979 profile->sip_force_expires = 0;
5980 }
5981 } else if (!strcasecmp(var, "sip-expires-max-deviation") && !zstr(val)_zstr(val)) {
5982 int32_t sip_expires_max_deviation = atoi(val);
5983 if (sip_expires_max_deviation >= 0) {
5984 profile->sip_expires_max_deviation = sip_expires_max_deviation;
5985 } else {
5986 profile->sip_expires_max_deviation = 0;
5987 }
5988 } else if (!strcasecmp(var, "sip-subscription-max-deviation") && !zstr(val)_zstr(val)) {
5989 int32_t sip_subscription_max_deviation = atoi(val);
5990 if (sip_subscription_max_deviation >= 0) {
5991 profile->sip_subscription_max_deviation = sip_subscription_max_deviation;
5992 } else {
5993 profile->sip_subscription_max_deviation = 0;
5994 }
5995 } else if (!strcasecmp(var, "reuse-connections")) {
5996 switch_bool_t value = switch_true(val);
5997 if (!value) {
5998 sofia_set_pflag(profile, PFLAG_NO_CONNECTION_REUSE)(profile)->pflags[PFLAG_NO_CONNECTION_REUSE] = 1;
5999 } else {
6000 sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE)(profile)->pflags[PFLAG_NO_CONNECTION_REUSE] = 0;
6001 }
6002 } else if (!strcasecmp(var, "p-asserted-id-parse")) {
6003 if (!val) {
6004 profile->paid_type = PAID_DEFAULT;
6005 } else if (!strncasecmp(val, "default", 7)) {
6006 profile->paid_type = PAID_DEFAULT;
6007 } else if (!strncasecmp(val, "user-only", 9)) {
6008 profile->paid_type = PAID_USER;
6009 } else if (!strncasecmp(val, "user-domain", 11)) {
6010 profile->paid_type = PAID_USER_DOMAIN;
6011 } else if (!strncasecmp(val, "verbatim", 8)) {
6012 profile->paid_type = PAID_VERBATIM;
6013 } else {
6014 profile->paid_type = PAID_DEFAULT;
6015 }
6016 } else if (!strcasecmp(var, "channel-xml-fetch-on-nightmare-transfer")) {
6017 if(switch_true(val)) {
6018 sofia_set_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)(profile)->pflags[PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER
] = 1
;
6019 } else {
6020 sofia_clear_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)(profile)->pflags[PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER
] = 0
;
6021 }
6022 } else if (!strcasecmp(var, "make-every-transfer-a-nightmare")) {
6023 if(switch_true(val)) {
6024 sofia_set_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)(profile)->pflags[PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE] =
1
;
6025 } else {
6026 sofia_clear_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)(profile)->pflags[PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE] =
0
;
6027 }
6028 } else if (!strcasecmp(var, "fire-transfer-events")) {
6029 if(switch_true(val)) {
6030 sofia_set_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)(profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] = 1;
6031 } else {
6032 sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)(profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] = 0;
6033 }
6034 } else if (!strcasecmp(var, "enforce-blind-auth-result")) {
6035 if(switch_true(val)) {
6036 sofia_set_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)(profile)->pflags[PFLAG_BLIND_AUTH_ENFORCE_RESULT] = 1;
6037 } else {
6038 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)(profile)->pflags[PFLAG_BLIND_AUTH_ENFORCE_RESULT] = 0;
6039 }
6040 } else if (!strcasecmp(var, "blind-auth-reply-403")) {
6041 if(switch_true(val)) {
6042 sofia_set_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)(profile)->pflags[PFLAG_BLIND_AUTH_REPLY_403] = 1;
6043 } else {
6044 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)(profile)->pflags[PFLAG_BLIND_AUTH_REPLY_403] = 0;
6045 }
6046 } else if (!strcasecmp(var, "auth-calls-acl-only")) {
6047 if(switch_true(val)) {
6048 sofia_set_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)(profile)->pflags[PFLAG_AUTH_CALLS_ACL_ONLY] = 1;
6049 } else {
6050 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)(profile)->pflags[PFLAG_AUTH_CALLS_ACL_ONLY] = 0;
6051 }
6052 } else if (!strcasecmp(var, "use-port-for-acl-check")) {
6053 if(switch_true(val)) {
6054 sofia_set_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK)(profile)->pflags[PFLAG_USE_PORT_FOR_ACL_CHECK] = 1;
6055 } else {
6056 sofia_clear_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK)(profile)->pflags[PFLAG_USE_PORT_FOR_ACL_CHECK] = 0;
6057 }
6058 } else if (!strcasecmp(var, "apply-inbound-acl-x-token")) {
6059 profile->acl_inbound_x_token_header = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 6059)
;
6060 } else if (!strcasecmp(var, "apply-proxy-acl-x-token")) {
6061 profile->acl_proxy_x_token_header = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 6061)
;
6062 } else if (!strcasecmp(var, "proxy-hold")) {
6063 if(switch_true(val)) {
6064 sofia_set_pflag(profile, PFLAG_PROXY_HOLD)(profile)->pflags[PFLAG_PROXY_HOLD] = 1;
6065 } else {
6066 sofia_clear_pflag(profile, PFLAG_PROXY_HOLD)(profile)->pflags[PFLAG_PROXY_HOLD] = 0;
6067 }
6068 } else if (!strcasecmp(var, "proxy-info")) {
6069 if(switch_true(val)) {
6070 sofia_set_pflag(profile, PFLAG_PROXY_INFO)(profile)->pflags[PFLAG_PROXY_INFO] = 1;
6071 } else {
6072 sofia_clear_pflag(profile, PFLAG_PROXY_INFO)(profile)->pflags[PFLAG_PROXY_INFO] = 0;
6073 }
6074 } else if (!strcasecmp(var, "proxy-message")) {
6075 if(switch_true(val)) {
6076 sofia_set_pflag(profile, PFLAG_PROXY_MESSAGE)(profile)->pflags[PFLAG_PROXY_MESSAGE] = 1;
6077 } else {
6078 sofia_clear_pflag(profile, PFLAG_PROXY_MESSAGE)(profile)->pflags[PFLAG_PROXY_MESSAGE] = 0;
6079 }
6080 } else if (!strcasecmp(var, "proxy-notify-events")) {
6081 profile->proxy_notify_events = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 6081)
;
6082 } else if (!strcasecmp(var, "proxy-info-content-types")) {
6083 profile->proxy_info_content_types = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 6083)
;
6084 } else if (!strcasecmp(var, "rfc8760-auth-algorithms")) {
6085 char *algs_arr[100] = { 0 };
6086 uint8_t algs = switch_separate_string(val, ',', algs_arr, (sizeof(algs_arr) / sizeof(algs_arr[0])));
6087 if (algs && algs < SOFIA_MAX_REG_ALGS7) {
6088 sofia_auth_algs_t temp;
6089 int i, j = 0;
6090 for (i = 0; i < algs && algs_arr[i]; i++) {
6091 temp = sofia_alg_str2id(algs_arr[i], SWITCH_TRUE);
6092 if (temp != ALG_NONE) {
6093 profile->auth_algs[j] = temp;
6094 j++;
6095 }
6096 }
6097 profile->rfc8760_algs_count = j;
6098 for (i = 0; i < profile->rfc8760_algs_count; i++) {
6099 for (j = i + 1; j < profile->rfc8760_algs_count; j++) {
6100 /* when adding algs: algs must be kept in priority order in the enum */
6101 if (profile->auth_algs[i] < profile->auth_algs[j])
6102 {
6103 temp = profile->auth_algs[i];
6104 profile->auth_algs[i] = profile->auth_algs[j];
6105 profile->auth_algs[j] = temp;
6106 }
6107 }
6108 }
6109 }
6110 }
6111 }
6112
6113 if (!disable_message_auth_flag) {
6114 if (!auth_messages_value || switch_true(auth_messages_value)) {
6115 sofia_set_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 1;
6116 } else {
6117 sofia_clear_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 0;
6118 }
6119 }
6120
6121 if (!disable_subscription_auth_flag) {
6122 if (!auth_subscriptions_value || switch_true(auth_subscriptions_value)) {
6123 sofia_set_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 1;
6124 } else {
6125 sofia_clear_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 0;
6126 }
6127 }
6128
6129 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)) {
6130 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6130
, ((void*)0)
, SWITCH_LOG_WARNING, "ZRTP passthrough 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_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)) {
6135 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6135
, ((void*)0)
, SWITCH_LOG_WARNING, "inbound-bypass-media implictly enables inbound-late-negotiation\n");
6136 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
6137 }
6138
6139 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)) {
6140 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6140
, ((void*)0)
, SWITCH_LOG_WARNING, "send-display-update=true is set, but we can't comply because allow-update=false\n");
6141 sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 0;
6142 }
6143 if (sofia_test_pflag(profile, PFLAG_PROXY_HOLD)((profile)->pflags[PFLAG_PROXY_HOLD] ? 1 : 0)) {
6144 if (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
6145 profile->media_options &= ~MEDIA_OPT_MEDIA_ON_HOLD;
6146 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6146
, ((void*)0)
, SWITCH_LOG_WARNING, "proxy-hold=true is set, incompatible with media-option=resume-media-on-hold\n");
6147 }
6148 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_HOLD) {
6149 profile->media_options &= ~MEDIA_OPT_BYPASS_AFTER_HOLD;
6150 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6150
, ((void*)0)
, SWITCH_LOG_WARNING, "proxy-hold=true is set, incompatible with media-option=bypass-media-after-hold\n");
6151 }
6152 }
6153
6154 if ((!profile->cng_pt) && (!sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)((profile)->media_flags[SCMF_SUPPRESS_CNG] ? 1 : 0))) {
6155 profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD13;
6156 }
6157
6158 if (!profile->sipip) {
6159 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__, 6159)
;
6160 }
6161
6162 if (!profile->rtpip[0] && !profile->rtpip6[0]) {
6163 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__, 6163)
;
6164 }
6165
6166 if (switch_nat_get_type()) {
6167 char *ip = switch_core_get_variable_dup("nat_public_addr");
6168 if (ip && !strchr(profile->sipip, ':')) {
6169 if (!profile->extrtpip) {
6170 profile->extrtpip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 6170)
;
6171 }
6172 if (!profile->extsipip) {
6173 profile->extsipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 6173)
;
6174 }
6175 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
6176 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6176
, ((void*)0)
, SWITCH_LOG_NOTICE, "NAT detected setting external ip to %s\n", ip);
6177 }
6178 switch_safe_free(ip)if (ip) {free(ip);ip=((void*)0);};
6179 }
6180
6181 if (profile->nonce_ttl < 60) {
6182 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6182
, ((void*)0)
, SWITCH_LOG_INFO, "Setting nonce TTL to 60 seconds\n");
6183 profile->nonce_ttl = 60;
6184 }
6185
6186 if (!profile->max_auth_validity) {
6187 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6187
, ((void*)0)
, SWITCH_LOG_INFO, "Setting MAX Auth Validity to 0 Attempts\n");
6188 profile->max_auth_validity = 0;
6189 }
6190
6191 if (!profile->sdp_username) {
6192 profile->sdp_username = switch_core_strdup(profile->pool, "FreeSWITCH")switch_core_perform_strdup(profile->pool, "FreeSWITCH", "sofia.c"
, (const char *)__func__, 6192)
;
6193 }
6194
6195 if (!profile->rtpip[0] && !profile->rtpip6[0]) {
6196 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6196
, ((void*)0)
, SWITCH_LOG_WARNING, "Setting ip to '127.0.0.1'\n");
6197 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__, 6197)
;
6198 }
6199
6200 if (!profile->sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_PORT] ? 1 : 0)) {
6201 profile->sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_PORT"5060");
6202 if (!profile->extsipport) profile->extsipport = profile->sip_port;
6203 }
6204
6205 if (!profile->dialplan) {
6206 profile->dialplan = switch_core_strdup(profile->pool, "XML")switch_core_perform_strdup(profile->pool, "XML", "sofia.c"
, (const char *)__func__, 6206)
;
6207 }
6208
6209 if (!profile->context) {
6210 profile->context = switch_core_strdup(profile->pool, "default")switch_core_perform_strdup(profile->pool, "default", "sofia.c"
, (const char *)__func__, 6210)
;
6211 }
6212
6213 if (!profile->sipdomain) {
6214 profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip)switch_core_perform_strdup(profile->pool, profile->sipip
, "sofia.c", (const char *)__func__, 6214)
;
6215 }
6216
6217 if (profile->pres_type == PRES_TYPE_PNP) {
6218 if (!profile->pnp_prov_url) {
6219 profile->pnp_prov_url = switch_core_sprintf(profile->pool, "http://%s/provision/", mod_sofia_globals.guess_ip);
6220 }
6221
6222 if (!profile->pnp_notify_profile) {
6223 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__, 6223)
;
6224 }
6225
6226 if (!profile->extsipip) {
6227 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__, 6227)
;
6228 }
6229
6230 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6230
, ((void*)0)
, SWITCH_LOG_INFO, "we're configured to provision to [%s] on profile [%s]\n",
6231 profile->pnp_prov_url, profile->pnp_notify_profile);
6232 }
6233
6234 config_sofia_profile_urls(profile);
6235
6236 if (profile->tls_cert_dir) {
6237 if (profile->wss_ip) {
6238 char *key, *cert;
6239 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.key");
6240 if (switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS) key = NULL((void*)0);
6241 cert = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.crt");
6242 if (switch_file_exists(cert, profile->pool) != SWITCH_STATUS_SUCCESS) cert = NULL((void*)0);
6243 if ( !key || !cert) {
6244 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
6245 if ( switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS ) {
6246 switch_core_gen_certs(key);
6247 }
6248 }
6249 }
6250 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
6251 char *key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "agent.pem");
6252 char *ca = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "cafile.pem");;
6253 if (switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS) key = NULL((void*)0);
6254 if (switch_file_exists(ca, profile->pool) != SWITCH_STATUS_SUCCESS) ca = NULL((void*)0);
6255 if ( !key || !ca ) {
6256 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "tls.pem");
6257 if ( switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS ) {
6258 switch_core_gen_certs(key);
6259 }
6260 }
6261 }
6262 }
6263 }
6264
6265 if (profile) {
6266 if (profile_already_started) {
6267 switch_xml_t gateways_tag, domain_tag, domains_tag, aliases_tag, alias_tag;
6268
6269 if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)((profile)->flags[TFLAG_ZRTP_PASSTHRU] ? 1 : 0)) {
6270 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
6271 }
6272
6273 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
6274 parse_gateways(profile, gateways_tag, NULL((void*)0));
6275 }
6276
6277 status = SWITCH_STATUS_SUCCESS;
6278
6279 if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
6280 switch_event_t *xml_params;
6281 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 6281, &xml_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
6282 switch_assert(xml_params)((xml_params) ? (void) (0) : __assert_fail ("xml_params", "sofia.c"
, 6282, __extension__ __PRETTY_FUNCTION__))
;
6283 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways");
6284 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
6285
6286 for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
6287 switch_xml_t droot, x_domain_tag;
6288 const char *dname = switch_xml_attr_soft(domain_tag, "name");
6289 const char *parse = switch_xml_attr_soft(domain_tag, "parse");
6290 const char *alias = switch_xml_attr_soft(domain_tag, "alias");
6291
6292 if (!zstr(dname)_zstr(dname)) {
6293 if (!strcasecmp(dname, "all")) {
6294 switch_xml_t xml_root, x_domains;
6295 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) {
6296 for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
6297 dname = switch_xml_attr_soft(x_domain_tag, "name");
6298 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
6299 }
6300 switch_xml_free(xml_root);
6301 }
6302 } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) {
6303 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
6304 switch_xml_free(droot);
6305 }
6306 }
6307 }
6308
6309 switch_event_destroy(&xml_params);
6310 }
6311
6312 if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
6313 for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
6314 char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
6315 if (!zstr(aname)_zstr(aname)) {
6316
6317 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname)switch_core_perform_strdup(profile->pool, aname, "sofia.c"
, (const char *)__func__, 6317)
, profile) == SWITCH_STATUS_SUCCESS) {
6318 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6318
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
6319 } else {
6320 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6320
, ((void*)0)
, SWITCH_LOG_WARNING, "Alias [%s] for profile [%s] (already exists)\n",
6321 aname, profile->name);
6322 }
6323 }
6324 }
6325 }
6326
6327 } else {
6328 switch_xml_t aliases_tag, alias_tag;
6329
6330 if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
6331 for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
6332 char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
6333 if (!zstr(aname)_zstr(aname)) {
6334
6335 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname)switch_core_perform_strdup(profile->pool, aname, "sofia.c"
, (const char *)__func__, 6335)
, profile) == SWITCH_STATUS_SUCCESS) {
6336 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6336
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
6337 } else {
6338 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6338
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Adding Alias [%s] for profile [%s] (name in use)\n",
6339 aname, profile->name);
6340 }
6341 }
6342 }
6343 }
6344
6345 if (profile->sipip) {
6346 switch_event_t *s_event;
6347 if (!profile->extsipport) profile->extsipport = profile->sip_port;
6348
6349 launch_sofia_profile_thread(profile);
6350 if (profile->odbc_dsn) {
6351 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6351
, ((void*)0)
, SWITCH_LOG_NOTICE, "Connecting ODBC Profile %s [%s]\n", profile->name, url);
6352 switch_yield(1000000)switch_sleep(1000000);;
6353 } else {
6354 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6354
, ((void*)0)
, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url);
6355 }
6356 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__, 6356, &s_event, SWITCH_EVENT_CUSTOM
, "sofia::profile_start")
== SWITCH_STATUS_SUCCESS)) {
6357 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
6358 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
6359 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
6360 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 6360, &s_event, ((void*)0))
;
6361 }
6362 } else {
6363 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6363
, ((void*)0)
, SWITCH_LOG_NOTICE, "Unable to start Profile %s due to no configured sip-ip\n", profile->name);
6364 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 6364)
;
6365 }
6366 profile = NULL((void*)0);
6367 }
6368 if (profile_found) {
6369 break;
6370 }
6371 }
6372 }
6373 }
6374 done:
6375
6376 if (profile_already_started) {
6377 sofia_glue_release_profile(profile_already_started)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 6377, profile_already_started)
;
6378 }
6379
6380 switch_event_destroy(&params);
6381
6382 if (xml) {
6383 switch_xml_free(xml);
6384 }
6385
6386 if (profile_name && !profile_found) {
6387 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6387
, ((void*)0)
, SWITCH_LOG_WARNING, "No Such Profile '%s'\n", profile_name);
6388 status = SWITCH_STATUS_FALSE;
6389 }
6390
6391 return status;
6392}
6393
6394const char *sofia_gateway_status_name(sofia_gateway_status_t status)
6395{
6396 static const char *status_names[] = { "DOWN", "UP", NULL((void*)0) };
6397
6398 if (status < SOFIA_GATEWAY_INVALID) {
6399 return status_names[status];
6400 } else {
6401 return "INVALID";
6402 }
6403}
6404
6405const char *sofia_sip_user_status_name(sofia_sip_user_status_t status)
6406{
6407 static const char *status_names[] = { "UNREACHABLE", "REACHABLE", NULL((void*)0) };
6408
6409 if (status < SOFIA_REG_INVALID) {
6410 return status_names[status];
6411 } else {
6412 return "INVALID";
6413 }
6414}
6415
6416struct cb_helper_sip_user_status {
6417 char *status;
6418 size_t status_len;
6419
6420 char *contact;
6421 size_t contact_len;
6422
6423 int count;
6424};
6425
6426int sofia_sip_user_status_callback(void *pArg, int argc, char **argv, char **columnNames)
6427{
6428 struct cb_helper_sip_user_status *cbt = (struct cb_helper_sip_user_status *) pArg;
6429
6430 if (argc != 3) {
6431 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6431
, ((void*)0)
, SWITCH_LOG_ERROR, "expected 3 arguments from query, instead got %d\n", argc);
6432 return 0;
6433 }
6434
6435 switch_copy_string(cbt->status, argv[0], cbt->status_len);
6436 cbt->count = (argv[1] && switch_is_number(argv[1])) ? atoi(argv[1]) : 0;
6437
6438 switch_copy_string(cbt->contact, argv[2], cbt->contact_len);
6439
6440 return 1;
6441}
6442
6443static void sofia_handle_sip_r_options(switch_core_session_t *session, int status,
6444 char const *phrase,
6445 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
6446 sofia_dispatch_event_t *de,
6447 tagi_t tags[])
6448{
6449 sofia_gateway_t *gateway = NULL((void*)0);
6450 switch_bool_t do_fire_gateway_state_event = SWITCH_FALSE;
6451
6452 if (sofia_private && !zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
6453 gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 6453
, sofia_private->gateway_name)
;
6454 sofia_private->destroy_me = 1;
6455 }
6456
6457 if (gateway) {
6458 if (status >= 200 && status < 600 && status != 408 && status != 503) {
6459 if (gateway->state == REG_STATE_FAILED) {
6460 gateway->state = REG_STATE_UNREGED;
6461 }
6462
6463 if (gateway->ping_count < 0) {
6464 gateway->ping_count = 0;
6465 }
6466
6467 if (gateway->ping_count < gateway->ping_max) {
6468 gateway->ping_count++;
6469
6470 if (gateway->ping_count >= gateway->ping_min && gateway->status != SOFIA_GATEWAY_UP) {
6471 gateway->status = SOFIA_GATEWAY_UP;
6472 gateway->uptime = switch_time_now();
6473 do_fire_gateway_state_event = SWITCH_TRUE;
6474 }
6475
6476 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6476, (const char*)(session)
, SWITCH_LOG_WARNING,
6477 "Ping succeeded %s with code %d - count %d/%d/%d, state %s\n",
6478 gateway->name, status, gateway->ping_min, gateway->ping_count, gateway->ping_max, sofia_gateway_status_name(gateway->status));
6479 }
6480 if (gateway->ping_sent) {
6481 gateway->ping_time = (float)(switch_time_now() - gateway->ping_sent) / 1000;
6482 gateway->ping_sent = 0;
6483 }
6484 } else {
6485 if (gateway->state == REG_STATE_REGED) {
6486 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6486, (const char*)(session)
, SWITCH_LOG_WARNING, "Unregister %s\n", gateway->name);
6487 gateway->state = REG_STATE_FAILED;
6488 gateway->ping_time = 0;
6489 }
6490
6491 if (gateway->ping_count > 0) {
6492 gateway->ping_count--;
6493 }
6494
6495 if (gateway->ping_count < gateway->ping_min && gateway->status != SOFIA_GATEWAY_DOWN) {
6496 gateway->status = SOFIA_GATEWAY_DOWN;
6497 do_fire_gateway_state_event = SWITCH_TRUE;
6498 gateway->ping_time = 0;
6499 }
6500
6501 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6501, (const char*)(session)
, SWITCH_LOG_WARNING,
6502 "Ping failed %s with code %d - count %d/%d/%d, state %s\n",
6503 gateway->name, status, gateway->ping_min, gateway->ping_count, gateway->ping_max, sofia_gateway_status_name(gateway->status));
6504 }
6505 if (gateway->ping_monitoring || do_fire_gateway_state_event) {
6506 sofia_reg_fire_custom_gateway_state_event(gateway, status, phrase);
6507 }
6508
6509 gateway->ping = switch_epoch_time_now(NULL((void*)0)) + gateway->ping_freq;
6510 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 6510, gateway);
;
6511 gateway->pinging = 0;
6512 } else if (sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')) {
6513 const char *call_id = strchr(sip->sip_call_id->i_id, '_') + 1;
6514 char *sql;
6515 struct cb_helper_sip_user_status sip_user_status;
6516 char ping_status[255] = "";
6517 char sip_contact[1024] = "";
6518 int sip_user_ping_min = profile->sip_user_ping_min;
6519 int sip_user_ping_max = profile->sip_user_ping_max;
6520
6521 char *sip_user = switch_mprintf("%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6522 int ping_time = 0;
6523
6524 if (sofia_private && sofia_private->ping_sent) {
6525 ping_time = (int)(switch_time_now() - sofia_private->ping_sent);
6526 }
6527
6528 sip_user_status.status = ping_status;
6529 sip_user_status.status_len = sizeof(ping_status);
6530 sip_user_status.contact = sip_contact;
6531 sip_user_status.contact_len = sizeof(sip_contact);
6532 sql = switch_mprintf("select ping_status, ping_count, contact from sip_registrations where sip_user='%q' and sip_host='%q' and call_id='%q'",
6533 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6534 sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sip_user_status_callback, &sip_user_status);
6535 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6536
6537 if (status != 200 && status != 486) {
6538 sip_user_status.count--;
6539 if (sip_user_status.count >= 0) {
6540 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6540, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' failed with code %d - count %d, state %s\n",
6541 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
6542 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'",
6543 sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6544 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6545 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6546 }
6547 if (sip_user_status.count < sip_user_ping_min) {
6548 if (strcmp(sip_user_status.status, "Unreachable")) {
6549 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6549, (const char*)(session)
, SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Unreachable\n",
6550 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6551 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'",
6552 ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6553 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6554 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6555 sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
6556 sip->sip_to->a_url->url_host, call_id, SOFIA_REG_REACHABLE, status, phrase);
6557
6558 if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)((profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] ? 1 : 0)) {
6559 time_t now = switch_epoch_time_now(NULL((void*)0));
6560 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6560, (const char*)(session)
, SWITCH_LOG_WARNING, "Expire sip user '%s@%s' due to options failure\n",
6561 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6562
6563 sql = switch_mprintf("update sip_registrations set expires=%ld, ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6564 (long) now, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6565 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6566 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6567 }
6568 }
6569 }
6570 } else {
6571 sip_user_status.count++;
6572 if (sip_user_status.count <= sip_user_ping_max) {
6573 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6573, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' succeeded with code %d - count %d, state %s\n",
6574 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
6575 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'",
6576 sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6577 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6578 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6579 }
6580 if (sip_user_status.count >= sip_user_ping_min) {
6581 if (strcmp(sip_user_status.status, "Reachable")) {
6582 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6582, (const char*)(session)
, SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Reachable\n",
6583 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6584 sql = switch_mprintf("update sip_registrations set ping_status='Reachable' where sip_user='%q' and sip_host='%q' and call_id='%q'",
6585 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6586 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6587 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
6588 sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
6589 sip->sip_to->a_url->url_host, call_id, SOFIA_REG_UNREACHABLE, status, phrase);
6590 }
6591 }
6592 }
6593
6594 switch_safe_free(sip_user)if (sip_user) {free(sip_user);sip_user=((void*)0);};
6595
6596 }
6597}
6598
6599static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
6600 char const *phrase,
6601 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
6602 sofia_dispatch_event_t *de,
6603 tagi_t tags[])
6604{
6605 char *call_info = NULL((void*)0);
6606 if (sip && session) {
6607 switch_channel_t *channel = switch_core_session_get_channel(session);
6608 const char *uuid;
6609 switch_core_session_t *other_session;
6610 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
6611 char network_ip[80] = "";
6612 int network_port = 0;
6613 switch_caller_profile_t *caller_profile = NULL((void*)0);
6614 int has_t38 = 0;
6615
6616 switch_channel_clear_flag(channel, CF_REQ_MEDIA);
6617
6618 if (status < 200) {
6619 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 6619)
== SWITCH_STATUS_SUCCESS) {
6620 if(switch_core_session_compare(session, other_session)) {
6621 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
6622 if (sofia_test_flag(other_tech_pvt, TFLAG_3PCC)((other_tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0)) {
6623 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", 6623, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_SKIP_EARLY] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
6624 }
6625 }
6626 switch_core_session_rwunlock(other_session);
6627 }
6628
6629 if (sofia_test_flag(tech_pvt, TFLAG_SKIP_EARLY)((tech_pvt)->flags[TFLAG_SKIP_EARLY] ? 1 : 0)) {
6630 return;
6631 }
6632 }
6633
6634 if (status >= 900) {
6635 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6635, (const char*)(session)
, SWITCH_LOG_ERROR, "%s status %d received.\n",
6636 switch_channel_get_name(channel), status);
6637 return;
6638 }
6639
6640 if (status > 299) {
6641 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_refuse")switch_channel_set_variable_var_check(channel, "sip_hangup_disposition"
, "recv_refuse", SWITCH_TRUE)
;
6642 }
6643
6644 if (status >= 400) {
6645 char status_str[5];
6646 switch_snprintf(status_str, sizeof(status_str), "%d", status);
6647 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)
;
6648 switch_channel_set_variable(channel, "sip_invite_failure_phrase", phrase)switch_channel_set_variable_var_check(channel, "sip_invite_failure_phrase"
, phrase, SWITCH_TRUE)
;
6649 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)
;
6650 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)
;
6651 } else {
6652 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)
;
6653 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)
;
6654 }
6655
6656 if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
6657 || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
6658 || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
6659 tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
6660 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6660, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote Reason: %d\n", tech_pvt->q850_cause);
6661 }
6662
6663 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
6664
6665 switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
6666 switch_channel_set_variable(channel, "sip_reply_host", network_ip)switch_channel_set_variable_var_check(channel, "sip_reply_host"
, network_ip, SWITCH_TRUE)
;
6667 switch_channel_set_variable_printf(channel, "sip_reply_port", "%d", network_port);
6668
6669 switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip);
6670 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
6671
6672 if ((caller_profile = switch_channel_get_caller_profile(channel)) && !zstr(network_ip)_zstr(network_ip) &&
6673 (zstr(caller_profile->network_addr)_zstr(caller_profile->network_addr) || strcmp(caller_profile->network_addr, network_ip))) {
6674 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__, 6674)
;
6675 }
6676
6677 if (tech_pvt->mparams.last_sdp_response) {
6678 tech_pvt->mparams.prev_sdp_response = tech_pvt->mparams.last_sdp_response;
6679 }
6680 tech_pvt->mparams.last_sdp_response = NULL((void*)0);
6681
6682 if (sip->sip_payload && sip->sip_payload->pl_data) {
6683 switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE);
6684
6685 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)) {
6686 tech_pvt->mparams.last_sdp_response = tech_pvt->mparams.prev_sdp_response;
6687 } else {
6688 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__, 6688)
;
6689 }
6690 }
6691
6692 if (status > 299 && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ)) {
6693 switch_channel_set_private(channel, "t38_options", NULL((void*)0));
6694 switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
6695 switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ);
6696 switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_FAIL);
6697 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6697, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s T38 invite failed\n", switch_channel_get_name(tech_pvt->channel));
6698 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
6699 }
6700
6701
6702 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
6703 if (channel && sip->sip_call_info) {
6704 char *p;
6705 call_info = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info);
6706
6707 if (switch_stristr("appearance", call_info)) {
6708 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)
;
6709 if ((p = strchr(call_info, ';'))) {
6710 switch_channel_set_variable(channel, "presence_call_info", p + 1)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p + 1, SWITCH_TRUE)
;
6711 }
6712 }
6713 } else if ((status == 180 || status == 183 || status == 200)) {
6714 char buf[128] = "";
6715 char *sql;
6716 char *state = "active";
6717
6718 if (status != 200) {
6719 state = "progressing";
6720 }
6721
6722 if (sip->sip_from && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
6723 sip->sip_to && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
6724 sql =
6725 switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
6726 "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
6727 sip->sip_from->a_url->url_host);
6728 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
6729
6730 if (mod_sofia_globals.debug_sla > 1) {
6731 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6731
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
6732 }
6733 free(sql);
6734
6735 if (!zstr(buf)_zstr(buf)) {
6736 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
6737 "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
6738
6739 if (mod_sofia_globals.debug_sla > 1) {
6740 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6740
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
6741 }
6742
6743 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
6744
6745 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6745, (const char*)(session)
, SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
6746 sip->sip_from->a_url->url_host, buf);
6747 switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
6748 switch_channel_set_variable(channel, "presence_call_info", buf)switch_channel_set_variable_var_check(channel, "presence_call_info"
, buf, SWITCH_TRUE)
;
6749 }
6750 }
6751 }
6752 }
6753
6754 if ((status == 180 || status == 183 || status > 199)) {
6755 const char *vval;
6756
6757 sofia_set_accept_language_channel_variable(channel, sip);
6758
6759 if (status > 199) {
6760 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_RESPONSE_HEADER_PREFIX"sip_rh_");
6761 } else {
6762 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_PROGRESS_HEADER_PREFIX"sip_ph_");
6763 }
6764
6765
6766 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)) {
6767 switch_core_session_t *other_session;
6768
6769 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 6769)
== SWITCH_STATUS_SUCCESS) {
6770 if (status > 199) {
6771 switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_RESPONSE_HEADER_PREFIX_T"~sip_rh_");
6772 } else {
6773 switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_PROGRESS_HEADER_PREFIX_T"~sip_ph_");
6774 }
6775 switch_core_session_rwunlock(other_session);
6776 }
6777 }
6778 }
6779
6780 if ((status == 180 || status == 183 || status == 200)) {
6781 const char *x_freeswitch_support;
6782
6783 switch_channel_set_flag(channel, CF_MEDIA_ACK)switch_channel_set_flag_value(channel, CF_MEDIA_ACK, 1);
6784
6785 sofia_glue_store_session_id(session, profile, sip, 1);
6786
6787 if ((x_freeswitch_support = sofia_glue_get_unknown_header(sip, "X-FS-Support"))) {
6788 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__, 6788)
;
6789 }
6790
6791 if (sip->sip_user_agent && sip->sip_user_agent->g_string) {
6792 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)
;
6793 } else if (sip->sip_server && sip->sip_server->g_string) {
6794 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)
;
6795 }
6796
6797 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_allow");
6798
6799 sofia_update_callee_id(session, profile, sip, SWITCH_FALSE);
6800
6801 if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)((tech_pvt->profile)->media_flags[SCMF_AUTOFIX_TIMING] ?
1 : 0)
) {
6802 switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
6803 }
6804
6805 }
6806
6807 if (channel && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
6808 sip_contact_t *p_contact = sip->sip_contact;
6809 int i = 0;
6810 char var_name[80];
6811 const char *diversion_header;
6812 char *full_contact = NULL((void*)0);
6813 char *invite_contact;
6814 const char *br;
6815 const char *v;
6816
6817 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)) {
6818 su_home_t *home = su_home_new(sizeof(*home));
6819 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6819, __extension__ __PRETTY_FUNCTION__))
;
6820
6821 for (p_contact = sip->sip_contact; p_contact; p_contact = p_contact->m_next) {
6822 full_contact = sip_header_as_string(home, (void *) p_contact);
6823 invite_contact = sofia_glue_strip_uri(full_contact);
6824
6825 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_%d", i);
6826 switch_channel_set_variable(channel, var_name, full_contact)switch_channel_set_variable_var_check(channel, var_name, full_contact
, SWITCH_TRUE)
;
6827
6828 if (i == 0) {
6829 switch_channel_set_variable(channel, "sip_redirected_to", full_contact)switch_channel_set_variable_var_check(channel, "sip_redirected_to"
, full_contact, SWITCH_TRUE)
;
6830 }
6831
6832 if (p_contact->m_url->url_user) {
6833 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_user_%d", i);
6834 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)
;
6835 }
6836 if (p_contact->m_url->url_host) {
6837 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_host_%d", i);
6838 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)
;
6839 }
6840 if (p_contact->m_url->url_params) {
6841 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_params_%d", i);
6842 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)
;
6843 }
6844
6845 free(invite_contact);
6846 i++;
6847 }
6848 su_home_unref(home);
6849 home = NULL((void*)0);
6850 switch_snprintf(var_name, sizeof(var_name), "sip:%d", status);
6851 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)
;
6852 switch_channel_hangup(channel, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6852, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL)
;
6853 goto end;
6854 }
6855
6856 if (!p_contact) {
6857 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6857, (const char*)(session)
, SWITCH_LOG_ERROR, "Missing contact header in redirect request\n");
6858 goto end;
6859 }
6860
6861 if ((br = switch_channel_get_partner_uuid(channel))) {
6862 switch_xml_t root = NULL((void*)0), domain = NULL((void*)0);
6863 switch_core_session_t *a_session;
6864 switch_channel_t *a_channel;
6865
6866 const char *sip_redirect_profile, *sip_redirect_context, *sip_redirect_dialplan, *sip_redirect_fork;
6867
6868 if ((a_session = switch_core_session_locate(br)switch_core_session_perform_locate(br, "sofia.c", (const char
*)__func__, 6868)
) && (a_channel = switch_core_session_get_channel(a_session))) {
6869 switch_stream_handle_t stream = { 0 };
6870 char separator[2] = "|";
6871 char *redirect_dialstring;
6872 su_home_t *home = su_home_new(sizeof(*home));
6873 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6873, __extension__ __PRETTY_FUNCTION__))
;
6874
6875 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 6875, __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
;
6876
6877 if (!(sip_redirect_profile = switch_channel_get_variable(channel, "sip_redirect_profile")switch_channel_get_variable_dup(channel, "sip_redirect_profile"
, SWITCH_TRUE, -1)
)) {
6878 sip_redirect_profile = profile->name;
6879 }
6880 if (!(sip_redirect_context = switch_channel_get_variable(channel, "sip_redirect_context")switch_channel_get_variable_dup(channel, "sip_redirect_context"
, SWITCH_TRUE, -1)
)) {
6881 sip_redirect_context = "redirected";
6882 }
6883 if (!(sip_redirect_dialplan = switch_channel_get_variable(channel, "sip_redirect_dialplan")switch_channel_get_variable_dup(channel, "sip_redirect_dialplan"
, SWITCH_TRUE, -1)
)) {
6884 sip_redirect_dialplan = "XML";
6885 }
6886
6887 sip_redirect_fork = switch_channel_get_variable(channel, "sip_redirect_fork")switch_channel_get_variable_dup(channel, "sip_redirect_fork",
SWITCH_TRUE, -1)
;
6888
6889 if (switch_true(sip_redirect_fork)) {
6890 *separator = ',';
6891 }
6892
6893 for (p_contact = sip->sip_contact; p_contact; p_contact = p_contact->m_next) {
6894 full_contact = sip_header_as_string(home, (void *) p_contact);
6895 invite_contact = sofia_glue_strip_uri(full_contact);
6896
6897 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_%d", i);
6898 switch_channel_set_variable(a_channel, var_name, full_contact)switch_channel_set_variable_var_check(a_channel, var_name, full_contact
, SWITCH_TRUE)
;
6899
6900 if (i == 0) {
6901 switch_channel_set_variable(channel, "sip_redirected_to", full_contact)switch_channel_set_variable_var_check(channel, "sip_redirected_to"
, full_contact, SWITCH_TRUE)
;
6902 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)
;
6903 }
6904
6905 if (p_contact->m_url->url_user) {
6906 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_user_%d", i);
6907 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)
;
6908 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)
;
6909 }
6910 if (p_contact->m_url->url_host) {
6911 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_host_%d", i);
6912 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)
;
6913 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)
;
6914 }
6915 if (p_contact->m_url->url_params) {
6916 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_params_%d", i);
6917 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)
;
6918 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)
;
6919 }
6920
6921 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_dialstring_%d", i);
6922 switch_channel_set_variable_printf(channel, var_name, "sofia/%s/%s", sip_redirect_profile, invite_contact);
6923 switch_channel_set_variable_printf(a_channel, var_name, "sofia/%s/%s", sip_redirect_profile, invite_contact);
6924 stream.write_function(&stream, "%ssofia/%s/%s", i ? separator : "", sip_redirect_profile, invite_contact);
6925 free(invite_contact);
6926 i++;
6927 }
6928
6929 redirect_dialstring = stream.data;
6930
6931 switch_channel_set_variable_printf(channel, "sip_redirect_count", "%d", i);
6932 switch_channel_set_variable(channel, "sip_redirect_dialstring", redirect_dialstring)switch_channel_set_variable_var_check(channel, "sip_redirect_dialstring"
, redirect_dialstring, SWITCH_TRUE)
;
6933 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)
;
6934
6935 p_contact = sip->sip_contact;
6936 full_contact = sip_header_as_string(home, (void *) sip->sip_contact);
6937
6938 if ((diversion_header = sofia_glue_get_unknown_header(sip, "diversion"))) {
6939 switch_channel_set_variable(channel, "sip_redirected_by", diversion_header)switch_channel_set_variable_var_check(channel, "sip_redirected_by"
, diversion_header, SWITCH_TRUE)
;
6940 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)
;
6941 }
6942
6943 if (sofia_test_pflag(profile, PFLAG_MANUAL_REDIRECT)((profile)->pflags[PFLAG_MANUAL_REDIRECT] ? 1 : 0)) {
6944 if (!(v = switch_channel_get_variable(channel, "outbound_redirect_info")switch_channel_get_variable_dup(channel, "outbound_redirect_info"
, SWITCH_TRUE, -1)
)) {
6945 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6945, (const char*)(session)
, SWITCH_LOG_DEBUG, "Redirect: Transfering to %s %s %s\n",
6946 p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
6947
6948 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
6949 switch_ivr_transfer_recordings(session, a_session);
6950 }
6951
6952 switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
6953 }
6954 switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6954, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION
)
;
6955 } else if( !p_contact->m_url->url_host ) {
6956 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6956, (const char*)(session)
, SWITCH_LOG_WARNING, "Received redirect with invalid URI\n");
6957 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "REDIRECT_ERROR")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "REDIRECT_ERROR", SWITCH_TRUE)
;
6958 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6958, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
6959 } else if ((!strcmp(profile->sipip, p_contact->m_url->url_host))
6960 || (profile->extsipip && !strcmp(profile->extsipip, p_contact->m_url->url_host))
6961 || (switch_xml_locate_domain(p_contact->m_url->url_host, NULL((void*)0), &root, &domain) == SWITCH_STATUS_SUCCESS)) {
6962 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6962, (const char*)(session)
, SWITCH_LOG_DEBUG, "Redirect: Transfering to %s\n",
6963 p_contact->m_url->url_user);
6964
6965 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
6966 switch_ivr_transfer_recordings(session, a_session);
6967 }
6968
6969 switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, NULL((void*)0), NULL((void*)0));
6970 switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6970, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION
)
;
6971 switch_xml_free(root);
6972 } else {
6973 invite_contact = sofia_glue_strip_uri(full_contact);
6974 tech_pvt->redirected = switch_core_session_strdup(session, invite_contact)switch_core_perform_session_strdup(session, invite_contact, "sofia.c"
, (const char *)__func__, 6974)
;
6975 free(invite_contact);
6976 }
6977
6978 su_home_unref(home);
6979 home = NULL((void*)0);
6980
6981 free(stream.data);
6982
6983 switch_core_session_rwunlock(a_session);
6984 }
6985 } else {
6986 su_home_t *home = su_home_new(sizeof(*home));
6987 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6987, __extension__ __PRETTY_FUNCTION__))
;
6988 full_contact = sip_header_as_string(home, (void *) sip->sip_contact);
6989 invite_contact = sofia_glue_strip_uri(full_contact);
6990
6991 switch_channel_set_variable(channel, "sip_redirected_to", invite_contact)switch_channel_set_variable_var_check(channel, "sip_redirected_to"
, invite_contact, SWITCH_TRUE)
;
6992 tech_pvt->redirected = switch_core_session_strdup(session, invite_contact)switch_core_perform_session_strdup(session, invite_contact, "sofia.c"
, (const char *)__func__, 6992)
;
6993
6994 free(invite_contact);
6995 su_home_unref(home);
6996 home = NULL((void*)0);
6997 }
6998 }
6999
7000
7001 if (sip->sip_payload && sip->sip_payload->pl_data && switch_stristr("m=image", sip->sip_payload->pl_data)) {
7002 has_t38 = 1;
7003 }
7004
7005 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7006 switch_channel_clear_flag(channel, CF_T38_PASSTHRU);
7007 has_t38 = 0;
7008 }
7009
7010 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && has_t38) {
7011 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
7012 switch_core_media_udptl_mode(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
7013
7014 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__, 7014)
)) {
7015 if (switch_core_session_compare(session, other_session)) {
7016 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7017 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
7018 switch_core_media_udptl_mode(other_tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
7019 }
7020 }
7021 switch_core_session_rwunlock(other_session);
7022 }
7023 }
7024
7025 has_t38 = 0;
7026 }
7027
7028 if (status > 199 && (switch_channel_test_flag(channel, CF_PROXY_MODE) ||
7029 switch_channel_test_flag(channel, CF_PROXY_MEDIA) ||
7030 (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && (has_t38 || status > 299)))) {
7031
7032 if (sofia_test_flag(tech_pvt, TFLAG_SENT_UPDATE)((tech_pvt)->flags[TFLAG_SENT_UPDATE] ? 1 : 0)) {
7033 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
);
;
7034
7035 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__, 7035)
)) {
7036 const char *r_sdp = NULL((void*)0);
7037 switch_core_session_message_t *msg;
7038 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7039 //switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
7040
7041 if (sip->sip_payload && sip->sip_payload->pl_data &&
7042 sip->sip_content_type && sip->sip_content_type->c_subtype && switch_stristr("sdp", sip->sip_content_type->c_subtype)) {
7043 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__, 7043
)
;
7044 r_sdp = tech_pvt->mparams.remote_sdp_str;
7045 switch_core_media_proxy_remote_addr(session, NULL((void*)0));
7046 }
7047
7048 if (status == 415) {
7049 int new_status = 488;
7050 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7050, (const char*)(session)
, SWITCH_LOG_DEBUG, "Overriding %d %s with %d\n", status, phrase, new_status);
7051 status = new_status;
7052 }
7053
7054 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7054, (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 : ""));
7055
7056 if (switch_core_session_compare(session, other_session)) {
7057 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7058 sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK)(other_tech_pvt)->flags[TFLAG_PASS_ACK] = 1;
7059 }
7060
7061
7062 if (status == 491 && (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) ||
7063 switch_channel_test_flag(channel, CF_PROXY_MODE))) {
7064 nua_respond(other_tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending, TAG_END()(tag_type_t)0, (tag_value_t)0);
7065 switch_core_session_rwunlock(other_session);
7066 goto end;
7067 } else if (status > 299) {
7068 switch_core_media_reset_t38(session);
7069 switch_core_media_reset_t38(other_session);
7070 } else if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) &&
7071 has_t38 && sip->sip_payload && sip->sip_payload->pl_data) {
7072 switch_t38_options_t *t38_options = switch_core_media_extract_t38_options(session, sip->sip_payload->pl_data);
7073
7074 if (!t38_options) {
7075 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7075, (const char*)(session)
, SWITCH_LOG_WARNING, "Could not parse T.38 options from sdp.\n");
7076 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)
;
7077 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7077, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7078 switch_core_session_rwunlock(other_session);
7079 goto end;
7080 } else {
7081 switch_core_media_process_t38_passthru(session, other_session, t38_options);
7082 }
7083 }
7084
7085
7086 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 7086)
;
7087 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
7088 msg->from = __FILE__"sofia.c";
7089 msg->numeric_arg = status;
7090 msg->string_arg = switch_core_session_strdup(other_session, phrase)switch_core_perform_session_strdup(other_session, phrase, "sofia.c"
, (const char *)__func__, 7090)
;
7091
7092 if (status == 200 && switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && has_t38) {
7093 msg->pointer_arg = switch_core_session_strdup(other_session, "t38")switch_core_perform_session_strdup(other_session, "t38", "sofia.c"
, (const char *)__func__, 7093)
;
7094 } else if (r_sdp) {
7095 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__, 7095)
;
7096 msg->pointer_arg_size = strlen(r_sdp);
7097 }
7098
7099 if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) && has_t38) {
7100 if (switch_core_media_ready(session, SWITCH_MEDIA_TYPE_AUDIO) &&
7101 switch_core_media_ready(other_session, SWITCH_MEDIA_TYPE_AUDIO)) {
7102 switch_channel_clear_flag(channel, CF_NOTIMER_DURING_BRIDGE);
7103 switch_core_media_udptl_mode(session, SWITCH_MEDIA_TYPE_AUDIO);
7104 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7104, (const char*)(session)
, SWITCH_LOG_INFO, "Activating T38 Passthru\n");
7105 }
7106 }
7107
7108 switch_core_session_queue_message(other_session, msg);
7109
7110 switch_core_session_rwunlock(other_session);
7111 }
7112 goto end;
7113 }
7114 }
7115
7116 if ((status == 180 || status == 183 || status == 200)) {
7117 const char *astate = "early";
7118 url_t *from = NULL((void*)0), *to = NULL((void*)0), *contact = NULL((void*)0);
7119
7120 if (sip->sip_to) {
7121 to = sip->sip_to->a_url;
7122 }
7123 if (sip->sip_from) {
7124 from = sip->sip_from->a_url;
7125 }
7126 if (sip->sip_contact) {
7127 contact = sip->sip_contact->m_url;
7128 }
7129
7130 if (status == 200) {
7131 astate = "confirmed";
7132 }
7133
7134 if ((!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED) &&
7135 !switch_channel_test_flag(channel, CF_RING_READY)) || switch_channel_test_flag(channel, CF_RECOVERING)) {
7136 const char *from_user = "", *from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
7137 const char *user_agent = "", *call_id = "";
7138 const char *to_tag = "";
7139 const char *from_tag = "";
7140 char *sql = NULL((void*)0);
7141
7142 if (sip->sip_user_agent) {
7143 user_agent = switch_str_nil(sip->sip_user_agent->g_string)(sip->sip_user_agent->g_string ? sip->sip_user_agent
->g_string : "")
;
7144 }
7145
7146 if (sip->sip_call_id) {
7147 call_id = switch_str_nil(sip->sip_call_id->i_id)(sip->sip_call_id->i_id ? sip->sip_call_id->i_id :
"")
;
7148 }
7149
7150 if (to) {
7151 from_user = switch_str_nil(to->url_user)(to->url_user ? to->url_user : "");
7152 from_tag = switch_str_nil(sip->sip_to->a_tag)(sip->sip_to->a_tag ? sip->sip_to->a_tag : "");
7153 }
7154
7155 if (from) {
7156 from_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
7157 to_user = switch_str_nil(from->url_user)(from->url_user ? from->url_user : "");
7158 to_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
7159 to_tag = switch_str_nil(sip->sip_from->a_tag)(sip->sip_from->a_tag ? sip->sip_from->a_tag : ""
)
;
7160 }
7161
7162 if (contact) {
7163 contact_user = switch_str_nil(contact->url_user)(contact->url_user ? contact->url_user : "");
7164 contact_host = switch_str_nil(contact->url_host)(contact->url_host ? contact->url_host : "");
7165 }
7166
7167 if (profile->pres_type) {
7168 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
7169 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
7170 char *full_contact = NULL((void*)0);
7171 char *p = NULL((void*)0);
7172 time_t now;
7173
7174 if (sip->sip_contact) {
7175 full_contact = sip_header_as_string(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), (void *) sip->sip_contact);
7176 }
7177
7178 if (call_info && (p = strchr(call_info, ';'))) {
7179 p++;
7180 }
7181
7182 now = switch_epoch_time_now(NULL((void*)0));
7183
7184 sql = switch_mprintf("insert into sip_dialogs "
7185 "(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
7186 "contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
7187 "call_info,rcd,call_info_state) "
7188 "values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
7189 call_id,
7190 switch_core_session_get_uuid(session),
7191 to_user, to_host, to_tag, from_user, from_host, from_tag, contact_user,
7192 contact_host, astate, "outbound", user_agent,
7193 profile->name, mod_sofia_globals.hostname, switch_str_nil(full_contact)(full_contact ? full_contact : ""),
7194 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);
7195 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 7195, __extension__
__PRETTY_FUNCTION__))
;
7196
7197 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7198
7199 if ( full_contact ) {
7200 su_free(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), full_contact);
7201 }
7202 }
7203 } else if (status == 200 && (profile->pres_type)) {
7204 char *sql = NULL((void*)0);
7205 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
7206 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
7207
7208 sql = switch_mprintf("update sip_dialogs set state='%q',presence_id='%q',presence_data='%q' "
7209 "where uuid='%q';\n", astate, switch_str_nil(presence_id)(presence_id ? presence_id : ""), switch_str_nil(presence_data)(presence_data ? presence_data : ""),
7210 switch_core_session_get_uuid(session));
7211 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 7211, __extension__
__PRETTY_FUNCTION__))
;
7212 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7213 }
7214
7215 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7216 switch_channel_set_variable(channel, "dlg_req_swap_direction", "true")switch_channel_set_variable_var_check(channel, "dlg_req_swap_direction"
, "true", SWITCH_TRUE)
;
7217 }
7218
7219 extract_header_vars(profile, sip, session, nh);
7220 extract_vars(profile, sip, session);
7221 switch_core_recovery_track(session);
7222 switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING);
7223 }
7224
7225 }
7226
7227 end:
7228
7229 if (call_info) {
7230 su_free(nua_handle_home(nh)((su_home_t *)(nh)), call_info);
7231 }
7232
7233 if (!session && (status == 180 || status == 183 || status == 200)) {
7234 /* nevermind */
7235 nua_handle_bind(nh, NULL((void*)0));
7236 nua_handle_destroy(nh);
7237 }
7238}
7239
7240/* Pure black magic, if you can't understand this code you are lucky.........*/
7241void *SWITCH_THREAD_FUNC media_on_hold_thread_run(switch_thread_t *thread, void *obj)
7242{
7243 switch_core_session_t *other_session = NULL((void*)0), *session = (switch_core_session_t *) obj;
7244 const char *uuid;
7245
7246 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
7247 switch_channel_t *channel = switch_core_session_get_channel(session);
7248 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
7249
7250 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__, 7250)
)) {
7251 if (switch_core_session_compare(session, other_session)) {
7252 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
7253 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", 7253, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_HOLD_LOCK] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
7254
7255 switch_yield(250000)switch_sleep(250000);;
7256 switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
7257 switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
7258
7259 if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7260 switch_ivr_3p_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE|SMF_REPLYONLY_B);
7261 } else {
7262 switch_ivr_3p_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE);
7263 }
7264
7265
7266 switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
7267 switch_core_media_clear_rtp_flag(other_session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
7268
7269
7270 switch_core_media_toggle_hold(session, 1);
7271 }
7272 switch_core_session_rwunlock(other_session);
7273 }
7274
7275 switch_core_session_rwunlock(session);
7276 }
7277
7278 return NULL((void*)0);
7279}
7280
7281static void launch_media_on_hold(switch_core_session_t *session)
7282{
7283 switch_thread_t *thread;
7284 switch_threadattr_t *thd_attr = NULL((void*)0);
7285
7286 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
7287 switch_threadattr_detach_set(thd_attr, 1);
7288 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
7289 switch_thread_create(&thread, thd_attr, media_on_hold_thread_run, session, switch_core_session_get_pool(session));
7290}
7291
7292
7293
7294static void mark_transfer_record(switch_core_session_t *session, const char *br_a, const char *br_b)
7295{
7296 switch_core_session_t *br_b_session, *br_a_session;
7297 switch_channel_t *channel;
7298 const char *uvar1, *dvar1, *uvar2, *dvar2;
7299
7300 channel = switch_core_session_get_channel(session);
7301
7302 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7303 uvar1 = "sip_from_user";
7304 dvar1 = "sip_from_host";
7305 } else {
7306 uvar1 = "sip_to_user";
7307 dvar1 = "sip_to_host";
7308 }
7309
7310
7311 if ((br_b_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 7311)
) ) {
7312 switch_channel_t *br_b_channel = switch_core_session_get_channel(br_b_session);
7313 switch_caller_profile_t *cp = switch_channel_get_caller_profile(br_b_channel);
7314
7315 if (switch_channel_direction(br_b_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7316 uvar2 = "sip_from_user";
7317 dvar2 = "sip_from_host";
7318 } else {
7319 uvar2 = "sip_to_user";
7320 dvar2 = "sip_to_host";
7321 }
7322
7323 cp->transfer_source = switch_core_sprintf(cp->pool,
7324 "%ld:%s:att_xfer:%s@%s/%s@%s",
7325 (long) switch_epoch_time_now(NULL((void*)0)),
7326 cp->uuid_str,
7327 switch_channel_get_variable(channel, uvar1)switch_channel_get_variable_dup(channel, uvar1, SWITCH_TRUE, -
1)
,
7328 switch_channel_get_variable(channel, dvar1)switch_channel_get_variable_dup(channel, dvar1, SWITCH_TRUE, -
1)
,
7329 switch_channel_get_variable(br_b_channel, uvar2)switch_channel_get_variable_dup(br_b_channel, uvar2, SWITCH_TRUE
, -1)
,
7330 switch_channel_get_variable(br_b_channel, dvar2)switch_channel_get_variable_dup(br_b_channel, dvar2, SWITCH_TRUE
, -1)
);
7331
7332 switch_channel_add_variable_var_check(br_b_channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history", cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
7333 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)
;
7334
7335 switch_core_session_rwunlock(br_b_session);
7336 }
7337
7338
7339
7340 if ((br_a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 7340)
) ) {
7341 switch_channel_t *br_a_channel = switch_core_session_get_channel(br_a_session);
7342 switch_caller_profile_t *cp = switch_channel_get_caller_profile(br_a_channel);
7343
7344 if (switch_channel_direction(br_a_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7345 uvar2 = "sip_from_user";
7346 dvar2 = "sip_from_host";
7347 } else {
7348 uvar2 = "sip_to_user";
7349 dvar2 = "sip_to_host";
7350 }
7351
7352 cp->transfer_source = switch_core_sprintf(cp->pool,
7353 "%ld:%s:att_xfer:%s@%s/%s@%s",
7354 (long) switch_epoch_time_now(NULL((void*)0)),
7355 cp->uuid_str,
7356 switch_channel_get_variable(channel, uvar1)switch_channel_get_variable_dup(channel, uvar1, SWITCH_TRUE, -
1)
,
7357 switch_channel_get_variable(channel, dvar1)switch_channel_get_variable_dup(channel, dvar1, SWITCH_TRUE, -
1)
,
7358 switch_channel_get_variable(br_a_channel, uvar2)switch_channel_get_variable_dup(br_a_channel, uvar2, SWITCH_TRUE
, -1)
,
7359 switch_channel_get_variable(br_a_channel, dvar2)switch_channel_get_variable_dup(br_a_channel, dvar2, SWITCH_TRUE
, -1)
);
7360
7361 switch_channel_add_variable_var_check(br_a_channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history", cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
7362 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)
;
7363
7364 switch_core_session_rwunlock(br_a_session);
7365 }
7366
7367
7368}
7369
7370
7371static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
7372 char const *phrase,
7373 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
7374 sofia_dispatch_event_t *de,
7375 tagi_t tags[])
7376{
7377 const char *l_sdp = NULL((void*)0), *r_sdp = NULL((void*)0);
7378 int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
7379 int ss_state = nua_callstate_init;
7380 switch_channel_t *channel = NULL((void*)0);
7381 private_object_t *tech_pvt = NULL((void*)0);
7382 const char *replaces_str = NULL((void*)0);
7383 switch_core_session_t *other_session = NULL((void*)0);
7384 switch_channel_t *other_channel = NULL((void*)0);
7385 //private_object_t *other_tech_pvt = NULL;
7386 char st[80] = "";
7387 int is_dup_sdp = 0;
7388 switch_event_t *s_event = NULL((void*)0);
7389 char *p;
7390 char *patched_sdp = NULL((void*)0);
7391 const char *session_id_header = sofia_glue_session_id_header(session, profile);
7392
7393 tl_gets(tags,
7394 NUTAG_CALLSTATE_REF(ss_state)nutag_callstate_ref, tag_int_vr(&(ss_state)),
7395 NUTAG_OFFER_RECV_REF(offer_recv)nutag_offer_recv_ref, tag_bool_vr(&(offer_recv)),
7396 NUTAG_ANSWER_RECV_REF(answer_recv)nutag_answer_recv_ref, tag_bool_vr(&(answer_recv)),
7397 NUTAG_OFFER_SENT_REF(offer_sent)nutag_offer_sent_ref, tag_bool_vr(&(offer_sent)),
7398 NUTAG_ANSWER_SENT_REF(answer_sent)nutag_answer_sent_ref, tag_bool_vr(&(answer_sent)),
7399 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);
7400
7401 if (session) {
7402 channel = switch_core_session_get_channel(session);
7403 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
7404
7405 if (!tech_pvt || !tech_pvt->nh) {
7406 goto done;
7407 }
7408
7409 if (!r_sdp && (status == 100 || status == 200)) {
7410 if (ss_state == nua_callstate_completing) {
7411 if (tech_pvt->mparams.last_sdp_response) {
7412 r_sdp = tech_pvt->mparams.last_sdp_response;
7413 }
7414 } else if (ss_state == nua_callstate_received || ss_state == nua_callstate_ready) {
7415 if (tech_pvt->mparams.last_sdp_str) {
7416 r_sdp = tech_pvt->mparams.last_sdp_str;
7417 }
7418 }
7419 }
7420
7421 if (tech_pvt->mparams.last_sdp_str) {
7422 tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
7423 }
7424
7425 if (tech_pvt->mparams.last_sdp_response) {
7426 tech_pvt->mparams.prev_sdp_response = tech_pvt->mparams.last_sdp_response;
7427 }
7428
7429 tech_pvt->mparams.last_sdp_str = NULL((void*)0);
7430 tech_pvt->mparams.last_sdp_response = NULL((void*)0);
7431
7432 if (r_sdp && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) {
7433 const char *var;
7434
7435 if ((var = switch_channel_get_variable(channel, "bypass_media_sdp_filter")switch_channel_get_variable_dup(channel, "bypass_media_sdp_filter"
, SWITCH_TRUE, -1)
)) {
7436 if ((patched_sdp = switch_core_media_process_sdp_filter(r_sdp, var, session))) {
7437 r_sdp = patched_sdp;
7438 }
7439 }
7440 }
7441
7442 if ((switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) ||
7443 (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))) {
7444
7445 /* This marr in our code brought to you by people who can't read........ */
7446 if (profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME && r_sdp && (p = (char *) switch_stristr("g729a/8000", r_sdp))) {
7447 p += 4;
7448 *p++ = '/';
7449 *p++ = '8';
7450 *p++ = '0';
7451 *p++ = '0';
7452 *p++ = '0';
7453 *p++ = ' ';
7454 }
7455 }
7456 }
7457
7458
7459 if (ss_state == nua_callstate_terminated) {
7460
7461 if ((status == 300 || status == 301 || status == 302 || status == 305) && session) {
7462 channel = switch_core_session_get_channel(session);
7463 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
7464
7465 if (!tech_pvt || !tech_pvt->nh) {
7466 goto done;
7467 }
7468
7469
7470 if (tech_pvt->redirected) {
7471 sofia_glue_do_invite(session);
7472 goto done;
7473 }
7474 }
7475
7476 if (sofia_private) {
7477 sofia_private->destroy_me = 1;
7478 }
7479 }
7480
7481 if (session) {
7482 if ((switch_channel_test_flag(channel, CF_ANSWERED) && (status == 180 || status == 183) && !r_sdp) || (ss_state == nua_callstate_ready && status >= 300)) {
7483 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7483, (const char*)(session)
, SWITCH_LOG_DEBUG, "Channel %s skipping state [%s][%d]\n",
7484 switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
7485 goto done;
7486 } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (status == 180 || status == 183) && r_sdp) {
7487 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
7488 }
7489
7490 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7490, (const char*)(session)
, SWITCH_LOG_DEBUG, "Channel %s entering state [%s][%d]\n",
7491 switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
7492
7493 if (r_sdp) {
7494 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)
;
7495
7496 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))) {
7497 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7497, (const char*)(session)
, SWITCH_LOG_DEBUG, "Duplicate SDP\n%s\n", r_sdp);
7498 is_dup_sdp = 1;
7499 } else {
7500 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7500, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
7501 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__, 7501)
;
7502 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && status < 200) {
7503 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 7503)
;
7504 }
7505 //if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
7506 // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE);
7507 //}
7508 switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
7509 sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
7510 sofia_set_flag(tech_pvt, TFLAG_NEW_SDP)(tech_pvt)->flags[TFLAG_NEW_SDP] = 1;
7511
7512 }
7513 }
7514 }
7515
7516 if (status == 988) {
7517 goto done;
7518 }
7519
7520 if (status == 183 && !r_sdp) {
7521 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)) {
7522 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7522, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s Ignoring 183 w/o sdp\n", channel ? switch_channel_get_name(channel) : "None");
7523 goto done;
7524 }
7525 status = 180;
7526 }
7527
7528 if (status == 180 && r_sdp) {
7529 status = 183;
7530 }
7531
7532 if (channel && profile->pres_type && ss_state == nua_callstate_ready && status == 200) {
7533 const char* to_tag = "";
7534 char *sql = NULL((void*)0);
7535 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) : "")
;
7536 sql = switch_mprintf("update sip_dialogs set sip_to_tag='%q' "
7537 "where uuid='%q' and sip_to_tag = ''", to_tag, switch_core_session_get_uuid(session));
7538
7539 if (mod_sofia_globals.debug_presence > 1) {
7540 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 7540
, ((void*)0)
, SWITCH_LOG_DEBUG, "QUERY SQL %s\n", sql);
7541 }
7542 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7543 }
7544
7545 if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
7546 const char *full_to = NULL((void*)0);
7547 const char *var;
7548 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) &&
7549 !((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))) {
7550 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) : "")
;
7551
7552 nua_notify(nh,
7553 NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1),
7554 NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
7555 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
7556 TAG_IF((full_to), SIPTAG_TO_STR(full_to))!((full_to)) ? tag_skip : siptag_to_str, tag_str_v(full_to),
7557 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
7558 SIPTAG_EVENT_STR("talk")siptag_event_str, tag_str_v("talk"),
7559 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))
,
7560 TAG_END()(tag_type_t)0, (tag_value_t)0);
7561 }
7562 }
7563
7564
7565
7566 state_process:
7567
7568 switch ((enum nua_callstate) ss_state) {
7569 case nua_callstate_terminated:
7570 case nua_callstate_terminating:
7571 case nua_callstate_ready:
7572 case nua_callstate_completed:
7573 case nua_callstate_received:
7574 case nua_callstate_proceeding:
7575 case nua_callstate_completing:
7576 case nua_callstate_calling:
7577 if (!(session && channel && tech_pvt))
7578 goto done;
7579 default:
7580 break;
7581 }
7582
7583 switch ((enum nua_callstate) ss_state) {
7584 case nua_callstate_init:
7585 break;
7586 case nua_callstate_authenticating:
7587 break;
7588 case nua_callstate_calling:
7589 tech_pvt->sent_last_invite = 1;
7590 tech_pvt->sent_invites++;
7591 break;
7592 case nua_callstate_proceeding:
7593
7594 if (sofia_test_flag(tech_pvt, TFLAG_SKIP_EARLY)((tech_pvt)->flags[TFLAG_SKIP_EARLY] ? 1 : 0)) {
7595 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
);
;
7596 goto done;
7597 }
7598
7599 switch (status) {
7600 case 180:
7601 switch_channel_mark_ring_ready(channel)switch_channel_perform_mark_ring_ready_value(channel, SWITCH_RING_READY_RINGING
, "sofia.c", (const char *)__func__, 7601)
;
7602 break;
7603 case 182:
7604 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__, 7604)
;
7605 break;
7606 default:
7607 break;
7608 }
7609
7610 if (r_sdp) {
7611 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7612 char ibuf[35] = "", pbuf[35] = "";
7613 const char *ptr;
7614
7615 if ((ptr = switch_stristr("c=IN IP4", r_sdp))) {
7616 int i = 0;
7617
7618 ptr += 8;
7619
7620 while(*ptr == ' ') {
7621 ptr++;
7622 }
7623 while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
7624 ibuf[i++] = *ptr++;
7625 }
7626
7627 switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, ibuf)switch_channel_set_variable_var_check(channel, "remote_media_ip"
, ibuf, SWITCH_TRUE)
;
7628 }
7629
7630 if ((ptr = switch_stristr("m=audio", r_sdp))) {
7631 int i = 0;
7632
7633 ptr += 7;
7634
7635 while(*ptr == ' ') {
7636 ptr++;
7637 }
7638 while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
7639 pbuf[i++] = *ptr++;
7640 }
7641
7642 switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, pbuf)switch_channel_set_variable_var_check(channel, "remote_media_port"
, pbuf, SWITCH_TRUE)
;
7643 }
7644
7645 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7646 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
7647 }
7648 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", 7648, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_EARLY_MEDIA] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
7649 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 7649)
;
7650 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7651 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) || switch_channel_test_flag(channel, CF_REINVITE)) {
7652 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7653 goto done;
7654 }
7655 }
7656 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7656)
== SWITCH_STATUS_SUCCESS) {
7657 other_channel = switch_core_session_get_channel(other_session);
7658 switch_channel_pass_sdp(channel, other_channel, r_sdp);
7659
7660 //switch_channel_pre_answer(other_channel);
7661 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_PROGRESS);
7662 switch_core_session_rwunlock(other_session);
7663 }
7664 goto done;
7665 } else {
7666 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) {
7667 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "DELAYED NEGOTIATION", SWITCH_TRUE)
;
7668 } else if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7669 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
7670 switch_core_media_patch_sdp(tech_pvt->session);
7671 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7672 nua_respond(nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
7673 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);
7674 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7674, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7675 } else{
7676 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 7676)
;
7677 }
7678
7679 } else {
7680 if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
7681 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)
;
7682 nua_respond(nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
7683 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);
7684 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7684, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7685 }
7686 }
7687 goto done;
7688 }
7689 }
7690 break;
7691 case nua_callstate_completing:
7692 {
7693 int send_ack = 1;
7694
7695 if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
7696 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)
;
7697
7698 if (switch_true(wait_for_ack)) {
7699 switch_core_session_t *other_session;
7700
7701 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7701)
== SWITCH_STATUS_SUCCESS) {
7702 if (switch_core_session_compare(session, other_session)) {
7703 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7704
7705 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)) {
7706 sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK)(other_tech_pvt)->flags[TFLAG_PASS_ACK] = 1;
7707 send_ack = 0;
7708 }
7709 }
7710 switch_core_session_rwunlock(other_session);
7711 }
7712 }
7713 }
7714
7715 if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED)) {
7716 if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG)) {
7717 switch_core_session_t *other_session;
7718
7719 switch_channel_clear_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG);
7720
7721 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7721)
== SWITCH_STATUS_SUCCESS) {
7722 if (switch_core_session_compare(session, other_session)) {
7723 //switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
7724 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7725
7726 sofia_glue_clear_soa(other_session, SWITCH_TRUE);
7727
7728 if (sofia_use_soa(other_tech_pvt)((other_tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
7729 nua_ack(other_tech_pvt->nh,
7730 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)
,
7731 SIPTAG_CONTACT_STR(other_tech_pvt->reply_contact)siptag_contact_str, tag_str_v(other_tech_pvt->reply_contact
)
,
7732 SOATAG_USER_SDP_STR(r_sdp)soatag_user_sdp_str, tag_str_v(r_sdp),
7733 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
7734 SOATAG_RTP_SELECT(1)soatag_rtp_select, tag_int_v(1),
7735 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7736 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)
,
7737 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))
,
7738 TAG_END()(tag_type_t)0, (tag_value_t)0);
7739 } else {
7740 nua_ack(other_tech_pvt->nh,
7741 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
7742 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)
,
7743 SIPTAG_CONTACT_STR(other_tech_pvt->reply_contact)siptag_contact_str, tag_str_v(other_tech_pvt->reply_contact
)
,
7744 TAG_IF(r_sdp, SIPTAG_CONTENT_TYPE_STR("application/sdp"))!(r_sdp) ? tag_skip : siptag_content_type_str, tag_str_v("application/sdp"
)
,
7745 TAG_IF(r_sdp, SIPTAG_PAYLOAD_STR(r_sdp))!(r_sdp) ? tag_skip : siptag_payload_str, tag_str_v(r_sdp),
7746 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7747 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))
,
7748 TAG_END()(tag_type_t)0, (tag_value_t)0);
7749 }
7750
7751 nua_ack(tech_pvt->nh,
7752 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)
,
7753 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7754 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))
,
7755 TAG_END()(tag_type_t)0, (tag_value_t)0);
7756
7757 }
7758 switch_core_session_rwunlock(other_session);
7759 }
7760 } else {
7761 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)
;
7762 }
7763
7764 switch_channel_clear_flag(channel, CF_3P_NOMEDIA_REQUESTED);
7765 goto done;
7766
7767 } else if (switch_channel_test_flag(channel, CF_3P_MEDIA_REQUESTED)) {
7768 uint8_t match = 0;
7769
7770 switch_channel_clear_flag(channel, CF_PROXY_MODE);
7771
7772 switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
7773 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
7774
7775 if (tech_pvt->mparams.num_codecs) {
7776 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
7777 }
7778
7779 if (!match) {
7780 if (switch_channel_get_state(channel) != CS_NEW) {
7781 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
7782 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);
7783 }
7784 } else {
7785 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
7786 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED", SWITCH_TRUE)
;
7787 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", 7787, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7788
7789 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7790 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7790, (const char*)(session)
, SWITCH_LOG_DEBUG, "RESTABLISH MEDIA SDP:\n%s\n", tech_pvt->mparams.local_sdp_str);
7791
7792 switch_channel_set_flag(channel, CF_REQ_MEDIA)switch_channel_set_flag_value(channel, CF_REQ_MEDIA, 1);
7793 switch_channel_set_flag(channel, CF_MEDIA_ACK)switch_channel_set_flag_value(channel, CF_MEDIA_ACK, 1);
7794 switch_channel_set_flag(channel, CF_MEDIA_SET)switch_channel_set_flag_value(channel, CF_MEDIA_SET, 1);
7795
7796 switch_core_media_activate_rtp(session);
7797
7798
7799 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
7800 nua_ack(tech_pvt->nh,
7801 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)
,
7802 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7803 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
7804 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
7805 SOATAG_RTP_SELECT(1)soatag_rtp_select, tag_int_v(1),
7806 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7807 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)
,
7808 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))
,
7809 TAG_END()(tag_type_t)0, (tag_value_t)0);
7810 } else {
7811 nua_ack(tech_pvt->nh,
7812 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
7813 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)
,
7814 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7815 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")
,
7816 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)
,
7817 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7818 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))
,
7819 TAG_END()(tag_type_t)0, (tag_value_t)0);
7820 }
7821
7822 switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED);
7823 goto done;
7824 }
7825
7826 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "NO CODECS", SWITCH_TRUE)
;
7827 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7827, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7828
7829 switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED);
7830 goto done;
7831 //ss_state = nua_callstate_ready;
7832 //goto state_process;
7833 }
7834
7835 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)) {
7836 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7837 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7837)
== SWITCH_STATUS_SUCCESS) {
7838 other_channel = switch_core_session_get_channel(other_session);
7839 //other_tech_pvt = switch_core_session_get_private(other_session);
7840
7841 switch_channel_pass_sdp(channel, other_channel, r_sdp);
7842 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
7843 switch_core_session_rwunlock(other_session);
7844 }
7845 goto done;
7846
7847 }
7848
7849 if (send_ack) {
7850 tech_send_ack(nh, tech_pvt, NULL((void*)0));
7851 } else {
7852 ss_state = nua_callstate_ready;
7853 goto state_process;
7854 }
7855
7856 }
7857 goto done;
7858 case nua_callstate_received:
7859 tech_pvt->recv_invites++;
7860 tech_pvt->sent_last_invite = 0;
7861
7862 if (!sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
7863 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7863)
== SWITCH_STATUS_SUCCESS) {
7864 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7865 int r = sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)((other_tech_pvt)->flags[TFLAG_REINVITED] ? 1 : 0);
7866 switch_core_session_rwunlock(other_session);
7867
7868 if (r) {
7869 /* Due to a race between simultaneous reinvites to both legs of a bridge,
7870 an earlier call to nua_invite silently failed.
7871 So we reject the incoming invite with a 491 and redo the failed outgoing invite. */
7872
7873 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7873, (const char*)(session)
, SWITCH_LOG_DEBUG,
7874 "Other leg already handling a reinvite, so responding with 491\n");
7875
7876 nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending,
7877 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);
7878 sofia_glue_do_invite(session);
7879 goto done;
7880 }
7881 }
7882
7883
7884 if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
7885 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7886 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOMEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOMEDIA", SWITCH_TRUE)
;
7887 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", 7887, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7888 if (switch_channel_get_state(channel) == CS_NEW) {
7889 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7889, CS_INIT)
;
7890 }
7891 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7892 goto done;
7893 } else if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
7894 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
7895 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", 7895, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7896 if (switch_channel_get_state(channel) == CS_NEW) {
7897 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7897, CS_INIT)
;
7898 }
7899 } else if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)((tech_pvt)->flags[TFLAG_LATE_NEGOTIATION] ? 1 : 0)) {
7900 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "DELAYED NEGOTIATION", SWITCH_TRUE)
;
7901 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", 7901, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7902 if (switch_channel_get_state(channel) == CS_NEW) {
7903 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7903, CS_INIT)
;
7904 }
7905 } else {
7906 uint8_t match = 0;
7907
7908 if (tech_pvt->mparams.num_codecs) {
7909 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
7910 }
7911
7912 if (!match) {
7913 if (switch_channel_get_state(channel) != CS_NEW) {
7914 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable, TAG_END()(tag_type_t)0, (tag_value_t)0);
7915 }
7916 } else {
7917 nua_handle_t *bnh;
7918 sip_replaces_t *replaces;
7919 su_home_t *home = NULL((void*)0);
7920 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED", SWITCH_TRUE)
;
7921 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", 7921, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7922
7923 if (switch_channel_get_state(channel) == CS_NEW) {
7924 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7924, CS_INIT)
;
7925 } else {
7926 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);
7927 }
7928 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7929 if (replaces_str) {
7930 home = su_home_new(sizeof(*home));
7931 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 7931, __extension__ __PRETTY_FUNCTION__))
;
7932 if ((replaces = sip_replaces_make(home, replaces_str))
7933 && (bnh = nua_handle_by_replaces(nua, replaces))) {
7934 sofia_private_t *b_private;
7935
7936 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7936, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing Replaces Attended Transfer\n");
7937 while (switch_channel_get_state(channel) < CS_EXECUTE) {
7938 switch_yield(10000)switch_sleep(10000);;
7939 }
7940
7941 if ((b_private = nua_handle_magic(bnh))) {
7942 const char *br_b = switch_channel_get_partner_uuid(channel);
7943 char *br_a = b_private->uuid;
7944
7945
7946 if (br_b) {
7947 switch_core_session_t *tmp;
7948
7949 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
) &&
7950 (tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 7950)
)) {
7951 switch_ivr_transfer_recordings(session, tmp);
7952 switch_core_session_rwunlock(tmp);
7953 }
7954
7955 switch_channel_set_variable_printf(channel, "transfer_to", "att:%s", br_b);
7956
7957 mark_transfer_record(session, br_a, br_b);
7958 switch_ivr_uuid_bridge(br_a, br_b);
7959 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "ATTENDED_TRANSFER", SWITCH_TRUE)
;
7960 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
);
;
7961 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
7962 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
);
;
7963 switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7963, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
7964 } else {
7965 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)
;
7966 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7966, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7967 }
7968 } else {
7969 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)
;
7970 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7970, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7971 }
7972 nua_handle_unref_user(bnh);
7973 }
7974 su_home_unref(home);
7975 home = NULL((void*)0);
7976 }
7977
7978 goto done;
7979 }
7980
7981 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "NO CODECS", SWITCH_TRUE)
;
7982 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7982, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7983 }
7984 } else {
7985 if (sofia_test_pflag(profile, PFLAG_3PCC)((profile)->pflags[PFLAG_3PCC] ? 1 : 0)) {
7986 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7987 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7987, (const char*)(session)
, SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc=yes cannot work with bypass or proxy media, hanging up.\n");
7988 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "3PCC DISABLED", SWITCH_TRUE)
;
7989 switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7989, SWITCH_CAUSE_MANDATORY_IE_MISSING)
;
7990 } else {
7991 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOSDP", SWITCH_TRUE)
;
7992 switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
7993 switch_core_media_prepare_codecs(session, 1);
7994 switch_channel_set_state(channel, CS_HIBERNATE)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7994, CS_HIBERNATE)
;
7995 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL((void*)0), 0, NULL((void*)0), 0);
7996 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", 7996, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
7997
7998 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
7999 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8000 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8001 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8002 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8003 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8004 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)
,
8005 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))
,
8006 TAG_END()(tag_type_t)0, (tag_value_t)0);
8007 } else {
8008 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8009 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8010 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8011 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
)
,
8012 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))
,
8013 TAG_END()(tag_type_t)0, (tag_value_t)0);
8014 }
8015 }
8016 } else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
8017 //3PCC proxy mode delays the 200 OK until the call is answered
8018 // 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...
8019 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOSDP", SWITCH_TRUE)
;
8020 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", 8020, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8021 //switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
8022 //switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
8023 sofia_set_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)(tech_pvt)->flags[TFLAG_LATE_NEGOTIATION] = 1;
8024 //Moves into CS_INIT so call moves forward into the dialplan
8025 if (switch_channel_get_state(channel) == CS_NEW) {
8026 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 8026, CS_INIT)
;
8027 }
8028 } else {
8029 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8029, (const char*)(session)
, SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc not enabled, hanging up.\n");
8030 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "3PCC DISABLED", SWITCH_TRUE)
;
8031 switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8031, SWITCH_CAUSE_MANDATORY_IE_MISSING)
;
8032 }
8033 goto done;
8034 }
8035
8036 } else if (tech_pvt && sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0) && !r_sdp) {
8037 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", 8037, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_NOSDP_REINVITE] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
8038 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)) {
8039 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", 8039, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8040 sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA)(tech_pvt)->flags[TFLAG_ENABLE_SOA] = 0;
8041
8042 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8042)
== SWITCH_STATUS_SUCCESS) {
8043 switch_core_session_message_t *msg;
8044 if (switch_core_session_compare(session, other_session)) {
8045 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
8046 sofia_clear_flag(other_tech_pvt, TFLAG_ENABLE_SOA)(other_tech_pvt)->flags[TFLAG_ENABLE_SOA] = 0;
8047 }
8048
8049 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8049)
;
8050 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
8051 msg->from = __FILE__"sofia.c";
8052 msg->string_arg = NULL((void*)0);
8053 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8053, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing NOSDP to other leg.\n");
8054 switch_core_session_queue_message(other_session, msg);
8055 switch_core_session_rwunlock(other_session);
8056 } else {
8057 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8057, (const char*)(session)
, SWITCH_LOG_WARNING,
8058 "NOSDP Re-INVITE to a proxy mode channel that is not in a bridge.\n");
8059 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8059, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8060 }
8061 goto done;
8062 }
8063
8064 if (switch_channel_var_true(channel, "sip_unhold_nosdp")) {
8065 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, "sendrecv",
8066 zstr(tech_pvt->mparams.local_sdp_str)_zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
8067 } else {
8068 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0),
8069 zstr(tech_pvt->mparams.local_sdp_str)_zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
8070 }
8071
8072 if (zstr(tech_pvt->mparams.local_sdp_str)_zstr(tech_pvt->mparams.local_sdp_str)) {
8073 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8073, (const char*)(session)
, SWITCH_LOG_WARNING, "Cannot find a SDP\n");
8074 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8074, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8075 } else {
8076 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
8077 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8078 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8079 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8080 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8081 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8082 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)
,
8083 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))
,
8084 TAG_END()(tag_type_t)0, (tag_value_t)0);
8085 } else {
8086 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8087 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8088 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8089 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
)
,
8090 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))
,
8091 TAG_END()(tag_type_t)0, (tag_value_t)0);
8092 }
8093 }
8094
8095 goto done;
8096
8097 } else {
8098 ss_state = nua_callstate_completed;
8099 goto state_process;
8100 }
8101
8102 break;
8103 case nua_callstate_early:
8104 if (answer_recv) {
8105 uint8_t match = 0;
8106 switch_assert(tech_pvt)((tech_pvt) ? (void) (0) : __assert_fail ("tech_pvt", "sofia.c"
, 8106, __extension__ __PRETTY_FUNCTION__))
;
8107 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", 8107, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_EARLY_MEDIA] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
8108 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 8108)
;
8109 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
8110
8111
8112 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8113 if (match) {
8114 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8115 goto done;
8116 }
8117
8118 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8119
8120 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8121 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8121, (const char*)(session)
, SWITCH_LOG_ERROR, "Early Media RTP Error!\n");
8122 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8122, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8123 }
8124 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8124, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
8125 } else {
8126 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8126, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8127 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8127, (const char*)(session)
, SWITCH_LOG_ERROR, "Early Media Codec Error!\n");
8128 }
8129 }
8130 break;
8131 case nua_callstate_completed:
8132 if (r_sdp) {
8133 const char *var;
8134 uint8_t match = 0, is_ok = 1, is_t38 = 0;
8135
8136 tech_pvt->mparams.hold_laps = 0;
8137
8138 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)) {
8139 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8139, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ignoring Re-invite\n");
8140 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);
8141 goto done;
8142 }
8143
8144 if (switch_stristr("m=image", r_sdp)) {
8145 is_t38 = 1;
8146 }
8147
8148
8149 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8150 if ((sofia_test_media_flag(profile, SCMF_DISABLE_HOLD)((profile)->media_flags[SCMF_DISABLE_HOLD] ? 1 : 0)
8151 || ((var = switch_channel_get_variable(channel, "rtp_disable_hold")switch_channel_get_variable_dup(channel, "rtp_disable_hold", SWITCH_TRUE
, -1)
) && switch_true(var)))
8152 && ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) || tech_pvt->mparams.hold_laps)) {
8153 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);
8154
8155 if (tech_pvt->mparams.hold_laps) {
8156 tech_pvt->mparams.hold_laps = 0;
8157 } else {
8158 tech_pvt->mparams.hold_laps = 1;
8159 }
8160
8161 goto done;
8162 }
8163
8164 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8164)
== SWITCH_STATUS_SUCCESS) {
8165 switch_core_session_message_t *msg;
8166 private_object_t *other_tech_pvt;
8167 int media_on_hold = switch_true(switch_channel_get_variable_dup(channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1));
8168
8169 switch_core_media_clear_rtp_flag(other_session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
8170
8171
8172 if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 &&
8173 ((profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) || media_on_hold)) {
8174 if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) {
8175 tech_pvt->mparams.hold_laps = 1;
8176 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)
;
8177 switch_channel_clear_flag(channel, CF_PROXY_MODE);
8178 switch_core_media_set_local_sdp(tech_pvt->session, NULL((void*)0), SWITCH_FALSE);
8179 switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
8180
8181 if (!switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) {
8182 //if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
8183 //const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
8184
8185
8186 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
8187 if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
8188 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)
;
8189 switch_core_session_rwunlock(other_session);
8190 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8190, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8191 goto done;
8192 }
8193 //}
8194 }
8195
8196
8197 if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
8198 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
8199 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8200 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8200, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8201 switch_core_session_rwunlock(other_session);
8202 goto done;
8203 }
8204 }
8205
8206 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 1);
8207
8208 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
8209 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8210 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8211 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8212 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8213 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8214 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)
,
8215 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))
,
8216 TAG_END()(tag_type_t)0, (tag_value_t)0);
8217 } else {
8218 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8219 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8220 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8221 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
)
,
8222 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))
,
8223 TAG_END()(tag_type_t)0, (tag_value_t)0);
8224 }
8225
8226 switch_channel_set_flag(channel, CF_PROXY_MODE)switch_channel_set_flag_value(channel, CF_PROXY_MODE, 1);
8227 switch_yield(250000)switch_sleep(250000);;
8228 launch_media_on_hold(session);
8229
8230 switch_core_session_rwunlock(other_session);
8231 goto done;
8232 }
8233 }
8234
8235 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8236 sofia_media_activate_rtp(tech_pvt);
8237 switch_core_media_proxy_remote_addr(session, r_sdp);
8238
8239 if ((tech_pvt->profile->mndlb & SM_NDLB_NEVER_PATCH_REINVITE)) {
8240 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);
8241 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8241, (const char*)(session)
, SWITCH_LOG_DEBUG, "NOT proxying re-invite.\n");
8242 switch_core_session_rwunlock(other_session);
8243 goto done;
8244 }
8245 }
8246
8247 other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
8248
8249 if (sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)((other_tech_pvt)->flags[TFLAG_REINVITED] ? 1 : 0)) {
8250 /* The other leg won the reinvite race */
8251 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8251, (const char*)(session)
, SWITCH_LOG_DEBUG, "Other leg already handling reinvite, so responding with 491\n");
8252 nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending,
8253 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);
8254 switch_core_session_rwunlock(other_session);
8255 goto done;
8256 }
8257 sofia_set_flag(tech_pvt, TFLAG_REINVITED)(tech_pvt)->flags[TFLAG_REINVITED] = 1;
8258
8259 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8259)
;
8260 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
8261 msg->from = __FILE__"sofia.c";
8262 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__, 8262)
;
8263 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8263, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing SDP to other leg.\n%s\n", r_sdp);
8264
8265 if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt)->flags[TFLAG_SIP_HOLD] ? 1 : 0)) {
8266 if (!switch_stristr("sendonly", r_sdp) && !switch_stristr("inactive", r_sdp)) {
8267 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
);
;
8268 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
8269 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__, 8269
)
;
8270 }
8271 } else if (switch_stristr("sendonly", r_sdp) && !switch_stristr("inactive", r_sdp)) {
8272 const char *msg = "hold";
8273
8274 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
8275 const char *info = switch_channel_get_variable(channel, "presence_call_info")switch_channel_get_variable_dup(channel, "presence_call_info"
, SWITCH_TRUE, -1)
;
8276 if (info) {
8277 if (switch_stristr("private", info)) {
8278 msg = "hold-private";
8279 }
8280 }
8281 }
8282
8283 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", 8283, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_SIP_HOLD] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
8284 switch_channel_set_flag(channel, CF_LEG_HOLDING)switch_channel_set_flag_value(channel, CF_LEG_HOLDING, 1);
8285 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__, 8285)
;
8286 }
8287
8288 switch_core_session_queue_message(other_session, msg);
8289
8290 switch_core_session_rwunlock(other_session);
8291 } else {
8292 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8292, (const char*)(session)
, SWITCH_LOG_WARNING,
8293 "Re-INVITE to a no-media channel that is not in a bridge.\n");
8294 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8294, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8295 }
8296 goto done;
8297 } else {
8298 int hold_related = 0;
8299
8300 if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt)->flags[TFLAG_SIP_HOLD] ? 1 : 0)) {
8301 hold_related = 2;
8302 } else if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) {
8303 hold_related = 1;
8304 }
8305
8306 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__, 8306)
== SWITCH_STATUS_SUCCESS) {
8307 if (switch_core_session_compare(session, other_session)) {
8308 switch_core_session_message_t *msg;
8309 const char *hold_msg = "hold";
8310 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
8311
8312 if (sofia_test_pflag(profile, PFLAG_PROXY_HOLD)((profile)->pflags[PFLAG_PROXY_HOLD] ? 1 : 0)) {
8313 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8314
8315 if (tech_pvt->mparams.num_codecs){
8316 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
8317 }
8318
8319 if (!match) {
8320 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8320, (const char*)(session)
, SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
8321 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
8322 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))
,
8323 TAG_END()(tag_type_t)0, (tag_value_t)0);
8324 switch_core_session_rwunlock(other_session);
8325 goto done;
8326 }
8327
8328 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8328)
;
8329
8330 if (switch_stristr("inactive", r_sdp)) {
8331 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"
, 8331, __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);
;
8332 //switch_channel_set_variable(channel, "sofia_hold_inactive", "true");
8333 } else {
8334 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);
;
8335 }
8336
8337 if (hold_related == 1) {
8338 msg->message_id = SWITCH_MESSAGE_INDICATE_HOLD;
8339 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
8340 const char *info = switch_channel_get_variable(channel, "presence_call_info")switch_channel_get_variable_dup(channel, "presence_call_info"
, SWITCH_TRUE, -1)
;
8341
8342 if (info) {
8343 if (switch_stristr("private", info)) {
8344 hold_msg = "hold-private";
8345 }
8346 }
8347 }
8348 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", 8348, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_SIP_HOLD] = 1;switch_mutex_unlock
(tech_pvt->flag_mutex);
;
8349 switch_channel_set_flag(channel, CF_LEG_HOLDING)switch_channel_set_flag_value(channel, CF_LEG_HOLDING, 1);
8350 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__, 8350
)
;
8351 } else {
8352 hold_msg = "unhold";
8353 msg->message_id = SWITCH_MESSAGE_INDICATE_UNHOLD;
8354 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
);
;
8355 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
8356 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__, 8356
)
;
8357 }
8358 msg->from = __FILE__"sofia.c";
8359 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8359, (const char*)(session)
, SWITCH_LOG_DEBUG, "Indicating %s to other leg.\n%s\n", hold_msg, r_sdp);
8360
8361 switch_core_session_queue_message(other_session, msg);
8362
8363
8364
8365 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8366 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)){
8367 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8368 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8369 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8370 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8371 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8372 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)
,
8373 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))
,
8374 TAG_END()(tag_type_t)0, (tag_value_t)0);
8375 } else {
8376 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8377 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8378 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8379 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
)
,
8380 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))
,
8381 TAG_END()(tag_type_t)0, (tag_value_t)0);
8382 }
8383 switch_core_session_rwunlock(other_session);
8384 goto done;
8385 }
8386 }
8387
8388 switch_core_session_rwunlock(other_session);
8389 }
8390
8391 if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) {
8392 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
8393 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8394 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8395 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8396 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8397 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8398 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)
,
8399 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))
,
8400 TAG_END()(tag_type_t)0, (tag_value_t)0);
8401 } else {
8402 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8403 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8404 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8405 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
)
,
8406 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))
,
8407 TAG_END()(tag_type_t)0, (tag_value_t)0);
8408 }
8409 goto done;
8410 }
8411
8412 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8413
8414 if (tech_pvt->mparams.num_codecs) {
8415 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
8416 }
8417
8418
8419 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
8420 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);
8421 goto done;
8422 }
8423
8424 if (match && sofia_test_flag(tech_pvt, TFLAG_NOREPLY)((tech_pvt)->flags[TFLAG_NOREPLY] ? 1 : 0)) {
8425 sofia_clear_flag(tech_pvt, TFLAG_NOREPLY)(tech_pvt)->flags[TFLAG_NOREPLY] = 0;
8426 goto done;
8427 }
8428
8429 if (match) {
8430 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8431 goto done;
8432 }
8433
8434 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8435
8436 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8437 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8437, (const char*)(session)
, SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
8438 is_ok = 0;
8439 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8439, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8440 }
8441 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8441, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
8442 } else {
8443 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8444 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);
8445 goto done;
8446 }
8447
8448 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8449 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8449, (const char*)(session)
, SWITCH_LOG_DEBUG, "Reinvite resulted in codec negotiation failure.\n");
8450 is_ok = 0;
8451 }
8452 }
8453
8454
8455 if (is_ok) {
8456
8457 if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
8458 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8459 }
8460
8461 if (!switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) {
8462 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
8463 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8464 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8465 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
8466 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
8467 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
8468 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)
,
8469 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))
,
8470 TAG_END()(tag_type_t)0, (tag_value_t)0);
8471 } else {
8472 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
8473 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
8474 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
8475 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
)
,
8476 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))
,
8477 TAG_END()(tag_type_t)0, (tag_value_t)0);
8478 }
8479 }
8480
8481 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__, 8481, &s_event, SWITCH_EVENT_CUSTOM
, "sofia::reinvite")
== SWITCH_STATUS_SUCCESS) {
8482 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
8483 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 8483, &s_event, ((void*)0))
;
8484 }
8485 } else {
8486 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable,
8487 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))
,
8488 TAG_END()(tag_type_t)0, (tag_value_t)0);
8489 }
8490 }
8491 break;
8492 case nua_callstate_ready:
8493 if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA) &&
8494 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)) {
8495 /* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */
8496 uint8_t match = 0;
8497
8498 sofia_clear_flag(tech_pvt, TFLAG_NEW_SDP)(tech_pvt)->flags[TFLAG_NEW_SDP] = 0;
8499 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8500
8501
8502 if (tech_pvt->mparams.num_codecs) {
8503 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8504 }
8505 if (match) {
8506 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8507 goto done;
8508 }
8509 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
8510
8511 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8511, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
8512 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8513
8514 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8515 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8515, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
8516 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8516, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8517 goto done;
8518 }
8519 } else {
8520 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8521 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8521, (const char*)(session)
, SWITCH_LOG_ERROR, "Codec Error! %s\n", r_sdp);
8522 goto done;
8523
8524 }
8525 }
8526
8527 if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)((tech_pvt)->flags[TFLAG_NOSDP_REINVITE] ? 1 : 0)) {
8528 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);
;
8529 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8530 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8531 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8532 goto done;
8533 }
8534 }
8535
8536 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8536)
== SWITCH_STATUS_SUCCESS) {
8537 other_channel = switch_core_session_get_channel(other_session);
8538 switch_channel_pass_sdp(channel, other_channel, r_sdp);
8539
8540 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)) {
8541 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8541, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8542 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
8543 } else {
8544 switch_core_session_message_t *msg;
8545
8546 if (sofia_test_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)((profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] ? 1
: 0)
) {
8547 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8547)
;
8548 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
8549 msg->from = __FILE__"sofia.c";
8550 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__, 8550)
;
8551 switch_core_session_queue_message(other_session, msg);
8552 }
8553
8554 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8555 }
8556
8557 switch_core_session_rwunlock(other_session);
8558 }
8559 } else {
8560 uint8_t match = 0;
8561 int is_ok = 1;
8562
8563 if (!tech_pvt) goto done;
8564
8565 if (tech_pvt->mparams.num_codecs) {
8566 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8567 }
8568
8569 if (match) {
8570 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8571 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8572 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8572, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
8573 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)
;
8574 is_ok = 0;
8575 }
8576 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8577 } else {
8578 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)
;
8579 is_ok = 0;
8580 }
8581
8582 if (!is_ok) {
8583 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);
8584 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 8584, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION
)
;
8585 }
8586 }
8587 goto done;
8588 }
8589
8590 if (channel) {
8591 switch_channel_clear_flag(channel, CF_REQ_MEDIA);
8592 }
8593 if (tech_pvt && nh == tech_pvt->nh2) {
8594 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8594, (const char*)(session)
, SWITCH_LOG_DEBUG, "Cheater Reinvite!\n");
8595 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
8596 tech_pvt->nh = tech_pvt->nh2;
8597 tech_pvt->nh2 = NULL((void*)0);
8598 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) == SWITCH_STATUS_SUCCESS) {
8599 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8600 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8600, (const char*)(session)
, SWITCH_LOG_ERROR, "Cheater Reinvite RTP Error!\n");
8601 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8601, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8602 }
8603 }
8604 goto done;
8605 }
8606
8607 if (channel) {
8608 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)) {
8609 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", 8609, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8610 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
8611 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 8611)
;
8612
8613 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8614 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8614)
== SWITCH_STATUS_SUCCESS) {
8615 //other_channel = switch_core_session_get_channel(other_session);
8616 //switch_channel_answer(other_channel);
8617 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8618 switch_core_session_rwunlock(other_session);
8619 }
8620 }
8621 goto done;
8622 }
8623
8624 if (!r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
8625 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)
;
8626 }
8627
8628 if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
8629 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8630 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", 8630, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8631 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", 8631, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_SDP] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8632 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 8632)
;
8633
8634 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8635 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8636 goto done;
8637 }
8638 }
8639
8640 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8640)
== SWITCH_STATUS_SUCCESS) {
8641 other_channel = switch_core_session_get_channel(other_session);
8642 switch_channel_pass_sdp(channel, other_channel, r_sdp);
8643
8644 //switch_channel_answer(other_channel);
8645 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8646
8647 switch_core_session_rwunlock(other_session);
8648 }
8649
8650 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)) {
8651 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8651, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8652 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
8653 }
8654
8655 goto done;
8656 } else {
8657 uint8_t match = 0;
8658
8659
8660 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8661
8662
8663 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", 8663, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8664
8665 if (match) {
8666 switch_channel_check_zrtp(channel);
8667
8668 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) == SWITCH_STATUS_SUCCESS) {
8669 if (sofia_media_activate_rtp(tech_pvt) == SWITCH_STATUS_SUCCESS) {
8670 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 8670)
;
8671 } else {
8672 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8672, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
8673 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8673, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
8674 }
8675
8676 if (sofia_test_flag(tech_pvt, TFLAG_3PCC)((tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0)) {
8677 /* Check if we are in 3PCC proxy mode, if so then set the flag to indicate we received the ack */
8678 if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
8679 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8679, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8680 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
8681 } else if (switch_channel_get_state(channel) == CS_HIBERNATE) {
8682 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", 8682, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8683 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 8683, CS_INIT)
;
8684 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
8685 }
8686 }
8687 goto done;
8688 }
8689 }
8690
8691 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "NO CODECS", SWITCH_TRUE)
;
8692 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8692, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
8693 }
8694 }
8695 }
8696
8697 break;
8698 case nua_callstate_terminating:
8699 if (status == 488 || switch_channel_get_state(channel) == CS_HIBERNATE) {
8700 tech_pvt->q850_cause = SWITCH_CAUSE_MANDATORY_IE_MISSING;
8701 }
8702 case nua_callstate_terminated:
8703 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", 8703, __extension__
__PRETTY_FUNCTION__));switch_mutex_lock(tech_pvt->flag_mutex
);(tech_pvt)->flags[TFLAG_BYE] = 1;switch_mutex_unlock(tech_pvt
->flag_mutex);
;
8704 if (sofia_test_flag(tech_pvt, TFLAG_NOHUP)((tech_pvt)->flags[TFLAG_NOHUP] ? 1 : 0)) {
8705 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
);
;
8706 } else if (switch_channel_up(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) < CS_HANGUP)
) {
8707 int cause;
8708 if (tech_pvt->q850_cause) {
8709 cause = tech_pvt->q850_cause;
8710 } else {
8711 cause = sofia_glue_sip_cause_to_freeswitch(status);
8712 }
8713 if (status) {
8714 switch_snprintf(st, sizeof(st), "%d", status);
8715 switch_channel_set_variable(channel, "sip_term_status", st)switch_channel_set_variable_var_check(channel, "sip_term_status"
, st, SWITCH_TRUE)
;
8716 switch_snprintf(st, sizeof(st), "sip:%d", status);
8717 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)
;
8718 if (phrase) {
8719 switch_channel_set_variable_partner(channel, "sip_hangup_phrase", phrase)switch_channel_set_variable_partner_var_check(channel, "sip_hangup_phrase"
, phrase, SWITCH_TRUE)
;
8720 }
8721 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_BYE_HEADER_PREFIX"sip_bye_h_");
8722 }
8723 switch_snprintf(st, sizeof(st), "%d", cause);
8724 switch_channel_set_variable(channel, "sip_term_cause", st)switch_channel_set_variable_var_check(channel, "sip_term_cause"
, st, SWITCH_TRUE)
;
8725 switch_channel_hangup(channel, cause)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 8725, cause)
;
8726 ss_state = nua_callstate_terminated;
8727 }
8728
8729 if (ss_state == nua_callstate_terminated) {
8730 if (tech_pvt->sofia_private) {
8731 tech_pvt->sofia_private = NULL((void*)0);
8732 }
8733
8734 tech_pvt->nh = NULL((void*)0);
8735
8736 if (nh) {
8737 nua_handle_bind(nh, NULL((void*)0));
8738 nua_handle_destroy(nh);
8739 }
8740 }
8741
8742 break;
8743 }
8744
8745 done:
8746
8747 switch_safe_free(patched_sdp)if (patched_sdp) {free(patched_sdp);patched_sdp=((void*)0);};
8748
8749 if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) {
8750 sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY)(tech_pvt)->flags[TFLAG_SIMPLIFY] = 1;
8751 }
8752
8753
8754 return;
8755}
8756
8757typedef struct {
8758 char *exten;
8759 char *exten_with_params;
8760 char *event;
8761 char *reply_uuid;
8762 char *bridge_to_uuid;
8763 switch_event_t *vars;
8764 switch_memory_pool_t *pool;
8765 sofia_profile_t *profile;
8766} nightmare_xfer_helper_t;
8767
8768void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void *obj)
8769{
8770 nightmare_xfer_helper_t *nhelper = (nightmare_xfer_helper_t *) obj;
8771 switch_memory_pool_t *pool;
8772 switch_status_t status = SWITCH_STATUS_FALSE;
8773 switch_core_session_t *session, *a_session;
8774
8775 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__, 8775)
)) {
8776 switch_core_session_t *tsession = NULL((void*)0);
8777 switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
8778 uint32_t timeout = 60;
8779 char *tuuid_str;
8780
8781 if ((session = switch_core_session_locate(nhelper->reply_uuid)switch_core_session_perform_locate(nhelper->reply_uuid, "sofia.c"
, (const char *)__func__, 8781)
)) {
8782 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8783 switch_channel_t *channel_a = switch_core_session_get_channel(session);
8784 const char *session_id_header = sofia_glue_session_id_header(session, nhelper->profile);
8785
8786 if ((status = switch_ivr_originate(NULL((void*)0), &tsession, &cause, nhelper->exten_with_params, timeout, NULL((void*)0), NULL((void*)0), NULL((void*)0),
8787 switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL((void*)0), NULL((void*)0))) == SWITCH_STATUS_SUCCESS) {
8788 if (switch_channel_up(channel_a)(switch_channel_check_signal(channel_a, SWITCH_TRUE) || switch_channel_get_state
(channel_a) < CS_HANGUP)
) {
8789
8790 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)
)) {
8791 switch_ivr_transfer_recordings(session, a_session);
8792 }
8793
8794
8795 tuuid_str = switch_core_session_get_uuid(tsession);
8796 switch_channel_set_variable_printf(channel_a, "transfer_to", "att:%s", tuuid_str);
8797 mark_transfer_record(session, nhelper->bridge_to_uuid, tuuid_str);
8798 switch_ivr_uuid_bridge(nhelper->bridge_to_uuid, tuuid_str);
8799 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)
;
8800 } else {
8801 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__, 8801, SWITCH_CAUSE_ORIGINATOR_CANCEL
)
;
8802 status = SWITCH_STATUS_FALSE;
8803 }
8804 switch_core_session_rwunlock(tsession);
8805 }
8806
8807 if (status == SWITCH_STATUS_SUCCESS) {
8808 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8808, (const char*)(session)
, SWITCH_LOG_DEBUG, "The nightmare is over.....\n");
8809 } else {
8810 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8810, (const char*)(session)
, SWITCH_LOG_DEBUG, "1 .. 2 .. Freddie's commin' for you...\n");
8811 }
8812
8813 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"),
8814 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"
)
,
8815 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")
8816 "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),
8817 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))
,
8818 TAG_END()(tag_type_t)0, (tag_value_t)0);
8819
8820 switch_core_session_rwunlock(session);
8821 }
8822
8823 switch_core_session_rwunlock(a_session);
8824 }
8825
8826 switch_event_destroy(&nhelper->vars);
8827
8828 pool = nhelper->pool;
8829 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia.c",
(const char *)__func__, 8829)
;
8830
8831 return NULL((void*)0);
8832}
8833
8834static void launch_nightmare_xfer(nightmare_xfer_helper_t *nhelper)
8835{
8836 switch_thread_t *thread;
8837 switch_threadattr_t *thd_attr = NULL((void*)0);
8838
8839 switch_threadattr_create(&thd_attr, nhelper->pool);
8840 switch_threadattr_detach_set(thd_attr, 1);
8841 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
8842 switch_thread_create(&thread, thd_attr, nightmare_xfer_thread_run, nhelper, nhelper->pool);
8843}
8844
8845/*---------------------------------------*/
8846
8847static switch_status_t xfer_hanguphook(switch_core_session_t *session)
8848{
8849 switch_channel_t *channel = switch_core_session_get_channel(session);
8850 switch_channel_state_t state = switch_channel_get_state(channel);
8851
8852 if (state == CS_HANGUP) {
8853 switch_core_session_t *ksession;
8854 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)
;
8855
8856 if (uuid && (ksession = switch_core_session_force_locate(uuid)switch_core_session_perform_force_locate(uuid, "sofia.c", (const
char *)__func__, 8856)
)) {
8857 switch_channel_t *kchannel = switch_core_session_get_channel(ksession);
8858
8859 switch_channel_clear_flag(kchannel, CF_XFER_ZOMBIE);
8860 switch_channel_clear_flag(kchannel, CF_TRANSFER);
8861 if (switch_channel_up(kchannel)(switch_channel_check_signal(kchannel, SWITCH_TRUE) || switch_channel_get_state
(kchannel) < CS_HANGUP)
) {
8862 switch_channel_hangup(kchannel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(kchannel, "sofia.c", (const char
*)__func__, 8862, SWITCH_CAUSE_NORMAL_CLEARING)
;
8863 }
8864
8865 switch_core_session_rwunlock(ksession);
8866 }
8867
8868 switch_core_event_hook_remove_state_change(session, xfer_hanguphook);
8869
8870 }
8871
8872 return SWITCH_STATUS_SUCCESS;
8873}
8874
8875nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces)
8876{
8877 nua_handle_t *nh = NULL((void*)0);
8878 switch_hash_index_t *hi;
8879 const void *var;
8880 void *val;
8881 sofia_profile_t *profile;
8882
8883 switch_mutex_lock(mod_sofia_globals.hash_mutex);
8884 if (mod_sofia_globals.profile_hash) {
8885 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)) {
8886 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
8887 if ((profile = (sofia_profile_t *) val)) {
8888 if (!(nh = nua_handle_by_replaces(profile->nua, replaces))) {
8889 nh = nua_handle_by_call_id(profile->nua, replaces->rp_call_id);
8890 }
8891 if (nh)
8892 break;
8893 }
8894 }
8895 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
8896 }
8897 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
8898
8899 return nh;
8900
8901}
8902
8903static switch_status_t sofia_process_proxy_refer(switch_core_session_t *session, const char *refer_to)
8904{
8905 switch_core_session_t *other_session;
8906 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8907
8908 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8908)
== SWITCH_STATUS_SUCCESS) {
8909 switch_core_session_message_t *msg;
8910
8911 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__, 8911)
;
8912 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 8912)
;
8913 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 8913
;
8914 msg->message_id = SWITCH_MESSAGE_INDICATE_DEFLECT;
8915 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__, 8915)
;
8916 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__, 8916)
;
8917 msg->from = __FILE__"sofia.c";
8918 switch_core_session_queue_message(other_session, msg);
8919 switch_core_session_rwunlock(other_session);
8920 return SWITCH_STATUS_SUCCESS;
8921 }
8922
8923 return SWITCH_STATUS_FALSE;
8924}
8925
8926void 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,
8927 sofia_dispatch_event_t *de, tagi_t tags[])
8928{
8929 /* Incoming refer */
8930 sip_from_t const *from;
8931 //sip_to_t const *to;
8932 sip_refer_to_t const *refer_to;
8933 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8934 char *etmp = NULL((void*)0), *exten = NULL((void*)0);
8935 switch_channel_t *channel_a = switch_core_session_get_channel(session);
8936 switch_channel_t *channel_b = NULL((void*)0);
8937 su_home_t *home = NULL((void*)0);
8938 char *full_ref_by = NULL((void*)0);
8939 char *full_ref_to = NULL((void*)0);
8940 nightmare_xfer_helper_t *nightmare_xfer_helper;
8941 switch_memory_pool_t *npool;
8942 switch_event_t *event = NULL((void*)0);
8943 const char *session_id_header = sofia_glue_session_id_header(session, profile);
8944
8945 if (!(profile->mflags & MFLAG_REFER)) {
8946 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);
8947 goto done;
8948 }
8949
8950 if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
8951 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8951, (const char*)(session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
8952 goto done;
8953 }
8954
8955 home = su_home_new(sizeof(*home));
8956 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 8956, __extension__ __PRETTY_FUNCTION__))
;
8957
8958 if ((refer_to = sip->sip_refer_to)) {
8959 full_ref_to = sip_header_as_string(home, (void *) sip->sip_refer_to);
8960 }
8961
8962 if (full_ref_to && sofia_test_pflag(profile, PFLAG_PROXY_REFER)((profile)->pflags[PFLAG_PROXY_REFER] ? 1 : 0)) {
8963 if (sofia_process_proxy_refer(session, full_ref_to) == SWITCH_STATUS_SUCCESS) {
8964 if (tech_pvt->proxy_refer_msg) {
8965 msg_ref_destroy(tech_pvt->proxy_refer_msg);
8966 tech_pvt->proxy_refer_msg = NULL((void*)0);
8967 }
8968 tech_pvt->proxy_refer_msg = msg_ref_create(de->data->e_msg);
8969 //nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), TAG_END());
8970 goto done;
8971 }
8972 }
8973
8974 from = sip->sip_from;
8975 //to = sip->sip_to;
8976
8977 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"),
8978 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);
8979
8980
8981 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)
;
8982
8983 if (sip->sip_referred_by) {
8984 full_ref_by = sip_header_as_string(home, (void *) sip->sip_referred_by);
8985 }
8986
8987 if (refer_to) {
8988 char *rep = NULL((void*)0);
8989
8990 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
8991 exten = switch_core_session_sprintf(session, "%s@%s", (char *) refer_to->r_url->url_user, (char *) refer_to->r_url->url_host);
8992 } else {
8993 exten = (char *) refer_to->r_url->url_user;
8994 }
8995
8996 if (refer_to->r_url->url_params) {
8997 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)
;
8998 }
8999
9000 switch_core_session_queue_indication(session, SWITCH_MESSAGE_REFER_EVENT);
9001 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9001, (const char*)(session)
, SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
9002
9003 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)
;
9004
9005
9006 if (refer_to->r_url->url_headers) {
9007 rep = (char *) switch_stristr("Replaces=", refer_to->r_url->url_headers);
9008 }
9009
9010
9011 if (rep) {
9012 sip_replaces_t *replaces;
9013 nua_handle_t *bnh = NULL((void*)0);
9014
9015 const char *br_a = NULL((void*)0), *br_b = NULL((void*)0);
9016 char *buf;
9017 char *p;
9018
9019 rep = switch_core_session_strdup(session, rep + 9)switch_core_perform_session_strdup(session, rep + 9, "sofia.c"
, (const char *)__func__, 9019)
;
9020
9021 if ((buf = switch_core_session_alloc(session, strlen(rep) + 1)switch_core_perform_session_alloc(session, strlen(rep) + 1, "sofia.c"
, (const char *)__func__, 9021)
)) {
9022 rep = url_unescape(buf, (const char *) rep);
9023 if ((p = strchr(rep, ';'))) {
9024 *p = '\0';
9025 }
9026 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9026, (const char*)(session)
, SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep);
9027 } else {
9028 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9028, (const char*)(session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
9029 goto done;
9030 }
9031
9032 if ((replaces = sip_replaces_make(home, rep))) {
9033 if (!(bnh = nua_handle_by_replaces(nua, replaces))) {
9034 if (!(bnh = nua_handle_by_call_id(nua, replaces->rp_call_id))) {
9035 bnh = sofia_global_nua_handle_by_replaces(replaces);
9036 }
9037 }
9038 }
9039
9040 if (bnh && !sofia_test_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)((profile)->pflags[PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE] ?
1 : 0)
) {
9041 sofia_private_t *b_private = NULL((void*)0);
9042 private_object_t *b_tech_pvt = NULL((void*)0);
9043 switch_core_session_t *b_session = NULL((void*)0);
9044
9045
9046 switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep)switch_channel_set_variable_var_check(channel_a, "_sofia_replaces_"
, rep, SWITCH_TRUE)
;
9047 if ((b_private = nua_handle_magic(bnh))) {
9048 int deny_refer_requests = 0;
9049
9050 if (!(b_session = switch_core_session_locate(b_private->uuid)switch_core_session_perform_locate(b_private->uuid, "sofia.c"
, (const char *)__func__, 9050)
)) {
9051 goto done;
9052 }
9053 b_tech_pvt = (private_object_t *) switch_core_session_get_private(b_session)switch_core_session_get_private_class(b_session, SWITCH_PVT_PRIMARY
)
;
9054 channel_b = switch_core_session_get_channel(b_session);
9055
9056 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)
;
9057 switch_channel_set_variable(channel_b, "transfer_disposition", "replaced")switch_channel_set_variable_var_check(channel_b, "transfer_disposition"
, "replaced", SWITCH_TRUE)
;
9058
9059 br_a = switch_channel_get_partner_uuid(channel_a);
9060 br_b = switch_channel_get_partner_uuid(channel_b);
9061
9062 if (!switch_ivr_uuid_exists(br_a)) {
9063 br_a = NULL((void*)0);
9064 }
9065
9066 if (!switch_ivr_uuid_exists(br_b)) {
9067 br_b = NULL((void*)0);
9068 }
9069
9070 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)
)) {
9071 deny_refer_requests = 1;
9072 }
9073
9074 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)
)) {
9075 deny_refer_requests = 1;
9076 }
9077
9078 if (!deny_refer_requests && br_a) {
9079 switch_core_session_t *a_session;
9080 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9080)
)) {
9081 switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
9082
9083 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)
)) {
9084 deny_refer_requests = 1;
9085 }
9086 switch_core_session_rwunlock(a_session);
9087 }
9088 }
9089
9090 if (!deny_refer_requests && br_b) {
9091 switch_core_session_t *b_session;
9092 if ((b_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 9092)
)) {
9093 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
9094
9095 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)
)) {
9096 deny_refer_requests = 1;
9097 }
9098 switch_core_session_rwunlock(b_session);
9099 }
9100 }
9101
9102 if (deny_refer_requests) {
9103 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9103, (const char*)(session)
, SWITCH_LOG_NOTICE, "Denying Attended Transfer, variable [deny_refer_requests] was set to true\n");
9104
9105 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"
)
,
9106 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"
)
,
9107 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))
,
9108 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);
9109
9110 } else if (switch_channel_test_flag(channel_b, CF_ORIGINATOR)) {
9111 switch_core_session_t *a_session;
9112
9113 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9113, (const char*)(session)
, SWITCH_LOG_NOTICE,
9114 "Attended Transfer on originating session %s\n", switch_core_session_get_uuid(b_session));
9115
9116
9117
9118 switch_channel_set_variable_printf(channel_b, "transfer_to", "satt:%s", br_a);
9119
9120 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)
;
9121
9122
9123 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);
;
9124 switch_channel_clear_flag(channel_b, CF_LEG_HOLDING);
9125 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
);
;
9126
9127 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)
;
9128 switch_channel_set_flag(channel_b, CF_XFER_ZOMBIE)switch_channel_set_flag_value(channel_b, CF_XFER_ZOMBIE, 1);
9129 switch_channel_set_flag(channel_b, CF_TRANSFER)switch_channel_set_flag_value(channel_b, CF_TRANSFER, 1);
9130
9131
9132 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9132)
)) {
9133 const char *moh = profile->hold_music;
9134 switch_core_session_t *tmpsess = NULL((void*)0);
9135 switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
9136 switch_caller_profile_t *prof = switch_channel_get_caller_profile(channel_b);
9137 const char *tmp;
9138
9139 switch_core_event_hook_add_state_change(a_session, xfer_hanguphook);
9140 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)
;
9141 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)
;
9142 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)
;
9143 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)
;
9144
9145 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) {
9146 switch_channel_set_flag(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
9147 }
9148
9149
9150 if ((tmp = switch_channel_get_hold_music(a_channel))) {
9151 moh = tmp;
9152 }
9153
9154 if (!zstr(moh)_zstr(moh) && !strcasecmp(moh, "silence")) {
9155 moh = NULL((void*)0);
9156 }
9157
9158 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9159 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9159, &event, SWITCH_EVENT_CUSTOM
, "sofia::replaced")
== SWITCH_STATUS_SUCCESS) {
9160 switch_channel_event_set_data(channel_b, event);
9161 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", br_a);
9162 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9162, &event, ((void*)0))
;
9163 }
9164
9165 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9165, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9166 switch_channel_event_set_data(channel_a, event);
9167 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9168 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9169 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_core_session_get_uuid(b_session));
9170 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9170, &event, ((void*)0))
;
9171 }
9172
9173 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9173, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9174 switch_channel_event_set_data(a_channel, event);
9175 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_call_id", switch_core_session_get_uuid(b_session));
9176 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9176, &event, ((void*)0))
;
9177 }
9178 }
9179
9180 if (moh) {
9181 char *xdest;
9182 xdest = switch_core_session_sprintf(a_session, "m:\":endless_playback:%s\"park", moh);
9183 switch_ivr_session_transfer(a_session, xdest, "inline", NULL((void*)0));
9184 } else {
9185 switch_ivr_session_transfer(a_session, "park", "inline", NULL((void*)0));
9186 }
9187 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)
)) {
9188 switch_ivr_transfer_recordings(session, a_session);
9189 }
9190 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__, 9190)
)) {
9191 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9191, (const char*)(session)
, SWITCH_LOG_NOTICE,
9192 "Early transfer detected with no media, moving recording bug to other leg\n");
9193 switch_ivr_transfer_recordings(b_session, tmpsess);
9194 switch_core_session_rwunlock(tmpsess);
9195 }
9196
9197 switch_core_session_rwunlock(a_session);
9198
9199 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"
)
,
9200 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),
9201 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))
,
9202 TAG_END()(tag_type_t)0, (tag_value_t)0);
9203
9204 if (b_tech_pvt && !sofia_test_flag(b_tech_pvt, TFLAG_BYE)((b_tech_pvt)->flags[TFLAG_BYE] ? 1 : 0)) {
9205 char *q850 = NULL((void*)0);
9206 const char *val = NULL((void*)0);
9207
9208 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", 9208, __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);
;
9209 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)
;
9210 if (!val || switch_true(val)) {
9211 q850 = switch_core_session_sprintf(a_session, "Q.850;cause=16;text=\"normal_clearing\"");
9212 }
9213 nua_bye(b_tech_pvt->nh,
9214 SIPTAG_CONTACT(SIP_NONE)siptag_contact, siptag_contact_v(((void const *)-1L)),
9215 TAG_IF(!zstr(q850), SIPTAG_REASON_STR(q850))!(!_zstr(q850)) ? tag_skip : siptag_reason_str, tag_str_v(q850
)
,
9216 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)
,
9217 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))
,
9218 TAG_END()(tag_type_t)0, (tag_value_t)0);
9219
9220 }
9221 } else {
9222 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"
)
,
9223 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"
)
,
9224 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),
9225 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))
,
9226 TAG_END()(tag_type_t)0, (tag_value_t)0);
9227 }
9228
9229 } else if (br_a && br_b) {
9230 switch_core_session_t *tmp = NULL((void*)0);
9231 switch_event_t *event = NULL((void*)0);
9232
9233 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9233, (const char*)(session)
, SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n",
9234 switch_str_nil(br_a)(br_a ? br_a : ""), switch_str_nil(br_b)(br_b ? br_b : ""));
9235
9236 if ((tmp = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 9236)
)) {
9237 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9238
9239 if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER)) {
9240 switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
9241 }
9242
9243 switch_channel_set_variable(tchannel, "transfer_disposition", "bridge")switch_channel_set_variable_var_check(tchannel, "transfer_disposition"
, "bridge", SWITCH_TRUE)
;
9244
9245 switch_channel_set_flag(tchannel, CF_ATTENDED_TRANSFER)switch_channel_set_flag_value(tchannel, CF_ATTENDED_TRANSFER,
1)
;
9246 switch_core_session_rwunlock(tmp);
9247 }
9248
9249 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__, 9249)
)) {
9250 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9251 switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
9252 switch_core_session_rwunlock(tmp);
9253 }
9254
9255
9256 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)
) &&
9257 (tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9257)
)) {
9258 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)
;
9259 switch_ivr_transfer_recordings(session, tmp);
9260 switch_core_session_rwunlock(tmp);
9261 }
9262
9263
9264 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)
) &&
9265 (tmp = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 9265)
)) {
9266 switch_ivr_transfer_recordings(b_session, tmp);
9267 switch_core_session_rwunlock(tmp);
9268 }
9269
9270 switch_channel_set_variable_printf(channel_a, "transfer_to", "att:%s", br_b);
9271
9272 mark_transfer_record(session, br_a, br_b);
9273
9274 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9275 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9275, &event, SWITCH_EVENT_CUSTOM
, "sofia::replaced")
== SWITCH_STATUS_SUCCESS) {
9276 switch_channel_event_set_data(channel_b, event);
9277 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", br_a);
9278 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9278, &event, ((void*)0))
;
9279 }
9280
9281 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9281, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9282 switch_channel_event_set_data(channel_a, event);
9283 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9284 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9285 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_core_session_get_uuid(b_session));
9286 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9286, &event, ((void*)0))
;
9287 }
9288
9289 if ((tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9289)
)) {
9290 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9291
9292 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9292, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9293 switch_channel_event_set_data(tchannel, event);
9294 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9294, &event, ((void*)0))
;
9295 }
9296
9297 switch_core_session_rwunlock(tmp);
9298 }
9299 }
9300
9301 switch_ivr_uuid_bridge(br_a, br_b);
9302 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)
;
9303 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"
)
,
9304 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),
9305 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))
,
9306 TAG_END()(tag_type_t)0, (tag_value_t)0);
9307
9308 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);
;
9309 switch_channel_clear_flag(channel_b, CF_LEG_HOLDING);
9310 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
);
;
9311 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)
;
9312 switch_channel_set_state(channel_b, CS_PARK)switch_channel_perform_set_state(channel_b, "sofia.c", (const
char *)__func__, 9312, CS_PARK)
;
9313 switch_channel_wait_for_state_timeout(channel_b, CS_PARK, 5000);
9314
9315 } else {
9316 if (!br_a && !br_b) {
9317 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9317, (const char*)(session)
, SWITCH_LOG_WARNING,
9318 "Cannot transfer channels that are not in a bridge.\n");
9319 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"
)
,
9320 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"),
9321 SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp),
9322 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))
,
9323 TAG_END()(tag_type_t)0, (tag_value_t)0);
9324 } else {
9325 switch_core_session_t *t_session, *hup_session;
9326 switch_channel_t *hup_channel;
9327 switch_event_t *event = NULL((void*)0);
9328 const char *ext;
9329
9330 if (br_a && !br_b) {
9331 t_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9331)
;
9332 hup_channel = channel_b;
9333 hup_session = b_session;
9334 } else {
9335 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
)
;
9336 t_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 9336)
;
9337 hup_channel = channel_a;
9338 hup_session = session;
9339 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
);
;
9340 switch_channel_clear_flag(tech_pvt->channel, CF_LEG_HOLDING);
9341 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);
;
9342 switch_channel_clear_flag(h_tech_pvt->channel, CF_LEG_HOLDING);
9343 switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(channel_b, "sofia.c", (const char
*)__func__, 9343, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
9344 }
9345
9346 if (t_session) {
9347 switch_channel_t *t_channel = switch_core_session_get_channel(t_session);
9348 const char *idest = switch_channel_get_variable(hup_channel, "inline_destination")switch_channel_get_variable_dup(hup_channel, "inline_destination"
, SWITCH_TRUE, -1)
;
9349 ext = switch_channel_get_variable(hup_channel, "destination_number")switch_channel_get_variable_dup(hup_channel, "destination_number"
, SWITCH_TRUE, -1)
;
9350
9351 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
9352 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)
;
9353 }
9354
9355 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
9356 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)
;
9357 }
9358
9359
9360 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)
)) {
9361 switch_ivr_transfer_recordings(hup_session, t_session);
9362 }
9363
9364 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9365 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9365, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9366 switch_channel_event_set_data(channel_a, event);
9367 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", switch_core_session_get_uuid(hup_session));
9368 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", switch_core_session_get_uuid(t_session));
9369 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_channel_get_partner_uuid(t_channel));
9370 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9370, &event, ((void*)0))
;
9371 }
9372
9373 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9373, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9374 switch_channel_event_set_data(t_channel, event);
9375 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9375, &event, ((void*)0))
;
9376 }
9377 }
9378
9379 if (idest) {
9380 switch_ivr_session_transfer(t_session, idest, "inline", NULL((void*)0));
9381 } else {
9382 switch_ivr_session_transfer(t_session, ext, NULL((void*)0), NULL((void*)0));
9383 }
9384
9385 nua_notify(tech_pvt->nh,
9386 NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1),
9387 SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
9388 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"
)
,
9389 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),
9390 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))
,
9391 TAG_END()(tag_type_t)0, (tag_value_t)0);
9392 switch_core_session_rwunlock(t_session);
9393 switch_channel_hangup(hup_channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(hup_channel, "sofia.c", (const char
*)__func__, 9393, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
9394 } else {
9395 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9395, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session to transfer to not found.\n");
9396 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"
)
,
9397 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"
)
,
9398 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),
9399 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))
,
9400 TAG_END()(tag_type_t)0, (tag_value_t)0);
9401 }
9402 }
9403 }
9404 switch_core_session_rwunlock(b_session);
9405 }
9406 nua_handle_unref_user(bnh);
9407 } else { /* the other channel is on a different box, we have to go find them */
9408 if (exten && (br_a = switch_channel_get_partner_uuid(channel_a))) {
9409 switch_core_session_t *a_session;
9410 switch_channel_t *channel;
9411
9412 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 9412)
)) {
9413 const char *port = NULL((void*)0);
9414 const char *rep_h = NULL((void*)0);
9415
9416 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9416, (const char*)(session)
, SWITCH_LOG_DEBUG,
9417 "REFER from %s replaces %s (%s@%s) with %s on another server\n",
9418 switch_core_session_get_uuid(session), rep, exten, (char *) refer_to->r_url->url_host, br_a);
9419
9420 if (refer_to->r_url->url_port) {
9421 port = refer_to->r_url->url_port;
9422 }
9423
9424 channel = switch_core_session_get_channel(a_session);
9425
9426 exten = NULL((void*)0);
9427
9428 if (sofia_test_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)((profile)->pflags[PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER
] ? 1 : 0)
) {
9429 switch_xml_t xml_root = NULL((void*)0), xml_channel = NULL((void*)0);
9430 switch_event_t *xml_params = NULL((void*)0);
9431 const char *xml_url = NULL((void*)0), *use_profile = profile->name, *dial_prefix = NULL((void*)0), *absolute_dial_string = NULL((void*)0);
9432 switch_xml_t params = NULL((void*)0), param = NULL((void*)0);
9433
9434 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9434, &xml_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
9435 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "nightmare_xfer");
9436 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
9437 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-user", refer_to->r_url->url_user);
9438 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-host", refer_to->r_url->url_host);
9439 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 : "");
9440 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 : "");
9441 if (replaces) {
9442 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "replaces-call-id", replaces->rp_call_id);
9443 }
9444 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-from-channel-id", switch_core_session_get_uuid(session));
9445 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-for-channel-id", br_a);
9446
9447 if (switch_xml_locate("channels", NULL((void*)0), NULL((void*)0), NULL((void*)0),
9448 &xml_root, &xml_channel, xml_params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
9449 if ((params = switch_xml_child(xml_channel, "params"))) {
9450 for (param = switch_xml_child(params, "param"); param; param = param->next) {
9451 const char *name = switch_xml_attr(param, "name");
9452 const char *value = switch_xml_attr(param, "value");
9453
9454 if (!(name && value)) continue;
9455
9456 if (!strcasecmp(name, "sip-url")) {
9457 xml_url = value;
9458 } else if (!strcasecmp(name, "dial-prefix")) {
9459 dial_prefix = value;
9460 } else if (!strcasecmp(name, "absolute-dial-string")) {
9461 absolute_dial_string = value;
9462 } else if (!strcasecmp(name, "sip-profile")) {
9463 use_profile = value;
9464 }
9465 }
9466 }
9467
9468 if (absolute_dial_string) {
9469 exten = switch_core_session_sprintf(session, "%s%s", dial_prefix, absolute_dial_string);
9470 } else if (xml_url) {
9471 exten = switch_core_session_sprintf(session, "%ssofia/%s/%s", dial_prefix, use_profile, xml_url);
9472 }
9473
9474 switch_xml_free(xml_root);
9475 }
9476
9477 switch_event_destroy(&xml_params);
9478 }
9479
9480
9481 if (zstr(exten)_zstr(exten)) {
9482 exten = switch_core_session_sprintf(session, "sofia/%s/sip:%s@%s%s%s",
9483 profile->name, refer_to->r_url->url_user,
9484 refer_to->r_url->url_host, port ? ":" : "", port ? port : "");
9485 }
9486
9487 switch_core_new_memory_pool(&npool)switch_core_perform_new_memory_pool(&npool, "sofia.c", (const
char *)__func__, 9487)
;
9488 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__, 9488)
;
9489 nightmare_xfer_helper->exten = switch_core_strdup(npool, exten)switch_core_perform_strdup(npool, exten, "sofia.c", (const char
*)__func__, 9489)
;
9490
9491 if (refer_to->r_url->url_params || refer_to->r_url->url_headers) {
9492 if (refer_to->r_url->url_headers) {
9493 nightmare_xfer_helper->exten_with_params = switch_core_sprintf(npool,
9494 "{sip_invite_params=%s?%s}%s",
9495 refer_to->r_url->url_params ? refer_to->r_url->
9496 url_params : "", refer_to->r_url->url_headers, exten);
9497 } else {
9498 nightmare_xfer_helper->exten_with_params = switch_core_sprintf(npool,
9499 "{sip_invite_params=%s}%s", refer_to->r_url->url_params,
9500 exten);
9501 }
9502 } else {
9503 nightmare_xfer_helper->exten_with_params = nightmare_xfer_helper->exten;
9504 }
9505
9506 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 9506
, ((void*)0)
, SWITCH_LOG_INFO, "Nightmare transfer to '%s'\n", nightmare_xfer_helper->exten_with_params);
9507
9508 nightmare_xfer_helper->event = switch_core_strdup(npool, etmp)switch_core_perform_strdup(npool, etmp, "sofia.c", (const char
*)__func__, 9508)
;
9509 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__, 9509)
;
9510 nightmare_xfer_helper->bridge_to_uuid = switch_core_strdup(npool, br_a)switch_core_perform_strdup(npool, br_a, "sofia.c", (const char
*)__func__, 9510)
;
9511 nightmare_xfer_helper->pool = npool;
9512
9513 if (refer_to->r_url->url_headers) {
9514 char *h, *v, *hp;
9515 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__, 9515)
;
9516 while (p && *p) {
9517 h = p;
9518 if ((p = strchr(p, '='))) {
9519 *p++ = '\0';
9520 v = p;
9521 if ((p = strchr(p, '&'))) {
9522 *p++ = '\0';
9523 }
9524
9525 url_unescape(h, (const char *) h);
9526 url_unescape(v, (const char *) v);
9527 if (strcasecmp("Replaces", h)) {
9528 hp = switch_core_session_sprintf(session, "%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", h);
9529 switch_channel_set_variable(channel, hp, v)switch_channel_set_variable_var_check(channel, hp, v, SWITCH_TRUE
)
;
9530 } else {
9531 // use this one instead of rep value from above to keep all parameters
9532 switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, v)switch_channel_set_variable_var_check(channel, "_sofia_replaces_"
, v, SWITCH_TRUE)
;
9533 }
9534 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9534, (const char*)(session)
, SWITCH_LOG_DEBUG, "Exporting replaces URL header [%s:%s]\n",
9535 h, v);
9536 }
9537 }
9538 }
9539
9540
9541 switch_event_create(&nightmare_xfer_helper->vars, SWITCH_EVENT_CHANNEL_DATA)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9541, &nightmare_xfer_helper->
vars, SWITCH_EVENT_CHANNEL_DATA, ((void*)0))
;
9542
9543 rep_h = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER)switch_channel_get_variable_dup(channel, "_sofia_replaces_", SWITCH_TRUE
, -1)
;
9544 if (rep_h) {
9545 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REPLACES_HEADER"_sofia_replaces_", rep_h);
9546 } else {
9547 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REPLACES_HEADER"_sofia_replaces_", rep);
9548 }
9549
9550
9551 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
9552 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "Referred-By", full_ref_by);
9553 }
9554
9555 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
9556 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REFER_TO_VARIABLE"sip_refer_to", full_ref_to);
9557 }
9558
9559 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9560 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9560, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9561 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9562 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9563 switch_channel_event_set_data(channel_a, event);
9564 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9564, &event, ((void*)0))
;
9565 }
9566
9567 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9567, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9568 switch_channel_event_set_data(channel, event);
9569 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9569, &event, ((void*)0))
;
9570 }
9571 }
9572
9573 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Refer-From", switch_core_session_get_uuid(session));
9574 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Refer-For", br_a);
9575
9576 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9576, (const char*)(session)
, SWITCH_LOG_DEBUG, "Good Luck, you'll need it......\n");
9577 nightmare_xfer_helper->profile = profile;
9578 launch_nightmare_xfer(nightmare_xfer_helper);
9579
9580 switch_core_session_rwunlock(a_session);
9581
9582 } else {
9583 goto error;
9584 }
9585
9586 } else {
9587 error:
9588 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9588, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid Transfer! [%s]\n", br_a);
9589 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)
;
9590 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"
)
,
9591 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),
9592 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))
,
9593 TAG_END()(tag_type_t)0, (tag_value_t)0);
9594 }
9595 }
9596 goto done;
9597 }
9598
9599 } else {
9600 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9600, (const char*)(session)
, SWITCH_LOG_ERROR, "Missing Refer-To\n");
9601 goto done;
9602 }
9603
9604 if (exten) {
9605 switch_channel_t *channel = switch_core_session_get_channel(session);
9606 const char *br = switch_channel_get_partner_uuid(channel);
9607 switch_core_session_t *b_session;
9608
9609 switch_channel_set_variable_printf(channel, "transfer_to", "blind:%s", br ? br : exten);
9610 switch_channel_set_variable_printf(channel, "transfer_destination", "blind:%s", exten);
9611
9612 if (!zstr(br)_zstr(br) && (b_session = switch_core_session_locate(br)switch_core_session_perform_locate(br, "sofia.c", (const char
*)__func__, 9612)
)) {
9613 const char *var;
9614 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
9615 switch_event_t *event = NULL((void*)0);
9616
9617 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)
;
9618 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
9619 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)
;
9620 }
9621
9622 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
9623 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)
;
9624 }
9625
9626 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
9627 switch_ivr_transfer_recordings(session, b_session);
9628 }
9629
9630 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "BLIND_TRANSFER")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "BLIND_TRANSFER", SWITCH_TRUE)
;
9631
9632 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)) ||
9633 sofia_test_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)((profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] ? 1 : 0)) {
9634
9635 switch_channel_set_state_flag(b_channel, CF_CONFIRM_BLIND_TRANSFER);
9636 switch_channel_set_variable(channel, "sip_blind_transfer_event", etmp)switch_channel_set_variable_var_check(channel, "sip_blind_transfer_event"
, etmp, SWITCH_TRUE)
;
9637 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)
;
9638 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)
;
9639
9640 switch_channel_set_variable(channel, "park_timeout", "600:blind_transfer")switch_channel_set_variable_var_check(channel, "park_timeout"
, "600:blind_transfer", SWITCH_TRUE)
;
9641 switch_channel_set_state(channel, CS_PARK)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 9641, CS_PARK)
;
9642 } else {
9643 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"
)
,
9644 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
9645 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
9646 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),
9647 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))
,
9648 TAG_END()(tag_type_t)0, (tag_value_t)0);
9649 }
9650
9651 if (refer_to->r_url->url_params) {
9652 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)
;
9653 }
9654
9655 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)) {
9656 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9656, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferor")
== SWITCH_STATUS_SUCCESS) {
9657 switch_channel_event_set_data(channel_a, event);
9658 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9658, &event, ((void*)0))
;
9659 }
9660
9661 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9661, &event, SWITCH_EVENT_CUSTOM
, "sofia::transferee")
== SWITCH_STATUS_SUCCESS) {
9662 switch_channel_event_set_data(b_channel, event);
9663 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9663, &event, ((void*)0))
;
9664 }
9665 }
9666
9667 switch_ivr_session_transfer(b_session, exten, NULL((void*)0), NULL((void*)0));
9668 switch_core_session_rwunlock(b_session);
9669 } else {
9670 switch_event_t *event;
9671
9672 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9672, &event, SWITCH_EVENT_CUSTOM
, "sofia::error")
== SWITCH_STATUS_SUCCESS) {
9673 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Error-Type", "blind_transfer");
9674 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Transfer-Exten", exten);
9675 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Full-Refer-To", full_ref_to);
9676 switch_channel_event_set_data(channel, event);
9677 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 9677, &event, ((void*)0))
;
9678 }
9679
9680 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9680, (const char*)(session)
, SWITCH_LOG_ERROR, "Cannot Blind Transfer 1 Legged calls\n");
9681 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)
;
9682 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"
)
,
9683 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
9684 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
9685 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),
9686 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))
,
9687 TAG_END()(tag_type_t)0, (tag_value_t)0);
9688 }
9689 }
9690
9691 done:
9692 if (home) {
9693 su_home_unref(home);
9694 home = NULL((void*)0);
9695 }
9696
9697 switch_safe_free(etmp)if (etmp) {free(etmp);etmp=((void*)0);};
9698}
9699
9700
9701static switch_status_t create_info_event(sip_t const *sip,
9702 nua_handle_t *nh, switch_event_t **revent)
9703{
9704 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
))
;
9705 switch_event_t *event;
9706
9707 if (!(sip && switch_event_create(&event, SWITCH_EVENT_RECV_INFO)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9707, &event, SWITCH_EVENT_RECV_INFO
, ((void*)0))
== SWITCH_STATUS_SUCCESS)) {
9708 return SWITCH_STATUS_FALSE;
9709 }
9710
9711 if (sip->sip_content_type) {
9712 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Content-Type", sip->sip_content_type->c_type);
9713 }
9714
9715 if (sip->sip_from) {
9716 if (sip->sip_from->a_url->url_user) {
9717 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-From-User", sip->sip_from->a_url->url_user);
9718 }
9719
9720 if (sip->sip_from->a_url->url_host) {
9721 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-From-Host", sip->sip_from->a_url->url_host);
9722 }
9723 }
9724
9725 if (sip->sip_to) {
9726 if (sip->sip_to->a_url->url_user) {
9727 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-To-User", sip->sip_to->a_url->url_user);
9728 }
9729
9730 if (sip->sip_to->a_url->url_host) {
9731 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-To-Host", sip->sip_to->a_url->url_host);
9732 }
9733 }
9734
9735
9736 if (sip->sip_contact) {
9737 if (sip->sip_contact->m_url->url_user) {
9738 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Contact-User", sip->sip_contact->m_url->url_user);
9739 }
9740
9741 if (sip->sip_contact->m_url->url_host) {
9742 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Contact-Host", sip->sip_contact->m_url->url_host);
9743 }
9744 }
9745
9746
9747 if (sip->sip_call_info) {
9748 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Call-Info",
9749 sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info));
9750 }
9751
9752 if (alert_info) {
9753 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));
9754 }
9755
9756
9757 if (sip->sip_payload && sip->sip_payload->pl_data) {
9758 switch_event_add_body(event, "%s", sip->sip_payload->pl_data);
9759 }
9760
9761 *revent = event;
9762
9763 return SWITCH_STATUS_SUCCESS;
9764}
9765
9766switch_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,
9767 sofia_dispatch_event_t *de, tagi_t tags[])
9768{
9769 switch_core_session_t *other_session = NULL((void*)0);
9770 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9771
9772 if (session && switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 9772)
== SWITCH_STATUS_SUCCESS) {
9773 if (switch_core_session_compare(session, other_session)) {
9774 private_object_t *other_tech_pvt = NULL((void*)0);
9775 const char *ct = NULL((void*)0);
9776 char *pl = NULL((void*)0);
9777
9778
9779 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
9780 pl = sip->sip_payload->pl_data;
9781 }
9782
9783 other_tech_pvt = (private_object_t *) switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
9784
9785 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype) {
9786 ct = sip->sip_content_type->c_type;
9787 }
9788
9789 nua_message(other_tech_pvt->nh,
9790 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))
,
9791 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)
,
9792 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))
,
9793 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))
,
9794 TAG_END()(tag_type_t)0, (tag_value_t)0);
9795 }
9796
9797 switch_core_session_rwunlock(other_session);
9798
9799 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),
9800 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))
,
9801 TAG_END()(tag_type_t)0, (tag_value_t)0);
9802
9803 return SWITCH_STATUS_SUCCESS;
9804 }
9805
9806 return SWITCH_STATUS_FALSE;
9807}
9808
9809switch_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,
9810 sofia_dispatch_event_t *de, tagi_t tags[])
9811{
9812 switch_core_session_t *other_session = NULL((void*)0);
9813 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9814
9815 if (session && switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 9815)
== SWITCH_STATUS_SUCCESS) {
9816 if (switch_core_session_compare(session, other_session)) {
9817 private_object_t *other_tech_pvt = NULL((void*)0);
9818 const char *ct = NULL((void*)0);
9819 char *pl = NULL((void*)0);
9820 switch_channel_t *channel = switch_core_session_get_channel(session);
9821
9822 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
9823 pl = sip->sip_payload->pl_data;
9824 }
9825
9826 other_tech_pvt = (private_object_t *) switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
9827
9828 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype) {
9829 ct = sip->sip_content_type->c_type;
9830 }
9831
9832 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")) {
9833 if (switch_channel_test_flag(channel, CF_VIDEO)) {
9834 switch_core_media_gen_key_frame(session)switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const
char *)__func__, 9834, (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))
;
9835 switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ)switch_channel_set_flag_value(channel, CF_VIDEO_REFRESH_REQ, 1
)
;
9836 }
9837 }
9838
9839 nua_info(other_tech_pvt->nh,
9840 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))
,
9841 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)
,
9842 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))
,
9843 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))
,
9844 TAG_END()(tag_type_t)0, (tag_value_t)0);
9845 }
9846
9847 switch_core_session_rwunlock(other_session);
9848
9849 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);
9850
9851 return SWITCH_STATUS_SUCCESS;
9852 }
9853
9854 return SWITCH_STATUS_FALSE;
9855}
9856
9857
9858void 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,
9859 sofia_dispatch_event_t *de, tagi_t tags[])
9860{
9861 /* placeholder for string searching */
9862 const char *signal_ptr;
9863 const char *rec_header;
9864 const char *clientcode_header;
9865 switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), 0, SWITCH_DTMF_ENDPOINT };
9866 switch_event_t *event;
9867 private_object_t *tech_pvt = NULL((void*)0);
9868 switch_channel_t *channel = NULL((void*)0);
9869 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9870
9871 if (session) {
9872 tech_pvt = (private_object_t *) switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
9873 channel = switch_core_session_get_channel(session);
9874 }
9875
9876 if (sofia_test_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)((profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] ? 1 : 0)) {
9877 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
9878 sip->sip_payload && sip->sip_payload->pl_data) {
9879
9880 if (!strncasecmp(sip->sip_content_type->c_type, "freeswitch", 10)) {
9881
9882 if (!strcasecmp(sip->sip_content_type->c_subtype, "session-event")) {
9883 if (session) {
9884
9885 if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
9886 if (switch_core_session_queue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
9887 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9887, (const char*)(session)
, SWITCH_LOG_DEBUG, "queued freeswitch event for INFO\n");
9888 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"
)
,
9889 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),
9890 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))
,
9891 TAG_END()(tag_type_t)0, (tag_value_t)0);
9892 } else {
9893 switch_event_destroy(&event);
9894 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"
)
,
9895 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),
9896 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))
,
9897 TAG_END()(tag_type_t)0, (tag_value_t)0);
9898 }
9899 }
9900
9901 } else {
9902 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"
)
,
9903 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),
9904 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))
,
9905 TAG_END()(tag_type_t)0, (tag_value_t)0);
9906
9907 }
9908
9909 return;
9910
9911 } else if (!strcasecmp(sip->sip_content_type->c_subtype, "api-request")) {
9912 char *cmd = strdup(sip->sip_payload->pl_data);
9913 char *arg;
9914 switch_stream_handle_t stream = { 0 };
9915 switch_status_t status;
9916
9917 switch_assert(cmd)((cmd) ? (void) (0) : __assert_fail ("cmd", "sofia.c", 9917, __extension__
__PRETTY_FUNCTION__))
;
9918 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 9918, __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
;
9919 switch_assert(stream.data)((stream.data) ? (void) (0) : __assert_fail ("stream.data", "sofia.c"
, 9919, __extension__ __PRETTY_FUNCTION__))
;
9920
9921 if ((arg = strchr(cmd, ':'))) {
9922 *arg++ = '\0';
9923 }
9924
9925 if ((status = switch_api_execute(cmd, arg, NULL((void*)0), &stream)) == SWITCH_STATUS_SUCCESS) {
9926 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"),
9927 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),
9928 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))
,
9929 TAG_END()(tag_type_t)0, (tag_value_t)0);
9930 } else {
9931
9932 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"),
9933 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),
9934 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))
,
9935 TAG_END()(tag_type_t)0, (tag_value_t)0);
9936 }
9937
9938 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
9939 switch_safe_free(cmd)if (cmd) {free(cmd);cmd=((void*)0);};
9940 return;
9941 }
9942
9943 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),
9944 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))
,
9945 TAG_END()(tag_type_t)0, (tag_value_t)0);
9946
9947 return;
9948 }
9949 }
9950 }
9951
9952 if (session) {
9953 const char *vval;
9954
9955 /* Barf if we didn't get our private */
9956 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", 9956, __extension__ __PRETTY_FUNCTION__))
;
9957
9958 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_INFO_HEADER_PREFIX"sip_info_h_");
9959 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 &&
9960 (!strcasecmp(profile->proxy_info_content_types,"all") || strstr(profile->proxy_info_content_types,sip->sip_content_type->c_type))) {
9961 switch_core_session_t *other_session;
9962
9963 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 9963)
== SWITCH_STATUS_SUCCESS) {
9964 char *pl = NULL((void*)0);
9965 char *ct = NULL((void*)0);
9966 char *extra_headers = NULL((void*)0);
9967 char *unknown = NULL((void*)0);
9968 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
9969
9970 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__
, 9970)
;
9971 if (sip->sip_payload && sip->sip_payload->pl_data) {
9972 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__, 9972
)
;
9973 }
9974 unknown = sofia_glue_get_non_extra_unknown_headers(sip);
9975
9976 extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_INFO_HEADER_PREFIX"sip_info_h_");
9977
9978 nua_info(other_tech_pvt->nh,
9979 SIPTAG_CONTENT_TYPE_STR(ct)siptag_content_type_str, tag_str_v(ct),
9980 TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers))!(!_zstr(extra_headers)) ? tag_skip : siptag_header_str, tag_str_v
((extra_headers))
,
9981 TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown))!(!_zstr(unknown)) ? tag_skip : siptag_header_str, tag_str_v(
(unknown))
,
9982 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)
,
9983 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))
,
9984 TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl))!(!_zstr(pl)) ? tag_skip : siptag_payload_str, tag_str_v(pl),
9985 TAG_END()(tag_type_t)0, (tag_value_t)0);
9986 switch_safe_free(extra_headers)if (extra_headers) {free(extra_headers);extra_headers=((void*
)0);}
;
9987 switch_safe_free(unknown)if (unknown) {free(unknown);unknown=((void*)0);};
9988 switch_core_session_rwunlock(other_session);
9989 }
9990 }
9991
9992 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && !strcasecmp(sip->sip_content_type->c_type, "freeswitch/data")) {
9993 char *data = NULL((void*)0);
9994
9995 if (sip->sip_payload && sip->sip_payload->pl_data) {
9996 data = sip->sip_payload->pl_data;
9997 }
9998
9999 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)) {
10000 switch_core_session_t *nsession = NULL((void*)0);
10001
10002 switch_core_session_get_partner(session, &nsession)switch_core_session_perform_get_partner(session, &nsession
, "sofia.c", (const char *)__func__, 10002)
;
10003
10004 if (nsession) {
10005 switch_core_session_message_t *msg;
10006
10007 switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_INFO_HEADER_PREFIX_T"~sip_info_h_");
10008 msg = switch_core_session_alloc(nsession, sizeof(*msg))switch_core_perform_session_alloc(nsession, sizeof(*msg), "sofia.c"
, (const char *)__func__, 10008)
;
10009 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 10009
;
10010 msg->message_id = SWITCH_MESSAGE_INDICATE_INFO;
10011
10012 msg->string_array_arg[2] = switch_core_session_strdup(nsession, data)switch_core_perform_session_strdup(nsession, data, "sofia.c",
(const char *)__func__, 10012)
;
10013
10014 msg->from = __FILE__"sofia.c";
10015 switch_core_session_queue_message(nsession, msg);
10016
10017 switch_core_session_rwunlock(nsession);
10018 }
10019 }
10020 }
10021
10022 if (sip && sip->sip_content_type && sip->sip_content_type->c_subtype && sip->sip_content_type->c_type &&
10023 !strncasecmp(sip->sip_content_type->c_type, "message", 7) &&
10024 !strcasecmp(sip->sip_content_type->c_subtype, "update_display")) {
10025 sofia_update_callee_id(session, profile, sip, SWITCH_TRUE);
10026 goto end;
10027 }
10028
10029 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
10030 sip->sip_payload && sip->sip_payload->pl_data) {
10031 if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) {
10032
10033 if (switch_channel_test_flag(channel, CF_VIDEO)) {
10034 switch_core_media_gen_key_frame(session)switch_log_printf(SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const
char *)__func__, 10034, (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))
;
10035 switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ)switch_channel_set_flag_value(channel, CF_VIDEO_REFRESH_REQ, 1
)
;
10036 }
10037
10038 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) &&
10039 !strcasecmp(sip->sip_content_type->c_subtype, "vnd.nortelnetworks.digits")) {
10040 int tmp;
10041 if ((signal_ptr = switch_stristr("d=", sip->sip_payload->pl_data))) {
10042 signal_ptr = signal_ptr + 2;
10043
10044 while (*signal_ptr && *signal_ptr == ' ') {
10045 signal_ptr++;
10046 }
10047
10048 if (*signal_ptr && (*signal_ptr == '*' || *signal_ptr == '#' || *signal_ptr == 'A' || *signal_ptr == 'B'
10049 || *signal_ptr == 'C' || *signal_ptr == 'D')) {
10050 dtmf.digit = *signal_ptr;
10051 } else {
10052 tmp = atoi(signal_ptr);
10053 dtmf.digit = switch_rfc2833_to_char(tmp);
10054 }
10055
10056 dtmf.duration = 100;
10057 } else {
10058 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10058, (const char*)(session)
, SWITCH_LOG_DEBUG, "Bad signal\n");
10059 goto end;
10060 }
10061 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) {
10062 /* Try and find signal information in the payload */
10063 if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) {
10064 int tmp;
10065 /* move signal_ptr where we need it (right past Signal=) */
10066 signal_ptr = signal_ptr + 7;
10067
10068 /* handle broken devices with spaces after the = (cough) VegaStream (cough) */
10069 while (*signal_ptr && *signal_ptr == ' ')
10070 signal_ptr++;
10071
10072 if (*signal_ptr
10073 && (*signal_ptr == '*' || *signal_ptr == '#' || *signal_ptr == 'A' || *signal_ptr == 'B' || *signal_ptr == 'C'
10074 || *signal_ptr == 'D')) {
10075 dtmf.digit = *signal_ptr;
10076 } else {
10077 tmp = atoi(signal_ptr);
10078 dtmf.digit = switch_rfc2833_to_char(tmp);
10079 }
10080 } else {
10081 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10081, (const char*)(session)
, SWITCH_LOG_DEBUG, "Bad signal\n");
10082 goto end;
10083 }
10084
10085 if ((signal_ptr = switch_stristr("Duration=", sip->sip_payload->pl_data))) {
10086 int tmp;
10087 signal_ptr += 9;
10088
10089 /* handle broken devices with spaces after the = (cough) VegaStream (cough) */
10090 while (*signal_ptr && *signal_ptr == ' ')
10091 signal_ptr++;
10092
10093 if ((tmp = atoi(signal_ptr)) <= 0) {
10094 tmp = switch_core_default_dtmf_duration(0);
10095 }
10096 dtmf.duration = tmp * 8;
10097 }
10098 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf")) {
10099 int tmp = atoi(sip->sip_payload->pl_data);
10100 dtmf.digit = switch_rfc2833_to_char(tmp);
10101 }
10102
10103 if (dtmf.digit) {
10104 if (tech_pvt->mparams.dtmf_type == DTMF_INFO ||
10105 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)) {
10106 /* queue it up */
10107 switch_channel_queue_dtmf(channel, &dtmf);
10108
10109 /* print debug info */
10110 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10110, (const char*)(session)
, SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit);
10111
10112 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
10113 const char *uuid;
10114 switch_core_session_t *session_b;
10115
10116 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__, 10116)
)) {
10117 while (switch_channel_has_dtmf(channel)) {
10118 switch_dtmf_t idtmf = { 0, 0 };
10119 if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) {
10120 switch_core_session_send_dtmf(session_b, &idtmf);
10121 }
10122 }
10123
10124 switch_core_session_rwunlock(session_b);
10125 }
10126 }
10127
10128 /* Send 200 OK response */
10129 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),
10130 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))
,
10131 TAG_END()(tag_type_t)0, (tag_value_t)0);
10132 } else {
10133 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10133, (const char*)(session)
, SWITCH_LOG_WARNING,
10134 "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
10135 }
10136 goto end;
10137 }
10138 }
10139
10140 if ((clientcode_header = sofia_glue_get_unknown_header(sip, "x-clientcode"))) {
10141 if (!zstr(clientcode_header)_zstr(clientcode_header)) {
10142 switch_channel_set_variable(channel, "call_clientcode", clientcode_header)switch_channel_set_variable_var_check(channel, "call_clientcode"
, clientcode_header, SWITCH_TRUE)
;
10143 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10143, (const char*)(session)
, SWITCH_LOG_NOTICE, "Setting CMC to %s\n", clientcode_header);
10144 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),
10145 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))
,
10146 TAG_END()(tag_type_t)0, (tag_value_t)0);
10147 }
10148 goto end;
10149 }
10150
10151 if ((rec_header = sofia_glue_get_unknown_header(sip, "record"))) {
10152 if (zstr(profile->record_template)_zstr(profile->record_template)) {
10153 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10153, (const char*)(session)
, SWITCH_LOG_WARNING, "Record attempted but no template defined.\n");
10154 nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10155 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))
,
10156 TAG_END()(tag_type_t)0, (tag_value_t)0);
10157 } else {
10158 if (!strcasecmp(rec_header, "on")) {
10159 char *file = NULL((void*)0), *tmp = NULL((void*)0);
10160
10161 if (switch_true(switch_channel_get_variable(channel, "sip_disable_recording")switch_channel_get_variable_dup(channel, "sip_disable_recording"
, SWITCH_TRUE, -1)
)) {
10162 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10162, (const char*)(session)
, SWITCH_LOG_WARNING, "Record attempted but is disabled by sip_disable_recording variable.\n");
10163 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),
10164 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);
10165 } else {
10166
10167 tmp = switch_mprintf("%s%s%s", profile->record_path ? profile->record_path : "${recordings_dir}",
10168 SWITCH_PATH_SEPARATOR"/", profile->record_template);
10169 file = switch_channel_expand_variables(channel, tmp)switch_channel_expand_variables_check(channel, tmp, ((void*)0
), ((void*)0), 0)
;
10170 switch_ivr_record_session(session, file, 0, NULL((void*)0));
10171 switch_channel_set_variable(channel, "sofia_record_file", file)switch_channel_set_variable_var_check(channel, "sofia_record_file"
, file, SWITCH_TRUE)
;
10172 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10172, (const char*)(session)
, SWITCH_LOG_NOTICE, "Recording %s to %s\n", switch_channel_get_name(channel),
10173 file);
10174 switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);};
10175 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),
10176 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))
,
10177 TAG_END()(tag_type_t)0, (tag_value_t)0);
10178 if (file != profile->record_template) {
10179 free(file);
10180 file = NULL((void*)0);
10181 }
10182 }
10183 } else {
10184 const char *file;
10185
10186 if ((file = switch_channel_get_variable(channel, "sofia_record_file")switch_channel_get_variable_dup(channel, "sofia_record_file",
SWITCH_TRUE, -1)
)) {
10187 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10187, (const char*)(session)
, SWITCH_LOG_NOTICE, "Done recording %s to %s\n",
10188 switch_channel_get_name(channel), file);
10189 switch_ivr_stop_record_session(session, file);
10190 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),
10191 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))
,
10192 TAG_END()(tag_type_t)0, (tag_value_t)0);
10193 } else {
10194 nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
10195 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))
,
10196 TAG_END()(tag_type_t)0, (tag_value_t)0);
10197 }
10198 }
10199 }
10200 }
10201 }
10202
10203 end:
10204
10205 if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
10206 if (channel) {
10207 switch_channel_event_set_data(channel, event);
10208 }
10209 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 10209, &event, ((void*)0))
;
10210 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10210, (const char*)(session)
, SWITCH_LOG_DEBUG1, "dispatched freeswitch event for INFO\n");
10211 }
10212
10213 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),
10214 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))
,
10215 TAG_END()(tag_type_t)0, (tag_value_t)0);
10216
10217 return;
10218
10219}
10220
10221void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
10222 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
10223 sofia_dispatch_event_t *de,
10224 tagi_t tags[])
10225{
10226 char *call_info = NULL((void*)0);
10227 switch_channel_t *channel = NULL((void*)0);
10228 private_object_t *tech_pvt = NULL((void*)0);
10229
10230 nua_respond(nh, SIP_100_TRYING100, sip_100_Trying, TAG_END()(tag_type_t)0, (tag_value_t)0);
10231
10232 if (session) {
10233 channel = switch_core_session_get_channel(session);
10234 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
10235
10236
10237 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10238 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__, 10238)
;
10239 }
10240 }
10241
10242 if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)((profile)->pflags[PFLAG_TRACK_CALLS] ? 1 : 0)) {
10243 switch_channel_t *channel = switch_core_session_get_channel(session);
10244 private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
10245 char network_ip[80] = "";
10246 int network_port = 0;
10247 char via_space[2048];
10248 char branch[16] = "";
10249
10250 sofia_glue_store_session_id(session, profile, sip, 0);
10251
10252 sofia_clear_flag(tech_pvt, TFLAG_GOT_ACK)(tech_pvt)->flags[TFLAG_GOT_ACK] = 0;
10253
10254 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
10255 switch_stun_random_string(branch, sizeof(branch) - 1, "0123456789abcdef");
10256
10257 switch_snprintf(via_space, sizeof(via_space), "SIP/2.0/UDP %s;rport=%d;branch=%s", network_ip, network_port, branch);
10258 switch_channel_set_variable(channel, "sip_full_via", via_space)switch_channel_set_variable_var_check(channel, "sip_full_via"
, via_space, SWITCH_TRUE)
;
10259 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
10260 switch_channel_set_variable_printf(channel, "sip_recieved_port", "%d", network_port);
10261 switch_channel_set_variable_printf(channel, "sip_via_rport", "%d", network_port);
10262
10263 switch_core_recovery_track(session);
10264 }
10265
10266 if (profile && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
10267 if (channel && sip && sip->sip_call_info) {
10268 char *p;
10269 if ((call_info = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info))) {
10270 if (switch_stristr("appearance", call_info)) {
10271 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)
;
10272 if ((p = strchr(call_info, ';'))) {
10273 switch_channel_set_variable(channel, "presence_call_info", p + 1)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p + 1, SWITCH_TRUE)
;
10274 }
10275 }
10276 su_free(nua_handle_home(nh)((su_home_t *)(nh)), call_info);
10277 }
10278 }
10279 }
10280
10281 if (channel) {
10282 if (tech_pvt->mparams.last_sdp_str) {
10283 tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
10284 }
10285 tech_pvt->mparams.last_sdp_str = NULL((void*)0);
10286
10287 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10288 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)) {
10289 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)
;
10290 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__, 10290)
;
10291 } else {
10292 tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str;
10293 }
10294 }
10295
10296 switch_channel_execute_on(channel, "execute_on_sip_reinvite");
10297 }
10298
10299}
10300
10301switch_status_t sofia_locate_user(char* user, switch_core_session_t *session, sip_t const *sip, switch_xml_t* x_user)
10302{
10303 char *username, *domain;
10304 switch_event_t *v_event = NULL((void*)0);
10305 switch_status_t result = SWITCH_STATUS_FALSE;
10306
10307 if (!session) {
10308 return SWITCH_STATUS_FALSE;
10309 }
10310
10311 if (zstr(user)_zstr(user)) {
10312 return SWITCH_STATUS_FALSE;
10313 }
10314
10315 if (!(username = switch_core_session_strdup(session, user)switch_core_perform_session_strdup(session, user, "sofia.c", (
const char *)__func__, 10315)
)) {
10316 return SWITCH_STATUS_FALSE;
10317 }
10318
10319 if (!(domain = strchr(username, '@'))) {
10320 return SWITCH_STATUS_FALSE;
10321 }
10322
10323 *domain++ = '\0';
10324
10325 if (switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 10325, &v_event, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
10326 sip_unknown_t *un;
10327 for (un = sip->sip_unknown; un; un = un->un_next) {
10328 switch_event_add_header_string(v_event, SWITCH_STACK_BOTTOM, un->un_name, un->un_value);
10329 };
10330 switch_channel_event_set_data(switch_core_session_get_channel(session), v_event);
10331 }
10332
10333 result = switch_xml_locate_user_merged("id", username, domain, NULL((void*)0), x_user, v_event);
10334
10335 if (v_event) {
10336 switch_event_destroy(&v_event);
10337 }
10338
10339 return result;
10340}
10341
10342void 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[])
10343{
10344 char key[128] = "";
10345 sip_unknown_t *un;
10346 sip_remote_party_id_t *rpid = NULL((void*)0);
10347 sip_p_asserted_identity_t *passerted = NULL((void*)0);
10348 sip_p_preferred_identity_t *ppreferred = NULL((void*)0);
10349 sip_privacy_t *privacy = NULL((void*)0);
10350 sip_alert_info_t *alert_info = NULL((void*)0);
10351 sip_call_info_t *call_info = NULL((void*)0);
10352 private_object_t *tech_pvt = NULL((void*)0);
10353 switch_channel_t *channel = NULL((void*)0);
10354 //const char *channel_name = NULL;
10355 const char *displayname = NULL((void*)0);
10356 const char *destination_number = NULL((void*)0);
10357 const char *from_user = NULL((void*)0), *from_host = NULL((void*)0);
10358 const char *referred_by_user = NULL((void*)0);//, *referred_by_host = NULL;
10359 const char *context = NULL((void*)0);
10360 const char *dialplan = NULL((void*)0);
10361 char network_ip[80] = "";
10362 char proxied_client_ip[80];
10363 switch_event_t *v_event = NULL((void*)0);
10364 switch_xml_t x_user = NULL((void*)0);
10365 uint32_t sess_count = switch_core_session_count();
10366 uint32_t sess_max = switch_core_session_limit(0);
10367 int is_auth = 0, calling_myself = 0;
10368 int network_port = 0;
10369 char *is_nat = NULL((void*)0);
10370 char *aniii = NULL((void*)0);
10371 char acl_token[512] = "";
10372 sofia_transport_t transport;
10373 const char *gw_name = NULL((void*)0);
10374 const char *gw_param_name = NULL((void*)0);
10375 char *call_info_str = NULL((void*)0);
10376 nua_handle_t *bnh = NULL((void*)0);
10377 char sip_acl_authed_by[512] = "";
10378 char sip_acl_token[512] = "";
10379 const char *dialog_from_user = "", *dialog_from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
10380 const char *user_agent = "", *call_id = "";
10381 url_t *from = NULL((void*)0), *to = NULL((void*)0), *contact = NULL((void*)0);
10382 const char *to_tag = "";
10383 const char *from_tag = "";
10384 char *sql = NULL((void*)0);
10385 char *acl_context = NULL((void*)0);
10386 const char *r_sdp = NULL((void*)0);
10387 int is_tcp = 0, is_tls = 0;
10388 const char *uparams = NULL((void*)0);
10389 char *name_params = NULL((void*)0);
10390 const char *req_uri = NULL((void*)0);
10391 char *req_user = NULL((void*)0);
10392 switch_time_t sip_invite_time;
10393 const char *session_id_header;
10394
10395 sofia_glue_store_session_id(session, profile, sip, 0);
10396 session_id_header = sofia_glue_session_id_header(session, profile);
10397
10398 if (sip && sip->sip_contact && sip->sip_contact->m_url->url_params) {
10399 uparams = sip->sip_contact->m_url->url_params;
10400 } else {
10401 uparams = NULL((void*)0);
10402 }
10403
10404
10405 if (uparams) {
10406 if (switch_stristr("transport=tcp", uparams)) {
10407 is_tcp = 1;
10408 } else if (switch_stristr("transport=tls", uparams)) {
10409 is_tls = 1;
10410 }
10411 }
10412
10413 profile->ib_calls++;
10414
10415 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10416 r_sdp = sip->sip_payload->pl_data;
10417 }
10418
10419 if (!session || (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0))) {
10420 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300")siptag_retry_after_str, tag_str_v("300"),
10421 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);
10422 goto fail;
10423 }
10424
10425 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
10426
10427 sip_invite_time = switch_micro_time_now();
10428
10429 if (!sip || !sip->sip_request || !sip->sip_request->rq_method_name) {
10430 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10430
, ((void*)0)
, SWITCH_LOG_ERROR, "Received an invalid packet!\n");
10431 nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE503, sip_503_Service_unavailable,
10432 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);
10433 goto fail;
10434 }
10435
10436 if (!(sip->sip_contact)) {
10437 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10437
, ((void*)0)
, SWITCH_LOG_ERROR, "NO CONTACT!\n");
10438 nua_respond(nh, 400, "Missing Contact Header",
10439 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);
10440 goto fail;
10441 }
10442
10443
10444 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
10445
10446 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10446, (const char*)(tech_pvt->session)
, SWITCH_LOG_INFO, "%s receiving invite from %s:%d version: %s call-id: %s\n",
10447 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 :
"")
: "");
10448
10449
10450 if (sip->sip_via && sip->sip_via->v_protocol && switch_stristr("sip/2.0/ws", sip->sip_via->v_protocol)) {
10451 is_nat = "websockets";
10452 }
10453
10454
10455 if (r_sdp) {
10456 switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
10457 }
10458
10459
10460 if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)((profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] ? 1 : 0
)
||
10461 (sofia_test_pflag(profile, PFLAG_TLS_ALWAYS_NAT)((profile)->pflags[PFLAG_TLS_ALWAYS_NAT] ? 1 : 0) && (is_tcp || is_tls)) ||
10462 (!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))
) &&
10463 profile->server_rport_level >= 2 && sip->sip_user_agent &&
10464 sip->sip_user_agent->g_string &&
10465 (!strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7) || !strncasecmp(sip->sip_user_agent->g_string, "KIRK Wireless Server", 20)))
10466 ) {
10467 if (sip->sip_via) {
10468 const char *port = sip->sip_via->v_port;
10469 const char *host = sip->sip_via->v_host;
10470
10471 if (host && sip->sip_via->v_received) {
10472 is_nat = "via received";
10473 } else if (host && strcmp(network_ip, host)) {
10474 is_nat = "via host";
10475 } else if (port && atoi(port) != network_port) {
10476 is_nat = "via port";
10477 }
10478 }
10479 }
10480
10481 if (!is_nat && profile->nat_acl_count) {
10482 uint32_t x = 0;
10483 int contact_private_ip = 1;
10484 int network_private_ip = 0;
10485 char *last_acl = NULL((void*)0);
10486 const char *contact_host = NULL((void*)0);
10487
10488 if (sip->sip_via && sip->sip_via->v_host) {
10489 contact_host = sip->sip_via->v_host;
10490 } else if (sip->sip_contact) {
10491 contact_host = sip->sip_contact->m_url->url_host;
10492 }
10493
10494 if (!zstr(contact_host)_zstr(contact_host)) {
10495 /* NAT mode double check logic and examples.
10496
10497 Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point
10498 is most likely behind nat with us so we need to veto that decision to turn on nat processing.
10499
10500 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
10501 the remote endpoint is likely behind a remote nat traversing the public internet.
10502
10503 This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net
10504 in cases where we don't really need to be doing this.
10505
10506 Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind
10507 remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process.
10508
10509 */
10510
10511 for (x = 0; x < profile->nat_acl_count; x++) {
10512 last_acl = profile->nat_acl[x];
10513 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))
)) {
10514 break;
10515 }
10516 }
10517 if (contact_private_ip) {
10518 for (x = 0; x < profile->nat_acl_count; x++) {
10519 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))
)) {
10520 break;
10521 }
10522 }
10523 }
10524
10525 if (contact_private_ip && !network_private_ip) {
10526 is_nat = last_acl;
10527 }
10528 }
10529 }
10530
10531 if (profile->acl_count) {
10532 uint32_t x = 0;
10533 int ok = 1;
10534 char *last_acl = NULL((void*)0);
10535 const char *token = NULL((void*)0);
10536 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;
10537
10538 for (x = 0; x < profile->acl_count; x++) {
10539 last_acl = profile->acl[x];
10540 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10540
, ((void*)0)
, SWITCH_LOG_DEBUG, "verifying acl \"%s\" for ip/port %s:%i.\n",
10541 switch_str_nil(last_acl)(last_acl ? last_acl : ""), network_ip, acl_port);
10542 if ((ok = switch_check_network_list_ip_port_token(network_ip, acl_port, last_acl, &token))) {
10543
10544 if (profile->acl_pass_context[x]) {
10545 acl_context = profile->acl_pass_context[x];
10546 }
10547 if(!token && profile->acl_inbound_x_token_header) {
10548 const char * x_auth_token = sofia_glue_get_unknown_header(sip, profile->acl_inbound_x_token_header);
10549 if (!zstr(x_auth_token)_zstr(x_auth_token)) {
10550 token = x_auth_token;
10551 }
10552 }
10553
10554 break;
10555 }
10556
10557 if (profile->acl_fail_context[x]) {
10558 acl_context = profile->acl_fail_context[x];
10559 } else {
10560 acl_context = NULL((void*)0);
10561 }
10562 }
10563
10564 if (ok) {
10565 if (token) {
10566 switch_set_string(acl_token, token)switch_copy_string(acl_token, token, sizeof(acl_token));
10567 }
10568 if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
10569 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10569
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
10570 network_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""), acl_token);
10571 switch_set_string(sip_acl_authed_by, last_acl)switch_copy_string(sip_acl_authed_by, last_acl, sizeof(sip_acl_authed_by
))
;
10572 switch_set_string(sip_acl_token, acl_token)switch_copy_string(sip_acl_token, acl_token, sizeof(sip_acl_token
))
;
10573 is_auth = 1;
10574 }
10575 } else {
10576 int network_ip_is_proxy = 0;
10577 const char* x_auth_ip = network_ip;
10578 /* Check if network_ip is a proxy allowed to send us calls */
10579 if (profile->proxy_acl_count) {
10580 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10580
, ((void*)0)
, SWITCH_LOG_DEBUG, "%d acls to check for proxy\n", profile->proxy_acl_count);
10581 for (x = 0; x < profile->proxy_acl_count; x++) {
10582 last_acl = profile->proxy_acl[x];
10583 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10583
, ((void*)0)
, SWITCH_LOG_DEBUG, "checking %s against acl %s\n", network_ip, last_acl);
10584 if (switch_check_network_list_ip_port_token(network_ip, network_port, last_acl, &token)) {
10585 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10585
, ((void*)0)
, SWITCH_LOG_INFO, "%s is a proxy according to the %s acl\n", network_ip, last_acl);
10586 network_ip_is_proxy = 1;
10587 break;
10588 }
10589 }
10590 }
10591
10592 /*
10593 * if network_ip is a proxy allowed to send calls, check for auth
10594 * ip header and see if it matches against the inbound acl
10595 */
10596 if (network_ip_is_proxy) {
10597 const char * x_auth_port = sofia_glue_get_unknown_header(sip, "X-AUTH-PORT");
10598 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;
10599
10600 /*
10601 * if network_ip is a proxy allowed to send calls,
10602 * authorize call if proxy provided matched token header
10603 */
10604 if (profile->acl_proxy_x_token_header) {
10605 const char * x_auth_token = sofia_glue_get_unknown_header(sip, profile->acl_proxy_x_token_header);
10606 if (!zstr(x_auth_token)_zstr(x_auth_token)) {
10607 token = x_auth_token;
10608 switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
10609 ok = 1;
10610 }
10611 }
10612
10613 if (!ok && (x_auth_ip = sofia_glue_get_unknown_header(sip, "X-AUTH-IP")) && !zstr(x_auth_ip)_zstr(x_auth_ip)) {
10614 for (x = 0; x < profile->acl_count; x++) {
10615 last_acl = profile->acl[x];
10616 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10616
, ((void*)0)
, SWITCH_LOG_DEBUG, "verifying acl \"%s\" from proxy for ip/port %s:%i.\n",
10617 switch_str_nil(last_acl)(last_acl ? last_acl : ""), x_auth_ip, x_auth_port_i);
10618 if ((ok = switch_check_network_list_ip_port_token(x_auth_ip, x_auth_port_i, last_acl, &token))) {
10619
10620 switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
10621
10622 if (profile->acl_pass_context[x]) {
10623 acl_context = profile->acl_pass_context[x];
10624 }
10625
10626 break;
10627 }
10628
10629 if (profile->acl_fail_context[x]) {
10630 acl_context = profile->acl_fail_context[x];
10631 } else {
10632 acl_context = NULL((void*)0);
10633 }
10634 }
10635 } else {
10636 x_auth_ip = network_ip;
10637 }
10638 }
10639
10640 if (ok) {
10641 if (token) {
10642 switch_set_string(acl_token, token)switch_copy_string(acl_token, token, sizeof(acl_token));
10643 }
10644 if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
10645 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10645
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
10646 x_auth_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""), acl_token);
10647 switch_set_string(sip_acl_authed_by, last_acl)switch_copy_string(sip_acl_authed_by, last_acl, sizeof(sip_acl_authed_by
))
;
10648 switch_set_string(sip_acl_token, acl_token)switch_copy_string(sip_acl_token, acl_token, sizeof(sip_acl_token
))
;
10649 is_auth = 1;
10650 }
10651 } else {
10652 if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
10653 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10653
, ((void*)0)
, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", x_auth_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""));
10654 if (!acl_context) {
10655 nua_respond(nh, SIP_403_FORBIDDEN403, sip_403_Forbidden,
10656 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);
10657 goto fail;
10658 } else {
10659 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10659
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
10660 x_auth_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""));
10661 }
10662 }
10663 }
10664 }
10665 }
10666
10667
10668 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)) {
10669 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10669
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP/Port %s %i Rejected by acls and auth-calls-acl-only flag is set, rejecting call\n",
10670 network_ip, network_port);
10671 nua_respond(nh, SIP_403_FORBIDDEN403, sip_403_Forbidden,
10672 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);
10673 goto fail;
10674 }
10675
10676 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)) {
10677 char *user = NULL((void*)0);
10678 switch_status_t blind_result = SWITCH_STATUS_FALSE;
10679
10680 if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
10681 calling_myself++;
10682 }
10683
10684 if (sip->sip_from) {
10685 user = switch_core_session_sprintf(session, "%s@%s", sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host);
10686 blind_result = sofia_locate_user(user, session, sip, &x_user);
10687 }
10688 if (!sofia_test_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)((profile)->pflags[PFLAG_BLIND_AUTH_ENFORCE_RESULT] ? 1 : 0
)
|| blind_result == SWITCH_STATUS_SUCCESS) {
10689 is_auth++;
10690 } else if (sofia_test_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)((profile)->pflags[PFLAG_BLIND_AUTH_REPLY_403] ? 1 : 0)) {
10691 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 10691
, ((void*)0)
, SWITCH_LOG_DEBUG, "blind auth enforce 403 enabled and couldn't find user %s, rejecting call\n", user);
10692 nua_respond(nh, SIP_403_FORBIDDEN403, sip_403_Forbidden, TAG_END()(tag_type_t)0, (tag_value_t)0);
10693 goto fail;
10694 }
10695 }
10696
10697 if (sip->sip_from && sip->sip_from->a_url) {
10698 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__, 10698)
;
10699 }
10700 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__, 10700)
;
10701 tech_pvt->mparams.remote_port = network_port;
10702
10703 if (!is_auth &&
10704 (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)
10705 || (!sofia_test_pflag(profile, PFLAG_BLIND_AUTH)((profile)->pflags[PFLAG_BLIND_AUTH] ? 1 : 0) && (sip->sip_proxy_authorization || sip->sip_authorization)))) {
10706 if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
10707 calling_myself++;
10708 } else {
10709 switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 10709, &v_event, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
10710
10711 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))
) {
10712 if (v_event) {
10713 switch_event_destroy(&v_event);
10714 }
10715 if (x_user) {
10716 switch_xml_free(x_user);
10717 }
10718
10719 if (sip->sip_authorization || sip->sip_proxy_authorization) {
10720 goto fail;
10721 }
10722
10723 return;
10724 }
10725 }
10726 is_auth++;
10727 }
10728
10729 channel = tech_pvt->channel = switch_core_session_get_channel(session);
10730
10731 switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
10732 switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip);
10733 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
10734 switch_channel_set_variable_printf(channel, "sip_invite_stamp", "%" SWITCH_TIME_T_FMT"ld", sip_invite_time);
10735
10736 if (*acl_token) {
10737 if (x_user) {
10738 switch_xml_free(x_user);
10739 x_user = NULL((void*)0);
10740 }
10741 switch_channel_set_variable(channel, "acl_token", acl_token)switch_channel_set_variable_var_check(channel, "acl_token", acl_token
, SWITCH_TRUE)
;
10742 if (sofia_locate_user(acl_token, session, sip, &x_user) == SWITCH_STATUS_SUCCESS) {
10743 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10743, (const char*)(session)
, SWITCH_LOG_DEBUG, "Authenticating user %s\n", acl_token);
10744 } else {
10745 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10745, (const char*)(session)
, SWITCH_LOG_WARNING, "Error Authenticating user %s\n", acl_token);
10746 if (sofia_test_pflag(profile, PFLAG_AUTH_REQUIRE_USER)((profile)->pflags[PFLAG_AUTH_REQUIRE_USER] ? 1 : 0)) {
10747 nua_respond(nh, SIP_480_TEMPORARILY_UNAVAILABLE480, sip_480_Temporarily_unavailable, TAG_END()(tag_type_t)0, (tag_value_t)0);
10748 if (v_event) {
10749 switch_event_destroy(&v_event);
10750 }
10751 goto fail;
10752 }
10753 }
10754 }
10755
10756 if (sip->sip_via) {
10757 char tmp[35] = "";
10758 const char *ipv6 = strchr(tech_pvt->mparams.remote_ip, ':');
10759
10760 transport = sofia_glue_via2transport(sip->sip_via);
10761
10762
10763 tech_pvt->record_route =
10764 switch_core_session_sprintf(session,
10765 "sip:%s%s%s:%d;transport=%s",
10766 ipv6 ? "[" : "", tech_pvt->mparams.remote_ip, ipv6 ? "]" : "",
10767 tech_pvt->mparams.remote_port, sofia_glue_transport2str(transport));
10768
10769 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)
;
10770 snprintf(tmp, sizeof(tmp), "%d", tech_pvt->mparams.remote_port);
10771 switch_channel_set_variable(channel, "sip_received_port", tmp)switch_channel_set_variable_var_check(channel, "sip_received_port"
, tmp, SWITCH_TRUE)
;
10772 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)
;
10773 }
10774
10775 if (*key != '\0') {
10776 tech_pvt->key = switch_core_session_strdup(session, key)switch_core_perform_session_strdup(session, key, "sofia.c", (
const char *)__func__, 10776)
;
10777 }
10778
10779
10780 if (is_auth) {
10781 switch_channel_set_variable(channel, "sip_authorized", "true")switch_channel_set_variable_var_check(channel, "sip_authorized"
, "true", SWITCH_TRUE)
;
10782
10783 if (!zstr(sip_acl_authed_by)_zstr(sip_acl_authed_by)) {
10784 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)
;
10785 }
10786
10787 if (!zstr(sip_acl_token)_zstr(sip_acl_token)) {
10788 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)
;
10789 }
10790
10791 }
10792
10793 if (calling_myself) {
10794 switch_channel_set_variable(channel, "sip_looped_call", "true")switch_channel_set_variable_var_check(channel, "sip_looped_call"
, "true", SWITCH_TRUE)
;
10795 }
10796
10797 tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
10798 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));
10799 switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
10800
10801 if (x_user) {
10802 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");
10803
10804 if (v_event) {
10805 switch_event_header_t *hp;
10806
10807 for (hp = v_event->headers; hp; hp = hp->next) {
10808 switch_channel_set_variable(channel, hp->name, hp->value)switch_channel_set_variable_var_check(channel, hp->name, hp
->value, SWITCH_TRUE)
;
10809 }
10810
10811 ruser = switch_event_get_header(v_event, "user_name")switch_event_get_header_idx(v_event, "user_name", -1);
10812 rdomain = switch_event_get_header(v_event, "domain_name")switch_event_get_header_idx(v_event, "domain_name", -1);
10813
10814 switch_channel_set_variable(channel, "requested_user_name", ruser)switch_channel_set_variable_var_check(channel, "requested_user_name"
, ruser, SWITCH_TRUE)
;
10815 switch_channel_set_variable(channel, "requested_domain_name", rdomain)switch_channel_set_variable_var_check(channel, "requested_domain_name"
, rdomain, SWITCH_TRUE)
;
10816 }
10817
10818 if (!user) user = ruser;
10819 if (!domain) domain = rdomain;
10820
10821 switch_ivr_set_user_xml(session, NULL((void*)0), user, domain, x_user);
10822 switch_xml_free(x_user);
10823 x_user = NULL((void*)0);
10824 }
10825
10826 if (v_event) {
10827 switch_event_destroy(&v_event);
10828 }
10829
10830 if (sip->sip_from) {
10831 from_user = sip->sip_from->a_url->url_user;
10832 from_host = sip->sip_from->a_url->url_host;
10833 //channel_name = url_set_chanvars(session, sip->sip_from->a_url, sip_from);
10834
10835 if (sip->sip_from->a_url->url_params) {
10836 aniii = switch_find_parameter(sip->sip_from->a_url->url_params, "isup-oli", switch_core_session_get_pool(session));
10837 }
10838
10839 if (!zstr(from_user)_zstr(from_user)) {
10840 if (*from_user == '+') {
10841 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)
;
10842 } else {
10843 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)
;
10844 }
10845 }
10846
10847 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)
;
10848
10849 if (sip->sip_from->a_params) {
10850 set_variable_sip_param(channel, "from", sip->sip_from->a_params);
10851 }
10852
10853 switch_channel_set_variable(channel, "sofia_profile_name", profile->name)switch_channel_set_variable_var_check(channel, "sofia_profile_name"
, profile->name, SWITCH_TRUE)
;
10854 switch_channel_set_variable(channel, "sofia_profile_url", profile->url)switch_channel_set_variable_var_check(channel, "sofia_profile_url"
, profile->url, SWITCH_TRUE)
;
10855 switch_channel_set_variable(channel, "recovery_profile_name", profile->name)switch_channel_set_variable_var_check(channel, "recovery_profile_name"
, profile->name, SWITCH_TRUE)
;
10856 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)
;
10857
10858 if (!zstr(sip->sip_from->a_display)_zstr(sip->sip_from->a_display)) {
10859 displayname = sip->sip_from->a_display;
10860 } else {
10861 displayname = zstr(from_user)_zstr(from_user) ? "unknown" : from_user;
10862 }
10863 }
10864
10865 if ((rpid = sip_remote_party_id(sip)((sip_remote_party_id_t *)msg_header_access((msg_pub_t*)(sip)
, sip_remote_party_id_class))
)) {
10866 if (rpid->rpid_url->url_user) {
10867 char *full_rpid_header = sip_header_as_string(nua_handle_get_home(nh), (void *) rpid);
10868 from_user = rpid->rpid_url->url_user;
10869 if (!zstr(full_rpid_header)_zstr(full_rpid_header)) {
10870 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)
;
10871 }
10872
10873 }
10874 if (!zstr(rpid->rpid_display)_zstr(rpid->rpid_display)) {
10875 displayname = rpid->rpid_display;
10876 }
10877 switch_channel_set_variable(channel, "sip_cid_type", "rpid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "rpid", SWITCH_TRUE)
;
10878 tech_pvt->cid_type = CID_TYPE_RPID;
10879 }
10880
10881 if ((passerted = sip_p_asserted_identity(sip)((sip_p_asserted_identity_t *)msg_header_access((msg_pub_t*)(
sip), sip_p_asserted_identity_class))
)) {
10882 if (passerted->paid_url->url_user) {
10883 char *full_paid_header = sip_header_as_string(nua_handle_get_home(nh), (void *) passerted);
10884 //char *full_paid_header = (char *)(passerted->paid_common->h_data);
10885 from_user = passerted->paid_url->url_user;
10886 if (!zstr(full_paid_header)_zstr(full_paid_header)) {
10887 if (profile->paid_type == PAID_DEFAULT || profile->paid_type == PAID_USER) {
10888 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)
;
10889 } else if (profile->paid_type == PAID_USER_DOMAIN) {
10890 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
)
10891 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
)
;
10892 } else if (profile->paid_type == PAID_VERBATIM) {
10893 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)
;
10894 }
10895 }
10896 }
10897 if (!zstr(passerted->paid_display)_zstr(passerted->paid_display)) {
10898 displayname = passerted->paid_display;
10899 }
10900 switch_channel_set_variable(channel, "sip_cid_type", "pid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "pid", SWITCH_TRUE)
;
10901 tech_pvt->cid_type = CID_TYPE_PID;
10902 }
10903
10904 if ((ppreferred = sip_p_preferred_identity(sip)((sip_p_preferred_identity_t *)msg_header_access((msg_pub_t*)
(sip), sip_p_preferred_identity_class))
)) {
10905 if (ppreferred->ppid_url->url_user) {
10906 char *full_ppid_header = sip_header_as_string(nua_handle_get_home(nh), (void *) ppreferred);
10907 from_user = ppreferred->ppid_url->url_user;
10908 if (!zstr(full_ppid_header)_zstr(full_ppid_header)) {
10909 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)
;
10910 }
10911
10912 }
10913 if (!zstr(ppreferred->ppid_display)_zstr(ppreferred->ppid_display)) {
10914 displayname = ppreferred->ppid_display;
10915 }
10916 switch_channel_set_variable(channel, "sip_cid_type", "pid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "pid", SWITCH_TRUE)
;
10917 tech_pvt->cid_type = CID_TYPE_PID;
10918 }
10919
10920 if (from_user) {
10921 check_decode(from_user, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 10921, __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__, 10921); 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__, 10921); from_user = tmp;
} if ((p = strchr(from_user, '"'))) { from_user = p+1; } if (
(p = strrchr(from_user, '"'))) { *p = '\0'; } } } break; } while
(0)
;
10922
10923 if ((name_params = strchr(from_user, ';'))) {
10924 *name_params++ = '\0';
10925 switch_channel_set_variable(channel, "sip_name_params", name_params)switch_channel_set_variable_var_check(channel, "sip_name_params"
, name_params, SWITCH_TRUE)
;
10926 }
10927 }
10928
10929 extract_header_vars(profile, sip, session, nh);
10930 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_allow");
10931
10932 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")
;
10933 if (sip->sip_request->rq_url->url_user) {
10934
10935 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__, 10935
)
;
10936 if (profile->parse_invite_tel_params) {
10937 if (strchr(req_user, ';')) {
10938 int argc1, x1 = 0;
10939 char *argv1[32] = { 0 };
10940
10941 if ((argc1 = switch_separate_string(req_user, ';', argv1, (sizeof(argv1) / sizeof(argv1[0]))))) {
10942 for (x1 = 0; x1 < argc1; x1++) {
10943 if (x1 == 0) {
10944 switch_channel_set_variable(channel, "sip_req_user", argv1[0])switch_channel_set_variable_var_check(channel, "sip_req_user"
, argv1[0], SWITCH_TRUE)
;
10945 } else {
10946 int argc2 = 0;
10947 char *argv2[2] = { 0 };
10948 if ((argc2 = switch_separate_string(argv1[x1], '=', argv2, (sizeof(argv2) / sizeof(argv2[0])))) == 2) {
10949 char *var_name = NULL((void*)0);
10950 var_name = switch_mprintf("sip_invite_%s", argv2[0]);
10951 switch_channel_set_variable(channel, var_name, argv2[1])switch_channel_set_variable_var_check(channel, var_name, argv2
[1], SWITCH_TRUE)
;
10952 switch_safe_free( var_name )if (var_name) {free(var_name);var_name=((void*)0);};
10953 } else {
10954 char *var_name = NULL((void*)0);
10955 var_name = switch_mprintf("sip_invite_%s", argv1[x1]);
10956 switch_channel_set_variable(channel, var_name, "true")switch_channel_set_variable_var_check(channel, var_name, "true"
, SWITCH_TRUE)
;
10957 switch_safe_free( var_name )if (var_name) {free(var_name);var_name=((void*)0);};
10958 }
10959 }
10960 }
10961 }
10962 }
10963 }
10964 }
10965
10966 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
10967 destination_number = req_uri;
10968 } else {
10969 destination_number = req_user;
10970 }
10971 if (sip->sip_request->rq_url->url_params && (sofia_glue_find_parameter(sip->sip_request->rq_url->url_params, "intercom=true"))) {
10972 switch_channel_set_variable(channel, "sip_auto_answer_detected", "true")switch_channel_set_variable_var_check(channel, "sip_auto_answer_detected"
, "true", SWITCH_TRUE)
;
10973 }
10974
10975 if (!destination_number && sip->sip_to) {
10976 destination_number = sip->sip_to->a_url->url_user;
10977 }
10978
10979 /* The human network, OH THE HUMANITY!!! lets send invites with no number! */
10980 if (!destination_number && sip->sip_from) {
10981 destination_number = sip->sip_from->a_url->url_user;
10982 }
10983
10984 if (destination_number) {
10985 check_decode(destination_number, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 10985, __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__, 10985); 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__
, 10985); destination_number = tmp; } if ((p = strchr(destination_number
, '"'))) { destination_number = p+1; } if ((p = strrchr(destination_number
, '"'))) { *p = '\0'; } } } break; } while (0)
;
10986 } else {
10987 destination_number = "service";
10988 }
10989
10990 if (sip->sip_to) {
10991 const char *host, *user;
10992 int port, check_nat = 0;
10993 url_t *transport_url;
10994
10995 if (sip->sip_record_route) {
10996 transport_url = sip->sip_record_route->r_url;
10997 } else {
10998 transport_url = sip->sip_contact->m_url;
10999 }
11000
11001 transport = sofia_glue_url2transport(transport_url);
11002 tech_pvt->transport = transport;
11003
11004 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")
;
11005 if (switch_channel_get_variable(channel, "sip_to_uri")switch_channel_get_variable_dup(channel, "sip_to_uri", SWITCH_TRUE
, -1)
) {
11006 const char *ipv6;
11007 const char *tmp, *at, *url = NULL((void*)0);
11008 const char *tmp_user = switch_channel_get_variable(channel, "sip_to_user")switch_channel_get_variable_dup(channel, "sip_to_user", SWITCH_TRUE
, -1)
;
11009
11010 user = switch_core_session_url_encode(session, tmp_user);
11011 host = switch_channel_get_variable(channel, "sip_to_host")switch_channel_get_variable_dup(channel, "sip_to_host", SWITCH_TRUE
, -1)
;
11012
11013 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)
;
11014
11015 if (sip->sip_to->a_params) {
11016 set_variable_sip_param(channel, "to", sip->sip_to->a_params);
11017 }
11018
11019 if (sip->sip_contact->m_url->url_port) {
11020 port = atoi(sip->sip_contact->m_url->url_port);
11021 } else {
11022 port = sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->extsipport;
11023 }
11024
11025 ipv6 = strchr(host, ':');
11026 tech_pvt->to_uri =
11027 switch_core_session_sprintf(session,
11028 "sip:%s@%s%s%s:%d;transport=%s",
11029 user, ipv6 ? "[" : "", host, ipv6 ? "]" : "", port, sofia_glue_transport2str(transport));
11030
11031 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
11032 check_nat = 1;
11033 }
11034 url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport);
11035
11036 if (!url) {
11037 if (check_nat) {
11038 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11038, (const char*)(session)
, SWITCH_LOG_WARNING, "Nat detected but no external address configured.\n");
11039 }
11040 url = profile->url;
11041 }
11042
11043 if (!url) {
11044 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 11044, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
11045 }
11046
11047 tmp = sofia_overcome_sip_uri_weakness(session, url, transport, SWITCH_TRUE, NULL((void*)0), NULL((void*)0));
11048
11049 if ((at = strchr(tmp, '@'))) {
11050 url = switch_core_session_sprintf(session, "sip:%s%s", user, at);
11051 }
11052
11053 if (url) {
11054 const char *brackets = NULL((void*)0);
11055 const char *proto = NULL((void*)0);
11056
11057 brackets = strchr(url, '>');
11058 proto = switch_stristr("transport=", url);
11059 tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s%s%s%s%s",
11060 brackets ? "" : "<", url,
11061 proto ? "" : ";transport=",
11062 proto ? "" : sofia_glue_transport2str(transport), brackets ? "" : ">");
11063 } else {
11064 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 11064, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
11065 }
11066
11067 } else {
11068 const char *url = NULL((void*)0);
11069 url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport);
11070
11071 if (url) {
11072 const char *brackets = NULL((void*)0);
11073 const char *proto = NULL((void*)0);
11074
11075 brackets = strchr(url, '>');
11076 proto = switch_stristr("transport=", url);
11077 tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s%s%s%s%s",
11078 brackets ? "" : "<", url,
11079 proto ? "" : ";transport=",
11080 proto ? "" : sofia_glue_transport2str(transport), brackets ? "" : ">");
11081 } else {
11082 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 11082, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
11083 }
11084 }
11085 }
11086
11087 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
11088 tech_pvt->user_via = sofia_glue_create_external_via(session, profile, tech_pvt->transport);
11089 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);
11090 }
11091
11092 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")
;
11093
11094 if (sip->sip_referred_by) {
11095 referred_by_user = sip->sip_referred_by->b_url->url_user;
11096 //referred_by_host = sip->sip_referred_by->b_url->url_host;
11097 //channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by);
11098
11099 check_decode(referred_by_user, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 11099, __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__, 11099); 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__
, 11099); 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)
;
11100
11101 if (!zstr(referred_by_user)_zstr(referred_by_user)) {
11102 if (*referred_by_user == '+') {
11103 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)
;
11104 } else {
11105 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)
;
11106 }
11107 }
11108
11109 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)
;
11110
11111 if (sip->sip_referred_by->b_params) {
11112 set_variable_sip_param(channel, "referred_by", sip->sip_referred_by->b_params);
11113 }
11114 }
11115
11116 //sofia_glue_set_name(tech_pvt, channel_name);
11117 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
11118
11119 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "INBOUND CALL")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "INBOUND CALL", SWITCH_TRUE)
;
11120
11121 if (sofia_test_flag(tech_pvt, TFLAG_INB_NOMEDIA)((tech_pvt)->flags[TFLAG_INB_NOMEDIA] ? 1 : 0)) {
11122 switch_channel_set_flag(channel, CF_PROXY_MODE)switch_channel_set_flag_value(channel, CF_PROXY_MODE, 1);
11123 }
11124
11125 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_HOLD) {
11126 switch_channel_set_flag(channel, CF_BYPASS_MEDIA_AFTER_HOLD)switch_channel_set_flag_value(channel, CF_BYPASS_MEDIA_AFTER_HOLD
, 1)
;
11127 }
11128
11129 if (sofia_test_flag(tech_pvt, TFLAG_PROXY_MEDIA)((tech_pvt)->flags[TFLAG_PROXY_MEDIA] ? 1 : 0)) {
11130 switch_channel_set_flag(channel, CF_PROXY_MEDIA)switch_channel_set_flag_value(channel, CF_PROXY_MEDIA, 1);
11131 }
11132
11133 if (sofia_test_flag(tech_pvt, TFLAG_ZRTP_PASSTHRU)((tech_pvt)->flags[TFLAG_ZRTP_PASSTHRU] ? 1 : 0)) {
11134 switch_channel_set_flag(channel, CF_ZRTP_PASSTHRU_REQ)switch_channel_set_flag_value(channel, CF_ZRTP_PASSTHRU_REQ, 1
)
;
11135 }
11136
11137 if (sip->sip_subject && sip->sip_subject->g_string) {
11138 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)
;
11139 }
11140
11141 if (sip->sip_user_agent && !zstr(sip->sip_user_agent->g_string)_zstr(sip->sip_user_agent->g_string)) {
11142 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)
;
11143 }
11144
11145 sofia_set_accept_language_channel_variable(channel, sip);
11146
11147 if (sip->sip_via) {
11148 if (sip->sip_via->v_host) {
11149 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)
;
11150 }
11151 if (sip->sip_via->v_port) {
11152 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)
;
11153 }
11154 if (sip->sip_via->v_rport) {
11155 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)
;
11156 }
11157 }
11158
11159
11160 if (sip->sip_multipart) {
11161 msg_multipart_t *mp;
11162
11163 for (mp = sip->sip_multipart; mp; mp = mp->mp_next) {
11164 if (mp->mp_payload && mp->mp_payload->pl_data && mp->mp_content_type && mp->mp_content_type->c_type) {
11165 char *val = switch_core_session_sprintf(session, "%s:%s", mp->mp_content_type->c_type, mp->mp_payload->pl_data);
11166 switch_channel_add_variable_var_check(channel, "sip_multipart", val, SWITCH_FALSE, SWITCH_STACK_PUSH);
11167 }
11168 }
11169 }
11170
11171 if (sip->sip_max_forwards) {
11172 char max_forwards[32];
11173 switch_snprintf(max_forwards, sizeof(max_forwards), "%lu", sip->sip_max_forwards->mf_count);
11174 switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards)switch_channel_set_variable_var_check(channel, "max_forwards"
, max_forwards, SWITCH_TRUE)
;
11175 }
11176
11177 if (acl_context) context = acl_context;
11178
11179 if (!context) {
11180 context = switch_channel_get_variable(channel, "user_context")switch_channel_get_variable_dup(channel, "user_context", SWITCH_TRUE
, -1)
;
11181 }
11182
11183 if (!context) {
11184 if (profile->context && !strcasecmp(profile->context, "_domain_")) {
11185 context = from_host;
11186 } else {
11187 context = profile->context;
11188 }
11189 }
11190
11191 if (!(dialplan = switch_channel_get_variable(channel, "inbound_dialplan")switch_channel_get_variable_dup(channel, "inbound_dialplan", SWITCH_TRUE
, -1)
)) {
11192 dialplan = profile->dialplan;
11193 }
11194
11195 if ((alert_info = sip_alert_info(sip)((sip_alert_info_t *)msg_header_access((msg_pub_t*)(sip), sip_alert_info_class
))
)) {
11196 char *tmp = sip_header_as_string(nua_handle_get_home(nh), (void *) alert_info);
11197 switch_channel_set_variable(channel, "alert_info", tmp)switch_channel_set_variable_var_check(channel, "alert_info", tmp
, SWITCH_TRUE)
;
11198 su_free(nua_handle_get_home(nh), tmp);
11199 }
11200
11201 if ((call_info = sip_call_info(sip)((sip_call_info_t *)msg_header_access((msg_pub_t*)(sip), sip_call_info_class
))
)) {
11202 call_info_str = sip_header_as_string(nua_handle_get_home(nh), (void *) call_info);
11203
11204 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
&& switch_stristr("appearance", call_info_str)) {
11205 char *p;
11206
11207 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)
;
11208 if ((p = strchr(call_info_str, ';'))) {
11209 p++;
11210 switch_channel_set_variable(channel, "presence_call_info", p)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p, SWITCH_TRUE)
;
11211 }
11212 }
11213
11214 if (call_info->ci_params && (msg_params_find(call_info->ci_params, "answer-after=0"))) {
11215 switch_channel_set_variable(channel, "sip_auto_answer_detected", "true")switch_channel_set_variable_var_check(channel, "sip_auto_answer_detected"
, "true", SWITCH_TRUE)
;
11216 }
11217
11218 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)
;
11219
11220 call_info = call_info->ci_next;
11221
11222 while (call_info) {
11223 call_info_str = sip_header_as_string(nua_handle_get_home(nh), (void *) call_info);
11224 switch_channel_add_variable_var_check(channel, "sip_call_info", call_info_str, SWITCH_FALSE, SWITCH_STACK_PUSH);
11225 call_info = call_info->ci_next;
11226 }
11227
11228 call_info = sip_call_info(sip)((sip_call_info_t *)msg_header_access((msg_pub_t*)(sip), sip_call_info_class
))
;
11229
11230 } else if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
11231 char buf[128] = "";
11232 char *sql;
11233 char *state = "progressing";
11234
11235 if (sip->sip_from && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
11236 sip->sip_to && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
11237 sql =
11238 switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
11239 "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
11240 sip->sip_from->a_url->url_host);
11241 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
11242
11243 if (mod_sofia_globals.debug_sla > 1) {
11244 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 11244
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
11245 }
11246 free(sql);
11247
11248 if (!zstr(buf)_zstr(buf)) {
11249 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
11250 "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
11251
11252 if (mod_sofia_globals.debug_sla > 1) {
11253 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 11253
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
11254 }
11255
11256 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11257
11258
11259 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11259, (const char*)(session)
, SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
11260 sip->sip_from->a_url->url_host, buf);
11261
11262 switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
11263 switch_channel_set_variable(channel, "presence_call_info", buf)switch_channel_set_variable_var_check(channel, "presence_call_info"
, buf, SWITCH_TRUE)
;
11264 call_info_str = switch_core_session_sprintf(session, "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
11265 }
11266 }
11267 }
11268
11269
11270 if (profile->pres_type) {
11271 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
11272 if (zstr(presence_id)_zstr(presence_id) && sip->sip_from && sip->sip_from->a_url) {
11273 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 : "")
;
11274 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 : "")
;
11275 char *tmp = switch_mprintf("%s@%s", user, host);
11276 switch_assert(tmp)((tmp) ? (void) (0) : __assert_fail ("tmp", "sofia.c", 11276,
__extension__ __PRETTY_FUNCTION__))
;
11277 switch_channel_set_variable(channel, "presence_id", tmp)switch_channel_set_variable_var_check(channel, "presence_id",
tmp, SWITCH_TRUE)
;
11278 free(tmp);
11279 }
11280 }
11281
11282
11283 if (sip->sip_request->rq_url->url_params) {
11284 gw_param_name = switch_find_parameter(sip->sip_request->rq_url->url_params, "gw", switch_core_session_get_pool(session));
11285 }
11286
11287 if (strstr(destination_number, "gw+")) {
11288 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
11289 char *tmp;
11290 gw_name = switch_core_session_strdup(session, destination_number + 3)switch_core_perform_session_strdup(session, destination_number
+ 3, "sofia.c", (const char *)__func__, 11290)
;
11291 if ((tmp = strchr(gw_name, '@'))) {
11292 *tmp = '\0';
11293 }
11294 } else {
11295 gw_name = destination_number + 3;
11296 }
11297 }
11298
11299 if (gw_name || gw_param_name) {
11300 sofia_gateway_t *gateway = NULL((void*)0);
11301 char *extension = NULL((void*)0);
11302
11303 if (gw_name && ((gateway = sofia_reg_find_gateway(gw_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 11303
, gw_name)
))) {
11304 gw_param_name = NULL((void*)0);
11305 extension = gateway->extension;
11306 }
11307
11308 if (!gateway && gw_param_name) {
11309 if ((gateway = sofia_reg_find_gateway(gw_param_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 11309
, gw_param_name)
)) {
11310 extension = gateway->real_extension;
11311 }
11312 }
11313
11314 if (gateway) {
11315 context = switch_core_session_strdup(session, gateway->register_context)switch_core_perform_session_strdup(session, gateway->register_context
, "sofia.c", (const char *)__func__, 11315)
;
11316 switch_channel_set_variable(channel, "sip_gateway", gateway->name)switch_channel_set_variable_var_check(channel, "sip_gateway",
gateway->name, SWITCH_TRUE)
;
11317
11318 if (!zstr(extension)_zstr(extension)) {
11319 if (!strcasecmp(extension, "auto_to_user") && sip->sip_to) {
11320 destination_number = sip->sip_to->a_url->url_user;
11321 } else if (!strcasecmp(extension, "auto")) {
11322 if (gw_name && sip->sip_to) {
11323 destination_number = sip->sip_to->a_url->url_user;
11324 }
11325 } else {
11326 destination_number = switch_core_session_strdup(session, extension)switch_core_perform_session_strdup(session, extension, "sofia.c"
, (const char *)__func__, 11326)
;
11327 }
11328 } else if (!gw_param_name && sip->sip_to) {
11329 destination_number = sip->sip_to->a_url->url_user;
11330 }
11331
11332 gateway->ib_calls++;
11333
11334 if (gateway->ib_vars) {
11335 switch_event_header_t *hp;
11336 for (hp = gateway->ib_vars->headers; hp; hp = hp->next) {
11337 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11337, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n",
11338 switch_channel_get_name(channel), hp->name, hp->value);
11339 switch_channel_set_variable(channel, hp->name, hp->value)switch_channel_set_variable_var_check(channel, hp->name, hp
->value, SWITCH_TRUE)
;
11340 }
11341 }
11342
11343 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 11343, gateway);
;
11344 }
11345 }
11346
11347 if (call_info_str) {
11348 char *sql;
11349 char cid[512] = "";
11350 char *str;
11351 char *p = NULL((void*)0);
11352 const char *user = NULL((void*)0), *host = NULL((void*)0), *from_user = NULL((void*)0), *from_host = NULL((void*)0);
11353
11354 if (sip->sip_to) {
11355 user = sip->sip_to->a_url->url_user;
11356 host = sip->sip_to->a_url->url_host;
11357 }
11358
11359 if (sip->sip_from) {
11360 from_user = sip->sip_from->a_url->url_user;
11361 from_host = sip->sip_from->a_url->url_host;
11362 }
11363
11364 if (!user) user = from_user;
11365 if (!host) user = from_host;
11366
11367 if (user && host && from_user && !strcmp(user, from_user)) {
11368 if ((p = strchr(call_info_str, ';'))) {
11369 p++;
11370 }
11371
11372 sql = switch_mprintf(
11373 "select call_id from sip_dialogs where (call_info='%q' or call_info='%q;appearance-state=held') and "
11374 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') and call_id is not null",
11375 switch_str_nil(p)(p ? p : ""), switch_str_nil(p)(p ? p : ""), user, host, user, host);
11376
11377 if ((str = sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, cid, sizeof(cid)))) {
11378 bnh = nua_handle_by_call_id(nua, str);
11379 }
11380
11381 if (mod_sofia_globals.debug_sla > 1) {
11382 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 11382
, ((void*)0)
, SWITCH_LOG_ERROR, "PICK SQL %s [%s] [%s] %d\n", sql, str, cid, !!bnh);
11383 }
11384
11385 free(sql);
11386 }
11387 }
11388
11389
11390 check_decode(displayname, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 11390, __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__, 11390); 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__, 11390
); displayname = tmp; } if ((p = strchr(displayname, '"'))) {
displayname = p+1; } if ((p = strrchr(displayname, '"'))) { *
p = '\0'; } } } break; } while (0)
;
11391
11392 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__, 11392)));} else { tech_pvt->caller_profile
->username = ""; }
;
11393 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__, 11393)));} else { tech_pvt->caller_profile
->dialplan = ""; }
;
11394 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__, 11394)));} else { tech_pvt->caller_profile
->caller_id_name = ""; }
;
11395 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__, 11395)));} else { tech_pvt->caller_profile
->caller_id_number = ""; }
;
11396 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__, 11396)));} else { tech_pvt->caller_profile
->orig_caller_id_name = ""; }
;
11397 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__, 11397)));} else { tech_pvt->caller_profile
->orig_caller_id_number = ""; }
;
11398 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__, 11398)));} else { tech_pvt->caller_profile
->network_addr = ""; }
;
11399 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__, 11399)));} else { tech_pvt->caller_profile
->ani = ""; }
;
11400 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__
, 11400)));} else { tech_pvt->caller_profile->aniii = ""
; }
;
11401 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__, 11401)));} else { tech_pvt->caller_profile
->context = ""; }
;
11402 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__, 11402
)));} else { tech_pvt->caller_profile->destination_number
= ""; }
;
11403
11404 if (!bnh && sip->sip_replaces) {
11405 if (!(bnh = nua_handle_by_replaces(nua, sip->sip_replaces))) {
11406 if (!(bnh = nua_handle_by_call_id(nua, sip->sip_replaces->rp_call_id))) {
11407 bnh = sofia_global_nua_handle_by_replaces(sip->sip_replaces);
11408 }
11409 }
11410 }
11411
11412 if (sip->sip_replaces) {
11413 msg_common_t *rp_common = sip->sip_replaces->rp_common;
11414 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)
;
11415 if (rp_common->h_class->hc_params) {
11416 int i, n;
11417 msg_param_t const *params = * (msg_param_t const **) ((char *)rp_common + rp_common->h_class->hc_params);
11418 for (i = 0; params && params[i]; i++) {
11419 msg_param_t param = params[i];
11420 if (strchr(param, '=')) {
11421 n = strcspn(param, "=");
11422 switch_channel_set_variable_name_printf(channel, param + n + 1, "sip_replaces_%.*s", n, param);
11423 } else {
11424 switch_channel_set_variable_name_printf(channel, "true", "sip_replaces_%s", param);
11425 }
11426 }
11427 }
11428 }
11429
11430 if (bnh) {
11431 sofia_private_t *b_private = NULL((void*)0);
11432 if ((b_private = nua_handle_magic(bnh))) {
11433 switch_core_session_t *b_session = NULL((void*)0);
11434 if ((b_session = switch_core_session_locate(b_private->uuid)switch_core_session_perform_locate(b_private->uuid, "sofia.c"
, (const char *)__func__, 11434)
)) {
11435 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
11436 sofia_handle_sip_i_invite_replaces(session, channel, b_channel, b_private->uuid, tech_pvt, call_info, profile, is_nat, sip);
11437 switch_core_session_rwunlock(b_session);
11438 }
11439 }
11440 nua_handle_unref_user(bnh);
11441 } else if (sip->sip_replaces && sip->sip_replaces->rp_call_id) {
11442 switch_core_session_t *b_session = NULL((void*)0);
11443 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__, 11443)
)) {
11444 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
11445 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);
11446 switch_core_session_rwunlock(b_session);
11447 }
11448 }
11449
11450 if (tech_pvt->caller_profile) {
11451
11452 int first_history_info = 1;
11453
11454 if (rpid) {
11455 if (rpid->rpid_privacy) {
11456 if (!strcasecmp(rpid->rpid_privacy, "yes")) {
11457 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)
;
11458 } else if (!strcasecmp(rpid->rpid_privacy, "full")) {
11459 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)
;
11460 } else if (!strcasecmp(rpid->rpid_privacy, "name")) {
11461 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NAME
)
;
11462 } else if (!strcasecmp(rpid->rpid_privacy, "number")) {
11463 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NUMBER
)
;
11464 } else {
11465 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_HIDE_NAME
)
;
11466 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_HIDE_NUMBER
)
;
11467 }
11468 }
11469
11470 if (rpid->rpid_screen && !strcasecmp(rpid->rpid_screen, "no")) {
11471 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_SCREEN
)
;
11472 }
11473 }
11474
11475 if ((privacy = sip_privacy(sip)((sip_privacy_t *)msg_header_access((msg_pub_t*)(sip), sip_privacy_class
))
)) {
11476 char *full_priv_header = sip_header_as_string(nua_handle_get_home(nh), (void *) privacy);
11477 if (!zstr(full_priv_header)_zstr(full_priv_header)) {
11478 switch_channel_set_variable(channel, "sip_Privacy", full_priv_header)switch_channel_set_variable_var_check(channel, "sip_Privacy",
full_priv_header, SWITCH_TRUE)
;
11479 }
11480 if (msg_params_find(privacy->priv_values, "id")) {
11481 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)
;
11482 }
11483 }
11484
11485 if (sip->sip_identity && sip->sip_identity->id_value) {
11486 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)
;
11487 }
11488 if (sip->sip_date && sip->sip_date->d_time > 0) {
11489 // This INVITE has a SIP Date header.
11490 // sofia-sip stores the Date header value in sip_date->d_time as seconds since January 1, 1900 0:00:00.
11491 // Unix epoch time is seconds since January 1, 1970 0:00:00, making d_time larger by 2208988800.
11492 // Convert to Unix epoch time and save it.
11493 switch_channel_set_variable_printf(channel, "sip_date_epoch_time", "%ld", sip->sip_date->d_time - 2208988800);
11494 }
11495
11496 /* Loop thru unknown Headers Here so we can do something with them */
11497 for (un = sip->sip_unknown; un; un = un->un_next) {
11498 if (!strncasecmp(un->un_name, "Accept-Language", 15)) {
11499 if (!zstr(un->un_value)_zstr(un->un_value)) {
11500 char *tmp_name;
11501 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name))) {
11502 switch_channel_set_variable(channel, tmp_name, un->un_value)switch_channel_set_variable_var_check(channel, tmp_name, un->
un_value, SWITCH_TRUE)
;
11503 free(tmp_name);
11504 }
11505 }
11506 } else if (!strncasecmp(un->un_name, "Diversion", 9)) {
11507 /* Basic Diversion Support for Diversion Indication in SIP */
11508 /* draft-levy-sip-diversion-08 */
11509 if (!zstr(un->un_value)_zstr(un->un_value)) {
11510 char *tmp_name;
11511 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name))) {
11512 switch_channel_set_variable(channel, tmp_name, un->un_value)switch_channel_set_variable_var_check(channel, tmp_name, un->
un_value, SWITCH_TRUE)
;
11513 free(tmp_name);
11514 }
11515 }
11516 } else if (!strncasecmp(un->un_name, "History-Info", 12)) {
11517 if (first_history_info) {
11518 /* If the header exists first time, make sure to remove old info and re-set the variable */
11519 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)
;
11520 first_history_info = 0;
11521 } else {
11522 /* Append the History-Info into one long string */
11523 const char *history_var = switch_channel_get_variable(channel, "sip_history_info")switch_channel_get_variable_dup(channel, "sip_history_info", SWITCH_TRUE
, -1)
;
11524 if (!zstr(history_var)_zstr(history_var)) {
11525 char *tmp_str;
11526 if ((tmp_str = switch_mprintf("%s, %s", history_var, un->un_value))) {
11527 switch_channel_set_variable(channel, "sip_history_info", tmp_str)switch_channel_set_variable_var_check(channel, "sip_history_info"
, tmp_str, SWITCH_TRUE)
;
11528 free(tmp_str);
11529 } else {
11530 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)
;
11531 }
11532 } else {
11533 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)
;
11534 }
11535 }
11536 } else if (!strcasecmp(un->un_name, "X-FS-Channel-Name") && !zstr(un->un_value)_zstr(un->un_value)) {
11537 switch_channel_set_name(channel, un->un_value);
11538 switch_channel_set_variable(channel, "push_channel_name", "true")switch_channel_set_variable_var_check(channel, "push_channel_name"
, "true", SWITCH_TRUE)
;
11539 } else if (!strcasecmp(un->un_name, "X-FS-Support")) {
11540 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__, 11540)
;
11541 } else if (!strcasecmp(un->un_name, "Geolocation")) {
11542 switch_channel_set_variable(channel, "sip_geolocation", un->un_value)switch_channel_set_variable_var_check(channel, "sip_geolocation"
, un->un_value, SWITCH_TRUE)
;
11543 } else if (!strcasecmp(un->un_name, "Geolocation-Error")) {
11544 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)
;
11545 } else if (!strcasecmp(un->un_name, "userLocation")) {
11546 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)
;
11547 } 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)) {
11548 if (!zstr(un->un_value)_zstr(un->un_value)) {
11549 char new_name[512] = "";
11550 int reps = 0;
11551 for (;;) {
11552 char postfix[25] = "";
11553 if (reps > 0) {
11554 switch_snprintf(postfix, sizeof(postfix), "-%d", reps);
11555 }
11556 reps++;
11557 switch_snprintf(new_name, sizeof(new_name), "%s%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name, postfix);
11558
11559 if (switch_channel_get_variable(channel, new_name)switch_channel_get_variable_dup(channel, new_name, SWITCH_TRUE
, -1)
) {
11560 continue;
11561 }
11562
11563 switch_channel_set_variable(channel, new_name, un->un_value)switch_channel_set_variable_var_check(channel, new_name, un->
un_value, SWITCH_TRUE)
;
11564 break;
11565 }
11566 }
11567 }
11568 }
11569
11570 }
11571
11572 tech_pvt->sofia_private = sofia_private;
11573 tech_pvt->nh = nh;
11574
11575 if (profile->pres_type && sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)((profile)->pflags[PFLAG_IN_DIALOG_CHAT] ? 1 : 0)) {
11576 sofia_presence_set_chat_hash(tech_pvt, sip);
11577 }
11578
11579 if (sofia_test_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)((profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] ? 1 : 0
)
) {
11580 sofia_parse_all_invite_headers(sip, session, nh);
11581 }
11582
11583 if (sip->sip_to) {
11584 to = sip->sip_to->a_url;
11585 }
11586 if (sip->sip_from) {
11587 from = sip->sip_from->a_url;
11588 }
11589 contact = sip->sip_contact->m_url;
11590
11591 if (sip->sip_user_agent) {
11592 user_agent = switch_str_nil(sip->sip_user_agent->g_string)(sip->sip_user_agent->g_string ? sip->sip_user_agent
->g_string : "")
;
11593 }
11594
11595 if (sip->sip_call_id) {
11596 call_id = switch_str_nil(sip->sip_call_id->i_id)(sip->sip_call_id->i_id ? sip->sip_call_id->i_id :
"")
;
11597 }
11598
11599 if (to) {
11600 to_user = switch_str_nil(to->url_user)(to->url_user ? to->url_user : "");
11601 to_host = switch_str_nil(to->url_host)(to->url_host ? to->url_host : "");
11602 to_tag = switch_str_nil(sip->sip_to->a_tag)(sip->sip_to->a_tag ? sip->sip_to->a_tag : "");
11603 }
11604
11605 if (from) {
11606 dialog_from_user = switch_str_nil(from->url_user)(from->url_user ? from->url_user : "");
11607 dialog_from_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
11608 from_tag = switch_str_nil(sip->sip_from->a_tag)(sip->sip_from->a_tag ? sip->sip_from->a_tag : ""
)
;
11609 }
11610
11611 contact_user = switch_str_nil(contact->url_user)(contact->url_user ? contact->url_user : "");
11612 contact_host = switch_str_nil(contact->url_host)(contact->url_host ? contact->url_host : "");
11613
11614 if (profile->pres_type) {
11615 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
11616 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
11617 char *full_contact = "";
11618 char *p = NULL((void*)0);
11619 time_t now;
11620
11621 full_contact = sip_header_as_string(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), (void *) sip->sip_contact);
11622
11623 if (call_info_str && switch_stristr("appearance", call_info_str)) {
11624 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)
;
11625 if ((p = strchr(call_info_str, ';'))) {
11626 p++;
11627 switch_channel_set_variable(channel, "presence_call_info", p)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p, SWITCH_TRUE)
;
11628 }
11629 }
11630
11631 now = switch_epoch_time_now(NULL((void*)0));
11632
11633 sql = switch_mprintf("insert into sip_dialogs "
11634 "(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
11635 "contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
11636 "call_info,rcd,call_info_state) "
11637 "values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
11638 call_id,
11639 tech_pvt->sofia_private->uuid,
11640 to_user, to_host, to_tag, dialog_from_user, dialog_from_host, from_tag,
11641 contact_user, contact_host, "confirmed", "inbound", user_agent,
11642 profile->name, mod_sofia_globals.hostname, switch_str_nil(full_contact)(full_contact ? full_contact : ""),
11643 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);
11644
11645 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 11645,
__extension__ __PRETTY_FUNCTION__))
;
11646
11647 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11648
11649 if ( full_contact ) {
11650 su_free(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), full_contact);
11651 }
11652 }
11653
11654 if (is_nat) {
11655 sofia_set_flag(tech_pvt, TFLAG_NAT)(tech_pvt)->flags[TFLAG_NAT] = 1;
11656 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11656, (const char*)(session)
, SWITCH_LOG_DEBUG, "Setting NAT mode based on %s\n", is_nat);
11657 switch_channel_set_variable(channel, "sip_nat_detected", "true")switch_channel_set_variable_var_check(channel, "sip_nat_detected"
, "true", SWITCH_TRUE)
;
11658 }
11659
11660 return;
11661
11662 fail:
11663 profile->ib_failed_calls++;
11664
11665 return;
11666
11667}
11668
11669void 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)
11670{
11671 const char *bridge_uuid;
11672 switch_caller_profile_t *orig_cp, *cp;
11673 //const char *sent_name, *sent_number;
11674 orig_cp = switch_channel_get_caller_profile(b_channel);
11675
11676 if (orig_cp) {
11677 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__
, 11677)
;
11678 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__
, 11678)
;
11679
11680 if (!call_info) {
11681 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__
, 11681)
;
11682 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__
, 11682)
;
11683 }
11684
11685 cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool, orig_cp);
11686 switch_channel_set_originator_caller_profile(channel, cp);
11687 }
11688
11689#if 0
11690 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)
;
11691 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)
;
11692
11693 if (!zstr(sent_name)_zstr(sent_name) && !zstr(sent_number)_zstr(sent_number)) {
11694 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__, 11694)
;
11695 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__, 11695)
;
11696 } else {
11697 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
11698 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__
, 11698)
;
11699 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__
, 11699)
;
11700 } else {
11701 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__
, 11701)
;
11702 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__
, 11702)
;
11703 }
11704 }
11705#endif
11706
11707 if (is_nat) {
11708 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11708, (const char*)(session)
, SWITCH_LOG_CRIT, "Setting NAT mode based on %s\n", is_nat);
11709 }
11710
11711 tech_pvt->caller_profile->dialplan = "inline";
11712
11713 bridge_uuid = switch_channel_get_partner_uuid(b_channel);
11714 if (bridge_uuid) {
11715 switch_core_session_t *bridge_session = NULL((void*)0);
11716 if ((bridge_session = switch_core_session_locate(bridge_uuid)switch_core_session_perform_locate(bridge_uuid, "sofia.c", (const
char *)__func__, 11716)
)) {
11717 switch_core_session_rwunlock(bridge_session);
11718 } else {
11719 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11719, (const char*)(session)
, SWITCH_LOG_WARNING, "could not locate partner_uuid %s, resetting\n", bridge_uuid);
11720 bridge_uuid = NULL((void*)0);
11721 }
11722 }
11723
11724 if (call_info) {
11725 switch_event_t *event = NULL((void*)0);
11726
11727 if (!zstr(bridge_uuid)_zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) {
11728 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)
;
11729
11730 if (b_call_id) {
11731 char *sql = switch_mprintf("update sip_dialogs set call_info_state='idle' where call_id='%q'", b_call_id);
11732 if (mod_sofia_globals.debug_sla > 1) {
11733 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11733, (const char*)(session)
, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
11734 }
11735 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11736
11737 switch_channel_presence(b_channel, "unknown", "idle", NULL)switch_channel_perform_presence(b_channel, "unknown", "idle",
((void*)0), "sofia.c", (const char *)__func__, 11737)
;
11738 }
11739 switch_channel_set_flag(tech_pvt->channel, CF_SLA_INTERCEPT)switch_channel_set_flag_value(tech_pvt->channel, CF_SLA_INTERCEPT
, 1)
;
11740 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
11741 "answer,intercept:%s", bridge_uuid);
11742
11743 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)
11744 && sip && sip->sip_call_id
11745 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 11745, &event, SWITCH_EVENT_CUSTOM
, "sofia::replaced")
== SWITCH_STATUS_SUCCESS) {
11746 switch_channel_event_set_data(b_channel, event);
11747 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", sip->sip_call_id->i_id);
11748 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 11748, &event, ((void*)0))
;
11749 }
11750 } else {
11751 switch_caller_profile_t *bcp = switch_channel_get_caller_profile(b_channel);
11752
11753 if (switch_channel_test_flag(b_channel, CF_BRIDGE_ORIGINATOR)) {
11754 switch_channel_set_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR)switch_channel_set_flag_value(tech_pvt->channel, CF_BRIDGE_ORIGINATOR
, 1)
;
11755 }
11756
11757 if (!zstr(bcp->callee_id_name)_zstr(bcp->callee_id_name)) {
11758 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__, 11758
)
;
11759 }
11760
11761 if (!zstr(bcp->callee_id_number)_zstr(bcp->callee_id_number)) {
11762 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__
, 11762)
;
11763 }
11764
11765
11766 if (!zstr(bcp->caller_id_name)_zstr(bcp->caller_id_name)) {
11767 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__, 11767
)
;
11768 }
11769
11770 if (!zstr(bcp->caller_id_number)_zstr(bcp->caller_id_number)) {
11771 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__
, 11771)
;
11772 }
11773
11774 if (bcp->originatee_caller_profile) {
11775 switch_caller_profile_t *cp;
11776
11777 cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool,
11778 bcp->originatee_caller_profile);
11779
11780 switch_channel_set_originatee_caller_profile(tech_pvt->channel, cp);
11781 }
11782
11783 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
11784 "answer,sofia_sla:%s", uuid);
11785 }
11786 } else {
11787 char const *nightmare_xfer_uuid = NULL((void*)0);
11788 switch_event_t *event = NULL((void*)0);
11789 if (switch_channel_var_true(channel, "sip_replaces_a-leg")) {
11790 switch_channel_mark_hold(b_channel, SWITCH_FALSE);
11791 if (sip) {
11792 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", sip->sip_replaces->rp_call_id);
11793 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11793, (const char*)(session)
, SWITCH_LOG_DEBUG, "call %s picked up on a-leg\n", sip->sip_replaces->rp_call_id);
11794 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)
11795 && sip->sip_call_id
11796 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 11796, &event, SWITCH_EVENT_CUSTOM
, "sofia::intercepted")
== SWITCH_STATUS_SUCCESS) {
11797 switch_channel_event_set_data(b_channel, event);
11798 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id);
11799 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 11799, &event, ((void*)0))
;
11800 }
11801 }
11802 } else {
11803 if (sip) {
11804 if ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-For"))) {
11805 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)
;
11806 }
11807 if ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-From"))) {
11808 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)
;
11809 }
11810 }
11811
11812 if (!zstr(bridge_uuid)_zstr(bridge_uuid)) {
11813 if (sip && sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id && switch_channel_test_flag(b_channel, CF_BRIDGED) &&
11814 switch_true(switch_find_parameter(*(sip->sip_replaces->rp_params), "early-only", switch_core_session_get_pool(session)))) {
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 intercept rejected\n", bridge_uuid);
11816 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "hangup:CALL_REJECTED");
11817 } else {
11818 switch_channel_mark_hold(b_channel, SWITCH_FALSE);
11819 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid);
11820 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
11820, (const char*)(session)
, SWITCH_LOG_DEBUG, "call %s intercepted\n", bridge_uuid);
11821 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)
11822 && sip && sip->sip_call_id
11823 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 11823, &event, SWITCH_EVENT_CUSTOM
, "sofia::intercepted")
== SWITCH_STATUS_SUCCESS) {
11824 switch_channel_event_set_data(b_channel, event);
11825 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id);
11826 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 11826, &event, ((void*)0))
;
11827 }
11828 }
11829 } else {
11830 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)
;
11831 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)
;
11832 if (b_data && b_app) {
11833 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s:%s", b_app, b_data);
11834 } else if (b_app) {
11835 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s", b_app);
11836 }
11837 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)((profile)->pflags[PFLAG_FIRE_TRANFER_EVENTS] ? 1 : 0)
11838 && sip && sip->sip_call_id
11839 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 11839, &event, SWITCH_EVENT_CUSTOM
, "sofia::replaced")
== SWITCH_STATUS_SUCCESS) {
11840 switch_channel_event_set_data(b_channel, event);
11841 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", sip->sip_call_id->i_id);
11842 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 11842, &event, ((void*)0))
;
11843 }
11844 switch_channel_hangup(b_channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(b_channel, "sofia.c", (const char
*)__func__, 11844, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
11845 }
11846 }
11847 }
11848
11849}
11850
11851void sofia_handle_sip_i_options(int status,
11852 char const *phrase,
11853 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
11854 sofia_dispatch_event_t *de,
11855 tagi_t tags[])
11856{
11857 uint32_t sess_count = switch_core_session_count();
11858 uint32_t sess_max = switch_core_session_limit(0);
11859
11860 if (sofia_test_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)((profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] ? 1 :
0)
&&
11861 (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0) || !switch_core_ready_inbound())) {
11862 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);
11863 } else {
11864 switch_assert(sip)((sip) ? (void) (0) : __assert_fail ("sip", "sofia.c", 11864,
__extension__ __PRETTY_FUNCTION__))
;
11865 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),
11866 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);
11867 }
11868
11869}
11870
11871/*
11872 * This subroutine will take the a_params of a sip_addr_s structure and spin through them.
11873 * Each param will be used to create a channel variable.
11874 * In the SIP RFC's, this data is called generic-param.
11875 * Note that the tag-param is also included in the a_params list.
11876 *
11877 * From: "John Doe" <sip:5551212@1.2.3.4>;tag=ed23266b52cbb17eo2;ref=101;mbid=201
11878 *
11879 * For example, the header above will produce an a_params list with three entries
11880 * tag=ed23266b52cbb17eo2
11881 * ref=101
11882 * mbid=201
11883 *
11884 * The a_params list is parsed and the lvalue is used to create the channel variable name while the
11885 * rvalue is used to create the channel variable value.
11886 *
11887 * If no equal (=) sign is found during parsing, a channel variable name is created with the param and
11888 * the value is set to NULL.
11889 *
11890 * Pointers are used for copying the sip_header_name for performance reasons. There are no calls to
11891 * any string functions and no memory is allocated/dealocated. The only limiter is the size of the
11892 * sip_header_name array.
11893*/
11894static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params)
11895{
11896 char sip_header_name[128] = "";
11897 char var1[] = "sip_";
11898 char *cp, *sh, *sh_end, *sh_save;
11899
11900 /* Build the static part of the sip_header_name variable from */
11901 /* the header_type. If the header type is "referred_by" then */
11902 /* sip_header_name = "sip_referred_by_". */
11903 sh = sip_header_name;
11904 sh_end = sh + sizeof(sip_header_name) - 1;
11905 for (cp = var1; *cp; cp++, sh++) {
11906 *sh = *cp;
11907 }
11908 *sh = '\0';
11909
11910 /* Copy the header_type to the sip_header_name. Before copying */
11911 /* each character, check that we aren't going to overflow the */
11912 /* the sip_header_name buffer. We have to account for the */
11913 /* trailing underscore and NULL that will be added to the end. */
11914 for (cp = header_type; (*cp && (sh < (sh_end - 1))); cp++, sh++) {
11915 *sh = *cp;
11916 }
11917 *sh++ = '_';
11918 *sh = '\0';
11919
11920 /* sh now points to the NULL at the end of the partially built */
11921 /* sip_header_name variable. This is also the start of the */
11922 /* variable part of the sip_header_name built from the lvalue */
11923 /* of the params data. */
11924 sh_save = sh;
11925
11926 while (params && params[0]) {
11927
11928 /* Copy the params data to the sip_header_name variable until */
11929 /* the end of the params string is reached, an '=' is detected */
11930 /* or until the sip_header_name buffer has been exhausted. */
11931 for (cp = (char *) (*params); ((*cp != '=') && *cp && (sh < sh_end)); cp++, sh++) {
11932 *sh = *cp;
11933 }
11934
11935 /* cp now points to either the end of the params data or the */
11936 /* equal (=) sign separating the lvalue and rvalue. */
11937 if (*cp == '=')
11938 cp++;
11939 *sh = '\0';
11940 switch_channel_set_variable(channel, sip_header_name, cp)switch_channel_set_variable_var_check(channel, sip_header_name
, cp, SWITCH_TRUE)
;
11941
11942 /* Bump pointer to next param in the list. Also reset the */
11943 /* sip_header_name pointer to the beginning of the dynamic area */
11944 params++;
11945 sh = sh_save;
11946 }
11947}
11948
11949/* For Emacs:
11950 * Local Variables:
11951 * mode:c
11952 * indent-tabs-mode:t
11953 * tab-width:4
11954 * c-basic-offset:4
11955 * End:
11956 * For VIM:
11957 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
11958 */