Bug Summary

File:src/mod/endpoints/mod_sofia/sofia.c
Location:line 8108, column 25
Description:Value stored to 'channel' during its initialization is never read

Annotated Source Code

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
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);
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
87void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
88 char const *phrase,
89 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
90 sofia_dispatch_event_t *de, tagi_t tags[])
91{
92
93 if (status == 481 && sip && !sip->sip_retry_after && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) {
94 char *sql;
95
96 sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", sip->sip_call_id->i_id);
97 switch_assert(sql != NULL)((sql != ((void*)0)) ? (void) (0) : __assert_fail ("sql != ((void*)0)"
, "sofia.c", 97, __PRETTY_FUNCTION__))
;
98 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
99 nua_handle_destroy(nh);
100 }
101
102}
103
104#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")
105
106static const char *_url_set_chanvars(switch_core_session_t *session, url_t *url, const char *user_var,
107 const char *host_var, const char *port_var, const char *uri_var, const char *params_var)
108{
109 const char *user = NULL((void*)0), *host = NULL((void*)0), *port = NULL((void*)0);
110 char *uri = NULL((void*)0);
111 switch_channel_t *channel = switch_core_session_get_channel(session);
112 char new_port[25] = "";
113
114 if (url) {
115 user = url->url_user;
116 host = url->url_host;
117 port = url->url_port;
118 if (!zstr(url->url_params)_zstr(url->url_params)) {
119 switch_channel_set_variable(channel, params_var, url->url_params)switch_channel_set_variable_var_check(channel, params_var, url
->url_params, SWITCH_TRUE)
;
120 }
121 }
122
123 if (zstr(user)_zstr(user)) {
124 user = "nobody";
125 }
126
127 if (zstr(host)_zstr(host)) {
128 host = "nowhere";
129 }
130
131 check_decode(user, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 131, __PRETTY_FUNCTION__)); if (!_zstr(user)) { int d = 0; char
*p; if ((__extension__ (__builtin_constant_p ('%') &&
!__builtin_constant_p (user) && ('%') == '\0' ? (char
*) __rawmemchr (user, '%') : __builtin_strchr (user, '%'))))
{ char *tmp = switch_core_perform_session_strdup(session, user
, "sofia.c", (const char *)__func__, 131); switch_url_decode(
tmp); user = tmp; d++; } if ((p = (__extension__ (__builtin_constant_p
('"') && !__builtin_constant_p (user) && ('"'
) == '\0' ? (char *) __rawmemchr (user, '"') : __builtin_strchr
(user, '"'))))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, user, "sofia.c", (const char *)__func__, 131); user
= tmp; } if ((p = (__extension__ (__builtin_constant_p ('"')
&& !__builtin_constant_p (user) && ('"') == '\0'
? (char *) __rawmemchr (user, '"') : __builtin_strchr (user,
'"'))))) { user = p+1; } if ((p = strrchr(user, '"'))) { *p =
'\0'; } } } if (session) break; } while(!session)
;
132
133 if (user) {
134 switch_channel_set_variable(channel, user_var, user)switch_channel_set_variable_var_check(channel, user_var, user
, SWITCH_TRUE)
;
135 }
136
137
138 if (port) {
139 switch_snprintf(new_port, sizeof(new_port), ":%s", port);
140 }
141
142 switch_channel_set_variable(channel, port_var, port)switch_channel_set_variable_var_check(channel, port_var, port
, SWITCH_TRUE)
;
143 if (host) {
144 if (user) {
145 uri = switch_core_session_sprintf(session, "%s@%s%s", user, host, new_port);
146 } else {
147 uri = switch_core_session_sprintf(session, "%s%s", host, new_port);
148 }
149 switch_channel_set_variable(channel, uri_var, uri)switch_channel_set_variable_var_check(channel, uri_var, uri, SWITCH_TRUE
)
;
150 switch_channel_set_variable(channel, host_var, host)switch_channel_set_variable_var_check(channel, host_var, host
, SWITCH_TRUE)
;
151 }
152
153 return uri;
154}
155
156static char *strip_quotes(const char *in)
157{
158 char *t = (char *) in;
159 char *r = (char *) in;
160
161 if (t && *t == '"') {
162 t++;
163
164 if (end_of(t)*(*t == '\0' ? t : t + strlen(t) - 1) == '"') {
165 r = strdup(t)(__extension__ (__builtin_constant_p (t) && ((size_t)
(const void *)((t) + 1) - (size_t)(const void *)(t) == 1) ? (
((const char *) (t))[0] == '\0' ? (char *) calloc ((size_t) 1
, (size_t) 1) : ({ size_t __len = strlen (t) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, t, __len); __retval; })) : __strdup
(t)))
;
166 end_of(r)*(*r == '\0' ? r : r + strlen(r) - 1) = '\0';
167 }
168 }
169
170 return r;
171}
172
173static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip,
174 switch_core_session_t *session, nua_handle_t *nh)
175{
176 switch_channel_t *channel = switch_core_session_get_channel(session);
177 char *full;
178
179 if (sip) {
180 if (sip->sip_route) {
181 if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_route))) {
182 const char *v = switch_channel_get_variable(channel, "sip_full_route")switch_channel_get_variable_dup(channel, "sip_full_route", SWITCH_TRUE
, -1)
;
183 if (!v) {
184 switch_channel_set_variable(channel, "sip_full_route", full)switch_channel_set_variable_var_check(channel, "sip_full_route"
, full, SWITCH_TRUE)
;
185 }
186 su_free(nh->nh_home, full);
187 }
188 }
189
190 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
191 if (sip->sip_contact) {
192 char *c = sip_header_as_string(nh->nh_home, (void *) sip->sip_contact);
193 switch_channel_set_variable(channel, "sip_recover_contact", c)switch_channel_set_variable_var_check(channel, "sip_recover_contact"
, c, SWITCH_TRUE)
;
194 su_free(nh->nh_home, c);
195 }
196 }
197
198 if (sip->sip_record_route) {
199 sip_record_route_t *rrp;
200 switch_stream_handle_t stream = { 0 };
201 int x = 0;
202
203 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 203, __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
;
204
205 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
206 char *tmp[128] = { 0 };
207 int y = 0;
208
209 for(rrp = sip->sip_record_route; rrp; rrp = rrp->r_next) {
210 char *rr = sip_header_as_string(nh->nh_home, (void *) rrp);
211 tmp[y++] = rr;
212 if (y == 127) break;
213 }
214
215 y--;
216
217 while(y >= 0) {
218 stream.write_function(&stream, x == 0 ? "%s" : ",%s", tmp[y]);
219 su_free(nh->nh_home, tmp[y]);
220 y--;
221 x++;
222 }
223
224 } else {
225 for(rrp = sip->sip_record_route; rrp; rrp = rrp->r_next) {
226 char *rr = sip_header_as_string(nh->nh_home, (void *) rrp);
227
228 stream.write_function(&stream, x == 0 ? "%s" : ",%s", rr);
229 su_free(nh->nh_home, rr);
230
231 x++;
232 }
233 }
234
235 switch_channel_set_variable(channel, "sip_invite_record_route", (char *)stream.data)switch_channel_set_variable_var_check(channel, "sip_invite_record_route"
, (char *)stream.data, SWITCH_TRUE)
;
236 free(stream.data);
237 }
238
239 if (sip->sip_via) {
240 sip_via_t *vp;
241 switch_stream_handle_t stream = { 0 };
242 int x = 0;
243
244 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 244, __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
;
245
246 for(vp = sip->sip_via; vp; vp = vp->v_next) {
247 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
248
249 stream.write_function(&stream, x == 0 ? "%s" : ",%s", v);
250 su_free(nh->nh_home, v);
251
252 x++;
253 }
254
255 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)
;
256
257 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND || switch_stristr("TCP", (char *)stream.data)) {
258 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)
;
259 }
260
261 free(stream.data);
262
263 }
264
265 if (sip->sip_from) {
266 char *p = strip_quotes(sip->sip_from->a_display);
267
268 if (p) {
269 switch_channel_set_variable(channel, "sip_from_display", p)switch_channel_set_variable_var_check(channel, "sip_from_display"
, p, SWITCH_TRUE)
;
270 }
271 if (p != sip->sip_from->a_display) free(p);
272 if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_from))) {
273 switch_channel_set_variable(channel, "sip_full_from", full)switch_channel_set_variable_var_check(channel, "sip_full_from"
, full, SWITCH_TRUE)
;
274 su_free(nh->nh_home, full);
275 }
276 }
277
278 if (sip->sip_to) {
279 char *p = strip_quotes(sip->sip_to->a_display);
280
281 if (p) {
282 switch_channel_set_variable(channel, "sip_to_display", p)switch_channel_set_variable_var_check(channel, "sip_to_display"
, p, SWITCH_TRUE)
;
283 }
284
285 if (p != sip->sip_to->a_display) free(p);
286
287 if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_to))) {
288 switch_channel_set_variable(channel, "sip_full_to", full)switch_channel_set_variable_var_check(channel, "sip_full_to",
full, SWITCH_TRUE)
;
289 su_free(nh->nh_home, full);
290 }
291 }
292
293 }
294}
295
296static void extract_vars(sofia_profile_t *profile, sip_t const *sip,
297 switch_core_session_t *session)
298{
299 switch_channel_t *channel = switch_core_session_get_channel(session);
300
301 if (sip) {
302 if (sip->sip_from && sip->sip_from->a_url)
303 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")
;
304 if (sip->sip_request && sip->sip_request->rq_url)
305 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")
;
306 if (sip->sip_to && sip->sip_to->a_url)
307 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")
;
308 if (sip->sip_contact && sip->sip_contact->m_url)
309 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")
;
310 if (sip->sip_referred_by && sip->sip_referred_by->b_url)
311 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"
)
;
312 if (sip->sip_to && sip->sip_to->a_tag) {
313 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)
;
314 }
315 if (sip->sip_from && sip->sip_from->a_tag) {
316 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)
;
317 }
318 if (sip->sip_cseq && sip->sip_cseq->cs_seq) {
319 char sip_cseq[40] = "";
320 switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq);
321 switch_channel_set_variable(channel, "sip_cseq", sip_cseq)switch_channel_set_variable_var_check(channel, "sip_cseq", sip_cseq
, SWITCH_TRUE)
;
322 }
323 if (sip->sip_call_id && sip->sip_call_id->i_id) {
324 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)
;
325 }
326 }
327}
328
329/**
330 * Add a specific SIP INVITE header to the channel variables, prefixed with "sip_i_"
331 */
332static void sofia_add_invite_header_to_chanvars(switch_channel_t *channel, nua_handle_t *nh, void *sip_header, const char *var)
333{
334 switch_assert(channel)((channel) ? (void) (0) : __assert_fail ("channel", "sofia.c"
, 334, __PRETTY_FUNCTION__))
;
335 switch_assert(nh)((nh) ? (void) (0) : __assert_fail ("nh", "sofia.c", 335, __PRETTY_FUNCTION__
))
;
336 switch_assert(var)((var) ? (void) (0) : __assert_fail ("var", "sofia.c", 336, __PRETTY_FUNCTION__
))
;
337
338 if (sip_header) {
339 char *full;
340 if ((full = sip_header_as_string(nh->nh_home, sip_header))) {
341 switch_channel_set_variable(channel, var, full)switch_channel_set_variable_var_check(channel, var, full, SWITCH_TRUE
)
;
342 su_free(nh->nh_home, full);
343 }
344 }
345}
346
347/**
348 * Deep search into the SIP message to recreate the original headers, including multiple Diversions, etc.
349 * Finally sets the "sip_invite_headers" to a string containing the 'original' SIP headers, except that the order may have changed.
350 * Multiple headers will have the original internal order, though.
351 *
352 * @param sip A sip_t struct containing the parsed message
353 * @param session A call session
354 * @param nh A NUA handle for string allocation
355 */
356static void sofia_parse_all_invite_headers(sip_t const *sip, switch_core_session_t *session, nua_handle_t *nh)
357{
358 switch_channel_t *channel = switch_core_session_get_channel(session);
359 sip_unknown_t *un;
360 sip_p_asserted_identity_t *passerted;
361 sip_p_preferred_identity_t *ppreferred;
362 sip_remote_party_id_t *rpid;
363 sip_reply_to_t *reply_to;
364 sip_alert_info_t *alert_info;
365
366 if (!sip) return;
367
368 /* Add simple (unique) headers first */
369 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_from, "sip_i_from");
370 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_to, "sip_i_to");
371 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_call_id, "sip_i_call_id");
372 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_cseq, "sip_i_cseq");
373 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_route, "sip_i_route");
374 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_max_forwards, "sip_i_max_forwards");
375 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_proxy_require, "sip_i_proxy_require");
376 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_contact, "sip_i_contact");
377 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_user_agent, "sip_i_user_agent");
378 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_subject, "sip_i_subject");
379 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_priority, "sip_i_priority");
380 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_organization, "sip_i_organization");
381 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_in_reply_to, "sip_i_in_reply_to");
382 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_accept_encoding, "sip_i_accept_encoding");
383 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_accept_language, "sip_i_accept_language");
384 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_i_allow");
385 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_require, "sip_i_require");
386 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_supported, "sip_i_supported");
387 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_date, "sip_i_date");
388 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_timestamp, "sip_i_timestamp");
389 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_expires, "sip_i_expires");
390 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_min_expires, "sip_i_min_expires");
391 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_session_expires, "sip_i_session_expires");
392 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_min_se, "sip_i_min_se");
393 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_privacy, "sip_i_privacy");
394 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_mime_version, "sip_i_mime_version");
395 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_type, "sip_i_content_type");
396 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_encoding, "sip_i_content_encoding");
397 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_language, "sip_i_content_language");
398 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_disposition, "sip_i_content_disposition");
399 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_length, "sip_i_content_length");
400
401 /* Add all other headers - which might exist more than once */
402
403 if (sip->sip_via) {
404 sip_via_t *vp;
405 for (vp = sip->sip_via; vp; vp = vp->v_next) {
406 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
407 switch_channel_add_variable_var_check(channel, "sip_i_via", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
408 su_free(nh->nh_home, v);
409 }
410 }
411
412 if (sip->sip_record_route) {
413 sip_record_route_t *rrp;
414 for (rrp = sip->sip_record_route; rrp; rrp = rrp->r_next) {
415 char *rr = sip_header_as_string(nh->nh_home, (void *) rrp);
416 switch_channel_add_variable_var_check(channel, "sip_i_record_route", rr, SWITCH_FALSE, SWITCH_STACK_PUSH);
417 su_free(nh->nh_home, rr);
418 }
419 }
420
421 if (sip->sip_proxy_authorization) {
422 sip_proxy_authorization_t *vp;
423 for (vp = sip->sip_proxy_authorization; vp; vp = vp->au_next) {
424 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
425 switch_channel_add_variable_var_check(channel, "sip_i_proxy_authorization", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
426 su_free(nh->nh_home, v);
427 }
428 }
429
430 if (sip->sip_call_info) {
431 sip_call_info_t *vp;
432 for (vp = sip->sip_call_info; vp; vp = vp->ci_next) {
433 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
434 switch_channel_add_variable_var_check(channel, "sip_i_call_info", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
435 su_free(nh->nh_home, v);
436 }
437 }
438
439 if (sip->sip_accept) {
440 sip_accept_t *vp;
441 for (vp = sip->sip_accept; vp; vp = vp->ac_next) {
442 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
443 switch_channel_add_variable_var_check(channel, "sip_i_accept", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
444 su_free(nh->nh_home, v);
445 }
446 }
447
448 if (sip->sip_authorization) {
449 sip_authorization_t *vp;
450 for (vp = sip->sip_authorization; vp; vp = vp->au_next) {
451 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
452 switch_channel_add_variable_var_check(channel, "sip_i_authorization", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
453 su_free(nh->nh_home, v);
454 }
455 }
456
457 if ((alert_info = sip_alert_info(sip)((sip_alert_info_t *)msg_header_access((msg_pub_t*)(sip), sip_alert_info_class
))
)) {
458 sip_alert_info_t *vp;
459 for (vp = alert_info; vp; vp = vp->ai_next) {
460 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
461 switch_channel_add_variable_var_check(channel, "sip_i_alert_info", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
462 su_free(nh->nh_home, v);
463 }
464 }
465
466 if ((passerted = sip_p_asserted_identity(sip)((sip_p_asserted_identity_t *)msg_header_access((msg_pub_t*)(
sip), sip_p_asserted_identity_class))
)) {
467 sip_p_asserted_identity_t *vp;
468 for (vp = passerted; vp; vp = vp->paid_next) {
469 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
470 switch_channel_add_variable_var_check(channel, "sip_i_p_asserted_identity", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
471 su_free(nh->nh_home, v);
472 }
473 }
474
475 if ((ppreferred = sip_p_preferred_identity(sip)((sip_p_preferred_identity_t *)msg_header_access((msg_pub_t*)
(sip), sip_p_preferred_identity_class))
)) {
476 sip_p_preferred_identity_t *vp;
477 for (vp = ppreferred; vp; vp = vp->ppid_next) {
478 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
479 switch_channel_add_variable_var_check(channel, "sip_i_p_preferred_identity", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
480 su_free(nh->nh_home, v);
481 }
482 }
483
484 if ((rpid = sip_remote_party_id(sip)((sip_remote_party_id_t *)msg_header_access((msg_pub_t*)(sip)
, sip_remote_party_id_class))
)) {
485 sip_remote_party_id_t *vp;
486 for (vp = rpid; vp; vp = vp->rpid_next) {
487 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
488 switch_channel_add_variable_var_check(channel, "sip_i_remote_party_id", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
489 su_free(nh->nh_home, v);
490 }
491 }
492
493 if ((reply_to = sip_reply_to(sip)((sip_reply_to_t *)msg_header_access((msg_pub_t*)(sip), sip_reply_to_class
))
)) {
494 sip_reply_to_t *vp;
495 for (vp = reply_to; vp; vp = vp->rplyto_next) {
496 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
497 switch_channel_add_variable_var_check(channel, "sip_i_reply_to", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
498 su_free(nh->nh_home, v);
499 }
500 }
501
502 /* Loop through the unknown headers */
503 for (un = sip->sip_unknown; un; un = un->un_next) {
504 if (!zstr(un->un_name)_zstr(un->un_name) && !zstr(un->un_value)_zstr(un->un_value)) {
505 char *parsed_name;
506 if ((parsed_name = switch_mprintf("sip_i_%s", un->un_name))) {
507 char *p, *x = parsed_name;
508 switch_tolower_max(x);
509 while ((p = strchr(x, '-')(__extension__ (__builtin_constant_p ('-') && !__builtin_constant_p
(x) && ('-') == '\0' ? (char *) __rawmemchr (x, '-')
: __builtin_strchr (x, '-')))
)) {
510 *p = '_';
511 x = ++p;
512 }
513 switch_channel_add_variable_var_check(channel, parsed_name, un->un_value, SWITCH_FALSE, SWITCH_STACK_PUSH);
514 free(parsed_name);
515 }
516 }
517 }
518}
519
520void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
521 char const *phrase,
522 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
523 sofia_dispatch_event_t *de, tagi_t tags[])
524{
525 switch_channel_t *channel = NULL((void*)0);
526 private_object_t *tech_pvt = NULL((void*)0);
527 switch_event_t *s_event = NULL((void*)0);
528 sofia_gateway_subscription_t *gw_sub_ptr;
529 int sub_state;
530 sofia_gateway_t *gateway = NULL((void*)0);
531
532 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);
533
534 /* make sure we have a proper event */
535 if (!sip || !sip->sip_event) {
536 goto error;
537 }
538
539 /* Automatically return a 200 OK for Event: keep-alive */
540 if (!strcasecmp(sip->sip_event->o_type, "keep-alive")) {
541 /* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */
542 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_END()(tag_type_t)0, (tag_value_t)0);
543 goto end;
544 }
545
546 if (session) {
547 channel = switch_core_session_get_channel(session);
548 switch_assert(channel != NULL)((channel != ((void*)0)) ? (void) (0) : __assert_fail ("channel != ((void*)0)"
, "sofia.c", 548, __PRETTY_FUNCTION__))
;
549 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
550 switch_assert(tech_pvt != NULL)((tech_pvt != ((void*)0)) ? (void) (0) : __assert_fail ("tech_pvt != ((void*)0)"
, "sofia.c", 550, __PRETTY_FUNCTION__))
;
551 }
552
553
554 if (sofia_test_pflag(profile, PFLAG_PROXY_REFER)((profile)->pflags[PFLAG_PROXY_REFER] ? 1 : 0) && sip->sip_payload && sip->sip_payload->pl_data &&
555 sip->sip_content_type && sip->sip_content_type->c_type &&
556 switch_stristr("sipfrag", sip->sip_content_type->c_type)) {
557 switch_core_session_t *other_session;
558 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 558)
== SWITCH_STATUS_SUCCESS) {
559 switch_core_session_message_t *msg;
560
561 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 561)
;
562 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 562
;
563 msg->message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE;
564 msg->string_arg = switch_core_session_strdup(other_session, sip->sip_payload->pl_data)switch_core_perform_session_strdup(other_session, sip->sip_payload
->pl_data, "sofia.c", (const char *)__func__, 564)
;
565 msg->from = __FILE__"sofia.c";
566 switch_core_session_queue_message(other_session, msg);
567 switch_core_session_rwunlock(other_session);
568
569 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
570 goto end;
571 }
572 }
573
574 /* For additional NOTIFY event packages see http://www.iana.org/assignments/sip-events. */
575 if (sip->sip_content_type &&
576 sip->sip_content_type->c_type && sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(sip->sip_event->o_type, "refer")) {
577 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__, 577, &s_event, SWITCH_EVENT_CUSTOM
, "sofia::notify_refer")
== SWITCH_STATUS_SUCCESS) {
578 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "content-type", sip->sip_content_type->c_type);
579 switch_event_add_body(s_event, "%s", sip->sip_payload->pl_data);
580 }
581 }
582
583 /* add common headers for the NOTIFY to the switch_event and fire if it exists */
584 if (s_event != NULL((void*)0)) {
585 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event-package", sip->sip_event->o_type);
586 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event-id", sip->sip_event->o_id);
587
588 if (sip->sip_contact && sip->sip_contact->m_url) {
589 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s@%s",
590 sip->sip_contact->m_url->url_user, sip->sip_contact->m_url->url_host);
591 }
592
593 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);
594 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-tag", sip->sip_from->a_tag);
595 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);
596 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-tag", sip->sip_to->a_tag);
597
598 if (sip->sip_call_id && sip->sip_call_id->i_id) {
599 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", sip->sip_call_id->i_id);
600 }
601 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_substate) {
602 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-substate", sip->sip_subscription_state->ss_substate);
603 }
604 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_reason) {
605 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-reason", sip->sip_subscription_state->ss_reason);
606 }
607 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_retry_after) {
608 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-retry-after", sip->sip_subscription_state->ss_retry_after);
609 }
610 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_expires) {
611 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-expires", sip->sip_subscription_state->ss_expires);
612 }
613 if (session) {
614 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "UniqueID", switch_core_session_get_uuid(session));
615 }
616 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 616, &s_event, ((void*)0))
;
617 }
618
619 if (!strcasecmp(sip->sip_event->o_type, "refer")) {
620 if (session && channel && tech_pvt) {
621 if (sip->sip_payload && sip->sip_payload->pl_data) {
622 char *p;
623 int status_val = 0;
624 if ((p = strchr(sip->sip_payload->pl_data, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(sip->sip_payload->pl_data) && (' ') == '\0' ?
(char *) __rawmemchr (sip->sip_payload->pl_data, ' ') :
__builtin_strchr (sip->sip_payload->pl_data, ' ')))
)) {
625 p++;
626 if (p) {
627 status_val = atoi(p);
628 }
629 }
630 if (!status_val || status_val >= 200) {
631 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)
;
632 if (status_val == 200) {
633 switch_channel_hangup(channel, SWITCH_CAUSE_BLIND_TRANSFER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 633, SWITCH_CAUSE_BLIND_TRANSFER)
;
634 }
635 if ((int)tech_pvt->want_event == 9999) {
636 tech_pvt->want_event = 0;
637 }
638 }
639 }
640 }
641 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_END()(tag_type_t)0, (tag_value_t)0);
642 }
643
644 /* if no session, assume it could be an incoming notify from a gateway subscription */
645 if (session) {
646 /* make sure we have a proper "talk" event */
647 if (strcasecmp(sip->sip_event->o_type, "talk")) {
648 goto error;
649 }
650
651 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
652 switch_channel_answer(channel)switch_channel_perform_answer(channel, "sofia.c", (const char
*)__func__, 652)
;
653 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)
;
654 switch_ivr_session_transfer(session, "auto_answer", NULL((void*)0), NULL((void*)0));
655 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_END()(tag_type_t)0, (tag_value_t)0);
656 goto end;
657 }
658 }
659
660 if (!sofia_private || zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
661 if (profile->debug) {
662 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
662, (const char*)(session)
, SWITCH_LOG_DEBUG, "Gateway information missing Subscription Event: %s\n",
663 sip->sip_event->o_type);
664 }
665 goto error;
666 }
667
668
669 if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 669
, sofia_private->gateway_name)
)) {
670 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 670
, ((void*)0)
, SWITCH_LOG_ERROR, "Gateway information missing\n");
671 goto error;
672 }
673
674 /* find the corresponding gateway subscription (if any) */
675 if (!(gw_sub_ptr = sofia_find_gateway_subscription(gateway, sip->sip_event->o_type))) {
676 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
676, (const char*)(session)
, SWITCH_LOG_WARNING,
677 "Could not find gateway subscription. Gateway: %s. Subscription Event: %s\n",
678 gateway->name, sip->sip_event->o_type);
679 goto error;
680 }
681
682 if (!(gw_sub_ptr->state == SUB_STATE_SUBED || gw_sub_ptr->state == SUB_STATE_SUBSCRIBE)) {
683 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
683, (const char*)(session)
, SWITCH_LOG_WARNING, "Ignoring notify due to subscription state: %d\n", gw_sub_ptr->state);
684 goto error;
685 }
686
687 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_expires) {
688 int delta = atoi(sip->sip_subscription_state->ss_expires);
689
690 delta /= 2;
691
692 if (delta < 1) {
693 delta = 1;
694 }
695 gw_sub_ptr->expires = switch_epoch_time_now(NULL((void*)0)) + delta;
696 }
697
698 /* dispatch freeswitch event */
699 if (switch_event_create(&s_event, SWITCH_EVENT_NOTIFY_IN)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 699, &s_event, SWITCH_EVENT_NOTIFY_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
700 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event", sip->sip_event->o_type);
701 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "pl_data", sip->sip_payload ? sip->sip_payload->pl_data : "");
702 if ( sip->sip_content_type != NULL((void*)0) )
703 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_content_type", sip->sip_content_type->c_type);
704 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", gateway->profile->sip_port);
705 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
706 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", gateway->profile->name);
707 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", gateway->profile->url);
708 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "gateway_name", gateway->name);
709 if ( sip->sip_call_info != NULL((void*)0) ) {
710 sip_call_info_t *call_info = sip->sip_call_info;
711 char *nua_hold = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) call_info);
712 size_t cur_len = strlen(nua_hold);
713 char *hold = strdup(nua_hold)(__extension__ (__builtin_constant_p (nua_hold) && ((
size_t)(const void *)((nua_hold) + 1) - (size_t)(const void *
)(nua_hold) == 1) ? (((const char *) (nua_hold))[0] == '\0' ?
(char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len =
strlen (nua_hold) + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, nua_hold, __len); __retval; })) : __strdup (nua_hold)))
;
714 su_free(nua_handle_home(nh)((su_home_t *)(nh)), nua_hold);
715
716 while ((call_info = call_info->ci_next) != NULL((void*)0)) {
717 char *tmp = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) call_info);
718 size_t tmp_len = strlen(tmp);
719 hold = realloc(hold, cur_len + tmp_len + 2);
720 switch_assert(hold)((hold) ? (void) (0) : __assert_fail ("hold", "sofia.c", 720,
__PRETTY_FUNCTION__))
;
721 strncpy(hold + cur_len, ",", 2)__builtin_strncpy (hold + cur_len, ",", 2);
722 strncpy(hold + cur_len + 1, tmp, tmp_len +1)__builtin_strncpy (hold + cur_len + 1, tmp, tmp_len +1);
723 su_free(nua_handle_home(nh)((su_home_t *)(nh)), tmp);
724 cur_len = cur_len + tmp_len + 2;
725 }
726 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, "Call-Info", hold);
727 }
728 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 728, &s_event, ((void*)0))
;
729 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
729, (const char*)(session)
, SWITCH_LOG_DEBUG, "dispatched freeswitch event for message-summary NOTIFY\n");
730 } else {
731 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
731, (const char*)(session)
, SWITCH_LOG_ERROR, "Failed to create event\n");
732 goto error;
733 }
734
735 goto end;
736
737 error:
738
739
740 if (sip && sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "message-summary")) {
741 /* unsolicited mwi, just say ok */
742 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_END()(tag_type_t)0, (tag_value_t)0);
743
744 if (sofia_test_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)((profile)->pflags[PFLAG_FORWARD_MWI_NOTIFY] ? 1 : 0)) {
745 const char *mwi_status = NULL((void*)0);
746 char network_ip[80];
747 uint32_t x = 0;
748 int acl_ok = 1;
749 char *last_acl = NULL((void*)0);
750
751 if (sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host
752 && sip->sip_payload && sip->sip_payload->pl_data ) {
753
754 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL((void*)0));
755 for (x = 0; x < profile->acl_count; x++) {
756 last_acl = profile->acl[x];
757 if (!(acl_ok = switch_check_network_list_ip(network_ip, last_acl)switch_check_network_list_ip_token(network_ip, last_acl, ((void
*)0))
)) {
758 break;
759 }
760 }
761
762 if ( acl_ok )
763 {
764 mwi_status = switch_stristr("Messages-Waiting: ", sip->sip_payload->pl_data);
765
766 if ( mwi_status ) {
767 char *mwi_stat;
768 mwi_status += strlen( "Messages-Waiting: " );
769 mwi_stat = switch_strip_whitespace( mwi_status );
770
771 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
771, (const char*)(session)
, SWITCH_LOG_DEBUG,
772 "Forwarding unsolicited MWI ( %s : %s@%s )\n",
773 mwi_stat, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
774 if (switch_event_create(&s_event, SWITCH_EVENT_MESSAGE_WAITING)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 774, &s_event, SWITCH_EVENT_MESSAGE_WAITING
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
775 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", mwi_stat );
776 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM,
777 "MWI-Message-Account", "%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
778 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 778, &s_event, ((void*)0))
;
779 }
780 switch_safe_free(mwi_stat)if (mwi_stat) {free(mwi_stat);mwi_stat=((void*)0);};
781 }
782 } else {
783 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
783, (const char*)(session)
, SWITCH_LOG_DEBUG, "Dropping unsolicited MWI ( %s@%s ) because of ACL\n",
784 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
785 };
786
787 }
788 }
789
790 } else {
791 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
792 }
793
794 end:
795
796 if (!gateway && sub_state == nua_substate_terminated && sofia_private && sofia_private != &mod_sofia_globals.destroy_private &&
797 sofia_private != &mod_sofia_globals.keep_private) {
798 sofia_private->destroy_nh = 1;
799 sofia_private->destroy_me = 1;
800 }
801
802 if (gateway) {
803 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 803, gateway);
;
804 }
805
806}
807
808void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
809 char const *phrase,
810 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
811 sofia_dispatch_event_t *de, tagi_t tags[])
812{
813 const char *tmp;
814 switch_channel_t *channel;
815 private_object_t *tech_pvt;
816 char *extra_headers;
817 const char *call_info = NULL((void*)0);
818 const char *vval = NULL((void*)0);
819#ifdef MANUAL_BYE1
820 int cause;
821 char st[80] = "";
822#endif
823
824 if (!session) {
825 return;
826 }
827
828 channel = switch_core_session_get_channel(session);
829 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
830
831#ifdef MANUAL_BYE1
832 status = 200;
833 phrase = "OK";
834
835 if (switch_channel_test_flag(tech_pvt->channel, CF_SLA_BARGING)) {
836 const char *bargee_uuid = switch_channel_get_variable(channel, "sip_barging_uuid")switch_channel_get_variable_dup(channel, "sip_barging_uuid", SWITCH_TRUE
, -1)
;
837 switch_core_session_t *bargee_session;
838 uint32_t ttl = 0;
839
840 if ((bargee_session = switch_core_session_locate(bargee_uuid)switch_core_session_perform_locate(bargee_uuid, "sofia.c", (const
char *)__func__, 840)
)) {
841 //switch_channel_t *bargee_channel = switch_core_session_get_channel(bargee_session);
842 if ((ttl = switch_core_media_bug_count(bargee_session, "eavesdrop")) == 1) {
843 if (switch_core_session_check_interface(bargee_session, sofia_endpoint_interface)) {
844 switch_channel_clear_flag(switch_core_session_get_channel(bargee_session), CF_SLA_BARGE);
845 }
846 }
847 switch_core_session_rwunlock(bargee_session);
848 }
849 }
850
851 if (switch_channel_test_flag(tech_pvt->channel, CF_SLA_BARGE)) {
852 switch_core_session_t *new_session, *other_session;
853 const char *other_uuid = switch_channel_get_partner_uuid(tech_pvt->channel);
854 char *cmd = NULL((void*)0);
855
856 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__, 856)
)) {
857 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
858
859 switch_mutex_lock(profile->ireg_mutex);
860 if (switch_ivr_eavesdrop_pop_eavesdropper(session, &new_session) == SWITCH_STATUS_SUCCESS) {
861 switch_channel_t *new_channel = switch_core_session_get_channel(new_session);
862 const char *new_uuid = switch_core_session_get_uuid(new_session);
863 switch_caller_profile_t *cp = switch_channel_get_caller_profile(new_channel);
864
865 cp->caller_id_name = cp->orig_caller_id_name;
866 cp->caller_id_number = cp->orig_caller_id_number;
867
868
869 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)
;
870
871 switch_channel_set_flag(other_channel, CF_REDIRECT)switch_channel_set_flag_value(other_channel, CF_REDIRECT, 1);
872
873 switch_channel_set_state(new_channel, CS_RESET)switch_channel_perform_set_state(new_channel, "sofia.c", (const
char *)__func__, 873, CS_RESET)
;
874
875 switch_ivr_uuid_bridge(new_uuid, other_uuid);
876 cmd = switch_core_session_sprintf(session, "sleep:500,sofia_sla:%s inline", new_uuid);
877
878 switch_channel_clear_flag(other_channel, CF_REDIRECT);
879
880 switch_core_session_rwunlock(new_session);
881 }
882 switch_mutex_unlock(profile->ireg_mutex);
883
884 switch_core_session_rwunlock(other_session);
885 }
886
887 if (!zstr(cmd)_zstr(cmd)) {
888 switch_ivr_eavesdrop_exec_all(session, "transfer", cmd);
889 }
890 }
891
892 sofia_set_flag_locked(tech_pvt, TFLAG_BYE)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 892, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_BYE] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
893 call_info = switch_channel_get_variable(channel, "presence_call_info_full")switch_channel_get_variable_dup(channel, "presence_call_info_full"
, SWITCH_TRUE, -1)
;
894
895 if (sip->sip_reason) {
896 char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason);
897
898 if (!zstr(reason_header)_zstr(reason_header)) {
899 switch_channel_set_variable_partner(channel, "sip_reason", reason_header)switch_channel_set_variable_partner_var_check(channel, "sip_reason"
, reason_header, SWITCH_TRUE)
;
900 }
901 }
902
903 if (sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
904 || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
905 || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
906 tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
907 cause = tech_pvt->q850_cause;
908 } else {
909 cause = sofia_glue_sip_cause_to_freeswitch(status);
910 }
911
912 if (sip->sip_content_type && sip->sip_content_type->c_type) {
913 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)
;
914 }
915
916 if (sip->sip_payload && sip->sip_payload->pl_data) {
917 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)
;
918 }
919
920 switch_snprintf(st, sizeof(st), "%d", status);
921 switch_channel_set_variable(channel, "sip_term_status", st)switch_channel_set_variable_var_check(channel, "sip_term_status"
, st, SWITCH_TRUE)
;
922 switch_snprintf(st, sizeof(st), "sip:%d", status);
923 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)
;
924
925 if (phrase) {
926 switch_channel_set_variable_partner(channel, "sip_hangup_phrase", phrase)switch_channel_set_variable_partner_var_check(channel, "sip_hangup_phrase"
, phrase, SWITCH_TRUE)
;
927 }
928
929 switch_snprintf(st, sizeof(st), "%d", cause);
930 switch_channel_set_variable(channel, "sip_term_cause", st)switch_channel_set_variable_var_check(channel, "sip_term_cause"
, st, SWITCH_TRUE)
;
931
932 extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_BYE_HEADER_PREFIX"sip_bye_h_");
933 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_BYE_HEADER_PREFIX"sip_bye_h_");
934
935 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)) {
936 switch_core_session_t *nsession = NULL((void*)0);
937
938 switch_core_session_get_partner(session, &nsession)switch_core_session_perform_get_partner(session, &nsession
, "sofia.c", (const char *)__func__, 938)
;
939
940 if (nsession) {
941 const char *vval;
942 switch_channel_t *nchannel = switch_core_session_get_channel(nsession);
943
944 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)) {
945 switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_BYE_HEADER_PREFIX_T"~sip_bye_h_");
946 }
947 switch_core_session_rwunlock(nsession);
948 }
949 }
950
951
952 switch_channel_hangup(channel, cause)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 952, cause)
;
953 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),
954 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))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
955
956 switch_safe_free(extra_headers)if (extra_headers) {free(extra_headers);extra_headers=((void*
)0);}
;
957
958 if (sofia_private) {
959 sofia_private->destroy_me = 1;
960 sofia_private->destroy_nh = 1;
961 }
962#endif
963
964
965 if (sip->sip_user_agent && !zstr(sip->sip_user_agent->g_string)_zstr(sip->sip_user_agent->g_string)) {
966 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)
;
967 } else if (sip->sip_server && !zstr(sip->sip_server->g_string)_zstr(sip->sip_server->g_string)) {
968 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)
;
969 }
970
971 if ((tmp = sofia_glue_get_unknown_header(sip, "rtp-txstat"))) {
972 switch_channel_set_variable(channel, "sip_rtp_txstat", tmp)switch_channel_set_variable_var_check(channel, "sip_rtp_txstat"
, tmp, SWITCH_TRUE)
;
973 }
974 if ((tmp = sofia_glue_get_unknown_header(sip, "rtp-rxstat"))) {
975 switch_channel_set_variable(channel, "sip_rtp_rxstat", tmp)switch_channel_set_variable_var_check(channel, "sip_rtp_rxstat"
, tmp, SWITCH_TRUE)
;
976 }
977 if ((tmp = sofia_glue_get_unknown_header(sip, "P-RTP-Stat"))) {
978 switch_channel_set_variable(channel, "sip_p_rtp_stat", tmp)switch_channel_set_variable_var_check(channel, "sip_p_rtp_stat"
, tmp, SWITCH_TRUE)
;
979 }
980
981 tech_pvt->got_bye = 1;
982 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_bye")switch_channel_set_variable_var_check(channel, "sip_hangup_disposition"
, "recv_bye", SWITCH_TRUE)
;
983
984 return;
985}
986
987void sofia_handle_sip_r_message(int status, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip)
988{
989 const char *call_id;
990 int *mstatus;
991
992 if (!(sip && sip->sip_call_id)) {
993 nua_handle_destroy(nh);
994 return;
995 }
996
997 call_id = sip->sip_call_id->i_id;
998
999
1000
1001 switch_mutex_lock(profile->flag_mutex);
1002 mstatus = switch_core_hash_find(profile->chat_hash, call_id);
1003 switch_mutex_unlock(profile->flag_mutex);
1004
1005 if (mstatus) {
1006 *mstatus = status;
1007 }
1008
1009}
1010
1011void sofia_wait_for_reply(struct private_object *tech_pvt, nua_event_t event, uint32_t timeout)
1012{
1013 time_t exp = switch_epoch_time_now(NULL((void*)0)) + timeout;
1014
1015 tech_pvt->want_event = event;
1016
1017 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) {
1018 switch_yield(100000)switch_sleep(100000);;
1019 }
1020
1021}
1022
1023void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number)
1024{
1025 const char *uuid;
1026 switch_core_session_t *session_b;
1027 switch_channel_t *channel = switch_core_session_get_channel(session);
1028 switch_caller_profile_t *caller_profile = switch_channel_get_caller_profile(channel);
1029
1030
1031 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)))
) {
1032 if (zstr(name)_zstr(name)) {
1033 name = caller_profile->caller_id_name;
1034 }
1035
1036 if (zstr(number)_zstr(number)) {
1037 number = caller_profile->caller_id_number;
1038 }
1039
1040 if (zstr(name)_zstr(name)) {
1041 name = number;
1042 }
1043
1044 if (zstr(number)_zstr(number)) {
1045 name = number = "UNKNOWN";
1046 }
1047 } else {
1048 if (zstr(name)_zstr(name)) {
1049 name = caller_profile->callee_id_name;
1050 }
1051
1052 if (zstr(number)_zstr(number)) {
1053 number = caller_profile->callee_id_number;
1054 }
1055
1056 if (zstr(name)_zstr(name)) {
1057 name = number;
1058 }
1059
1060 if (zstr(number)_zstr(number)) {
1061 number = caller_profile->destination_number;
1062 }
1063 }
1064
1065 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__, 1065)
)) {
1066 switch_core_session_message_t *msg;
1067 //switch_channel_t *channel_b = switch_core_session_get_channel(session_b);
1068
1069 //switch_channel_set_profile_var(channel_b, "callee_id_name", name);
1070 //switch_channel_set_profile_var(channel_b, "callee_id_number", number);
1071
1072 msg = switch_core_session_alloc(session_b, sizeof(*msg))switch_core_perform_session_alloc(session_b, sizeof(*msg), "sofia.c"
, (const char *)__func__, 1072)
;
1073 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 1073
;
1074 msg->message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
1075 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__, 1075)
;
1076 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__, 1076)
;
1077 msg->from = __FILE__"sofia.c";
1078 switch_core_session_queue_message(session_b, msg);
1079 switch_core_session_rwunlock(session_b);
1080 }
1081}
1082
1083void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip,
1084 switch_bool_t send)
1085{
1086 switch_channel_t *channel = switch_core_session_get_channel(session);
1087 sip_p_asserted_identity_t *passerted = NULL((void*)0);
1088 char *name = NULL((void*)0);
1089 const char *number = "unknown", *tmp;
1090 switch_caller_profile_t *caller_profile;
1091 char *dup = NULL((void*)0);
1092 switch_event_t *event;
1093 const char *val;
1094 int fs = 0, lazy = 0, att = 0;
1095 const char *name_var = "callee_id_name";
1096 const char *num_var = "callee_id_number";
1097
1098 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)) {
1099 return;
1100 }
1101
1102
1103 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)))
) {
1104 name_var = "caller_id_name";
1105 num_var = "caller_id_number";
1106 }
1107
1108
1109 number = (char *) switch_channel_get_variable(channel, num_var)switch_channel_get_variable_dup(channel, num_var, SWITCH_TRUE
, -1)
;
1110 name = (char *) switch_channel_get_variable(channel, name_var)switch_channel_get_variable_dup(channel, name_var, SWITCH_TRUE
, -1)
;
1111
1112
1113 if (zstr(number)_zstr(number) && sip->sip_to) {
1114 number = sip->sip_to->a_url->url_user;
1115 }
1116
1117 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Display-Number"))) {
1118 number = val;
1119 fs++;
1120 }
1121
1122 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Display-Name"))) {
1123 name = (char *) val;
1124 check_decode(name, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 1124, __PRETTY_FUNCTION__)); if (!_zstr(name)) { int d = 0;
char *p; if ((__extension__ (__builtin_constant_p ('%') &&
!__builtin_constant_p (name) && ('%') == '\0' ? (char
*) __rawmemchr (name, '%') : __builtin_strchr (name, '%'))))
{ char *tmp = switch_core_perform_session_strdup(session, name
, "sofia.c", (const char *)__func__, 1124); switch_url_decode
(tmp); name = tmp; d++; } if ((p = (__extension__ (__builtin_constant_p
('"') && !__builtin_constant_p (name) && ('"'
) == '\0' ? (char *) __rawmemchr (name, '"') : __builtin_strchr
(name, '"'))))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, name, "sofia.c", (const char *)__func__, 1124); name
= tmp; } if ((p = (__extension__ (__builtin_constant_p ('"')
&& !__builtin_constant_p (name) && ('"') == '\0'
? (char *) __rawmemchr (name, '"') : __builtin_strchr (name,
'"'))))) { name = p+1; } if ((p = strrchr(name, '"'))) { *p =
'\0'; } } } if (session) break; } while(!session)
;
1125 fs++;
1126 }
1127
1128 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Lazy-Attended-Transfer"))) {
1129 lazy = switch_true(val);
1130 fs++;
1131 }
1132
1133 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Attended-Transfer"))) {
1134 att = switch_true(val);
1135 fs++;
1136 }
1137
1138 if (!fs) {
1139 if ((passerted = sip_p_asserted_identity(sip)((sip_p_asserted_identity_t *)msg_header_access((msg_pub_t*)(
sip), sip_p_asserted_identity_class))
)) {
1140 if (passerted->paid_url && passerted->paid_url->url_user) {
1141 number = passerted->paid_url->url_user;
1142 }
1143 if (!zstr(passerted->paid_display)_zstr(passerted->paid_display)) {
1144 dup = strdup(passerted->paid_display)(__extension__ (__builtin_constant_p (passerted->paid_display
) && ((size_t)(const void *)((passerted->paid_display
) + 1) - (size_t)(const void *)(passerted->paid_display) ==
1) ? (((const char *) (passerted->paid_display))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (passerted->paid_display) + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, passerted->paid_display, __len
); __retval; })) : __strdup (passerted->paid_display)))
;
1145 if (*dup == '"') {
1146 name = dup + 1;
1147 } else {
1148 name = dup;
1149 }
1150 if (end_of(name)*(*name == '\0' ? name : name + strlen(name) - 1) == '"') {
1151 end_of(name)*(*name == '\0' ? name : name + strlen(name) - 1) = '\0';
1152 }
1153 }
1154 }
1155 }
1156
1157
1158 if (zstr(number)_zstr(number)) {
1159 if ((tmp = switch_channel_get_variable(channel, num_var)switch_channel_get_variable_dup(channel, num_var, SWITCH_TRUE
, -1)
) && !zstr(tmp)_zstr(tmp)) {
1160 number = (char *) tmp;
1161 }
1162
1163 if (zstr(number)_zstr(number)) {
1164 number = "unknown";
1165 }
1166 }
1167
1168 if (zstr(name)_zstr(name)) {
1169 if ((tmp = switch_channel_get_variable(channel, name_var)switch_channel_get_variable_dup(channel, name_var, SWITCH_TRUE
, -1)
) && !zstr(tmp)_zstr(tmp)) {
1170 name = (char *) tmp;
1171 }
1172 }
1173
1174 if (zstr(name)_zstr(name)) {
1175 name = (char *) number;
1176 }
1177
1178 if (zstr(name)_zstr(name) || zstr(number)_zstr(number)) {
1179 goto end;
1180 }
1181
1182 caller_profile = switch_channel_get_caller_profile(channel);
1183
1184 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)))
) {
1185
1186 if (!strcmp(caller_profile->caller_id_name, name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(caller_profile->caller_id_name) && __builtin_constant_p
(name) && (__s1_len = __builtin_strlen (caller_profile
->caller_id_name), __s2_len = __builtin_strlen (name), (!(
(size_t)(const void *)((caller_profile->caller_id_name) + 1
) - (size_t)(const void *)(caller_profile->caller_id_name)
== 1) || __s1_len >= 4) && (!((size_t)(const void
*)((name) + 1) - (size_t)(const void *)(name) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (caller_profile->caller_id_name
, name) : (__builtin_constant_p (caller_profile->caller_id_name
) && ((size_t)(const void *)((caller_profile->caller_id_name
) + 1) - (size_t)(const void *)(caller_profile->caller_id_name
) == 1) && (__s1_len = __builtin_strlen (caller_profile
->caller_id_name), __s1_len < 4) ? (__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) ? __builtin_strcmp (caller_profile
->caller_id_name, name) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (name); int
__result = (((const unsigned char *) (const char *) (caller_profile
->caller_id_name))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (caller_profile->caller_id_name))[1] - __s2[1]); if
(__s1_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (caller_profile->caller_id_name
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (caller_profile
->caller_id_name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) && (__s2_len = __builtin_strlen
(name), __s2_len < 4) ? (__builtin_constant_p (caller_profile
->caller_id_name) && ((size_t)(const void *)((caller_profile
->caller_id_name) + 1) - (size_t)(const void *)(caller_profile
->caller_id_name) == 1) ? __builtin_strcmp (caller_profile
->caller_id_name, name) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (caller_profile
->caller_id_name); int __result = (((const unsigned char *
) (const char *) (name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(caller_profile->caller_id_name, name)))); })
&& !strcmp(caller_profile->caller_id_number, number)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(caller_profile->caller_id_number) && __builtin_constant_p
(number) && (__s1_len = __builtin_strlen (caller_profile
->caller_id_number), __s2_len = __builtin_strlen (number),
(!((size_t)(const void *)((caller_profile->caller_id_number
) + 1) - (size_t)(const void *)(caller_profile->caller_id_number
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)((number) + 1) - (size_t)(const void *)(number) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (caller_profile->caller_id_number
, number) : (__builtin_constant_p (caller_profile->caller_id_number
) && ((size_t)(const void *)((caller_profile->caller_id_number
) + 1) - (size_t)(const void *)(caller_profile->caller_id_number
) == 1) && (__s1_len = __builtin_strlen (caller_profile
->caller_id_number), __s1_len < 4) ? (__builtin_constant_p
(number) && ((size_t)(const void *)((number) + 1) - (
size_t)(const void *)(number) == 1) ? __builtin_strcmp (caller_profile
->caller_id_number, number) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (number)
; int __result = (((const unsigned char *) (const char *) (caller_profile
->caller_id_number))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (caller_profile->caller_id_number))[1] - __s2[1])
; if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (caller_profile->caller_id_number
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (caller_profile
->caller_id_number))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (number) && ((size_t)(const void
*)((number) + 1) - (size_t)(const void *)(number) == 1) &&
(__s2_len = __builtin_strlen (number), __s2_len < 4) ? (__builtin_constant_p
(caller_profile->caller_id_number) && ((size_t)(const
void *)((caller_profile->caller_id_number) + 1) - (size_t
)(const void *)(caller_profile->caller_id_number) == 1) ? __builtin_strcmp
(caller_profile->caller_id_number, number) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (caller_profile->caller_id_number); int __result =
(((const unsigned char *) (const char *) (number))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (number))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (number))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (number))[3] - __s2
[3]); } } __result; })))) : __builtin_strcmp (caller_profile->
caller_id_number, number)))); })
) {
1187 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1187
, ((void*)0)
, SWITCH_LOG_DEBUG1, "%s Same Caller ID \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1188 send = 0;
1189 } else {
1190 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__, 1190)
);
1191 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__, 1191)
);
1192 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1192
, ((void*)0)
, SWITCH_LOG_INFO, "%s Update Caller ID to \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1193 }
1194
1195 } else {
1196
1197 if (!strcmp(caller_profile->callee_id_name, name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(caller_profile->callee_id_name) && __builtin_constant_p
(name) && (__s1_len = __builtin_strlen (caller_profile
->callee_id_name), __s2_len = __builtin_strlen (name), (!(
(size_t)(const void *)((caller_profile->callee_id_name) + 1
) - (size_t)(const void *)(caller_profile->callee_id_name)
== 1) || __s1_len >= 4) && (!((size_t)(const void
*)((name) + 1) - (size_t)(const void *)(name) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (caller_profile->callee_id_name
, name) : (__builtin_constant_p (caller_profile->callee_id_name
) && ((size_t)(const void *)((caller_profile->callee_id_name
) + 1) - (size_t)(const void *)(caller_profile->callee_id_name
) == 1) && (__s1_len = __builtin_strlen (caller_profile
->callee_id_name), __s1_len < 4) ? (__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) ? __builtin_strcmp (caller_profile
->callee_id_name, name) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (name); int
__result = (((const unsigned char *) (const char *) (caller_profile
->callee_id_name))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (caller_profile->callee_id_name))[1] - __s2[1]); if
(__s1_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (caller_profile->callee_id_name
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (caller_profile
->callee_id_name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(name) && ((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) && (__s2_len = __builtin_strlen
(name), __s2_len < 4) ? (__builtin_constant_p (caller_profile
->callee_id_name) && ((size_t)(const void *)((caller_profile
->callee_id_name) + 1) - (size_t)(const void *)(caller_profile
->callee_id_name) == 1) ? __builtin_strcmp (caller_profile
->callee_id_name, name) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (caller_profile
->callee_id_name); int __result = (((const unsigned char *
) (const char *) (name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(caller_profile->callee_id_name, name)))); })
&& !strcmp(caller_profile->callee_id_number, number)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(caller_profile->callee_id_number) && __builtin_constant_p
(number) && (__s1_len = __builtin_strlen (caller_profile
->callee_id_number), __s2_len = __builtin_strlen (number),
(!((size_t)(const void *)((caller_profile->callee_id_number
) + 1) - (size_t)(const void *)(caller_profile->callee_id_number
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)((number) + 1) - (size_t)(const void *)(number) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (caller_profile->callee_id_number
, number) : (__builtin_constant_p (caller_profile->callee_id_number
) && ((size_t)(const void *)((caller_profile->callee_id_number
) + 1) - (size_t)(const void *)(caller_profile->callee_id_number
) == 1) && (__s1_len = __builtin_strlen (caller_profile
->callee_id_number), __s1_len < 4) ? (__builtin_constant_p
(number) && ((size_t)(const void *)((number) + 1) - (
size_t)(const void *)(number) == 1) ? __builtin_strcmp (caller_profile
->callee_id_number, number) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (number)
; int __result = (((const unsigned char *) (const char *) (caller_profile
->callee_id_number))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (caller_profile->callee_id_number))[1] - __s2[1])
; if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (caller_profile->callee_id_number
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (caller_profile
->callee_id_number))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (number) && ((size_t)(const void
*)((number) + 1) - (size_t)(const void *)(number) == 1) &&
(__s2_len = __builtin_strlen (number), __s2_len < 4) ? (__builtin_constant_p
(caller_profile->callee_id_number) && ((size_t)(const
void *)((caller_profile->callee_id_number) + 1) - (size_t
)(const void *)(caller_profile->callee_id_number) == 1) ? __builtin_strcmp
(caller_profile->callee_id_number, number) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (caller_profile->callee_id_number); int __result =
(((const unsigned char *) (const char *) (number))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (number))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (number))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (number))[3] - __s2
[3]); } } __result; })))) : __builtin_strcmp (caller_profile->
callee_id_number, number)))); })
) {
1198 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1198
, ((void*)0)
, SWITCH_LOG_DEBUG1, "%s Same Callee ID \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1199 send = 0;
1200 } else {
1201 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__, 1201)
);
1202 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__, 1202)
);
1203 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1203
, ((void*)0)
, SWITCH_LOG_INFO, "%s Update Callee ID to \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1204
1205 if (lazy || (att && !switch_channel_get_partner_uuid(channel))) {
1206 switch_channel_flip_cid(channel);
1207 }
1208 }
1209 }
1210
1211 if (send) {
1212
1213 if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 1213, &event, SWITCH_EVENT_CALL_UPDATE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1214 const char *uuid = switch_channel_get_partner_uuid(channel);
1215 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "RECV");
1216 if (uuid) {
1217 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
1218 }
1219 switch_channel_event_set_data(channel, event);
1220 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 1220, &event, ((void*)0))
;
1221 }
1222
1223 sofia_send_callee_id(session, NULL((void*)0), NULL((void*)0));
1224 }
1225
1226 end:
1227 switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);};
1228}
1229
1230static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt)
1231{
1232 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)
;
1233 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)
;
1234
1235
1236 if (sofia_test_pflag(tech_pvt->profile, PFLAG_TRACK_CALLS)((tech_pvt->profile)->pflags[PFLAG_TRACK_CALLS] ? 1 : 0
)
) {
1237 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)
;
1238 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)
;
1239
1240 nua_ack(nh,
1241 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
)
,
1242 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
)
,
1243 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)
,
1244 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)
,
1245 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)
,
1246 TAG_END()(tag_type_t)0, (tag_value_t)0);
1247
1248
1249 } else {
1250 nua_ack(nh,
1251 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
)
,
1252 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
)
,
1253 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)
,
1254 TAG_END()(tag_type_t)0, (tag_value_t)0);
1255 }
1256
1257}
1258
1259
1260//sofia_dispatch_event_t *de
1261static void our_sofia_event_callback(nua_event_t event,
1262 int status,
1263 char const *phrase,
1264 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
1265 sofia_dispatch_event_t *de, tagi_t tags[])
1266{
1267 struct private_object *tech_pvt = NULL((void*)0);
1268 auth_res_t auth_res = AUTH_FORBIDDEN;
1269 switch_core_session_t *session = NULL((void*)0);
1270 switch_channel_t *channel = NULL((void*)0);
1271 sofia_gateway_t *gateway = NULL((void*)0);
1272 int locked = 0;
1273 int check_destroy = 1;
1274
1275 profile->last_sip_event = switch_time_now();
1276
1277 /* sofia_private will be == &mod_sofia_globals.keep_private whenever a request is done with a new handle that has to be
1278 freed whenever the request is done */
1279 if (nh && sofia_private == &mod_sofia_globals.keep_private) {
1280 if (status >= 300) {
1281 nua_handle_bind(nh, NULL((void*)0));
1282 nua_handle_destroy(nh);
1283 return;
1284 }
1285 }
1286
1287
1288 if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
1289
1290 if (!zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
1291 if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 1291
, sofia_private->gateway_name)
)) {
1292 return;
1293 }
1294 } else if (!zstr(sofia_private->uuid)_zstr(sofia_private->uuid)) {
1295 if ((session = de->init_session)) {
1296 de->init_session = NULL((void*)0);
1297 } 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__, 1297)
)) {
1298 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
1299 channel = switch_core_session_get_channel(session);
1300 if (tech_pvt) {
1301 switch_mutex_lock(tech_pvt->sofia_mutex);
1302 locked = 1;
1303 } else {
1304 if (session != de->session) switch_core_session_rwunlock(session);
1305 return;
1306 }
1307
1308 if (status >= 180 && !*sofia_private->auth_gateway_name) {
1309 const char *gwname = switch_channel_get_variable(channel, "sip_use_gateway")switch_channel_get_variable_dup(channel, "sip_use_gateway", SWITCH_TRUE
, -1)
;
1310 if (!zstr(gwname)_zstr(gwname)) {
1311 switch_set_string(sofia_private->auth_gateway_name, gwname)switch_copy_string(sofia_private->auth_gateway_name, gwname
, sizeof(sofia_private->auth_gateway_name))
;
1312 }
1313 }
1314 if (!tech_pvt->call_id && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
1315 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__, 1315)
;
1316 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)
;
1317 }
1318
1319 if (tech_pvt->gateway_name) {
1320 gateway = sofia_reg_find_gateway(tech_pvt->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 1320
, tech_pvt->gateway_name)
;
1321 }
1322
1323 if (channel && switch_channel_down(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) >= CS_HANGUP)
) {
1324 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
1324, (const char*)(session)
, SWITCH_LOG_DEBUG, "Channel is already hungup.\n");
1325 goto done;
1326 }
1327 } else {
1328 /* we can't find the session it must be hanging up or something else, its too late to do anything with it. */
1329 return;
1330 }
1331 }
1332 }
1333
1334 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)) {
1335 sip_authorization_t const *authorization = NULL((void*)0);
1336
1337 if (sip->sip_authorization) {
1338 authorization = sip->sip_authorization;
1339 } else if (sip->sip_proxy_authorization) {
1340 authorization = sip->sip_proxy_authorization;
1341 }
1342
1343 if (authorization) {
1344 char network_ip[80];
1345 int network_port;
1346 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
1347 auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
1348 (char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, network_port, NULL((void*)0), 0,
1349 REG_INVITE, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
1350 }
1351
1352 if ((auth_res != AUTH_OK && auth_res != AUTH_RENEWED)) {
1353 //switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
1354 nua_respond(nh, SIP_401_UNAUTHORIZED401, sip_401_Unauthorized, TAG_END()(tag_type_t)0, (tag_value_t)0);
1355 goto done;
1356 }
1357
1358 if (channel) {
1359 switch_channel_set_variable(channel, "sip_authorized", "true")switch_channel_set_variable_var_check(channel, "sip_authorized"
, "true", SWITCH_TRUE)
;
1360 }
1361 }
1362
1363 if (sip && (status == 401 || status == 407)) {
1364 sofia_reg_handle_sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, session, gateway, sip, de, tags);
1365 goto done;
1366 }
1367
1368 switch (event) {
1369 case nua_r_get_params:
1370 case nua_i_fork:
1371 case nua_r_info:
1372 break;
1373 case nua_r_bye:
1374 case nua_r_unregister:
1375 case nua_r_unsubscribe:
1376 case nua_i_terminated:
1377 case nua_r_publish:
1378 case nua_i_error:
1379 case nua_i_active:
1380 case nua_r_set_params:
1381 case nua_i_prack:
1382 case nua_r_prack:
1383 break;
1384
1385 case nua_i_cancel:
1386
1387 if (sip && channel) {
1388 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_cancel")switch_channel_set_variable_var_check(channel, "sip_hangup_disposition"
, "recv_cancel", SWITCH_TRUE)
;
1389
1390 if (sip->sip_reason) {
1391 char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason);
1392
1393 if (!zstr(reason_header)_zstr(reason_header)) {
1394 switch_channel_set_variable_partner(channel, "sip_reason", reason_header)switch_channel_set_variable_partner_var_check(channel, "sip_reason"
, reason_header, SWITCH_TRUE)
;
1395 }
1396 }
1397 }
1398
1399 break;
1400 case nua_r_cancel:
1401 {
1402 if (status > 299 && nh) {
1403 nua_handle_destroy(nh);
1404 }
1405 }
1406 break;
1407 case nua_i_ack:
1408 {
1409 if (channel && sip) {
1410 if (sip->sip_to && sip->sip_to->a_tag) {
1411 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)
;
1412 }
1413
1414 if (sip->sip_from && sip->sip_from->a_tag) {
1415 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)
;
1416 }
1417
1418 if (sip->sip_cseq && sip->sip_cseq->cs_seq) {
1419 char sip_cseq[40] = "";
1420 switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq);
1421 switch_channel_set_variable(channel, "sip_cseq", sip_cseq)switch_channel_set_variable_var_check(channel, "sip_cseq", sip_cseq
, SWITCH_TRUE)
;
1422 }
1423
1424 if (sip->sip_call_id && sip->sip_call_id->i_id) {
1425 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)
;
1426 }
1427
1428 extract_header_vars(profile, sip, session, nh);
1429 switch_core_recovery_track(session);
1430 sofia_set_flag(tech_pvt, TFLAG_GOT_ACK)(tech_pvt)->flags[TFLAG_GOT_ACK] = 1;
1431
1432 if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)((tech_pvt)->flags[TFLAG_PASS_ACK] ? 1 : 0)) {
1433 switch_core_session_t *other_session;
1434
1435 sofia_clear_flag(tech_pvt, TFLAG_PASS_ACK)(tech_pvt)->flags[TFLAG_PASS_ACK] = 0;
1436
1437
1438 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 1438)
== SWITCH_STATUS_SUCCESS) {
1439 if (switch_core_session_compare(session, other_session)) {
1440 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
1441 tech_send_ack(other_tech_pvt->nh, other_tech_pvt);
1442 }
1443 switch_core_session_rwunlock(other_session);
1444 }
1445
1446 }
1447
1448
1449 }
1450 }
1451 case nua_r_ack:
1452 if (channel)
1453 switch_channel_set_flag(channel, CF_MEDIA_ACK)switch_channel_set_flag_value(channel, CF_MEDIA_ACK, 1);
1454 break;
1455 case nua_r_shutdown:
1456 if (status >= 200) {
1457 sofia_set_pflag(profile, PFLAG_SHUTDOWN)(profile)->pflags[PFLAG_SHUTDOWN] = 1;
1458 su_root_break(profile->s_root);
1459 }
1460 break;
1461 case nua_r_message:
1462 sofia_handle_sip_r_message(status, profile, nh, sip);
1463 break;
1464 case nua_r_invite:
1465 sofia_handle_sip_r_invite(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1466 break;
1467 case nua_r_options:
1468 sofia_handle_sip_r_options(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1469 break;
1470 case nua_i_bye:
1471 sofia_handle_sip_i_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1472 break;
1473 case nua_r_notify:
1474 sofia_handle_sip_r_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1475 break;
1476 case nua_i_notify:
1477 sofia_handle_sip_i_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1478 break;
1479 case nua_r_register:
1480 sofia_reg_handle_sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1481 break;
1482 case nua_i_options:
1483 sofia_handle_sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1484 break;
1485 case nua_i_invite:
1486 if (session && sofia_private) {
1487 if (sofia_private->is_call > 1) {
1488 sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, de, tags);
1489 } else {
1490 sofia_private->is_call++;
1491 sofia_handle_sip_i_invite(session, nua, profile, nh, sofia_private, sip, de, tags);
1492 }
1493 }
1494 break;
1495 case nua_i_publish:
1496 sofia_presence_handle_sip_i_publish(nua, profile, nh, sofia_private, sip, de, tags);
1497 break;
1498 case nua_i_register:
1499 //nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
1500 //nua_handle_destroy(nh);
1501 sofia_reg_handle_sip_i_register(nua, profile, nh, &sofia_private, sip, de, tags);
1502 break;
1503 case nua_i_state:
1504 sofia_handle_sip_i_state(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1505 break;
1506 case nua_i_message:
1507 sofia_presence_handle_sip_i_message(status, phrase, nua, profile, nh, session, sofia_private, sip, de, tags);
1508 break;
1509 case nua_i_info:
1510 sofia_handle_sip_i_info(nua, profile, nh, session, sip, de, tags);
1511 break;
1512 case nua_i_update:
1513 break;
1514 case nua_r_update:
1515 if (session && tech_pvt && locked) {
1516 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);
;
1517 }
1518 break;
1519 case nua_r_refer:
1520 break;
1521 case nua_i_refer:
1522 if (session) {
1523 sofia_handle_sip_i_refer(nua, profile, nh, session, sip, de, tags);
1524 } else {
1525 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);
1526 char *refer_to = NULL((void*)0), *referred_by = NULL((void*)0), *method = NULL((void*)0), *full_url = NULL((void*)0);
1527 char *params = NULL((void*)0), *iparams = NULL((void*)0);
1528 switch_event_t *event;
1529 char *tmp;
1530
1531 if (sip->sip_refer_to) {
1532 ref_to_user = sip->sip_refer_to->r_url->url_user;
1533 ref_to_host = sip->sip_refer_to->r_url->url_host;
1534
1535 if (sip->sip_refer_to->r_url->url_params && switch_stristr("method=", sip->sip_refer_to->r_url->url_params)) {
1536 params = su_strdup(nua_handle_home(nh)((su_home_t *)(nh)), sip->sip_refer_to->r_url->url_params);
1537 }
1538
1539
1540 if ((refer_to = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_refer_to))) {
1541 if ((iparams = strchr(refer_to, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(refer_to) && (';') == '\0' ? (char *) __rawmemchr (
refer_to, ';') : __builtin_strchr (refer_to, ';')))
)) {
1542 *iparams++ = '\0';
1543
1544 if (!params || !switch_stristr("method=", params)) {
1545 params = iparams;
1546 }
1547 }
1548
1549 if ((tmp = sofia_glue_get_url_from_contact(refer_to, 0))) {
1550 refer_to = tmp;
1551 }
1552 }
1553
1554 if (params) {
1555 method = switch_find_parameter(params, "method", NULL((void*)0));
1556 full_url = switch_find_parameter(params, "full_url", NULL((void*)0));
1557 }
1558
1559
1560 }
1561
1562 if (!method) {
1563 method = strdup("INVITE")(__extension__ (__builtin_constant_p ("INVITE") && ((
size_t)(const void *)(("INVITE") + 1) - (size_t)(const void *
)("INVITE") == 1) ? (((const char *) ("INVITE"))[0] == '\0' ?
(char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len =
strlen ("INVITE") + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, "INVITE", __len); __retval; })) : __strdup ("INVITE")))
;
1564 }
1565
1566 if (!strcasecmp(method, "INVITE")) {
1567 action = "call";
1568 } else if (!strcasecmp(method, "BYE")) {
1569 action = "end";
1570 } else {
1571 action = method;
1572 }
1573
1574 if (sip->sip_referred_by) {
1575 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);
1576 ref_by_user = sip->sip_referred_by->b_url->url_user;
1577 }
1578 else if(sip->sip_to && sip->sip_to->a_url)
1579 {
1580 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);
1581 ref_by_user = sip->sip_to->a_url->url_user;
1582 }
1583
1584 if (sip->sip_to && sip->sip_to->a_url) {
1585 req_user = sip->sip_to->a_url->url_user;
1586 req_host = sip->sip_to->a_url->url_host;
1587 }
1588
1589 if (switch_event_create(&event, SWITCH_EVENT_CALL_SETUP_REQ)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 1589, &event, SWITCH_EVENT_CALL_SETUP_REQ
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1590 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Requesting-Component", "mod_sofia");
1591 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Component", req_user);
1592 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Domain", req_host);
1593 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Action", action);
1594 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Target", "sofia/%s/%s", profile->name, refer_to);
1595 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Target-URI", "%s", refer_to);
1596 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Target-Extension", ref_to_user);
1597 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Target-Domain", ref_to_host);
1598 if (switch_true(full_url)) {
1599 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "full_url", "true");
1600 }
1601
1602 if (sip->sip_call_id && sip->sip_call_id->i_id) {
1603 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Call-ID", sip->sip_call_id->i_id);
1604 }
1605
1606 if (!zstr(referred_by)_zstr(referred_by)) {
1607 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Sender", "sofia/%s/%s", profile->name, referred_by);
1608 }
1609
1610 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_number", ref_by_user);
1611 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_name", ref_by_user);
1612 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 1612, &event, ((void*)0))
;
1613 }
1614
1615
1616
1617 if (sip) {
1618 char *sql;
1619 sofia_nat_parse_t np = { { 0 } };
1620 char *contact_str;
1621 char *proto = "sip", *orig_proto = "sip";
1622 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;
1623 char to_tag[13] = "";
1624 char *event_str = "refer";
1625 sip_accept_t *ap = sip->sip_accept;
1626 char accept_header[256] = "";
1627
1628 np.fs_path = 1;
1629 contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, &np);
1630
1631 call_id = sip->sip_call_id->i_id;
1632 full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from);
1633 full_to = sip_header_as_string(nh->nh_home, (void *) sip->sip_to);
1634 full_via = sip_header_as_string(nh->nh_home, (void *) sip->sip_via);
1635
1636 full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent);
1637
1638 switch_stun_random_string(to_tag, 12, NULL((void*)0));
1639
1640 if (sip->sip_from) {
1641 from_user = sip->sip_from->a_url->url_user;
1642 from_host = sip->sip_from->a_url->url_host;
1643 } else {
1644 from_user = "n/a";
1645 from_host = "n/a";
1646 }
1647
1648 if (sip->sip_to) {
1649 to_user = sip->sip_to->a_url->url_user;
1650 to_host = sip->sip_to->a_url->url_host;
1651 } else {
1652 to_user = "n/a";
1653 to_host = "n/a";
1654 }
1655
1656 while (ap) {
1657 switch_snprintf(accept_header + strlen(accept_header), sizeof(accept_header) - strlen(accept_header),
1658 "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
1659 ap = ap->ac_next;
1660 }
1661
1662 sql = switch_mprintf("insert into sip_subscriptions "
1663 "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
1664 "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip,version,orig_proto, full_to) "
1665 "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q',-1,'%q','%q;tag=%q')",
1666 proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : "",
1667 event_str, contact_str, call_id, full_from, full_via,
1668 (long) switch_epoch_time_now(NULL((void*)0)) + 60,
1669 full_agent, accept_header, profile->name, mod_sofia_globals.hostname,
1670 np.network_port, np.network_ip, orig_proto, full_to, to_tag);
1671
1672 switch_assert(sql != NULL)((sql != ((void*)0)) ? (void) (0) : __assert_fail ("sql != ((void*)0)"
, "sofia.c", 1672, __PRETTY_FUNCTION__))
;
1673
1674
1675 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
1676 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1676
, ((void*)0)
, SWITCH_LOG_CRIT, "%s REFER SUBSCRIBE %s@%s %s@%s\n%s\n",
1677 profile->name, from_user, from_host, to_user, to_host, sql);
1678 }
1679
1680
1681 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1682
1683 sip_to_tag(nh->nh_home, sip->sip_to, to_tag);
1684 }
1685
1686 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);
1687 switch_safe_free(method)if (method) {free(method);method=((void*)0);};
1688 switch_safe_free(full_url)if (full_url) {free(full_url);full_url=((void*)0);};
1689
1690 }
1691 break;
1692 case nua_r_subscribe:
1693 sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1694 break;
1695 case nua_i_subscribe:
1696 sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1697 break;
1698 case nua_i_media_error:
1699 {
1700
1701 if (sofia_private && sofia_private->call_id && sofia_private->network_ip && sofia_private->network_port) {
1702 char *sql;
1703 switch_event_t *event = NULL((void*)0);
1704
1705 sql = switch_mprintf("delete from sip_registrations where call_id='%q' and network_ip='%q' and network_port='%q'",
1706 sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
1707 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1707
, ((void*)0)
, SWITCH_LOG_DEBUG1, "SOCKET DISCONNECT: %s %s:%s\n",
1708 sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
1709 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
1710
1711 switch_core_del_registration(sofia_private->user, sofia_private->realm, sofia_private->call_id);
1712
1713
1714
1715 if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 1715, &event, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1716 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
1717 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
1718 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
1719 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent",
1720 (sip && sip->sip_user_agent) ? sip->sip_user_agent->g_string : "unknown");
1721 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", sofia_private->user, sofia_private->realm);
1722 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Unregistered");
1723 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-source", "register");
1724 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
1725 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 1725, &event, ((void*)0))
;
1726 }
1727
1728
1729 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 1729, &event, SWITCH_EVENT_CUSTOM
, "sofia::unregister")
== SWITCH_STATUS_SUCCESS) {
1730 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
1731 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from-user", sofia_private->user);
1732 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from-host", sofia_private->realm);
1733 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-id", sofia_private->call_id);
1734 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
1735 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "reason", "socket-disconnection");
1736 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 1736, &event, ((void*)0))
;
1737 }
1738
1739
1740 sofia_reg_check_socket(profile, sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
1741 nua_handle_destroy(nh);
1742 }
1743 }
1744 break;
1745 case nua_r_authenticate:
1746
1747 if (status >= 500) {
1748 if (sofia_private && !zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
1749 sofia_gateway_t *gateway = NULL((void*)0);
1750
1751 if ((gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 1751
, sofia_private->gateway_name)
)) {
1752 gateway->state = REG_STATE_FAILED;
1753 gateway->failure_status = status;
1754 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 1754, gateway);
;
1755 }
1756 } else {
1757 nua_handle_destroy(nh);
1758 }
1759 }
1760
1761 break;
1762 default:
1763 if (status > 100) {
1764 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
1764, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s: unknown event %d: %03d %s\n", nua_event_name(event), event,
1765 status, phrase);
1766 } else {
1767 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
1767, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s: unknown event %d\n", nua_event_name(event), event);
1768 }
1769 break;
1770 }
1771
1772 done:
1773
1774 if (tech_pvt && tech_pvt->want_event && event == tech_pvt->want_event) {
1775 tech_pvt->want_event = 0;
1776 }
1777
1778 if (sofia_private && sofia_private->call_id) {
1779 check_destroy = 0;
1780 }
1781
1782 switch (event) {
1783 case nua_i_subscribe:
1784 case nua_r_notify:
1785 check_destroy = 0;
1786 break;
1787
1788 case nua_i_notify:
1789
1790 if (sip && sip->sip_event && !strcmp(sip->sip_event->o_type, "dialog")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(sip->sip_event->o_type) && __builtin_constant_p
("dialog") && (__s1_len = __builtin_strlen (sip->
sip_event->o_type), __s2_len = __builtin_strlen ("dialog")
, (!((size_t)(const void *)((sip->sip_event->o_type) + 1
) - (size_t)(const void *)(sip->sip_event->o_type) == 1
) || __s1_len >= 4) && (!((size_t)(const void *)((
"dialog") + 1) - (size_t)(const void *)("dialog") == 1) || __s2_len
>= 4)) ? __builtin_strcmp (sip->sip_event->o_type, "dialog"
) : (__builtin_constant_p (sip->sip_event->o_type) &&
((size_t)(const void *)((sip->sip_event->o_type) + 1) -
(size_t)(const void *)(sip->sip_event->o_type) == 1) &&
(__s1_len = __builtin_strlen (sip->sip_event->o_type),
__s1_len < 4) ? (__builtin_constant_p ("dialog") &&
((size_t)(const void *)(("dialog") + 1) - (size_t)(const void
*)("dialog") == 1) ? __builtin_strcmp (sip->sip_event->
o_type, "dialog") : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) ("dialog"); int __result
= (((const unsigned char *) (const char *) (sip->sip_event
->o_type))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
sip->sip_event->o_type))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (sip->sip_event->o_type))[2] - __s2[
2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (sip->sip_event->
o_type))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("dialog") && ((size_t)(const void *)(("dialog") + 1
) - (size_t)(const void *)("dialog") == 1) && (__s2_len
= __builtin_strlen ("dialog"), __s2_len < 4) ? (__builtin_constant_p
(sip->sip_event->o_type) && ((size_t)(const void
*)((sip->sip_event->o_type) + 1) - (size_t)(const void
*)(sip->sip_event->o_type) == 1) ? __builtin_strcmp (sip
->sip_event->o_type, "dialog") : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(sip->sip_event->o_type); int __result = (((const unsigned
char *) (const char *) ("dialog"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("dialog"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("dialog"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("dialog"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (sip->sip_event->o_type, "dialog"
)))); })
&& sip->sip_event->o_params && !strcmp(sip->sip_event->o_params[0], "sla")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(sip->sip_event->o_params[0]) && __builtin_constant_p
("sla") && (__s1_len = __builtin_strlen (sip->sip_event
->o_params[0]), __s2_len = __builtin_strlen ("sla"), (!((size_t
)(const void *)((sip->sip_event->o_params[0]) + 1) - (size_t
)(const void *)(sip->sip_event->o_params[0]) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)(("sla") + 1) -
(size_t)(const void *)("sla") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(sip->sip_event->o_params[0], "sla") : (__builtin_constant_p
(sip->sip_event->o_params[0]) && ((size_t)(const
void *)((sip->sip_event->o_params[0]) + 1) - (size_t)(
const void *)(sip->sip_event->o_params[0]) == 1) &&
(__s1_len = __builtin_strlen (sip->sip_event->o_params
[0]), __s1_len < 4) ? (__builtin_constant_p ("sla") &&
((size_t)(const void *)(("sla") + 1) - (size_t)(const void *
)("sla") == 1) ? __builtin_strcmp (sip->sip_event->o_params
[0], "sla") : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) ("sla"); int __result =
(((const unsigned char *) (const char *) (sip->sip_event->
o_params[0]))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
sip->sip_event->o_params[0]))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (sip->sip_event->o_params[0]))[
2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (sip->sip_event
->o_params[0]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("sla") && ((size_t)(const void *)(("sla") + 1) - (size_t
)(const void *)("sla") == 1) && (__s2_len = __builtin_strlen
("sla"), __s2_len < 4) ? (__builtin_constant_p (sip->sip_event
->o_params[0]) && ((size_t)(const void *)((sip->
sip_event->o_params[0]) + 1) - (size_t)(const void *)(sip->
sip_event->o_params[0]) == 1) ? __builtin_strcmp (sip->
sip_event->o_params[0], "sla") : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(sip->sip_event->o_params[0]); int __result = (((const
unsigned char *) (const char *) ("sla"))[0] - __s2[0]); if (
__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("sla"))[1] - __s2[1]); if (
__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("sla"))[2] - __s2[2]); if (
__s2_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) ("sla"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (sip->sip_event->o_params[0]
, "sla")))); })
) {
1791 check_destroy = 0;
1792 }
1793
1794 break;
1795 default:
1796 break;
1797 }
1798
1799 if ((sofia_private && sofia_private == &mod_sofia_globals.destroy_private)) {
1800 nua_handle_bind(nh, NULL((void*)0));
1801 nua_handle_destroy(nh);
1802 nh = NULL((void*)0);
1803 }
1804
1805 if (check_destroy) {
1806 if (nh && ((sofia_private && sofia_private->destroy_nh) || !nua_handle_magic(nh))) {
1807 if (sofia_private) {
1808 nua_handle_bind(nh, NULL((void*)0));
1809 }
1810
1811 if (tech_pvt && (tech_pvt->nh == nh)) {
1812 tech_pvt->nh = NULL((void*)0);
1813 }
1814
1815 nua_handle_destroy(nh);
1816 nh = NULL((void*)0);
1817 }
1818 }
1819
1820 if (sofia_private && sofia_private->destroy_me) {
1821 if (tech_pvt) {
1822 tech_pvt->sofia_private = NULL((void*)0);
1823 }
1824
1825 if (nh) {
1826 nua_handle_bind(nh, NULL((void*)0));
1827 }
1828 sofia_private->destroy_me = 12;
1829 sofia_private_free(sofia_private)if (sofia_private && ! sofia_private->is_static) {
free(sofia_private);} sofia_private = ((void*)0);
;
1830
1831 }
1832
1833 if (gateway) {
1834 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 1834, gateway);
;
1835 }
1836
1837 if (locked && tech_pvt) {
1838 switch_mutex_unlock(tech_pvt->sofia_mutex);
1839 }
1840
1841 if (session && session != de->session) {
1842 switch_core_session_rwunlock(session);
1843 }
1844}
1845
1846static uint32_t DE_THREAD_CNT = 0;
1847
1848void *SWITCH_THREAD_FUNC sofia_msg_thread_run_once(switch_thread_t *thread, void *obj)
1849{
1850 sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) obj;
1851 switch_memory_pool_t *pool = NULL((void*)0);
1852
1853 switch_mutex_lock(mod_sofia_globals.mutex);
1854 DE_THREAD_CNT++;
1855 switch_mutex_unlock(mod_sofia_globals.mutex);
1856
1857 if (de) {
1858 pool = de->pool;
1859 de->pool = NULL((void*)0);
1860 sofia_process_dispatch_event(&de);
1861 }
1862
1863 if (pool) {
1864 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia.c",
(const char *)__func__, 1864)
;
1865 }
1866
1867 switch_mutex_lock(mod_sofia_globals.mutex);
1868 DE_THREAD_CNT--;
1869 switch_mutex_unlock(mod_sofia_globals.mutex);
1870
1871 return NULL((void*)0);
1872}
1873
1874void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep)
1875{
1876 sofia_dispatch_event_t *de = *dep;
1877 switch_memory_pool_t *pool;
1878 //sofia_profile_t *profile = (*dep)->profile;
1879 switch_thread_data_t *td;
1880
1881 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "sofia.c", (const
char *)__func__, 1881)
;
1882
1883 *dep = NULL((void*)0);
1884 de->pool = pool;
1885
1886 td = switch_core_alloc(pool, sizeof(*td))switch_core_perform_alloc(pool, sizeof(*td), "sofia.c", (const
char *)__func__, 1886)
;
1887 td->func = sofia_msg_thread_run_once;
1888 td->obj = de;
1889
1890 switch_thread_pool_launch_thread(&td);
1891
1892}
1893
1894void sofia_process_dispatch_event(sofia_dispatch_event_t **dep)
1895{
1896 sofia_dispatch_event_t *de = *dep;
1897 nua_handle_t *nh = de->nh;
1898 nua_t *nua = de->nua;
1899 sofia_profile_t *profile = de->profile;
1900 sofia_private_t *sofia_private = nua_handle_magic(de->nh);
1901 *dep = NULL((void*)0);
1902
1903 our_sofia_event_callback(de->data->e_event, de->data->e_status, de->data->e_phrase, de->nua, de->profile,
1904 de->nh, sofia_private, de->sip, de, (tagi_t *) de->data->e_tags);
1905
1906 nua_destroy_event(de->event);
1907 su_free(nh->nh_home, de);
1908
1909 switch_mutex_lock(profile->flag_mutex);
1910 profile->queued_events--;
1911 switch_mutex_unlock(profile->flag_mutex);
1912
1913 nua_handle_unref(nh);
1914 nua_stack_unref(nua);
1915}
1916
1917
1918
1919static int msg_queue_threads = 0;
1920//static int count = 0;
1921
1922void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj)
1923{
1924 void *pop;
1925 switch_queue_t *q = (switch_queue_t *) obj;
1926 int my_id;
1927
1928
1929 for (my_id = 0; my_id < mod_sofia_globals.msg_queue_len; my_id++) {
1930 if (mod_sofia_globals.msg_queue_thread[my_id] == thread) {
1931 break;
1932 }
1933 }
1934
1935 switch_mutex_lock(mod_sofia_globals.mutex);
1936 msg_queue_threads++;
1937 switch_mutex_unlock(mod_sofia_globals.mutex);
1938
1939 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1939
, ((void*)0)
, SWITCH_LOG_WARNING, "MSG Thread %d Started\n", my_id);
1940
1941
1942 for(;;) {
1943
1944 if (switch_queue_pop(q, &pop) != SWITCH_STATUS_SUCCESS) {
1945 switch_cond_next();
1946 continue;
1947 }
1948
1949 if (pop) {
1950 sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop;
1951 sofia_process_dispatch_event(&de);
1952 } else {
1953 break;
1954 }
1955 }
1956
1957 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 1957
, ((void*)0)
, SWITCH_LOG_WARNING, "MSG Thread Ended\n");
1958
1959 switch_mutex_lock(mod_sofia_globals.mutex);
1960 msg_queue_threads--;
1961 switch_mutex_unlock(mod_sofia_globals.mutex);
1962
1963 return NULL((void*)0);
1964}
1965
1966void sofia_msg_thread_start(int idx)
1967{
1968
1969 if (idx >= mod_sofia_globals.max_msg_queues ||
1970 idx >= SOFIA_MAX_MSG_QUEUE64 || (idx < mod_sofia_globals.msg_queue_len && mod_sofia_globals.msg_queue_thread[idx])) {
1971 return;
1972 }
1973
1974 switch_mutex_lock(mod_sofia_globals.mutex);
1975
1976 if (idx >= mod_sofia_globals.msg_queue_len) {
1977 int i;
1978 mod_sofia_globals.msg_queue_len = idx + 1;
1979
1980 for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) {
1981 if (!mod_sofia_globals.msg_queue_thread[i]) {
1982 switch_threadattr_t *thd_attr = NULL((void*)0);
1983
1984 switch_threadattr_create(&thd_attr, mod_sofia_globals.pool);
1985 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
1986 //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
1987 switch_thread_create(&mod_sofia_globals.msg_queue_thread[i],
1988 thd_attr,
1989 sofia_msg_thread_run,
1990 mod_sofia_globals.msg_queue,
1991 mod_sofia_globals.pool);
1992 }
1993 }
1994 }
1995
1996 switch_mutex_unlock(mod_sofia_globals.mutex);
1997}
1998
1999//static int foo = 0;
2000void sofia_queue_message(sofia_dispatch_event_t *de)
2001{
2002 int launch = 0;
2003
2004 if (mod_sofia_globals.running == 0 || !mod_sofia_globals.msg_queue) {
2005 sofia_process_dispatch_event(&de);
2006 return;
2007 }
2008
2009
2010 if (de->profile && sofia_test_pflag(de->profile, PFLAG_THREAD_PER_REG)((de->profile)->pflags[PFLAG_THREAD_PER_REG] ? 1 : 0) &&
2011 de->data->e_event == nua_i_register && DE_THREAD_CNT < mod_sofia_globals.max_reg_threads) {
2012 sofia_process_dispatch_event_in_thread(&de);
2013 return;
2014 }
2015
2016
2017 if ((switch_queue_size(mod_sofia_globals.msg_queue) > (SOFIA_MSG_QUEUE_SIZE1000 * (unsigned int)msg_queue_threads))) {
2018 launch++;
2019 }
2020
2021
2022 if (launch) {
2023 if (mod_sofia_globals.msg_queue_len < mod_sofia_globals.max_msg_queues) {
2024 sofia_msg_thread_start(mod_sofia_globals.msg_queue_len + 1);
2025 }
2026 }
2027
2028 switch_queue_push(mod_sofia_globals.msg_queue, de);
2029}
2030
2031static void set_call_id(private_object_t *tech_pvt, sip_t const *sip)
2032{
2033 if (!tech_pvt->call_id && tech_pvt->session && tech_pvt->channel && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
2034 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__, 2034
)
;
2035 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)
;
2036 }
2037}
2038
2039
2040void sofia_event_callback(nua_event_t event,
2041 int status,
2042 char const *phrase,
2043 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
2044 tagi_t tags[])
2045{
2046 sofia_dispatch_event_t *de;
2047 int critical = (((SOFIA_MSG_QUEUE_SIZE1000 * mod_sofia_globals.max_msg_queues) * 900) / 1000);
2048 uint32_t sess_count = switch_core_session_count();
2049 uint32_t sess_max = switch_core_session_limit(0);
2050
2051 switch(event) {
2052 case nua_i_terminated:
2053 if ((status == 401 || status == 407 || status == 403) && sofia_private && sofia_private->uuid) {
2054 switch_core_session_t *session;
2055
2056 if ((session = switch_core_session_locate(sofia_private->uuid)switch_core_session_perform_locate(sofia_private->uuid, "sofia.c"
, (const char *)__func__, 2056)
)) {
2057 switch_channel_t *channel = switch_core_session_get_channel(session);
2058 int end = 0;
2059
2060 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_ANSWERED)) {
2061 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
2062
2063 if (status == 403) {
2064 switch_channel_set_flag(channel, CF_NO_CDR)switch_channel_set_flag_value(channel, CF_NO_CDR, 1);
2065 switch_channel_hangup(channel, SWITCH_CAUSE_CALL_REJECTED)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 2065, SWITCH_CAUSE_CALL_REJECTED)
;
2066 } else {
2067 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2067
, ((void*)0)
, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid);
2068
2069 if (!zstr(tech_pvt->call_id)_zstr(tech_pvt->call_id)) {
2070 tech_pvt->sofia_private = NULL((void*)0);
2071 tech_pvt->nh = NULL((void*)0);
2072 sofia_set_flag(tech_pvt, TFLAG_BYE)(tech_pvt)->flags[TFLAG_BYE] = 1;
2073 switch_mutex_lock(profile->flag_mutex);
2074 switch_core_hash_insert(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session)))switch_core_hash_insert_destructor(profile->chat_hash, tech_pvt
->call_id, (__extension__ (__builtin_constant_p (switch_core_session_get_uuid
(session)) && ((size_t)(const void *)((switch_core_session_get_uuid
(session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(session)) == 1) ? (((const char *) (switch_core_session_get_uuid
(session)))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (switch_core_session_get_uuid
(session)) + 1; char *__retval = (char *) malloc (__len); if (
__retval != ((void*)0)) __retval = (char *) memcpy (__retval,
switch_core_session_get_uuid(session), __len); __retval; }))
: __strdup (switch_core_session_get_uuid(session)))), ((void
*)0))
;
2075 switch_mutex_unlock(profile->flag_mutex);
2076 nua_handle_destroy(nh);
2077 } else {
2078 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 2078, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
2079 }
2080 }
2081 end++;
2082 }
2083
2084 switch_core_session_rwunlock(session);
2085
2086 if (end) {
2087 goto end;
2088 }
2089 }
2090 }
2091 break;
2092 case nua_i_invite:
2093 case nua_i_register:
2094 case nua_i_options:
2095 case nua_i_notify:
2096 case nua_i_info:
2097
2098
2099 if (event == nua_i_invite) {
2100 if (sip->sip_session_expires && profile->minimum_session_expires) {
2101 if (sip->sip_session_expires->x_delta < profile->minimum_session_expires) {
2102 char buf[64] = "";
2103 switch_snprintf(buf, sizeof(buf), "Min-SE: %d", profile->minimum_session_expires);
2104 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);
2105 goto end;
2106 }
2107 }
2108 }
2109
2110 if (!sofia_private) {
2111 if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0) || !switch_core_ready_inbound()) {
2112 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);
2113 goto end;
2114 }
2115
2116
2117 if (switch_queue_size(mod_sofia_globals.msg_queue) > (unsigned int)critical) {
2118 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);
2119 goto end;
2120 }
2121
2122 if (sofia_test_pflag(profile, PFLAG_STANDBY)((profile)->pflags[PFLAG_STANDBY] ? 1 : 0)) {
2123 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);
2124 goto end;
2125 }
2126 }
2127
2128 break;
2129
2130 default:
2131 break;
2132
2133 }
2134
2135 switch_mutex_lock(profile->flag_mutex);
2136 profile->queued_events++;
2137 switch_mutex_unlock(profile->flag_mutex);
2138
2139 de = su_alloc(nh->nh_home, sizeof(*de));
2140 memset(de, 0, sizeof(*de));
2141 nua_save_event(nua, de->event);
2142 de->nh = nua_handle_ref(nh);
2143 de->data = nua_event_data(de->event);
2144 de->sip = sip_object(de->data->e_msg);
2145 de->profile = profile;
2146 de->nua = nua_stack_ref(nua);
2147
2148 if (event == nua_i_invite && !sofia_private) {
2149 switch_core_session_t *session;
2150 private_object_t *tech_pvt = NULL((void*)0);
2151
2152 if (!(sofia_private = su_alloc(nh->nh_home, sizeof(*sofia_private)))) {
2153 abort();
2154 }
2155
2156 memset(sofia_private, 0, sizeof(*sofia_private));
2157 sofia_private->is_call++;
2158 sofia_private->is_static++;
2159 nua_handle_bind(nh, sofia_private);
2160
2161
2162 if (sip->sip_call_id && sip->sip_call_id->i_id) {
2163 char *uuid;
2164
2165 switch_mutex_lock(profile->flag_mutex);
2166 if ((uuid = (char *) switch_core_hash_find(profile->chat_hash, sip->sip_call_id->i_id))) {
2167 switch_core_hash_delete(profile->chat_hash, sip->sip_call_id->i_id);
2168 }
2169 switch_mutex_unlock(profile->flag_mutex);
2170
2171 if (uuid) {
2172 if ((session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia.c", (const char
*)__func__, 2172)
)) {
2173 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
2174 switch_copy_string(sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid));
2175 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2175
, ((void*)0)
, SWITCH_LOG_DEBUG, "Re-attaching to session %s\n", sofia_private->uuid);
2176 de->init_session = session;
2177 sofia_clear_flag(tech_pvt, TFLAG_BYE)(tech_pvt)->flags[TFLAG_BYE] = 0;
2178 tech_pvt->sofia_private = NULL((void*)0);
2179 tech_pvt->nh = NULL((void*)0);
2180 switch_core_session_queue_signal_data(session, de);
2181 switch_core_session_rwunlock(session);
2182 session = NULL((void*)0);
2183 free(uuid);
2184 uuid = NULL((void*)0);
2185 goto end;
2186 } else {
2187 free(uuid);
2188 uuid = NULL((void*)0);
2189 sip = NULL((void*)0);
2190 }
2191 }
2192 }
2193
2194 if (!sip || !sip->sip_call_id || zstr(sip->sip_call_id->i_id)_zstr(sip->sip_call_id->i_id)) {
2195 nua_respond(nh, 503, "INVALID INVITE", TAG_END()(tag_type_t)0, (tag_value_t)0);
2196 nua_destroy_event(de->event);
2197 su_free(nh->nh_home, de);
2198
2199 switch_mutex_lock(profile->flag_mutex);
2200 profile->queued_events--;
2201 switch_mutex_unlock(profile->flag_mutex);
2202
2203 nua_handle_unref(nh);
2204 nua_stack_unref(nua);
2205
2206 goto end;
2207 }
2208
2209 if (sofia_test_pflag(profile, PFLAG_CALLID_AS_UUID)((profile)->pflags[PFLAG_CALLID_AS_UUID] ? 1 : 0)) {
2210 session = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL((void*)0), sip->sip_call_id->i_id);
2211 } else {
2212 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))
;
2213 }
2214
2215 if (session) {
2216 const char *channel_name = NULL((void*)0);
2217 tech_pvt = sofia_glue_new_pvt(session);
2218
2219 if (sip->sip_from) {
2220 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")
;
2221 }
2222 if (!channel_name && sip->sip_contact && sip->sip_contact->m_url) {
2223 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")
;
2224 }
2225 if (sip->sip_referred_by) {
2226 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"
)
;
2227 }
2228
2229 sofia_glue_attach_private(session, profile, tech_pvt, channel_name);
2230
2231 set_call_id(tech_pvt, sip);
2232 } else {
2233 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);
2234 nua_destroy_event(de->event);
2235 su_free(nh->nh_home, de);
2236
2237 switch_mutex_lock(profile->flag_mutex);
2238 profile->queued_events--;
2239 switch_mutex_unlock(profile->flag_mutex);
2240
2241 nua_handle_unref(nh);
2242 nua_stack_unref(nua);
2243
2244 goto end;
2245 }
2246
2247
2248 if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
2249 char *uuid;
2250
2251 if (!switch_core_session_running(session) && !switch_core_session_started(session)) {
2252 nua_handle_bind(nh, NULL((void*)0));
2253 sofia_private_free(sofia_private)if (sofia_private && ! sofia_private->is_static) {
free(sofia_private);} sofia_private = ((void*)0);
;
2254 switch_core_session_destroy(&session)switch_core_session_perform_destroy(&session, "sofia.c", (
const char *)__func__, 2254)
;
2255 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);
2256 }
2257 switch_mutex_lock(profile->flag_mutex);
2258 if ((uuid = switch_core_hash_find(profile->chat_hash, tech_pvt->call_id))) {
2259 free(uuid);
2260 uuid = NULL((void*)0);
2261 switch_core_hash_delete(profile->chat_hash, tech_pvt->call_id);
2262 }
2263 switch_mutex_unlock(profile->flag_mutex);
2264
2265 goto end;
2266 }
2267
2268 switch_copy_string(sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid));
2269
2270 de->init_session = session;
2271 switch_core_session_queue_signal_data(session, de);
2272 goto end;
2273 }
2274
2275 if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
2276 switch_core_session_t *session;
2277
2278 if ((session = switch_core_session_locate(sofia_private->uuid)switch_core_session_perform_locate(sofia_private->uuid, "sofia.c"
, (const char *)__func__, 2278)
)) {
2279 switch_core_session_queue_signal_data(session, de);
2280 switch_core_session_rwunlock(session);
2281 goto end;
2282 }
2283 }
2284
2285 sofia_queue_message(de);
2286
2287 end:
2288 //switch_cond_next();
2289
2290 return;
2291}
2292
2293
2294void event_handler(switch_event_t *event)
2295{
2296 char *subclass, *sql;
2297 char *class;
2298 switch_event_t *pevent;
2299
2300 /* Get Original Event Name */
2301 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) : "")
;
2302 if (!strcasecmp(class, "PRESENCE_IN")) {
2303 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2303
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nGot Presence IN event via MultiCast\n");
2304 if (switch_event_create(&pevent, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2304, &pevent, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2305 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) : "")
);
2306 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) :
"")
);
2307 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) : "")
);
2308 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) : "")
);
2309 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) : "")
);
2310 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) : "")
);
2311 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) : "")
);
2312 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) : "")
);
2313 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) : "")
);
2314 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) : "")
);
2315 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) : "")
);
2316 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) :
"")
);
2317 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) : "")
);
2318 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) : "")
);
2319 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) : "")
);
2320 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) : "")
);
2321 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) : "")
);
2322 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) : "")
);
2323 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) : "")
);
2324 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) : "")
);
2325 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) : "")
);
2326 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) : "")
);
2327 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) : "")
);
2328 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) : "")
);
2329 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) : "")
);
2330 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) : "")
);
2331 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) : "")
);
2332
2333 /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
2334 sofia_presence_event_handler(pevent);
2335 return;
2336 } else {
2337 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2337
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nCannot inject PRESENCE_IN event\n");
2338 return;
2339 }
2340 } else if (!strcasecmp(class, "MESSAGE_WAITING")) {
2341 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2341
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nGot MWI event via MultiCast\n");
2342 if (switch_event_create(&pevent, SWITCH_EVENT_MESSAGE_WAITING)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2342, &pevent, SWITCH_EVENT_MESSAGE_WAITING
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2343 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) : "")
);
2344 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) : "")
);
2345 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) : "")
);
2346 /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
2347 sofia_presence_event_handler(pevent);
2348 return;
2349 } else {
2350 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2350
, ((void*)0)
, SWITCH_LOG_DEBUG, "\nCannot inject MWI event\n");
2351 return;
2352 }
2353 } 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")) {
2354 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) :
"")
;
2355 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) : "")
;
2356 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) : "")
;
2357 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) : "")
;
2358 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) : "")
;
2359
2360 sofia_profile_t *profile = NULL((void*)0);
2361
2362 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2362
, profile_name)
)) {
2363 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2363
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2364 return;
2365 }
2366
2367 if (sofia_test_pflag(profile, PFLAG_MULTIREG)((profile)->pflags[PFLAG_MULTIREG] ? 1 : 0)) {
2368 sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
2369 } else {
2370 sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", from_user, from_host);
2371 }
2372
2373 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2374 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2374
, ((void*)0)
, SWITCH_LOG_DEBUG, "Expired propagated registration for %s@%s->%s\n", from_user, from_host, contact_str);
2375
2376 if (profile) {
2377 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2377, profile)
;
2378 }
2379 } 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")) {
2380 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) : "")
;
2381 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) : "")
;
2382 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) : "")
;
2383 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) : "")
;
2384 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) : "")
;
2385 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) : "")
;
2386 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) : "")
;
2387 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) : "")
;
2388 long expires = (long) switch_epoch_time_now(NULL((void*)0));
2389 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) :
"")
;
2390 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) : "")
;
2391 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) : "")
;
2392 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) : "")
;
2393 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) :
"")
;
2394 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) : "")
;
2395 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) : "")
;
2396 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) : "")
;
2397 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) : "")
;
2398 char *fixed_contact_str = NULL((void*)0);
2399
2400 sofia_profile_t *profile = NULL((void*)0);
2401 char guess_ip4[256];
2402
2403 char *mwi_account = NULL((void*)0);
2404 char *dup_mwi_account = NULL((void*)0);
2405 char *mwi_user = NULL((void*)0);
2406 char *mwi_host = NULL((void*)0);
2407
2408 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) :
"")
)) {
2409 dup_mwi_account = strdup(mwi_account)(__extension__ (__builtin_constant_p (mwi_account) &&
((size_t)(const void *)((mwi_account) + 1) - (size_t)(const void
*)(mwi_account) == 1) ? (((const char *) (mwi_account))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (mwi_account) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, mwi_account, __len); __retval; })) : __strdup (mwi_account
)))
;
2410 switch_assert(dup_mwi_account != NULL)((dup_mwi_account != ((void*)0)) ? (void) (0) : __assert_fail
("dup_mwi_account != ((void*)0)", "sofia.c", 2410, __PRETTY_FUNCTION__
))
;
2411 switch_split_user_domain(dup_mwi_account, &mwi_user, &mwi_host);
2412 }
2413
2414 if (!mwi_user) {
2415 mwi_user = (char *) from_user;
2416 }
2417 if (!mwi_host) {
2418 mwi_host = (char *) from_host;
2419 }
2420
2421 if (exp_str) {
2422 expires += atol(exp_str);
2423 }
2424
2425 if (!rpid) {
2426 rpid = "unknown";
2427 }
2428
2429 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2429
, profile_name)
)) {
2430 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2430
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2431 goto end;
2432 }
2433 if (sofia_test_pflag(profile, PFLAG_MULTIREG)((profile)->pflags[PFLAG_MULTIREG] ? 1 : 0)) {
2434 sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
2435 } else {
2436 sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", from_user, from_host);
2437 }
2438
2439 if (mod_sofia_globals.rewrite_multicasted_fs_path && contact_str) {
2440 const char *needle = ";fs_path=";
2441 char *sptr, *eptr = NULL((void*)0);
2442 /* allocate enough room for worst-case scenario */
2443 size_t len = strlen(contact_str) + strlen(to_host) + 14;
2444 fixed_contact_str = malloc(len);
2445 switch_assert(fixed_contact_str)((fixed_contact_str) ? (void) (0) : __assert_fail ("fixed_contact_str"
, "sofia.c", 2445, __PRETTY_FUNCTION__))
;
2446 switch_copy_string(fixed_contact_str, contact_str, len);
2447
2448 if ((sptr = strstr(fixed_contact_str, needle))) {
2449 char *origsptr = strstr(contact_str, needle);
2450 eptr = strchr(++origsptr, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(++origsptr) && (';') == '\0' ? (char *) __rawmemchr
(++origsptr, ';') : __builtin_strchr (++origsptr, ';')))
;
2451 } else {
2452 sptr = strchr(fixed_contact_str, '\0')(__extension__ (__builtin_constant_p ('\0') && !__builtin_constant_p
(fixed_contact_str) && ('\0') == '\0' ? (char *) __rawmemchr
(fixed_contact_str, '\0') : __builtin_strchr (fixed_contact_str
, '\0')))
- 1;
2453 }
2454
2455 switch (mod_sofia_globals.rewrite_multicasted_fs_path) {
2456 case 1:
2457 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", to_host, eptr ? eptr : ">");
2458 break;
2459 case 2:
2460 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", orig_server_host, eptr ? eptr : ">");
2461 break;
2462 case 3:
2463 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", orig_hostname, eptr ? eptr : ">");
2464 break;
2465 default:
2466 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", to_host, eptr ? eptr : ">");
2467 break;
2468 }
2469
2470 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2470
, ((void*)0)
, SWITCH_LOG_DEBUG, "Rewrote contact string from '%s' to '%s'\n", contact_str, fixed_contact_str);
2471 contact_str = fixed_contact_str;
2472 }
2473
2474
2475 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2476
2477 switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL((void*)0), AF_INET2);
2478 sql = switch_mprintf("insert into sip_registrations "
2479 "(call_id, sip_user, sip_host, presence_hosts, contact, status, rpid, expires,"
2480 "user_agent, server_user, server_host, profile_name, hostname, network_ip, network_port, sip_username, sip_realm,"
2481 "mwi_user, mwi_host, orig_server_host, orig_hostname, ping_status, ping_count) "
2482 "values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)",
2483 call_id, from_user, from_host, presence_hosts, contact_str, rpid, expires, user_agent, to_user, guess_ip4,
2484 profile_name, mod_sofia_globals.hostname, network_ip, network_port, username, realm, mwi_user, mwi_host,
2485 orig_server_host, orig_hostname, "Reachable", 0);
2486
2487 if (sql) {
2488 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2489 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2489
, ((void*)0)
, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str);
2490 }
2491
2492
2493 if (profile) {
2494 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2494, profile)
;
2495 }
2496 end:
2497 switch_safe_free(fixed_contact_str)if (fixed_contact_str) {free(fixed_contact_str);fixed_contact_str
=((void*)0);}
;
2498 switch_safe_free(dup_mwi_account)if (dup_mwi_account) {free(dup_mwi_account);dup_mwi_account=(
(void*)0);}
;
2499 } 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")) {
2500 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) :
"")
;
2501 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) : "")
;
2502 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) : "")
;
2503 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) : "")
;
2504 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) :
"")
;
2505 sofia_profile_t *profile = NULL((void*)0);
2506
2507 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 2507
, profile_name)
)) {
2508 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2508
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid Profile\n");
2509 } else {
2510 if (!strcmp(ping_status, "REACHABLE")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(ping_status) && __builtin_constant_p ("REACHABLE") &&
(__s1_len = __builtin_strlen (ping_status), __s2_len = __builtin_strlen
("REACHABLE"), (!((size_t)(const void *)((ping_status) + 1) -
(size_t)(const void *)(ping_status) == 1) || __s1_len >= 4
) && (!((size_t)(const void *)(("REACHABLE") + 1) - (
size_t)(const void *)("REACHABLE") == 1) || __s2_len >= 4)
) ? __builtin_strcmp (ping_status, "REACHABLE") : (__builtin_constant_p
(ping_status) && ((size_t)(const void *)((ping_status
) + 1) - (size_t)(const void *)(ping_status) == 1) &&
(__s1_len = __builtin_strlen (ping_status), __s1_len < 4)
? (__builtin_constant_p ("REACHABLE") && ((size_t)(const
void *)(("REACHABLE") + 1) - (size_t)(const void *)("REACHABLE"
) == 1) ? __builtin_strcmp (ping_status, "REACHABLE") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("REACHABLE"); int __result = (((const unsigned char
*) (const char *) (ping_status))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (ping_status))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (ping_status))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (ping_status))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("REACHABLE") && ((size_t
)(const void *)(("REACHABLE") + 1) - (size_t)(const void *)("REACHABLE"
) == 1) && (__s2_len = __builtin_strlen ("REACHABLE")
, __s2_len < 4) ? (__builtin_constant_p (ping_status) &&
((size_t)(const void *)((ping_status) + 1) - (size_t)(const void
*)(ping_status) == 1) ? __builtin_strcmp (ping_status, "REACHABLE"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (ping_status); int __result = (((const
unsigned char *) (const char *) ("REACHABLE"))[0] - __s2[0])
; if (__s2_len > 0 && __result == 0) { __result = (
((const unsigned char *) (const char *) ("REACHABLE"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("REACHABLE"))[2]
- __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("REACHABLE"))[3]
- __s2[3]); } } __result; })))) : __builtin_strcmp (ping_status
, "REACHABLE")))); })
) {
2511 sql = switch_mprintf("update sip_registrations set ping_status='%s' where sip_user='%s' and sip_host='%s' and call_id='%q'",
2512 "Reachable", from_user, from_host, call_id);
2513 } else {
2514 sql = switch_mprintf("update sip_registrations set ping_status='%s' where sip_user='%s' and sip_host='%s' and call_id='%q'",
2515 "Unreachable", from_user, from_host, call_id);
2516 }
2517 if (sql) {
2518 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2519 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2519
, ((void*)0)
, SWITCH_LOG_DEBUG, "Propagating sip_user_state for %s@%s. Ping-Status: %s\n", from_user, from_host, ping_status);
2520 }
2521
2522 if (profile) {
2523 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 2523, profile)
;
2524 }
2525 }
2526 }
2527}
2528
2529static void sofia_perform_profile_start_failure(sofia_profile_t *profile, char *profile_name, char *file, int line)
2530{
2531 int arg = 0;
2532 switch_event_t *s_event;
2533
2534 if (profile) {
2535 if (!strcasecmp(profile->shutdown_type, "true")) {
2536 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2536
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Shutting down!\n", profile->name);
2537 switch_core_session_ctl(SCSC_SHUTDOWN, &arg);
2538 } else if (!strcasecmp(profile->shutdown_type, "elegant")) {
2539 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2539
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Waiting for calls to finish, then shutting down!\n",
2540 profile->name);
2541 switch_core_session_ctl(SCSC_SHUTDOWN_ELEGANT, &arg);
2542 } else if (!strcasecmp(profile->shutdown_type, "asap")) {
2543 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2543
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Shutting down ASAP!\n", profile->name);
2544 switch_core_session_ctl(SCSC_SHUTDOWN_ASAP, &arg);
2545 } else if (!strcasecmp(profile->shutdown_type, "reincarnate-now")) {
2546 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2546
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s could not load! Asking for reincarnation now!\n", profile->name);
2547 switch_core_session_ctl(SCSC_REINCARNATE_NOW, &arg);
2548 }
2549 }
2550
2551 if ((switch_event_create(&s_event, SWITCH_EVENT_FAILURE)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2551, &s_event, SWITCH_EVENT_FAILURE
, ((void*)0))
== SWITCH_STATUS_SUCCESS)) {
2552 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
2553 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile_name);
2554 if (profile) {
2555 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
2556 }
2557 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "failure_message", "Profile failed to start.");
2558 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "file", file);
2559 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "line", "%d", line);
2560
2561 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 2561, &s_event, ((void*)0))
;
2562 }
2563}
2564
2565/* not a static function so that it's still visible on stacktraces */
2566void watchdog_triggered_abort(void) {
2567 abort();
2568}
2569
2570#define sofia_profile_start_failure(p, xp)sofia_perform_profile_start_failure(p, xp, "sofia.c", 2570) sofia_perform_profile_start_failure(p, xp, __FILE__"sofia.c", __LINE__2570)
2571
2572
2573#define SQLLEN1024 * 1024 1024 * 1024
2574void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread, void *obj)
2575{
2576 sofia_profile_t *profile = (sofia_profile_t *) obj;
2577 uint32_t ireg_loops = profile->ireg_seconds; /* Number of loop iterations done when we haven't checked for registrations */
2578 uint32_t iping_loops = profile->iping_freq; /* Number of loop iterations done when we haven't checked for ping expires */
2579 uint32_t gateway_loops = GATEWAY_SECONDS1; /* Number of loop iterations done when we haven't checked for gateways */
2580
2581 sofia_set_pflag_locked(profile, PFLAG_WORKER_RUNNING)((profile->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("profile->flag_mutex != ((void*)0)", "sofia.c", 2581, __PRETTY_FUNCTION__
));switch_mutex_lock(profile->flag_mutex);(profile)->pflags
[PFLAG_WORKER_RUNNING] = 1;switch_mutex_unlock(profile->flag_mutex
);
;
2582
2583 while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0))) {
2584
2585 if (profile->watchdog_enabled) {
2586 uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0;
2587
2588 if (profile->step_timeout) {
2589 step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000);
2590
2591 if (step_diff > profile->step_timeout) {
2592 step_fail = 1;
2593 }
2594 }
2595
2596 if (profile->event_timeout) {
2597 event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000);
2598
2599 if (event_diff > profile->event_timeout) {
2600 event_fail = 1;
2601 }
2602 }
2603
2604 if (step_fail && profile->event_timeout && !event_fail) {
2605 step_fail = 0;
2606 }
2607
2608 if (event_fail || step_fail) {
2609 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2609
, ((void*)0)
, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED BY WATCHDOG!\n"
2610 "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name);
2611 switch_yield(2000000)switch_sleep(2000000);;
2612 watchdog_triggered_abort();
2613 }
2614 }
2615
2616
2617 if (!sofia_test_pflag(profile, PFLAG_STANDBY)((profile)->pflags[PFLAG_STANDBY] ? 1 : 0)) {
2618 if (++ireg_loops >= (uint32_t)profile->ireg_seconds) {
2619 time_t now = switch_epoch_time_now(NULL((void*)0));
2620 sofia_reg_check_expire(profile, now, 0);
2621 ireg_loops = 0;
2622 }
2623
2624 if(++iping_loops >= (uint32_t)profile->iping_freq) {
2625 time_t now = switch_epoch_time_now(NULL((void*)0));
2626 sofia_reg_check_ping_expire(profile, now, profile->iping_seconds);
2627 iping_loops = 0;
2628 }
2629
2630 if (++gateway_loops >= GATEWAY_SECONDS1) {
2631 sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
2632 sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL((void*)0)));
2633 gateway_loops = 0;
2634 }
2635 }
2636
2637 switch_yield(1000000)switch_sleep(1000000);;
2638
2639 }
2640
2641 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
);
;
2642
2643 return NULL((void*)0);
2644}
2645
2646switch_thread_t *launch_sofia_worker_thread(sofia_profile_t *profile)
2647{
2648 switch_thread_t *thread = NULL((void*)0);
2649 switch_threadattr_t *thd_attr = NULL((void*)0);
2650 int x = 0;
2651 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);
2652 switch_event_t *params = NULL((void*)0);
2653 char *cf = "sofia.conf";
2654
2655 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2655
, ((void*)0)
, SWITCH_LOG_DEBUG, "Launching worker thread for %s\n", profile->name);
2656
2657 /* Parse gateways */
2658 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2658, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
2659 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "sofia.c", 2659
, __PRETTY_FUNCTION__))
;
2660 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile->name);
2661
2662 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
2663 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2663
, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
2664 goto end;
2665 }
2666
2667 if ((xprofiles = switch_xml_child(cfg, "profiles"))) {
2668 if ((xprofile = switch_xml_find_child(xprofiles, "profile", "name", profile->name))) {
2669
2670 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
2671 parse_gateways(profile, gateways_tag);
2672 }
2673
2674 if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
2675 switch_event_t *xml_params;
2676 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2676, &xml_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
2677 switch_assert(xml_params)((xml_params) ? (void) (0) : __assert_fail ("xml_params", "sofia.c"
, 2677, __PRETTY_FUNCTION__))
;
2678 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways");
2679 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
2680
2681 for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
2682 switch_xml_t droot, x_domain_tag;
2683 const char *dname = switch_xml_attr_soft(domain_tag, "name");
2684 const char *parse = switch_xml_attr_soft(domain_tag, "parse");
2685 const char *alias = switch_xml_attr_soft(domain_tag, "alias");
2686
2687 if (!zstr(dname)_zstr(dname)) {
2688 if (!strcasecmp(dname, "all")) {
2689 switch_xml_t xml_root, x_domains;
2690 if (switch_xml_locate("directory", NULL((void*)0), NULL((void*)0), NULL((void*)0), &xml_root, &x_domains, xml_params, SWITCH_FALSE) ==
2691 SWITCH_STATUS_SUCCESS) {
2692 for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
2693 dname = switch_xml_attr_soft(x_domain_tag, "name");
2694 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
2695 }
2696 switch_xml_free(xml_root);
2697 }
2698 } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) {
2699 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
2700 switch_xml_free(droot);
2701 }
2702 }
2703 }
2704
2705 switch_event_destroy(&xml_params);
2706 }
2707
2708 }
2709 }
2710
2711 switch_threadattr_create(&thd_attr, profile->pool);
2712 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
2713 //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
2714 switch_thread_create(&thread, thd_attr, sofia_profile_worker_thread_run, profile, profile->pool);
2715
2716 while (!sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)((profile)->pflags[PFLAG_WORKER_RUNNING] ? 1 : 0)) {
2717 switch_yield(100000)switch_sleep(100000);;
2718 if (++x >= 100) {
2719 break;
2720 }
2721 }
2722
2723 end:
2724 switch_event_destroy(&params);
2725
2726 if (xml) {
2727 switch_xml_free(xml);
2728 }
2729
2730 return thread;
2731}
2732
2733void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj)
2734{
2735 sofia_profile_t *profile = (sofia_profile_t *) obj;
2736 //switch_memory_pool_t *pool;
2737 sip_alias_node_t *node;
2738 switch_event_t *s_event;
2739 int use_100rel = !sofia_test_pflag(profile, PFLAG_DISABLE_100REL)((profile)->pflags[PFLAG_DISABLE_100REL] ? 1 : 0);
2740 int use_timer = !sofia_test_pflag(profile, PFLAG_DISABLE_TIMER)((profile)->pflags[PFLAG_DISABLE_TIMER] ? 1 : 0);
2741 int use_rfc_5626 = sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626)((profile)->pflags[PFLAG_ENABLE_RFC5626] ? 1 : 0);
2742 const char *supported = NULL((void*)0);
2743 int sanity, attempts = 0;
2744 switch_thread_t *worker_thread;
2745 switch_status_t st;
2746 char qname [128] = "";
2747
2748 switch_mutex_lock(mod_sofia_globals.mutex);
2749 mod_sofia_globals.threads++;
2750 switch_mutex_unlock(mod_sofia_globals.mutex);
2751
2752 profile->s_root = su_root_create(NULL((void*)0));
2753 //profile->home = su_home_new(sizeof(*profile->home));
2754
2755 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2755
, ((void*)0)
, SWITCH_LOG_DEBUG, "Creating agent for %s\n", profile->name);
2756
2757 if (!sofia_glue_init_sql(profile)) {
2758 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2758
, ((void*)0)
, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name);
2759 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 2759)
;
2760 sofia_glue_del_profile(profile);
2761 goto end;
2762 }
2763
2764 supported = switch_core_sprintf(profile->pool, "%s%s%spath, replaces", use_100rel ? "precondition, 100rel, " : "", use_timer ? "timer, " : "", use_rfc_5626 ? "outbound, " : "");
2765
2766 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0) && switch_nat_get_type()) {
2767 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) {
2768 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2768
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
2769 }
2770 if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_TCP, NULL((void*)0), SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
2771 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2771
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
2772 }
2773 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)
2774 && switch_nat_add_mapping(profile->tls_sip_port, SWITCH_NAT_TCP, NULL((void*)0), SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
2775 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2775
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
2776 }
2777 }
2778
2779 /* 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 */
2780 if ( (profile->tls_verify_policy & TPTLS_VERIFY_SUBJECTS_IN) && profile->tls_verify_in_subjects_str && ! profile->tls_verify_in_subjects) {
2781 profile->tls_verify_in_subjects = su_strlst_dup_split((su_home_t *)profile->nua, profile->tls_verify_in_subjects_str, "|");
2782 }
2783
2784 do {
2785 profile->nua = nua_create(profile->s_root, /* Event loop */
2786 sofia_event_callback, /* Callback for processing events */
2787 profile, /* Additional data to pass to callback */
2788 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
)
,
2789 NTATAG_USER_VIA(1)ntatag_user_via, tag_bool_v((1)),
2790 TPTAG_PONG2PING(1)tptag_pong2ping, tag_bool_v((1)),
2791 NTATAG_TCP_RPORT(0)ntatag_tcp_rport, tag_bool_v((0)),
2792 NTATAG_TLS_RPORT(0)ntatag_tls_rport, tag_bool_v((0)),
2793 NUTAG_RETRY_AFTER_ENABLE(0)nutag_retry_after_enable, tag_bool_v(0),
2794 TAG_IF(!strchr(profile->sipip, ':'),!(!(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))) ? tag_skip : soatag_af, tag_int_v((SOA_AF_IP4_ONLY)
)
2795 SOATAG_AF(SOA_AF_IP4_ONLY))!(!(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))) ? tag_skip : soatag_af, tag_int_v((SOA_AF_IP4_ONLY)
)
,
2796 TAG_IF(strchr(profile->sipip, ':'),!((__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))) ? tag_skip : soatag_af, tag_int_v((SOA_AF_IP6_ONLY)
)
2797 SOATAG_AF(SOA_AF_IP6_ONLY))!((__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))) ? tag_skip : soatag_af, tag_int_v((SOA_AF_IP6_ONLY)
)
,
2798 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)
2799 NUTAG_SIPS_URL(profile->tls_bindurl))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : nutag_sips_url
, urltag_url_v(profile->tls_bindurl)
,
2800 TAG_IF(profile->ws_bindurl,!(profile->ws_bindurl) ? tag_skip : nutag_ws_url, urltag_url_v
(profile->ws_bindurl)
2801 NUTAG_WS_URL(profile->ws_bindurl))!(profile->ws_bindurl) ? tag_skip : nutag_ws_url, urltag_url_v
(profile->ws_bindurl)
,
2802 TAG_IF(profile->wss_bindurl,!(profile->wss_bindurl) ? tag_skip : nutag_wss_url, urltag_url_v
(profile->wss_bindurl)
2803 NUTAG_WSS_URL(profile->wss_bindurl))!(profile->wss_bindurl) ? tag_skip : nutag_wss_url, urltag_url_v
(profile->wss_bindurl)
,
2804 TAG_IF(profile->tls_cert_dir,!(profile->tls_cert_dir) ? tag_skip : nutag_certificate_dir
, tag_str_v(profile->tls_cert_dir)
2805 NUTAG_CERTIFICATE_DIR(profile->tls_cert_dir))!(profile->tls_cert_dir) ? tag_skip : nutag_certificate_dir
, tag_str_v(profile->tls_cert_dir)
,
2806 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)
2807 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)
,
2808 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))
2809 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))
,
2810 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))
2811 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))
,
2812 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))
2813 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))
,
2814 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))
2815 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))
,
2816 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))
2817 TPTAG_TLS_CIPHERS(profile->tls_ciphers))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_ciphers
, tag_str_v((profile->tls_ciphers))
,
2818 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))
2819 TPTAG_TLS_VERSION(profile->tls_version))!(((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? tag_skip : tptag_tls_version
, tag_uint_v((profile->tls_version))
,
2820 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))
2821 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))
,
2822 TAG_IF(!strchr(profile->sipip, ':'),!(!(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))) ? tag_skip : ntatag_udp_mtu, tag_uint_v((65535))
2823 NTATAG_UDP_MTU(65535))!(!(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))) ? tag_skip : ntatag_udp_mtu, tag_uint_v((65535))
,
2824 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))
2825 NTATAG_USE_SRV(0))!(((profile)->pflags[PFLAG_DISABLE_SRV] ? 1 : 0)) ? tag_skip
: ntatag_use_srv, tag_bool_v((0))
,
2826 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))
2827 NTATAG_USE_NAPTR(0))!(((profile)->pflags[PFLAG_DISABLE_NAPTR] ? 1 : 0)) ? tag_skip
: ntatag_use_naptr, tag_bool_v((0))
,
2828 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))
2829 TPTAG_PINGPONG(profile->tcp_pingpong))!(((profile)->pflags[PFLAG_TCP_PINGPONG] ? 1 : 0)) ? tag_skip
: tptag_pingpong, tag_uint_v((profile->tcp_pingpong))
,
2830 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))
2831 TPTAG_PINGPONG(profile->tcp_ping2pong))!(((profile)->pflags[PFLAG_TCP_PING2PONG] ? 1 : 0)) ? tag_skip
: tptag_pingpong, tag_uint_v((profile->tcp_ping2pong))
,
2832 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))
2833 NTATAG_SRV_503(0))!(((profile)->pflags[PFLAG_DISABLE_SRV503] ? 1 : 0)) ? tag_skip
: ntatag_srv_503, tag_bool_v((0))
,
2834 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))
2835 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))
,
2836 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))
2837 TPTAG_KEEPALIVE(profile->tcp_keepalive))!(((profile)->pflags[PFLAG_TCP_KEEPALIVE] ? 1 : 0)) ? tag_skip
: tptag_keepalive, tag_uint_v((profile->tcp_keepalive))
,
2838 NTATAG_DEFAULT_PROXY(profile->outbound_proxy)ntatag_default_proxy, urltag_url_v((profile->outbound_proxy
))
,
2839 NTATAG_SERVER_RPORT(profile->server_rport_level)ntatag_server_rport, tag_int_v((profile->server_rport_level
))
,
2840 NTATAG_CLIENT_RPORT(profile->client_rport_level)ntatag_client_rport, tag_bool_v((profile->client_rport_level
))
,
2841 TPTAG_LOG(sofia_test_flag(profile, TFLAG_TPORT_LOG))tptag_log, tag_bool_v((((profile)->flags[TFLAG_TPORT_LOG] ?
1 : 0)))
,
2842 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)))
,
2843 TAG_IF(sofia_test_pflag(profile, PFLAG_SIPCOMPACT),!(((profile)->pflags[PFLAG_SIPCOMPACT] ? 1 : 0)) ? tag_skip
: ntatag_sipflags, tag_uint_v((MSG_FLG_COMPACT))
2844 NTATAG_SIPFLAGS(MSG_DO_COMPACT))!(((profile)->pflags[PFLAG_SIPCOMPACT] ? 1 : 0)) ? tag_skip
: ntatag_sipflags, tag_uint_v((MSG_FLG_COMPACT))
,
2845 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))
,
2846 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))
,
2847 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))
,
2848 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))
,
2849 SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed")siptag_accept_str, tag_str_v("application/sdp, multipart/mixed"
)
,
2850 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))
2851 TPTAG_REUSE(0))!(((profile)->pflags[PFLAG_NO_CONNECTION_REUSE] ? 1 : 0)) ?
tag_skip : tptag_reuse, tag_bool_v((0))
,
2852 TAG_END()(tag_type_t)0, (tag_value_t)0); /* Last tag should always finish the sequence */
2853
2854 if (!profile->nua) {
2855 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2855
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s) ATTEMPT %d (RETRY IN %d SEC)\n",
2856 profile->name, profile->bindurl, attempts + 1, profile->bind_attempt_interval);
2857 if (attempts < profile->bind_attempts) {
2858 switch_yield(1000000 * profile->bind_attempt_interval)switch_sleep(1000000 * profile->bind_attempt_interval);;
2859 }
2860 }
2861
2862 } while (!profile->nua && attempts++ < profile->bind_attempts);
2863
2864 if (!profile->nua) {
2865 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2865
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s)\n"
2866 "The likely causes for this are:\n" "1) Another application is already listening on the specified address.\n"
2867 "2) The IP the profile is attempting to bind to is not local to this system.\n", profile->name, profile->bindurl);
2868 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 2868)
;
2869 sofia_glue_del_profile(profile);
2870 goto end;
2871 }
2872
2873 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2873
, ((void*)0)
, SWITCH_LOG_DEBUG, "Created agent for %s\n", profile->name);
2874
2875 nua_set_params(profile->nua,
2876 SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO")siptag_allow_str, tag_str_v("INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO"
)
,
2877 NUTAG_AUTOANSWER(0)nutag_autoanswer, tag_bool_v(0),
2878 NUTAG_AUTOACK(0)nutag_autoack, tag_bool_v(0),
2879 NUTAG_AUTOALERT(0)nutag_autoalert, tag_bool_v(0),
2880 NUTAG_ENABLEMESSENGER(1)nutag_enablemessenger, tag_bool_v(1),
2881 NTATAG_EXTRA_100(0)ntatag_extra_100, tag_bool_v((0)),
2882 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")
,
2883 TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER"))!((profile->mflags & MFLAG_REGISTER)) ? tag_skip : nutag_allow
, tag_str_v("REGISTER")
,
2884 TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER"))!((profile->mflags & MFLAG_REFER)) ? tag_skip : nutag_allow
, tag_str_v("REFER")
,
2885 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")
,
2886 NUTAG_ALLOW("INFO")nutag_allow, tag_str_v("INFO"),
2887 NUTAG_ALLOW("NOTIFY")nutag_allow, tag_str_v("NOTIFY"),
2888 NUTAG_ALLOW_EVENTS("talk")nutag_allow_events, tag_str_v("talk"),
2889 NUTAG_ALLOW_EVENTS("hold")nutag_allow_events, tag_str_v("hold"),
2890 NUTAG_ALLOW_EVENTS("conference")nutag_allow_events, tag_str_v("conference"),
2891 NUTAG_APPL_METHOD("OPTIONS")nutag_appl_method, tag_str_v("OPTIONS"),
2892 NUTAG_APPL_METHOD("REFER")nutag_appl_method, tag_str_v("REFER"),
2893 NUTAG_APPL_METHOD("REGISTER")nutag_appl_method, tag_str_v("REGISTER"),
2894 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"),
2895#ifdef MANUAL_BYE1
2896 NUTAG_APPL_METHOD("BYE")nutag_appl_method, tag_str_v("BYE"),
2897#endif
2898 NUTAG_APPL_METHOD("MESSAGE")nutag_appl_method, tag_str_v("MESSAGE"),
2899
2900 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
))
,
2901 NUTAG_SESSION_TIMER(profile->session_timeout)nutag_session_timer, tag_uint_v((profile->session_timeout)
)
,
2902 NTATAG_MAX_PROCEEDING(profile->max_proceeding)ntatag_max_proceeding, tag_usize_v((profile->max_proceeding
))
,
2903 TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"PUBLISH")
,
2904 TAG_IF(profile->pres_type, NUTAG_ALLOW("SUBSCRIBE"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"SUBSCRIBE")
,
2905 TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1))!(profile->pres_type) ? tag_skip : nutag_enablemessage, tag_bool_v
(1)
,
2906 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("presence")
,
2907 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")
,
2908 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"
)
,
2909 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"
)
,
2910 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("call-info"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("call-info")
,
2911 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"
)
,
2912 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")
,
2913 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence.winfo"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("presence.winfo")
,
2914 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("message-summary"))!(profile->pres_type) ? tag_skip : nutag_allow_events, tag_str_v
("message-summary")
,
2915 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")
,
2916 NUTAG_ALLOW_EVENTS("refer")nutag_allow_events, tag_str_v("refer"), SIPTAG_SUPPORTED_STR(supported)siptag_supported_str, tag_str_v(supported), SIPTAG_USER_AGENT_STR(profile->user_agent)siptag_user_agent_str, tag_str_v(profile->user_agent), TAG_END()(tag_type_t)0, (tag_value_t)0);
2917
2918 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2918
, ((void*)0)
, SWITCH_LOG_DEBUG, "Set params for %s\n", profile->name);
2919
2920 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)) {
2921 sip_via_t *vias = nta_agent_via(profile->nua->nua_nta);
2922 sip_via_t *via = NULL((void*)0);
2923
2924 for (via = vias; via; via = via->v_next) {
2925 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")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(via->v_protocol) && __builtin_constant_p ("SIP/2.0/UDP"
) && (__s1_len = __builtin_strlen (via->v_protocol
), __s2_len = __builtin_strlen ("SIP/2.0/UDP"), (!((size_t)(const
void *)((via->v_protocol) + 1) - (size_t)(const void *)(via
->v_protocol) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)(("SIP/2.0/UDP") + 1) - (size_t)(const void *)
("SIP/2.0/UDP") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(via->v_protocol, "SIP/2.0/UDP") : (__builtin_constant_p (
via->v_protocol) && ((size_t)(const void *)((via->
v_protocol) + 1) - (size_t)(const void *)(via->v_protocol)
== 1) && (__s1_len = __builtin_strlen (via->v_protocol
), __s1_len < 4) ? (__builtin_constant_p ("SIP/2.0/UDP") &&
((size_t)(const void *)(("SIP/2.0/UDP") + 1) - (size_t)(const
void *)("SIP/2.0/UDP") == 1) ? __builtin_strcmp (via->v_protocol
, "SIP/2.0/UDP") : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) ("SIP/2.0/UDP"); int
__result = (((const unsigned char *) (const char *) (via->
v_protocol))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
via->v_protocol))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (via->v_protocol))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (via->v_protocol))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("SIP/2.0/UDP") && ((size_t
)(const void *)(("SIP/2.0/UDP") + 1) - (size_t)(const void *)
("SIP/2.0/UDP") == 1) && (__s2_len = __builtin_strlen
("SIP/2.0/UDP"), __s2_len < 4) ? (__builtin_constant_p (via
->v_protocol) && ((size_t)(const void *)((via->
v_protocol) + 1) - (size_t)(const void *)(via->v_protocol)
== 1) ? __builtin_strcmp (via->v_protocol, "SIP/2.0/UDP")
: (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (via->v_protocol); int __result = (
((const unsigned char *) (const char *) ("SIP/2.0/UDP"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("SIP/2.0/UDP"))[
1] - __s2[1]); if (__s2_len > 1 && __result == 0) {
__result = (((const unsigned char *) (const char *) ("SIP/2.0/UDP"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("SIP/2.0/UDP"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (via
->v_protocol, "SIP/2.0/UDP")))); })
) {
2926 profile->sip_port = (switch_port_t)atoi(via->v_port);
2927 if (!profile->extsipport) profile->extsipport = profile->sip_port;
2928 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2928
, ((void*)0)
, SWITCH_LOG_DEBUG, "Found auto sip port %d for %s\n", profile->sip_port, profile->name);
2929 }
2930
2931 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")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(via->v_protocol) && __builtin_constant_p ("SIP/2.0/TLS"
) && (__s1_len = __builtin_strlen (via->v_protocol
), __s2_len = __builtin_strlen ("SIP/2.0/TLS"), (!((size_t)(const
void *)((via->v_protocol) + 1) - (size_t)(const void *)(via
->v_protocol) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)(("SIP/2.0/TLS") + 1) - (size_t)(const void *)
("SIP/2.0/TLS") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(via->v_protocol, "SIP/2.0/TLS") : (__builtin_constant_p (
via->v_protocol) && ((size_t)(const void *)((via->
v_protocol) + 1) - (size_t)(const void *)(via->v_protocol)
== 1) && (__s1_len = __builtin_strlen (via->v_protocol
), __s1_len < 4) ? (__builtin_constant_p ("SIP/2.0/TLS") &&
((size_t)(const void *)(("SIP/2.0/TLS") + 1) - (size_t)(const
void *)("SIP/2.0/TLS") == 1) ? __builtin_strcmp (via->v_protocol
, "SIP/2.0/TLS") : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) ("SIP/2.0/TLS"); int
__result = (((const unsigned char *) (const char *) (via->
v_protocol))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
via->v_protocol))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (via->v_protocol))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (via->v_protocol))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("SIP/2.0/TLS") && ((size_t
)(const void *)(("SIP/2.0/TLS") + 1) - (size_t)(const void *)
("SIP/2.0/TLS") == 1) && (__s2_len = __builtin_strlen
("SIP/2.0/TLS"), __s2_len < 4) ? (__builtin_constant_p (via
->v_protocol) && ((size_t)(const void *)((via->
v_protocol) + 1) - (size_t)(const void *)(via->v_protocol)
== 1) ? __builtin_strcmp (via->v_protocol, "SIP/2.0/TLS")
: (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (via->v_protocol); int __result = (
((const unsigned char *) (const char *) ("SIP/2.0/TLS"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("SIP/2.0/TLS"))[
1] - __s2[1]); if (__s2_len > 1 && __result == 0) {
__result = (((const unsigned char *) (const char *) ("SIP/2.0/TLS"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("SIP/2.0/TLS"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (via
->v_protocol, "SIP/2.0/TLS")))); })
) {
2932 profile->tls_sip_port = (switch_port_t)atoi(via->v_port);
2933 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2933
, ((void*)0)
, SWITCH_LOG_DEBUG, "Found auto sip port %d for %s (TLS)\n", profile->tls_sip_port, profile->name);
2934 }
2935
2936 }
2937
2938 config_sofia_profile_urls(profile);
2939 }
2940
2941 for (node = profile->aliases; node; node = node->next) {
2942 node->nua = nua_create(profile->s_root, /* Event loop */
2943 sofia_event_callback, /* Callback for processing events */
2944 profile, /* Additional data to pass to callback */
2945 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 */
2946
2947 nua_set_params(node->nua,
2948 NUTAG_APPL_METHOD("OPTIONS")nutag_appl_method, tag_str_v("OPTIONS"),
2949 NUTAG_APPL_METHOD("REFER")nutag_appl_method, tag_str_v("REFER"),
2950 NUTAG_APPL_METHOD("SUBSCRIBE")nutag_appl_method, tag_str_v("SUBSCRIBE"),
2951 NUTAG_AUTOANSWER(0)nutag_autoanswer, tag_bool_v(0),
2952 NUTAG_AUTOACK(0)nutag_autoack, tag_bool_v(0),
2953 NUTAG_AUTOALERT(0)nutag_autoalert, tag_bool_v(0),
2954 TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER"))!((profile->mflags & MFLAG_REGISTER)) ? tag_skip : nutag_allow
, tag_str_v("REGISTER")
,
2955 TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER"))!((profile->mflags & MFLAG_REFER)) ? tag_skip : nutag_allow
, tag_str_v("REFER")
,
2956 NUTAG_ALLOW("INFO")nutag_allow, tag_str_v("INFO"),
2957 TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH"))!(profile->pres_type) ? tag_skip : nutag_allow, tag_str_v(
"PUBLISH")
,
2958 TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1))!(profile->pres_type) ? tag_skip : nutag_enablemessage, tag_bool_v
(1)
,
2959 SIPTAG_SUPPORTED_STR(supported)siptag_supported_str, tag_str_v(supported), SIPTAG_USER_AGENT_STR(profile->user_agent)siptag_user_agent_str, tag_str_v(profile->user_agent), TAG_END()(tag_type_t)0, (tag_value_t)0);
2960 }
2961
2962 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 2962
, ((void*)0)
, SWITCH_LOG_DEBUG, "Activated db for %s\n", profile->name);
2963
2964 switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
2965 switch_mutex_init(&profile->dbh_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
2966 switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
2967 switch_queue_create(&profile->event_queue, SOFIA_QUEUE_SIZE50000, profile->pool);
2968
2969
2970 switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name);
2971 switch_sql_queue_manager_init_name(qname,
2972 &profile->qm,
2973 2,
2974 profile->odbc_dsn ? profile->odbc_dsn : profile->dbname,
2975 SWITCH_MAX_TRANS2000,
2976 profile->pre_trans_execute,
2977 profile->post_trans_execute,
2978 profile->inner_pre_trans_execute,
2979 profile->inner_post_trans_execute);
2980 switch_sql_queue_manager_start(profile->qm);
2981
2982 if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 2982, &s_event, SWITCH_EVENT_PUBLISH
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
2983 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s",
2984 (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? ",_sips._tcp" : "");
2985
2986 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
2987 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
2988 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
2989 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
2990
2991 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
2992 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "tls_port", "%d", profile->tls_sip_port);
2993 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_tls_uri", profile->tls_url);
2994 }
2995 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 2995, &s_event, ((void*)0))
;
2996 }
2997
2998 sofia_glue_add_profile(profile->name, profile);
2999
3000 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3000
, ((void*)0)
, SWITCH_LOG_DEBUG, "Starting thread for %s\n", profile->name);
3001
3002 profile->started = switch_epoch_time_now(NULL((void*)0));
3003
3004 sofia_set_pflag_locked(profile, PFLAG_RUNNING)((profile->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("profile->flag_mutex != ((void*)0)", "sofia.c", 3004, __PRETTY_FUNCTION__
));switch_mutex_lock(profile->flag_mutex);(profile)->pflags
[PFLAG_RUNNING] = 1;switch_mutex_unlock(profile->flag_mutex
);
;
3005 worker_thread = launch_sofia_worker_thread(profile);
3006
3007 switch_yield(1000000)switch_sleep(1000000);;
3008
3009
3010 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)) {
3011 su_root_step(profile->s_root, 1000);
3012 profile->last_root_step = switch_time_now();
3013 }
3014
3015 sofia_clear_pflag_locked(profile, PFLAG_RUNNING)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_RUNNING] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3016 sofia_reg_close_handles(profile);
3017
3018 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)
;
3019 sanity = 10;
3020 while (profile->inuse) {
3021 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3021
, ((void*)0)
, SWITCH_LOG_CRIT, "Waiting for %d session(s)\n", profile->inuse);
3022 su_root_step(profile->s_root, 1000);
3023 if (!--sanity) {
3024 break;
3025 } else if (sanity == 5) {
3026 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)
;
3027 }
3028 }
3029
3030
3031 sofia_reg_unregister(profile);
3032 nua_shutdown(profile->nua);
3033
3034 sanity = 100;
3035 while (!sofia_test_pflag(profile, PFLAG_SHUTDOWN)((profile)->pflags[PFLAG_SHUTDOWN] ? 1 : 0) || profile->queued_events > 0) {
3036 su_root_step(profile->s_root, 1000);
3037 if (!--sanity) {
3038 break;
3039 }
3040 }
3041
3042 sofia_clear_pflag_locked(profile, PFLAG_RUNNING)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_RUNNING] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3043 sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN)switch_mutex_lock(profile->flag_mutex); (profile)->pflags
[PFLAG_SHUTDOWN] = 0; switch_mutex_unlock(profile->flag_mutex
);
;
3044 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3044
, ((void*)0)
, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
3045
3046 if ( worker_thread ) {
3047 switch_thread_join(&st, worker_thread);
3048 } else {
3049 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3049
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n");
3050 }
3051
3052 sanity = 4;
3053 while (profile->inuse) {
3054 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)
;
3055 switch_yield(5000000)switch_sleep(5000000);;
3056 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3056
, ((void*)0)
, SWITCH_LOG_CRIT, "Waiting for %d session(s)\n", profile->inuse);
3057 if (!--sanity) {
3058 break;
3059 }
3060 }
3061 nua_destroy(profile->nua);
3062
3063 switch_mutex_lock(profile->ireg_mutex);
3064 switch_mutex_unlock(profile->ireg_mutex);
3065
3066 switch_mutex_lock(profile->flag_mutex);
3067 switch_mutex_unlock(profile->flag_mutex);
3068
3069 switch_sql_queue_manager_destroy(&profile->qm);
3070
3071 if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3071, &s_event, SWITCH_EVENT_UNPUBLISH
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
3072 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s",
3073 (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) ? ",_sips._tcp" : "");
3074
3075 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
3076 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
3077 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
3078 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
3079
3080 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
3081 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "tls_port", "%d", profile->tls_sip_port);
3082 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_tls_uri", profile->tls_url);
3083 }
3084 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 3084, &s_event, ((void*)0))
;
3085 }
3086
3087 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0) && switch_nat_get_type()) {
3088 if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_UDP) == SWITCH_STATUS_SUCCESS) {
3089 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3089
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3090 }
3091 if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_TCP) == SWITCH_STATUS_SUCCESS) {
3092 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3092
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3093 }
3094 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) {
3095 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3095
, ((void*)0)
, SWITCH_LOG_DEBUG, "Deleted TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
3096 }
3097 }
3098
3099 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3099
, ((void*)0)
, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name);
3100 switch_thread_rwlock_wrlock(profile->rwlock);
3101
3102 //su_home_unref(profile->home);
3103 su_root_destroy(profile->s_root);
3104 //pool = profile->pool;
3105
3106 sofia_glue_del_profile(profile);
3107 switch_core_hash_destroy(&profile->chat_hash);
3108 switch_core_hash_destroy(&profile->reg_nh_hash);
3109 switch_core_hash_destroy(&profile->mwi_debounce_hash);
3110
3111 switch_thread_rwlock_unlock(profile->rwlock);
3112 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3112
, ((void*)0)
, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name);
3113
3114 if (sofia_test_pflag(profile, PFLAG_RESPAWN)((profile)->pflags[PFLAG_RESPAWN] ? 1 : 0)) {
3115 config_sofia(SOFIA_CONFIG_RESPAWN, profile->name);
3116 }
3117
3118 sofia_profile_destroy(profile);
3119
3120 end:
3121 switch_mutex_lock(mod_sofia_globals.mutex);
3122 mod_sofia_globals.threads--;
3123 switch_mutex_unlock(mod_sofia_globals.mutex);
3124
3125 return NULL((void*)0);
3126}
3127
3128void sofia_profile_destroy(sofia_profile_t *profile)
3129{
3130 if (!profile->inuse) {
3131 switch_memory_pool_t *pool = profile->pool;
3132 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia.c",
(const char *)__func__, 3132)
;
3133 } else {
3134 sofia_set_pflag(profile, PFLAG_DESTROY)(profile)->pflags[PFLAG_DESTROY] = 1;
3135 }
3136}
3137
3138void launch_sofia_profile_thread(sofia_profile_t *profile)
3139{
3140 //switch_thread_t *thread;
3141 switch_threadattr_t *thd_attr = NULL((void*)0);
3142
3143 switch_threadattr_create(&thd_attr, profile->pool);
3144 switch_threadattr_detach_set(thd_attr, 1);
3145 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
3146 switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
3147 switch_thread_create(&profile->thread, thd_attr, sofia_profile_thread_run, profile, profile->pool);
3148}
3149
3150static void logger(void *logarg, char const *fmt, va_list ap)
3151{
3152 if (!fmt) return;
3153
3154 switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEANSWITCH_CHANNEL_ID_LOG_CLEAN, "sofia.c", (const char *)__func__
, 3154, ((void*)0)
, mod_sofia_globals.tracelevel, fmt, ap);
3155}
3156
3157static su_log_t *sofia_get_logger(const char *name)
3158{
3159 if (!strcasecmp(name, "tport")) {
3160 return tport_log;
3161 } else if (!strcasecmp(name, "iptsec")) {
3162 return iptsec_log;
3163 } else if (!strcasecmp(name, "nea")) {
3164 return nea_log;
3165 } else if (!strcasecmp(name, "nta")) {
3166 return nta_log;
3167 } else if (!strcasecmp(name, "nth_client")) {
3168 return nth_client_log;
3169 } else if (!strcasecmp(name, "nth_server")) {
3170 return nth_server_log;
3171 } else if (!strcasecmp(name, "nua")) {
3172 return nua_log;
3173 } else if (!strcasecmp(name, "soa")) {
3174 return soa_log;
3175 } else if (!strcasecmp(name, "sresolv")) {
3176 return sresolv_log;
3177#ifdef HAVE_SOFIA_STUN
3178 } else if (!strcasecmp(name, "stun")) {
3179 return stun_log;
3180#endif
3181 } else if (!strcasecmp(name, "default")) {
3182 return su_log_default;
3183 } else {
3184 return NULL((void*)0);
3185 }
3186}
3187
3188switch_status_t sofia_set_loglevel(const char *name, int level)
3189{
3190 su_log_t *log = NULL((void*)0);
3191
3192 if (level < 0 || level > 9) {
3193 return SWITCH_STATUS_FALSE;
3194 }
3195
3196 if (!strcasecmp(name, "all")) {
3197 su_log_set_level(su_log_default, level);
3198 su_log_set_level(tport_log, level);
3199 su_log_set_level(iptsec_log, level);
3200 su_log_set_level(nea_log, level);
3201 su_log_set_level(nta_log, level);
3202 su_log_set_level(nth_client_log, level);
3203 su_log_set_level(nth_server_log, level);
3204 su_log_set_level(nua_log, level);
3205 su_log_set_level(soa_log, level);
3206 su_log_set_level(sresolv_log, level);
3207#ifdef HAVE_SOFIA_STUN
3208 su_log_set_level(stun_log, level);
3209#endif
3210 return SWITCH_STATUS_SUCCESS;
3211 }
3212
3213 if (!(log = sofia_get_logger(name))) {
3214 return SWITCH_STATUS_FALSE;
3215 }
3216
3217 su_log_set_level(log, level);
3218
3219 return SWITCH_STATUS_SUCCESS;
3220}
3221
3222int sofia_get_loglevel(const char *name)
3223{
3224 su_log_t *log = NULL((void*)0);
3225
3226 if ((log = sofia_get_logger(name))) {
3227 return log->log_level;
3228 } else {
3229 return -1;
3230 }
3231}
3232
3233static void parse_gateway_subscriptions(sofia_profile_t *profile, sofia_gateway_t *gateway, switch_xml_t gw_subs_tag)
3234{
3235 switch_xml_t subscription_tag, param;
3236
3237 for (subscription_tag = switch_xml_child(gw_subs_tag, "subscription"); subscription_tag; subscription_tag = subscription_tag->next) {
3238 sofia_gateway_subscription_t *gw_sub;
3239
3240 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__, 3240)
)) {
3241 char *expire_seconds = "3600", *retry_seconds = "30", *content_type = "NO_CONTENT_TYPE";
3242 uint32_t username_in_request = 0;
3243 char *event = (char *) switch_xml_attr_soft(subscription_tag, "event");
3244 gw_sub->event = switch_core_strdup(gateway->pool, event)switch_core_perform_strdup(gateway->pool, event, "sofia.c"
, (const char *)__func__, 3244)
;
3245 gw_sub->gateway = gateway;
3246 gw_sub->next = NULL((void*)0);
3247
3248 for (param = switch_xml_child(subscription_tag, "param"); param; param = param->next) {
3249 char *var = (char *) switch_xml_attr_soft(param, "name");
3250 char *val = (char *) switch_xml_attr_soft(param, "value");
3251 if (!strcmp(var, "expire-seconds")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("expire-seconds") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("expire-seconds"), (!((size_t)(const void *)((var) + 1) - (
size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("expire-seconds") + 1) - (size_t)
(const void *)("expire-seconds") == 1) || __s2_len >= 4)) ?
__builtin_strcmp (var, "expire-seconds") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("expire-seconds"
) && ((size_t)(const void *)(("expire-seconds") + 1) -
(size_t)(const void *)("expire-seconds") == 1) ? __builtin_strcmp
(var, "expire-seconds") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("expire-seconds"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("expire-seconds"
) && ((size_t)(const void *)(("expire-seconds") + 1) -
(size_t)(const void *)("expire-seconds") == 1) && (__s2_len
= __builtin_strlen ("expire-seconds"), __s2_len < 4) ? (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) ? __builtin_strcmp (var, "expire-seconds"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("expire-seconds"))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("expire-seconds"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("expire-seconds"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("expire-seconds"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "expire-seconds")))); })
) {
3252 expire_seconds = val;
3253 } else if (!strcmp(var, "retry-seconds")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("retry-seconds") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("retry-seconds"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("retry-seconds") + 1) - (size_t)(const
void *)("retry-seconds") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "retry-seconds") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("retry-seconds") &&
((size_t)(const void *)(("retry-seconds") + 1) - (size_t)(const
void *)("retry-seconds") == 1) ? __builtin_strcmp (var, "retry-seconds"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("retry-seconds"); int __result = (((
const unsigned char *) (const char *) (var))[0] - __s2[0]); if
(__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (var))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var))[3] - __s2[3]); } } __result; }))) :
(__builtin_constant_p ("retry-seconds") && ((size_t)
(const void *)(("retry-seconds") + 1) - (size_t)(const void *
)("retry-seconds") == 1) && (__s2_len = __builtin_strlen
("retry-seconds"), __s2_len < 4) ? (__builtin_constant_p (
var) && ((size_t)(const void *)((var) + 1) - (size_t)
(const void *)(var) == 1) ? __builtin_strcmp (var, "retry-seconds"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("retry-seconds"))[0] - __s2[0]); if (
__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("retry-seconds"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("retry-seconds")
)[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("retry-seconds"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "retry-seconds")))); })
) {
3254 retry_seconds = val;
3255 } else if (!strcmp(var, "content-type")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("content-type") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("content-type"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("content-type") + 1) - (size_t)(const
void *)("content-type") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "content-type") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("content-type") && (
(size_t)(const void *)(("content-type") + 1) - (size_t)(const
void *)("content-type") == 1) ? __builtin_strcmp (var, "content-type"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("content-type"); int __result = (((const
unsigned char *) (const char *) (var))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("content-type") && ((size_t)(const void *)(("content-type"
) + 1) - (size_t)(const void *)("content-type") == 1) &&
(__s2_len = __builtin_strlen ("content-type"), __s2_len <
4) ? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "content-type") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("content-type"))
[0] - __s2[0]); if (__s2_len > 0 && __result == 0)
{ __result = (((const unsigned char *) (const char *) ("content-type"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("content-type"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("content-type"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "content-type")))); })
) {
3256 content_type = val;
3257 } else if (!strcmp(var, "username-in-request")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("username-in-request"
) && (__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("username-in-request"), (!((size_t)(const void *)((var) + 1
) - (size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("username-in-request") + 1) - (size_t
)(const void *)("username-in-request") == 1) || __s2_len >=
4)) ? __builtin_strcmp (var, "username-in-request") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("username-in-request"
) && ((size_t)(const void *)(("username-in-request") +
1) - (size_t)(const void *)("username-in-request") == 1) ? __builtin_strcmp
(var, "username-in-request") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("username-in-request"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("username-in-request"
) && ((size_t)(const void *)(("username-in-request") +
1) - (size_t)(const void *)("username-in-request") == 1) &&
(__s2_len = __builtin_strlen ("username-in-request"), __s2_len
< 4) ? (__builtin_constant_p (var) && ((size_t)(const
void *)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "username-in-request") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (var); int
__result = (((const unsigned char *) (const char *) ("username-in-request"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("username-in-request"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("username-in-request"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("username-in-request"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "username-in-request")))); })
) {
3258 username_in_request = switch_true(val);
3259 }
3260 }
3261
3262 gw_sub->retry_seconds = atoi(retry_seconds);
3263 if (gw_sub->retry_seconds < 10) {
3264 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3264
, ((void*)0)
, SWITCH_LOG_WARNING, "INVALID: retry_seconds correcting the value to 30\n");
3265 gw_sub->retry_seconds = 30;
3266 }
3267
3268 gw_sub->expires_str = switch_core_strdup(gateway->pool, expire_seconds)switch_core_perform_strdup(gateway->pool, expire_seconds, "sofia.c"
, (const char *)__func__, 3268)
;
3269
3270 if ((gw_sub->freq = atoi(gw_sub->expires_str)) < 5) {
3271 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3271
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid Freq: %d. Setting Register-Frequency to 3600\n", gw_sub->freq);
3272 gw_sub->freq = 3600;
3273 }
3274
3275 if(username_in_request) {
3276 gw_sub->request_uri = gateway->register_to;
3277 } else {
3278 gw_sub->request_uri = gateway->register_url;
3279 }
3280
3281 gw_sub->freq -= 2;
3282 gw_sub->content_type = switch_core_strdup(gateway->pool, content_type)switch_core_perform_strdup(gateway->pool, content_type, "sofia.c"
, (const char *)__func__, 3282)
;
3283 gw_sub->next = gateway->subscriptions;
3284 }
3285 gateway->subscriptions = gw_sub;
3286 }
3287}
3288
3289static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
3290{
3291 switch_xml_t gateway_tag, param = NULL((void*)0), x_params, gw_subs_tag;
3292 sofia_gateway_t *gp;
3293
3294 for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
3295 char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
3296 sofia_gateway_t *gateway;
3297 char *pkey = switch_mprintf("%s::%s", profile->name, name);
3298
3299 if (zstr(name)_zstr(name) || switch_regex_match(name, "^[\\w\\.\\-\\_]+$") != SWITCH_STATUS_SUCCESS) {
3300 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3300
, ((void*)0)
, SWITCH_LOG_ERROR, "Ignoring invalid name '%s'\n", name ? name : "NULL");
3301 goto skip;
3302 }
3303
3304 switch_mutex_lock(mod_sofia_globals.hash_mutex);
3305 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) {
3306 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3306
, ((void*)0)
, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", name);
3307 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
3308 free(pkey);
3309 goto skip;
3310 }
3311 free(pkey);
3312 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
3313
3314 if ((gateway = switch_core_alloc(profile->pool, sizeof(*gateway))switch_core_perform_alloc(profile->pool, sizeof(*gateway),
"sofia.c", (const char *)__func__, 3314)
)) {
3315 const char *sipip, *format;
3316 switch_uuid_t uuid;
3317 uint32_t ping_freq = 0, extension_in_contact = 0, ping_monitoring = 0, distinct_to = 0, rfc_5626 = 0;
3318 int ping_max = 1, ping_min = 1;
3319 char *register_str = "true", *scheme = "Digest",
3320 *realm = NULL((void*)0),
3321 *username = NULL((void*)0),
3322 *auth_username = NULL((void*)0),
3323 *password = NULL((void*)0),
3324 *caller_id_in_from = "false",
3325 *extension = NULL((void*)0),
3326 *proxy = NULL((void*)0),
3327 *options_user_agent = NULL((void*)0),
3328 *context = profile->context,
3329 *expire_seconds = "3600",
3330 *retry_seconds = "30",
3331 *fail_908_retry_seconds = NULL((void*)0),
3332 *timeout_seconds = "60",
3333 *from_user = "", *from_domain = NULL((void*)0), *outbound_proxy = NULL((void*)0), *register_proxy = NULL((void*)0), *contact_host = NULL((void*)0),
3334 *contact_params = "", *params = NULL((void*)0), *register_transport = NULL((void*)0),
3335 *reg_id = NULL((void*)0), *str_rfc_5626 = "";
3336
3337 if (!context) {
3338 context = "default";
3339 }
3340
3341 switch_uuid_get(&uuid);
3342 switch_uuid_format(gateway->uuid_str, &uuid);
3343
3344 gateway->register_transport = SOFIA_TRANSPORT_UDP;
3345 gateway->pool = profile->pool;
3346 gateway->profile = profile;
3347 gateway->name = switch_core_strdup(gateway->pool, name)switch_core_perform_strdup(gateway->pool, name, "sofia.c",
(const char *)__func__, 3347)
;
3348 gateway->freq = 0;
3349 gateway->next = NULL((void*)0);
3350 gateway->ping = 0;
3351 gateway->ping_freq = 0;
3352 gateway->ping_max = 0;
3353 gateway->ping_min = 0;
3354 gateway->ping_sent = 0;
3355 gateway->ping_time = 0;
3356 gateway->ping_count = 0;
3357 gateway->ping_monitoring = SWITCH_FALSE;
3358 gateway->ib_calls = 0;
3359 gateway->ob_calls = 0;
3360 gateway->ib_failed_calls = 0;
3361 gateway->ob_failed_calls = 0;
3362 gateway->destination_prefix = "";
3363
3364 if ((x_params = switch_xml_child(gateway_tag, "variables"))) {
3365 param = switch_xml_child(x_params, "variable");
3366 } else {
3367 param = switch_xml_child(gateway_tag, "variable");
3368 }
3369
3370
3371 for (; param; param = param->next) {
3372 const char *var = switch_xml_attr(param, "name");
3373 const char *val = switch_xml_attr(param, "value");
3374 const char *direction = switch_xml_attr(param, "direction");
3375 int in = 0, out = 0;
3376
3377 if (var && val) {
3378 if (direction) {
3379 if (!strcasecmp(direction, "inbound")) {
3380 in = 1;
3381 } else if (!strcasecmp(direction, "outbound")) {
3382 out = 1;
3383 }
3384 } else {
3385 in = out = 1;
3386 }
3387
3388 if (in) {
3389 if (!gateway->ib_vars) {
3390 switch_event_create_plain(&gateway->ib_vars, SWITCH_EVENT_GENERAL);
3391 }
3392 switch_event_add_header_string(gateway->ib_vars, SWITCH_STACK_BOTTOM, var, val);
3393 }
3394
3395 if (out) {
3396 if (!gateway->ob_vars) {
3397 switch_event_create_plain(&gateway->ob_vars, SWITCH_EVENT_GENERAL);
3398 }
3399 switch_event_add_header_string(gateway->ob_vars, SWITCH_STACK_BOTTOM, var, val);
3400 }
3401 }
3402 }
3403
3404 if ((x_params = switch_xml_child(gateway_tag, "params"))) {
3405 param = switch_xml_child(x_params, "param");
3406 } else {
3407 param = switch_xml_child(gateway_tag, "param");
3408 }
3409
3410 for (; param; param = param->next) {
3411 char *var = (char *) switch_xml_attr_soft(param, "name");
3412 char *val = (char *) switch_xml_attr_soft(param, "value");
3413
3414 if (!strcmp(var, "register")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("register") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("register"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("register") + 1) - (size_t)(const void
*)("register") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "register") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("register") && ((size_t
)(const void *)(("register") + 1) - (size_t)(const void *)("register"
) == 1) ? __builtin_strcmp (var, "register") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("register"); int __result = (((const unsigned char *
) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("register") && ((size_t)(const void *)(("register")
+ 1) - (size_t)(const void *)("register") == 1) && (
__s2_len = __builtin_strlen ("register"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "register") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("register"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("register"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("register"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("register"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (var, "register"
)))); })
) {
3415 register_str = val;
3416 } else if (!strcmp(var, "scheme")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("scheme") && (
__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("scheme"), (!((size_t)(const void *)((var) + 1) - (size_t)(
const void *)(var) == 1) || __s1_len >= 4) && (!((
size_t)(const void *)(("scheme") + 1) - (size_t)(const void *
)("scheme") == 1) || __s2_len >= 4)) ? __builtin_strcmp (var
, "scheme") : (__builtin_constant_p (var) && ((size_t
)(const void *)((var) + 1) - (size_t)(const void *)(var) == 1
) && (__s1_len = __builtin_strlen (var), __s1_len <
4) ? (__builtin_constant_p ("scheme") && ((size_t)(const
void *)(("scheme") + 1) - (size_t)(const void *)("scheme") ==
1) ? __builtin_strcmp (var, "scheme") : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
("scheme"); int __result = (((const unsigned char *) (const char
*) (var))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
var))[1] - __s2[1]); if (__s1_len > 1 && __result ==
0) { __result = (((const unsigned char *) (const char *) (var
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("scheme"
) && ((size_t)(const void *)(("scheme") + 1) - (size_t
)(const void *)("scheme") == 1) && (__s2_len = __builtin_strlen
("scheme"), __s2_len < 4) ? (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) ? __builtin_strcmp (var, "scheme") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (var); int __result = (((const unsigned char *) (const
char *) ("scheme"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("scheme"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("scheme"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("scheme"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(var, "scheme")))); })
) {
3417 scheme = val;
3418 } else if (!strcmp(var, "realm")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("realm") && (
__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("realm"), (!((size_t)(const void *)((var) + 1) - (size_t)(const
void *)(var) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)(("realm") + 1) - (size_t)(const void *)("realm"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (var, "realm"
) : (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) &&
(__s1_len = __builtin_strlen (var), __s1_len < 4) ? (__builtin_constant_p
("realm") && ((size_t)(const void *)(("realm") + 1) -
(size_t)(const void *)("realm") == 1) ? __builtin_strcmp (var
, "realm") : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) ("realm"); int __result = ((
(const unsigned char *) (const char *) (var))[0] - __s2[0]); if
(__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (var))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var))[3] - __s2[3]); } } __result; }))) :
(__builtin_constant_p ("realm") && ((size_t)(const void
*)(("realm") + 1) - (size_t)(const void *)("realm") == 1) &&
(__s2_len = __builtin_strlen ("realm"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "realm") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("realm"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("realm"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("realm"))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) ("realm"))[3] - __s2
[3]); } } __result; })))) : __builtin_strcmp (var, "realm")))
); })
) {
3419 realm = val;
3420 } else if (!strcmp(var, "username")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("username") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("username"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("username") + 1) - (size_t)(const void
*)("username") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "username") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("username") && ((size_t
)(const void *)(("username") + 1) - (size_t)(const void *)("username"
) == 1) ? __builtin_strcmp (var, "username") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("username"); int __result = (((const unsigned char *
) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("username") && ((size_t)(const void *)(("username")
+ 1) - (size_t)(const void *)("username") == 1) && (
__s2_len = __builtin_strlen ("username"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "username") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("username"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("username"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("username"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("username"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (var, "username"
)))); })
) {
3421 username = val;
3422 } else if (!strcmp(var, "extension-in-contact")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("extension-in-contact"
) && (__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("extension-in-contact"), (!((size_t)(const void *)((var) + 1
) - (size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("extension-in-contact") + 1) - (size_t
)(const void *)("extension-in-contact") == 1) || __s2_len >=
4)) ? __builtin_strcmp (var, "extension-in-contact") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("extension-in-contact"
) && ((size_t)(const void *)(("extension-in-contact")
+ 1) - (size_t)(const void *)("extension-in-contact") == 1) ?
__builtin_strcmp (var, "extension-in-contact") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("extension-in-contact"); int __result = (((const unsigned
char *) (const char *) (var))[0] - __s2[0]); if (__s1_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("extension-in-contact") && ((size_t)(const void *)(
("extension-in-contact") + 1) - (size_t)(const void *)("extension-in-contact"
) == 1) && (__s2_len = __builtin_strlen ("extension-in-contact"
), __s2_len < 4) ? (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) ? __builtin_strcmp (var, "extension-in-contact") : (-
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("extension-in-contact"))[0] - __s2[0
]); if (__s2_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) ("extension-in-contact"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("extension-in-contact"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("extension-in-contact"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "extension-in-contact")))); })
) {
3423 extension_in_contact = switch_true(val);
3424 } else if (!strcmp(var, "auth-username")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("auth-username") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("auth-username"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("auth-username") + 1) - (size_t)(const
void *)("auth-username") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "auth-username") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("auth-username") &&
((size_t)(const void *)(("auth-username") + 1) - (size_t)(const
void *)("auth-username") == 1) ? __builtin_strcmp (var, "auth-username"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("auth-username"); int __result = (((
const unsigned char *) (const char *) (var))[0] - __s2[0]); if
(__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (var))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var))[3] - __s2[3]); } } __result; }))) :
(__builtin_constant_p ("auth-username") && ((size_t)
(const void *)(("auth-username") + 1) - (size_t)(const void *
)("auth-username") == 1) && (__s2_len = __builtin_strlen
("auth-username"), __s2_len < 4) ? (__builtin_constant_p (
var) && ((size_t)(const void *)((var) + 1) - (size_t)
(const void *)(var) == 1) ? __builtin_strcmp (var, "auth-username"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("auth-username"))[0] - __s2[0]); if (
__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("auth-username"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("auth-username")
)[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("auth-username"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "auth-username")))); })
) {
3425 auth_username = val;
3426 } else if (!strcmp(var, "password")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("password") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("password"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("password") + 1) - (size_t)(const void
*)("password") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "password") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("password") && ((size_t
)(const void *)(("password") + 1) - (size_t)(const void *)("password"
) == 1) ? __builtin_strcmp (var, "password") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("password"); int __result = (((const unsigned char *
) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("password") && ((size_t)(const void *)(("password")
+ 1) - (size_t)(const void *)("password") == 1) && (
__s2_len = __builtin_strlen ("password"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "password") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("password"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("password"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("password"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("password"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (var, "password"
)))); })
) {
3427 password = val;
3428 } else if (!strcmp(var, "caller-id-in-from")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("caller-id-in-from") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("caller-id-in-from"), (!((size_t)(const void *)((var) + 1) -
(size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("caller-id-in-from") + 1) - (size_t
)(const void *)("caller-id-in-from") == 1) || __s2_len >= 4
)) ? __builtin_strcmp (var, "caller-id-in-from") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("caller-id-in-from"
) && ((size_t)(const void *)(("caller-id-in-from") + 1
) - (size_t)(const void *)("caller-id-in-from") == 1) ? __builtin_strcmp
(var, "caller-id-in-from") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("caller-id-in-from"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("caller-id-in-from"
) && ((size_t)(const void *)(("caller-id-in-from") + 1
) - (size_t)(const void *)("caller-id-in-from") == 1) &&
(__s2_len = __builtin_strlen ("caller-id-in-from"), __s2_len
< 4) ? (__builtin_constant_p (var) && ((size_t)(const
void *)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "caller-id-in-from") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (var); int
__result = (((const unsigned char *) (const char *) ("caller-id-in-from"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("caller-id-in-from"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("caller-id-in-from"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("caller-id-in-from"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "caller-id-in-from")))); })
) {
3429 caller_id_in_from = val;
3430 } else if (!strcmp(var, "extension")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("extension") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("extension"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("extension") + 1) - (size_t)(const void
*)("extension") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "extension") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("extension") && ((size_t
)(const void *)(("extension") + 1) - (size_t)(const void *)("extension"
) == 1) ? __builtin_strcmp (var, "extension") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("extension"); int __result = (((const unsigned char
*) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("extension") && ((size_t)(const void *)(("extension"
) + 1) - (size_t)(const void *)("extension") == 1) &&
(__s2_len = __builtin_strlen ("extension"), __s2_len < 4)
? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "extension") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("extension"))[0]
- __s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("extension"))[1]
- __s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("extension"))[2]
- __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("extension"))[3]
- __s2[3]); } } __result; })))) : __builtin_strcmp (var, "extension"
)))); })
) {
3431 extension = val;
3432 } else if (!strcmp(var, "ping")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("ping") && (__s1_len
= __builtin_strlen (var), __s2_len = __builtin_strlen ("ping"
), (!((size_t)(const void *)((var) + 1) - (size_t)(const void
*)(var) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)(("ping") + 1) - (size_t)(const void *)("ping") == 1)
|| __s2_len >= 4)) ? __builtin_strcmp (var, "ping") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("ping") &&
((size_t)(const void *)(("ping") + 1) - (size_t)(const void *
)("ping") == 1) ? __builtin_strcmp (var, "ping") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("ping"); int __result = (((const unsigned char *) (
const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("ping") && ((size_t)(const void *)(("ping") + 1) - (
size_t)(const void *)("ping") == 1) && (__s2_len = __builtin_strlen
("ping"), __s2_len < 4) ? (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) ? __builtin_strcmp (var, "ping") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (var); int __result = (((const unsigned char *) (const
char *) ("ping"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("ping"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("ping"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("ping"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(var, "ping")))); })
) {
3433 ping_freq = atoi(val);
3434 } else if (!strcmp(var, "ping-max")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("ping-max") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("ping-max"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("ping-max") + 1) - (size_t)(const void
*)("ping-max") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "ping-max") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("ping-max") && ((size_t
)(const void *)(("ping-max") + 1) - (size_t)(const void *)("ping-max"
) == 1) ? __builtin_strcmp (var, "ping-max") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("ping-max"); int __result = (((const unsigned char *
) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("ping-max") && ((size_t)(const void *)(("ping-max")
+ 1) - (size_t)(const void *)("ping-max") == 1) && (
__s2_len = __builtin_strlen ("ping-max"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "ping-max") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("ping-max"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("ping-max"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("ping-max"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("ping-max"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (var, "ping-max"
)))); })
) {
3435 ping_max = atoi(val);
3436 } else if (!strcmp(var, "ping-min")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("ping-min") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("ping-min"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("ping-min") + 1) - (size_t)(const void
*)("ping-min") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "ping-min") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("ping-min") && ((size_t
)(const void *)(("ping-min") + 1) - (size_t)(const void *)("ping-min"
) == 1) ? __builtin_strcmp (var, "ping-min") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("ping-min"); int __result = (((const unsigned char *
) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("ping-min") && ((size_t)(const void *)(("ping-min")
+ 1) - (size_t)(const void *)("ping-min") == 1) && (
__s2_len = __builtin_strlen ("ping-min"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "ping-min") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("ping-min"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("ping-min"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("ping-min"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("ping-min"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (var, "ping-min"
)))); })
) {
3437 ping_min = atoi(val);
3438 } else if (!strcmp(var, "ping-user-agent")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("ping-user-agent") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("ping-user-agent"), (!((size_t)(const void *)((var) + 1) - (
size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("ping-user-agent") + 1) - (size_t
)(const void *)("ping-user-agent") == 1) || __s2_len >= 4)
) ? __builtin_strcmp (var, "ping-user-agent") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("ping-user-agent"
) && ((size_t)(const void *)(("ping-user-agent") + 1)
- (size_t)(const void *)("ping-user-agent") == 1) ? __builtin_strcmp
(var, "ping-user-agent") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("ping-user-agent"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("ping-user-agent"
) && ((size_t)(const void *)(("ping-user-agent") + 1)
- (size_t)(const void *)("ping-user-agent") == 1) &&
(__s2_len = __builtin_strlen ("ping-user-agent"), __s2_len <
4) ? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "ping-user-agent") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (var); int
__result = (((const unsigned char *) (const char *) ("ping-user-agent"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("ping-user-agent"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("ping-user-agent"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("ping-user-agent"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "ping-user-agent")))); })
) {
3439 options_user_agent = val;
3440 } else if (!strcmp(var, "ping-monitoring")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("ping-monitoring") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("ping-monitoring"), (!((size_t)(const void *)((var) + 1) - (
size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("ping-monitoring") + 1) - (size_t
)(const void *)("ping-monitoring") == 1) || __s2_len >= 4)
) ? __builtin_strcmp (var, "ping-monitoring") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("ping-monitoring"
) && ((size_t)(const void *)(("ping-monitoring") + 1)
- (size_t)(const void *)("ping-monitoring") == 1) ? __builtin_strcmp
(var, "ping-monitoring") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("ping-monitoring"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("ping-monitoring"
) && ((size_t)(const void *)(("ping-monitoring") + 1)
- (size_t)(const void *)("ping-monitoring") == 1) &&
(__s2_len = __builtin_strlen ("ping-monitoring"), __s2_len <
4) ? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "ping-monitoring") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (var); int
__result = (((const unsigned char *) (const char *) ("ping-monitoring"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("ping-monitoring"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("ping-monitoring"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("ping-monitoring"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "ping-monitoring")))); })
) { // if true then every gw ping result will fire a gateway status event
3441 ping_monitoring = switch_true(val);
3442 } else if (!strcmp(var, "proxy")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("proxy") && (
__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("proxy"), (!((size_t)(const void *)((var) + 1) - (size_t)(const
void *)(var) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)(("proxy") + 1) - (size_t)(const void *)("proxy"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (var, "proxy"
) : (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) &&
(__s1_len = __builtin_strlen (var), __s1_len < 4) ? (__builtin_constant_p
("proxy") && ((size_t)(const void *)(("proxy") + 1) -
(size_t)(const void *)("proxy") == 1) ? __builtin_strcmp (var
, "proxy") : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) ("proxy"); int __result = ((
(const unsigned char *) (const char *) (var))[0] - __s2[0]); if
(__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (var))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var))[3] - __s2[3]); } } __result; }))) :
(__builtin_constant_p ("proxy") && ((size_t)(const void
*)(("proxy") + 1) - (size_t)(const void *)("proxy") == 1) &&
(__s2_len = __builtin_strlen ("proxy"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "proxy") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("proxy"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("proxy"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("proxy"))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) ("proxy"))[3] - __s2
[3]); } } __result; })))) : __builtin_strcmp (var, "proxy")))
); })
) {
3443 proxy = val;
3444 } else if (!strcmp(var, "context")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("context") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("context"), (!((size_t)(const void *)((var) + 1) - (size_t)
(const void *)(var) == 1) || __s1_len >= 4) && (!(
(size_t)(const void *)(("context") + 1) - (size_t)(const void
*)("context") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "context") : (__builtin_constant_p (var) && ((
size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("context") && ((size_t
)(const void *)(("context") + 1) - (size_t)(const void *)("context"
) == 1) ? __builtin_strcmp (var, "context") : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) ("context"); int __result = (((const unsigned char *) (const
char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("context") && ((size_t)(const void *)(("context") +
1) - (size_t)(const void *)("context") == 1) && (__s2_len
= __builtin_strlen ("context"), __s2_len < 4) ? (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) ? __builtin_strcmp (var, "context"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("context"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("context"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("context"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("context"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (var, "context")))); })
) {
3445 context = val;
3446 } else if (!strcmp(var, "expire-seconds")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("expire-seconds") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("expire-seconds"), (!((size_t)(const void *)((var) + 1) - (
size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("expire-seconds") + 1) - (size_t)
(const void *)("expire-seconds") == 1) || __s2_len >= 4)) ?
__builtin_strcmp (var, "expire-seconds") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("expire-seconds"
) && ((size_t)(const void *)(("expire-seconds") + 1) -
(size_t)(const void *)("expire-seconds") == 1) ? __builtin_strcmp
(var, "expire-seconds") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("expire-seconds"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("expire-seconds"
) && ((size_t)(const void *)(("expire-seconds") + 1) -
(size_t)(const void *)("expire-seconds") == 1) && (__s2_len
= __builtin_strlen ("expire-seconds"), __s2_len < 4) ? (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) ? __builtin_strcmp (var, "expire-seconds"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("expire-seconds"))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("expire-seconds"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("expire-seconds"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("expire-seconds"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "expire-seconds")))); })
) {
3447 expire_seconds = val;
3448 } else if (!strcmp(var, "908-retry-seconds")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("908-retry-seconds") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("908-retry-seconds"), (!((size_t)(const void *)((var) + 1) -
(size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("908-retry-seconds") + 1) - (size_t
)(const void *)("908-retry-seconds") == 1) || __s2_len >= 4
)) ? __builtin_strcmp (var, "908-retry-seconds") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("908-retry-seconds"
) && ((size_t)(const void *)(("908-retry-seconds") + 1
) - (size_t)(const void *)("908-retry-seconds") == 1) ? __builtin_strcmp
(var, "908-retry-seconds") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("908-retry-seconds"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("908-retry-seconds"
) && ((size_t)(const void *)(("908-retry-seconds") + 1
) - (size_t)(const void *)("908-retry-seconds") == 1) &&
(__s2_len = __builtin_strlen ("908-retry-seconds"), __s2_len
< 4) ? (__builtin_constant_p (var) && ((size_t)(const
void *)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "908-retry-seconds") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (var); int
__result = (((const unsigned char *) (const char *) ("908-retry-seconds"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("908-retry-seconds"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("908-retry-seconds"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("908-retry-seconds"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "908-retry-seconds")))); })
) {
3449 fail_908_retry_seconds = val;
3450 } else if (!strcmp(var, "retry-seconds")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("retry-seconds") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("retry-seconds"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("retry-seconds") + 1) - (size_t)(const
void *)("retry-seconds") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "retry-seconds") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("retry-seconds") &&
((size_t)(const void *)(("retry-seconds") + 1) - (size_t)(const
void *)("retry-seconds") == 1) ? __builtin_strcmp (var, "retry-seconds"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("retry-seconds"); int __result = (((
const unsigned char *) (const char *) (var))[0] - __s2[0]); if
(__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (var))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var))[3] - __s2[3]); } } __result; }))) :
(__builtin_constant_p ("retry-seconds") && ((size_t)
(const void *)(("retry-seconds") + 1) - (size_t)(const void *
)("retry-seconds") == 1) && (__s2_len = __builtin_strlen
("retry-seconds"), __s2_len < 4) ? (__builtin_constant_p (
var) && ((size_t)(const void *)((var) + 1) - (size_t)
(const void *)(var) == 1) ? __builtin_strcmp (var, "retry-seconds"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("retry-seconds"))[0] - __s2[0]); if (
__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("retry-seconds"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("retry-seconds")
)[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("retry-seconds"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "retry-seconds")))); })
) {
3451 retry_seconds = val;
3452 } else if (!strcmp(var, "timeout-seconds")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("timeout-seconds") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("timeout-seconds"), (!((size_t)(const void *)((var) + 1) - (
size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("timeout-seconds") + 1) - (size_t
)(const void *)("timeout-seconds") == 1) || __s2_len >= 4)
) ? __builtin_strcmp (var, "timeout-seconds") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("timeout-seconds"
) && ((size_t)(const void *)(("timeout-seconds") + 1)
- (size_t)(const void *)("timeout-seconds") == 1) ? __builtin_strcmp
(var, "timeout-seconds") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("timeout-seconds"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("timeout-seconds"
) && ((size_t)(const void *)(("timeout-seconds") + 1)
- (size_t)(const void *)("timeout-seconds") == 1) &&
(__s2_len = __builtin_strlen ("timeout-seconds"), __s2_len <
4) ? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "timeout-seconds") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (var); int
__result = (((const unsigned char *) (const char *) ("timeout-seconds"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("timeout-seconds"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("timeout-seconds"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("timeout-seconds"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "timeout-seconds")))); })
) {
3453 timeout_seconds = val;
3454 } else if (!strcmp(var, "retry_seconds")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("retry_seconds") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("retry_seconds"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("retry_seconds") + 1) - (size_t)(const
void *)("retry_seconds") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "retry_seconds") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("retry_seconds") &&
((size_t)(const void *)(("retry_seconds") + 1) - (size_t)(const
void *)("retry_seconds") == 1) ? __builtin_strcmp (var, "retry_seconds"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("retry_seconds"); int __result = (((
const unsigned char *) (const char *) (var))[0] - __s2[0]); if
(__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (var))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var))[3] - __s2[3]); } } __result; }))) :
(__builtin_constant_p ("retry_seconds") && ((size_t)
(const void *)(("retry_seconds") + 1) - (size_t)(const void *
)("retry_seconds") == 1) && (__s2_len = __builtin_strlen
("retry_seconds"), __s2_len < 4) ? (__builtin_constant_p (
var) && ((size_t)(const void *)((var) + 1) - (size_t)
(const void *)(var) == 1) ? __builtin_strcmp (var, "retry_seconds"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("retry_seconds"))[0] - __s2[0]); if (
__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("retry_seconds"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("retry_seconds")
)[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("retry_seconds"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "retry_seconds")))); })
) { // support typo for back compat
3455 retry_seconds = val;
3456 } else if (!strcmp(var, "from-user")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("from-user") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("from-user"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("from-user") + 1) - (size_t)(const void
*)("from-user") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "from-user") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("from-user") && ((size_t
)(const void *)(("from-user") + 1) - (size_t)(const void *)("from-user"
) == 1) ? __builtin_strcmp (var, "from-user") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("from-user"); int __result = (((const unsigned char
*) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("from-user") && ((size_t)(const void *)(("from-user"
) + 1) - (size_t)(const void *)("from-user") == 1) &&
(__s2_len = __builtin_strlen ("from-user"), __s2_len < 4)
? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "from-user") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("from-user"))[0]
- __s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("from-user"))[1]
- __s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("from-user"))[2]
- __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("from-user"))[3]
- __s2[3]); } } __result; })))) : __builtin_strcmp (var, "from-user"
)))); })
) {
3457 from_user = val;
3458 } else if (!strcmp(var, "from-domain")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("from-domain") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("from-domain"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("from-domain") + 1) - (size_t)(const
void *)("from-domain") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "from-domain") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("from-domain") && (
(size_t)(const void *)(("from-domain") + 1) - (size_t)(const void
*)("from-domain") == 1) ? __builtin_strcmp (var, "from-domain"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("from-domain"); int __result = (((const
unsigned char *) (const char *) (var))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("from-domain") && ((size_t)(const void *)(("from-domain"
) + 1) - (size_t)(const void *)("from-domain") == 1) &&
(__s2_len = __builtin_strlen ("from-domain"), __s2_len < 4
) ? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "from-domain") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("from-domain"))[
0] - __s2[0]); if (__s2_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) ("from-domain"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("from-domain"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("from-domain"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "from-domain")))); })
) {
3459 from_domain = val;
3460 } else if (!strcmp(var, "contact-host")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("contact-host") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("contact-host"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("contact-host") + 1) - (size_t)(const
void *)("contact-host") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "contact-host") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("contact-host") && (
(size_t)(const void *)(("contact-host") + 1) - (size_t)(const
void *)("contact-host") == 1) ? __builtin_strcmp (var, "contact-host"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("contact-host"); int __result = (((const
unsigned char *) (const char *) (var))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("contact-host") && ((size_t)(const void *)(("contact-host"
) + 1) - (size_t)(const void *)("contact-host") == 1) &&
(__s2_len = __builtin_strlen ("contact-host"), __s2_len <
4) ? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "contact-host") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("contact-host"))
[0] - __s2[0]); if (__s2_len > 0 && __result == 0)
{ __result = (((const unsigned char *) (const char *) ("contact-host"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("contact-host"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("contact-host"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "contact-host")))); })
) {
3461 contact_host = val;
3462 } else if (!strcmp(var, "register-proxy")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("register-proxy") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("register-proxy"), (!((size_t)(const void *)((var) + 1) - (
size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("register-proxy") + 1) - (size_t)
(const void *)("register-proxy") == 1) || __s2_len >= 4)) ?
__builtin_strcmp (var, "register-proxy") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("register-proxy"
) && ((size_t)(const void *)(("register-proxy") + 1) -
(size_t)(const void *)("register-proxy") == 1) ? __builtin_strcmp
(var, "register-proxy") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("register-proxy"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("register-proxy"
) && ((size_t)(const void *)(("register-proxy") + 1) -
(size_t)(const void *)("register-proxy") == 1) && (__s2_len
= __builtin_strlen ("register-proxy"), __s2_len < 4) ? (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) ? __builtin_strcmp (var, "register-proxy"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("register-proxy"))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("register-proxy"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("register-proxy"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("register-proxy"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "register-proxy")))); })
) {
3463 register_proxy = val;
3464 } else if (!strcmp(var, "outbound-proxy")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("outbound-proxy") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("outbound-proxy"), (!((size_t)(const void *)((var) + 1) - (
size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("outbound-proxy") + 1) - (size_t)
(const void *)("outbound-proxy") == 1) || __s2_len >= 4)) ?
__builtin_strcmp (var, "outbound-proxy") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("outbound-proxy"
) && ((size_t)(const void *)(("outbound-proxy") + 1) -
(size_t)(const void *)("outbound-proxy") == 1) ? __builtin_strcmp
(var, "outbound-proxy") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("outbound-proxy"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("outbound-proxy"
) && ((size_t)(const void *)(("outbound-proxy") + 1) -
(size_t)(const void *)("outbound-proxy") == 1) && (__s2_len
= __builtin_strlen ("outbound-proxy"), __s2_len < 4) ? (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) ? __builtin_strcmp (var, "outbound-proxy"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("outbound-proxy"))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("outbound-proxy"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("outbound-proxy"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("outbound-proxy"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "outbound-proxy")))); })
) {
3465 outbound_proxy = val;
3466 } else if (!strcmp(var, "distinct-to")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("distinct-to") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("distinct-to"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("distinct-to") + 1) - (size_t)(const
void *)("distinct-to") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "distinct-to") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("distinct-to") && (
(size_t)(const void *)(("distinct-to") + 1) - (size_t)(const void
*)("distinct-to") == 1) ? __builtin_strcmp (var, "distinct-to"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("distinct-to"); int __result = (((const
unsigned char *) (const char *) (var))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("distinct-to") && ((size_t)(const void *)(("distinct-to"
) + 1) - (size_t)(const void *)("distinct-to") == 1) &&
(__s2_len = __builtin_strlen ("distinct-to"), __s2_len < 4
) ? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "distinct-to") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("distinct-to"))[
0] - __s2[0]); if (__s2_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) ("distinct-to"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("distinct-to"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("distinct-to"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "distinct-to")))); })
) {
3467 distinct_to = switch_true(val);
3468 } else if (!strcmp(var, "destination-prefix")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("destination-prefix")
&& (__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("destination-prefix"), (!((size_t)(const void *)((var) + 1)
- (size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("destination-prefix") + 1) - (size_t
)(const void *)("destination-prefix") == 1) || __s2_len >=
4)) ? __builtin_strcmp (var, "destination-prefix") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("destination-prefix"
) && ((size_t)(const void *)(("destination-prefix") +
1) - (size_t)(const void *)("destination-prefix") == 1) ? __builtin_strcmp
(var, "destination-prefix") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("destination-prefix"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("destination-prefix"
) && ((size_t)(const void *)(("destination-prefix") +
1) - (size_t)(const void *)("destination-prefix") == 1) &&
(__s2_len = __builtin_strlen ("destination-prefix"), __s2_len
< 4) ? (__builtin_constant_p (var) && ((size_t)(const
void *)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "destination-prefix") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (var); int
__result = (((const unsigned char *) (const char *) ("destination-prefix"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("destination-prefix"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("destination-prefix"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("destination-prefix"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "destination-prefix")))); })
) {
3469 if (!zstr(val)_zstr(val)) {
3470 gateway->destination_prefix = switch_core_strdup(gateway->pool, val)switch_core_perform_strdup(gateway->pool, val, "sofia.c", (
const char *)__func__, 3470)
;
3471 }
3472 } else if (!strcmp(var, "rfc-5626")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("rfc-5626") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("rfc-5626"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("rfc-5626") + 1) - (size_t)(const void
*)("rfc-5626") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "rfc-5626") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("rfc-5626") && ((size_t
)(const void *)(("rfc-5626") + 1) - (size_t)(const void *)("rfc-5626"
) == 1) ? __builtin_strcmp (var, "rfc-5626") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("rfc-5626"); int __result = (((const unsigned char *
) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("rfc-5626") && ((size_t)(const void *)(("rfc-5626")
+ 1) - (size_t)(const void *)("rfc-5626") == 1) && (
__s2_len = __builtin_strlen ("rfc-5626"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "rfc-5626") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("rfc-5626"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("rfc-5626"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("rfc-5626"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("rfc-5626"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (var, "rfc-5626"
)))); })
) {
3473 rfc_5626 = switch_true(val);
3474 } else if (!strcmp(var, "reg-id")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("reg-id") && (
__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("reg-id"), (!((size_t)(const void *)((var) + 1) - (size_t)(
const void *)(var) == 1) || __s1_len >= 4) && (!((
size_t)(const void *)(("reg-id") + 1) - (size_t)(const void *
)("reg-id") == 1) || __s2_len >= 4)) ? __builtin_strcmp (var
, "reg-id") : (__builtin_constant_p (var) && ((size_t
)(const void *)((var) + 1) - (size_t)(const void *)(var) == 1
) && (__s1_len = __builtin_strlen (var), __s1_len <
4) ? (__builtin_constant_p ("reg-id") && ((size_t)(const
void *)(("reg-id") + 1) - (size_t)(const void *)("reg-id") ==
1) ? __builtin_strcmp (var, "reg-id") : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
("reg-id"); int __result = (((const unsigned char *) (const char
*) (var))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
var))[1] - __s2[1]); if (__s1_len > 1 && __result ==
0) { __result = (((const unsigned char *) (const char *) (var
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("reg-id"
) && ((size_t)(const void *)(("reg-id") + 1) - (size_t
)(const void *)("reg-id") == 1) && (__s2_len = __builtin_strlen
("reg-id"), __s2_len < 4) ? (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) ? __builtin_strcmp (var, "reg-id") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (var); int __result = (((const unsigned char *) (const
char *) ("reg-id"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("reg-id"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("reg-id"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("reg-id"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(var, "reg-id")))); })
) {
3475 reg_id = val;
3476 } else if (!strcmp(var, "contact-params")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("contact-params") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("contact-params"), (!((size_t)(const void *)((var) + 1) - (
size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("contact-params") + 1) - (size_t)
(const void *)("contact-params") == 1) || __s2_len >= 4)) ?
__builtin_strcmp (var, "contact-params") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("contact-params"
) && ((size_t)(const void *)(("contact-params") + 1) -
(size_t)(const void *)("contact-params") == 1) ? __builtin_strcmp
(var, "contact-params") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("contact-params"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("contact-params"
) && ((size_t)(const void *)(("contact-params") + 1) -
(size_t)(const void *)("contact-params") == 1) && (__s2_len
= __builtin_strlen ("contact-params"), __s2_len < 4) ? (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) ? __builtin_strcmp (var, "contact-params"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("contact-params"))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("contact-params"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("contact-params"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("contact-params"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "contact-params")))); })
) {
3477 contact_params = val;
3478 } else if (!strcmp(var, "register-transport")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("register-transport")
&& (__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("register-transport"), (!((size_t)(const void *)((var) + 1)
- (size_t)(const void *)(var) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("register-transport") + 1) - (size_t
)(const void *)("register-transport") == 1) || __s2_len >=
4)) ? __builtin_strcmp (var, "register-transport") : (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) && (__s1_len = __builtin_strlen
(var), __s1_len < 4) ? (__builtin_constant_p ("register-transport"
) && ((size_t)(const void *)(("register-transport") +
1) - (size_t)(const void *)("register-transport") == 1) ? __builtin_strcmp
(var, "register-transport") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("register-transport"
); int __result = (((const unsigned char *) (const char *) (var
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (var)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (var))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("register-transport"
) && ((size_t)(const void *)(("register-transport") +
1) - (size_t)(const void *)("register-transport") == 1) &&
(__s2_len = __builtin_strlen ("register-transport"), __s2_len
< 4) ? (__builtin_constant_p (var) && ((size_t)(const
void *)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "register-transport") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (var); int
__result = (((const unsigned char *) (const char *) ("register-transport"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("register-transport"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("register-transport"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("register-transport"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "register-transport")))); })
) {
3479 sofia_transport_t transport = sofia_glue_str2transport(val);
3480
3481 if (transport == SOFIA_TRANSPORT_UNKNOWN || (!sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) && sofia_glue_transport_has_tls(transport))) {
3482 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3482
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: unsupported transport\n");
3483 goto skip;
3484 }
3485
3486 gateway->register_transport = transport;
3487 }
3488 }
3489
3490 /* RFC 5626 enable in the GW profile and the UA profile */
3491 if (rfc_5626 && sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626)((profile)->pflags[PFLAG_ENABLE_RFC5626] ? 1 : 0)) {
3492 char str_guid[su_guid_strlen + 1];
3493 su_guid_t guid[1];
3494 su_guid_generate(guid);
3495 su_guid_sprintf(str_guid, su_guid_strlen + 1, guid);
3496 str_rfc_5626 = switch_core_sprintf(gateway->pool, ";reg-id=%s;+sip.instance=\"<urn:uuid:%s>\"",reg_id,str_guid);
3497 }
3498
3499 if (zstr(realm)_zstr(realm)) {
3500 if (zstr(proxy)_zstr(proxy)) {
3501 realm = name;
3502 } else {
3503 realm = proxy;
3504 }
3505 }
3506
3507 if (switch_true(register_str)) {
3508 if (zstr(username)_zstr(username)) {
3509 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3509
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: username param is REQUIRED!\n");
3510 goto skip;
3511 }
3512
3513 if (zstr(password)_zstr(password)) {
3514 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3514
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: password param is REQUIRED!\n");
3515 goto skip;
3516 }
3517 } else {
3518 if (zstr(username)_zstr(username)) {
3519 username = "FreeSWITCH";
3520 }
3521
3522 if (zstr(password)_zstr(password)) {
3523 password = "";
3524 }
3525 }
3526
3527 if (zstr(from_user)_zstr(from_user)) {
3528 from_user = username;
3529 }
3530
3531 if (zstr(proxy)_zstr(proxy)) {
3532 proxy = realm;
3533 }
3534
3535 if (!switch_true(register_str)) {
3536 gateway->state = REG_STATE_NOREG;
3537 gateway->status = SOFIA_GATEWAY_UP;
3538 gateway->uptime = switch_time_now();
3539 }
3540
3541 if (zstr(auth_username)_zstr(auth_username)) {
3542 auth_username = username;
3543 }
3544
3545 if (!zstr(register_proxy)_zstr(register_proxy)) {
3546 if (strncasecmp(register_proxy, "sip:", 4) && strncasecmp(register_proxy, "sips:", 5)) {
3547 gateway->register_sticky_proxy = switch_core_sprintf(gateway->pool, "sip:%s", register_proxy);
3548 } else {
3549 gateway->register_sticky_proxy = switch_core_strdup(gateway->pool, register_proxy)switch_core_perform_strdup(gateway->pool, register_proxy, "sofia.c"
, (const char *)__func__, 3549)
;
3550 }
3551 }
3552
3553 if (!zstr(outbound_proxy)_zstr(outbound_proxy)) {
3554 if (strncasecmp(outbound_proxy, "sip:", 4) && strncasecmp(outbound_proxy, "sips:", 5)) {
3555 gateway->outbound_sticky_proxy = switch_core_sprintf(gateway->pool, "sip:%s", outbound_proxy);
3556 } else {
3557 gateway->outbound_sticky_proxy = switch_core_strdup(gateway->pool, outbound_proxy)switch_core_perform_strdup(gateway->pool, outbound_proxy, "sofia.c"
, (const char *)__func__, 3557)
;
3558 }
3559 }
3560
3561 gateway->retry_seconds = atoi(retry_seconds);
3562
3563 if (fail_908_retry_seconds) {
3564 gateway->fail_908_retry_seconds = atoi(fail_908_retry_seconds);
3565 }
3566
3567 if (gateway->retry_seconds < 5) {
3568 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3568
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid retry-seconds of %d on gateway %s, using the value of 30 instead.\n",
3569 gateway->retry_seconds, name);
3570 gateway->retry_seconds = 30;
3571 }
3572
3573 gateway->reg_timeout_seconds = atoi(timeout_seconds);
3574
3575 if (gateway->reg_timeout_seconds < 5) {
3576 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3576
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid timeout-seconds of %d on gateway %s, using the value of 60 instead.\n",
3577 gateway->reg_timeout_seconds, name);
3578 gateway->reg_timeout_seconds = 60;
3579 }
3580
3581
3582 gateway->register_scheme = switch_core_strdup(gateway->pool, scheme)switch_core_perform_strdup(gateway->pool, scheme, "sofia.c"
, (const char *)__func__, 3582)
;
3583 gateway->register_context = switch_core_strdup(gateway->pool, context)switch_core_perform_strdup(gateway->pool, context, "sofia.c"
, (const char *)__func__, 3583)
;
3584 gateway->register_realm = switch_core_strdup(gateway->pool, realm)switch_core_perform_strdup(gateway->pool, realm, "sofia.c"
, (const char *)__func__, 3584)
;
3585 gateway->register_username = switch_core_strdup(gateway->pool, username)switch_core_perform_strdup(gateway->pool, username, "sofia.c"
, (const char *)__func__, 3585)
;
3586 gateway->auth_username = switch_core_strdup(gateway->pool, auth_username)switch_core_perform_strdup(gateway->pool, auth_username, "sofia.c"
, (const char *)__func__, 3586)
;
3587 gateway->register_password = switch_core_strdup(gateway->pool, password)switch_core_perform_strdup(gateway->pool, password, "sofia.c"
, (const char *)__func__, 3587)
;
3588 gateway->distinct_to = distinct_to;
3589 gateway->options_user_agent = options_user_agent;
3590
3591 if (switch_true(caller_id_in_from)) {
3592 sofia_set_flag(gateway, REG_FLAG_CALLERID)(gateway)->flags[REG_FLAG_CALLERID] = 1;
3593 }
3594
3595 register_transport = (char *) sofia_glue_transport2str(gateway->register_transport);
3596
3597 if (! zstr(contact_params)_zstr(contact_params)) {
3598 if (*contact_params == ';') {
3599 params = switch_core_sprintf(gateway->pool, "%s;transport=%s;gw=%s", contact_params, register_transport, gateway->name);
3600 } else {
3601 params = switch_core_sprintf(gateway->pool, ";%s;transport=%s;gw=%s", contact_params, register_transport, gateway->name);
3602 }
3603 } else {
3604 params = switch_core_sprintf(gateway->pool, ";transport=%s;gw=%s", register_transport, gateway->name);
3605 }
3606
3607 if (!zstr(from_domain)_zstr(from_domain)) {
3608 gateway->from_domain = switch_core_strdup(gateway->pool, from_domain)switch_core_perform_strdup(gateway->pool, from_domain, "sofia.c"
, (const char *)__func__, 3608)
;
3609 }
3610
3611 if (!zstr(register_transport)_zstr(register_transport) && !switch_stristr("transport=", proxy)) {
3612 gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", proxy, register_transport);
3613 } else {
3614 gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
3615 }
3616
3617 gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s>",
3618 from_user, !zstr(from_domain)_zstr(from_domain) ? from_domain : proxy);
3619
3620 if (ping_freq) {
3621 if (ping_freq >= 5) {
3622 gateway->ping_freq = ping_freq;
3623 gateway->ping_max = ping_max;
3624 gateway->ping_min = ping_min;
3625 gateway->ping_monitoring = ping_monitoring;
3626 gateway->ping = switch_epoch_time_now(NULL((void*)0)) + ping_freq;
3627 gateway->options_to_uri = switch_core_sprintf(gateway->pool, "<sip:%s>",
3628 !zstr(from_domain)_zstr(from_domain) ? from_domain : proxy);
3629 gateway->options_from_uri = gateway->options_to_uri;
3630 } else {
3631 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3631
, ((void*)0)
, SWITCH_LOG_ERROR, "ERROR: invalid ping!\n");
3632 }
3633 }
3634
3635 if (contact_host) {
3636 if (!strcmp(contact_host, "sip-ip")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(contact_host) && __builtin_constant_p ("sip-ip") &&
(__s1_len = __builtin_strlen (contact_host), __s2_len = __builtin_strlen
("sip-ip"), (!((size_t)(const void *)((contact_host) + 1) - (
size_t)(const void *)(contact_host) == 1) || __s1_len >= 4
) && (!((size_t)(const void *)(("sip-ip") + 1) - (size_t
)(const void *)("sip-ip") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(contact_host, "sip-ip") : (__builtin_constant_p (contact_host
) && ((size_t)(const void *)((contact_host) + 1) - (size_t
)(const void *)(contact_host) == 1) && (__s1_len = __builtin_strlen
(contact_host), __s1_len < 4) ? (__builtin_constant_p ("sip-ip"
) && ((size_t)(const void *)(("sip-ip") + 1) - (size_t
)(const void *)("sip-ip") == 1) ? __builtin_strcmp (contact_host
, "sip-ip") : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) ("sip-ip"); int __result
= (((const unsigned char *) (const char *) (contact_host))[0
] - __s2[0]); if (__s1_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) (contact_host
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (contact_host
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (contact_host
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
"sip-ip") && ((size_t)(const void *)(("sip-ip") + 1) -
(size_t)(const void *)("sip-ip") == 1) && (__s2_len =
__builtin_strlen ("sip-ip"), __s2_len < 4) ? (__builtin_constant_p
(contact_host) && ((size_t)(const void *)((contact_host
) + 1) - (size_t)(const void *)(contact_host) == 1) ? __builtin_strcmp
(contact_host, "sip-ip") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (contact_host
); int __result = (((const unsigned char *) (const char *) ("sip-ip"
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("sip-ip"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("sip-ip"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("sip-ip"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (contact_host
, "sip-ip")))); })
) {
3637 sipip = profile->sipip;
3638 } else {
3639 sipip = contact_host;
3640 }
3641 } else if (profile->extsipip) {
3642 sipip = profile->extsipip;
3643 } else {
3644 sipip = profile->sipip;
3645 }
3646
3647 if (zstr(extension)_zstr(extension)) {
3648 extension = username;
3649 } else {
3650 gateway->real_extension = switch_core_strdup(gateway->pool, extension)switch_core_perform_strdup(gateway->pool, extension, "sofia.c"
, (const char *)__func__, 3650)
;
3651 }
3652
3653 gateway->extension = switch_core_strdup(gateway->pool, extension)switch_core_perform_strdup(gateway->pool, extension, "sofia.c"
, (const char *)__func__, 3653)
;
3654
3655 if (!strncasecmp(proxy, "sip:", 4)) {
3656 gateway->register_proxy = switch_core_strdup(gateway->pool, proxy)switch_core_perform_strdup(gateway->pool, proxy, "sofia.c"
, (const char *)__func__, 3656)
;
3657 gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy + 4);
3658 } else {
3659 gateway->register_proxy = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
3660 gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy);
3661 }
3662
3663 /* This checks to make sure we provide the right contact on register for targets behind nat with us. */
3664 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
3665 char *register_host = NULL((void*)0);
3666
3667 register_host = sofia_glue_get_register_host(gateway->register_proxy);
3668
3669 if (register_host && switch_is_lan_addr(register_host)) {
3670 sipip = profile->sipip;
3671 }
3672
3673 switch_safe_free(register_host)if (register_host) {free(register_host);register_host=((void*
)0);}
;
3674 }
3675
3676 if (extension_in_contact) {
3677 if (rfc_5626) {
3678 format = strchr(sipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(sipip) && (':') == '\0' ? (char *) __rawmemchr (sipip
, ':') : __builtin_strchr (sipip, ':')))
? "<sip:%s@[%s]:%d>%s" : "<sip:%s@%s:%d%s>%s";
3679 gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
3680 sipip,
3681 sofia_glue_transport_has_tls(gateway->register_transport) ?
3682 profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
3683
3684 } else {
3685 format = strchr(sipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(sipip) && (':') == '\0' ? (char *) __rawmemchr (sipip
, ':') : __builtin_strchr (sipip, ':')))
? "<sip:%s@[%s]:%d%s>" : "<sip:%s@%s:%d%s>";
3686 gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
3687 sipip,
3688 sofia_glue_transport_has_tls(gateway->register_transport) ?
3689 profile->tls_sip_port : profile->extsipport, params);
3690 }
3691 } else {
3692 if (rfc_5626) {
3693 format = strchr(sipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(sipip) && (':') == '\0' ? (char *) __rawmemchr (sipip
, ':') : __builtin_strchr (sipip, ':')))
? "<sip:gw+%s@[%s]:%d%s>%s" : "<sip:gw+%s@%s:%d%s>%s";
3694 gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
3695 sipip,
3696 sofia_glue_transport_has_tls(gateway->register_transport) ?
3697 profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
3698
3699 } else {
3700 format = strchr(sipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(sipip) && (':') == '\0' ? (char *) __rawmemchr (sipip
, ':') : __builtin_strchr (sipip, ':')))
? "<sip:gw+%s@[%s]:%d%s>" : "<sip:gw+%s@%s:%d%s>";
3701 gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
3702 sipip,
3703 sofia_glue_transport_has_tls(gateway->register_transport) ?
3704 profile->tls_sip_port : profile->extsipport, params);
3705
3706 }
3707 }
3708
3709 gateway->expires_str = switch_core_strdup(gateway->pool, expire_seconds)switch_core_perform_strdup(gateway->pool, expire_seconds, "sofia.c"
, (const char *)__func__, 3709)
;
3710
3711 if ((gateway->freq = atoi(gateway->expires_str)) < 5) {
3712 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3712
, ((void*)0)
, SWITCH_LOG_WARNING,
3713 "Invalid register-frequency of %d on gateway %s, using the value of 3600 instead\n", gateway->freq, name);
3714 gateway->freq = 3600;
3715 }
3716
3717 if ((gw_subs_tag = switch_xml_child(gateway_tag, "subscriptions"))) {
3718 parse_gateway_subscriptions(profile, gateway, gw_subs_tag);
3719 }
3720
3721 sofia_reg_add_gateway(profile, gateway->name, gateway);
3722
3723 }
3724
3725 skip:
3726 switch_assert(gateway_tag)((gateway_tag) ? (void) (0) : __assert_fail ("gateway_tag", "sofia.c"
, 3726, __PRETTY_FUNCTION__))
;
3727 }
3728}
3729
3730static void parse_domain_tag(sofia_profile_t *profile, switch_xml_t x_domain_tag, const char *dname, const char *parse, const char *alias)
3731{
3732 if (switch_true(alias)) {
3733 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, dname)switch_core_perform_strdup(profile->pool, dname, "sofia.c"
, (const char *)__func__, 3733)
, profile) == SWITCH_STATUS_SUCCESS) {
3734 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3734
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", dname, profile->name);
3735 } else {
3736 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3736
, ((void*)0)
, SWITCH_LOG_DEBUG1, "Alias [%s] for profile [%s] (already exists)\n", dname, profile->name);
3737 }
3738 }
3739
3740 if (switch_true(parse)) {
3741 switch_xml_t gts, gt, uts, ut, gateways_tag;
3742 /* Backwards Compatibility */
3743 for (ut = switch_xml_child(x_domain_tag, "user"); ut; ut = ut->next) {
3744 if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
3745 parse_gateways(profile, gateways_tag);
3746 }
3747 }
3748 /* New Method with <groups> tags and users are now inside a <users> tag */
3749 for (gts = switch_xml_child(x_domain_tag, "groups"); gts; gts = gts->next) {
3750 for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
3751 for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
3752 for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
3753 if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
3754 parse_gateways(profile, gateways_tag);
3755 }
3756 }
3757 }
3758 }
3759 }
3760 }
3761}
3762
3763static void config_sofia_profile_urls(sofia_profile_t * profile)
3764{
3765
3766 if (profile->extsipip) {
3767 char *ipv6 = strchr(profile->extsipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->extsipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->extsipip, ':') : __builtin_strchr (profile->
extsipip, ':')))
;
3768 profile->public_url = switch_core_sprintf(profile->pool,
3769 "sip:%s@%s%s%s:%d",
3770 profile->contact_user,
3771 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
3772 }
3773
3774 if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
3775 char *ipv6 = strchr(profile->extsipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->extsipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->extsipip, ':') : __builtin_strchr (profile->
extsipip, ':')))
;
3776 profile->url = switch_core_sprintf(profile->pool,
3777 "sip:%s@%s%s%s:%d",
3778 profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
3779 profile->bindurl = switch_core_sprintf(profile->pool, "%s;maddr=%s", profile->url, profile->sipip);
3780 } else {
3781 char *ipv6 = strchr(profile->sipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))
;
3782 profile->url = switch_core_sprintf(profile->pool,
3783 "sip:%s@%s%s%s:%d",
3784 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->sip_port);
3785 profile->bindurl = profile->url;
3786 }
3787
3788 profile->tcp_contact = switch_core_sprintf(profile->pool, "<%s;transport=tcp>", profile->url);
3789
3790 if (profile->public_url) {
3791 profile->tcp_public_contact = switch_core_sprintf(profile->pool, "<%s;transport=tcp>", profile->public_url);
3792 }
3793
3794 if (profile->bind_params) {
3795 char *bindurl;
3796 if (!switch_stristr("transport=", profile->bind_params)) {
3797 profile->bind_params = switch_core_sprintf(profile->pool, "%s;transport=udp,tcp", profile->bind_params);
3798 }
3799 bindurl = switch_core_sprintf(profile->pool, "%s;%s", profile->bindurl, profile->bind_params);
3800 profile->bindurl = bindurl;
3801 } else {
3802 char *bindurl = switch_core_sprintf(profile->pool, "%s;transport=udp,tcp", profile->bindurl);
3803 profile->bindurl = bindurl;
3804 }
3805
3806
3807 if ( profile->ws_port ) {
3808 char *ip = !zstr(profile->ws_ip)_zstr(profile->ws_ip) ? profile->ws_ip : profile->sipip;
3809 switch_port_t port = profile->ws_port;
3810 char *ipv6 = strchr(ip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(ip) && (':') == '\0' ? (char *) __rawmemchr (ip, ':'
) : __builtin_strchr (ip, ':')))
;
3811 profile->ws_bindurl =
3812 switch_core_sprintf(profile->pool,
3813 "sip:%s@%s%s%s:%d;transport=ws",
3814 profile->contact_user, ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
3815 }
3816
3817 if ( profile->wss_port ) {
3818 char *ip = !zstr(profile->wss_ip)_zstr(profile->wss_ip) ? profile->wss_ip : profile->sipip;
3819 switch_port_t port = profile->wss_port;
3820 char *ipv6 = strchr(ip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(ip) && (':') == '\0' ? (char *) __rawmemchr (ip, ':'
) : __builtin_strchr (ip, ':')))
;
3821 profile->wss_bindurl =
3822 switch_core_sprintf(profile->pool,
3823 "sips:%s@%s%s%s:%d;transport=wss",
3824 profile->contact_user, ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
3825 }
3826
3827 /*
3828 * handle TLS params #2
3829 */
3830 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
3831 if (!profile->tls_sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] ? 1 : 0)) {
3832 profile->tls_sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_TLS_PORT"5061");
3833 }
3834
3835 if (profile->extsipip) {
3836 char *ipv6 = strchr(profile->extsipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->extsipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->extsipip, ':') : __builtin_strchr (profile->
extsipip, ':')))
;
3837 profile->tls_public_url = switch_core_sprintf(profile->pool,
3838 "sip:%s@%s%s%s:%d",
3839 profile->contact_user,
3840 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port);
3841 }
3842
3843 if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)((profile)->pflags[PFLAG_AUTO_NAT] ? 1 : 0)) {
3844 char *ipv6 = strchr(profile->extsipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->extsipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->extsipip, ':') : __builtin_strchr (profile->
extsipip, ':')))
;
3845 profile->tls_url =
3846 switch_core_sprintf(profile->pool,
3847 "sip:%s@%s%s%s:%d",
3848 profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port);
3849 profile->tls_bindurl =
3850 switch_core_sprintf(profile->pool,
3851 "sips:%s@%s%s%s:%d;maddr=%s",
3852 profile->contact_user,
3853 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port, profile->sipip);
3854 } else {
3855 char *ipv6 = strchr(profile->sipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))
;
3856 profile->tls_url =
3857 switch_core_sprintf(profile->pool,
3858 "sip:%s@%s%s%s:%d",
3859 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->tls_sip_port);
3860 profile->tls_bindurl =
3861 switch_core_sprintf(profile->pool,
3862 "sips:%s@%s%s%s:%d",
3863 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->tls_sip_port);
3864 }
3865
3866 if (profile->tls_bind_params) {
3867 char *tls_bindurl = profile->tls_bindurl;
3868 profile->tls_bindurl = switch_core_sprintf(profile->pool, "%s;%s", tls_bindurl, profile->tls_bind_params);
3869 }
3870
3871 profile->tls_contact = switch_core_sprintf(profile->pool, "<%s;transport=tls>", profile->tls_url);
3872 if (profile->tls_public_url) {
3873 profile->tls_public_contact = switch_core_sprintf(profile->pool, "<%s;transport=tls>", profile->tls_public_url);
3874 }
3875
3876
3877 }
3878}
3879
3880#ifdef SOFIA_CUSTOM_TIME
3881/* appears to not be granular enough */
3882static void sofia_time(su_time_t *tv)
3883{
3884 switch_time_t now;
3885
3886 if (tv) {
3887 now = switch_micro_time_now();
3888 tv->tv_sec = ((uint32_t) (now / 1000000)) + 2208988800UL;
3889 tv->tv_usec = (uint32_t) (now % 1000000);
3890 }
3891
3892}
3893#endif
3894
3895switch_status_t sofia_init(void)
3896{
3897 su_init();
3898 if (sip_update_default_mclass(sip_extend_mclass(NULL((void*)0))) < 0) {
3899 su_deinit();
3900 return SWITCH_STATUS_GENERR;
3901 }
3902
3903#ifdef SOFIA_TIME
3904 su_set_time_func(sofia_time);
3905#endif
3906
3907 /* Redirect loggers in sofia */
3908 su_log_redirect(su_log_default, logger, NULL((void*)0));
3909 su_log_redirect(tport_log, logger, NULL((void*)0));
3910 su_log_redirect(iptsec_log, logger, NULL((void*)0));
3911 su_log_redirect(nea_log, logger, NULL((void*)0));
3912 su_log_redirect(nta_log, logger, NULL((void*)0));
3913 su_log_redirect(nth_client_log, logger, NULL((void*)0));
3914 su_log_redirect(nth_server_log, logger, NULL((void*)0));
3915 su_log_redirect(nua_log, logger, NULL((void*)0));
3916 su_log_redirect(soa_log, logger, NULL((void*)0));
3917 su_log_redirect(sresolv_log, logger, NULL((void*)0));
3918#ifdef HAVE_SOFIA_STUN
3919 su_log_redirect(stun_log, logger, NULL((void*)0));
3920#endif
3921
3922 return SWITCH_STATUS_SUCCESS;
3923}
3924
3925
3926switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
3927{
3928 char *cf = "sofia.conf";
3929 switch_xml_t cfg, xml = NULL((void*)0), xprofile, param, settings, profiles;
3930 switch_status_t status = SWITCH_STATUS_SUCCESS;
3931 sofia_profile_t *profile = NULL((void*)0);
3932 char url[512] = "";
3933 int profile_found = 0;
3934 switch_event_t *params = NULL((void*)0);
3935 sofia_profile_t *profile_already_started = NULL((void*)0);
3936
3937 if (!zstr(profile_name)_zstr(profile_name) && (profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia.c", (const char *)__func__, 3937
, profile_name)
)) {
3938 if (reload == SOFIA_CONFIG_RESCAN) {
3939 profile_already_started = profile;
3940 } else {
3941 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3941
, ((void*)0)
, SWITCH_LOG_WARNING, "Profile [%s] Already exists.\n", switch_str_nil(profile_name)(profile_name ? profile_name : ""));
3942 status = SWITCH_STATUS_FALSE;
3943 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 3943, profile)
;
3944 return status;
3945 }
3946 }
3947
3948 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 3948, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
3949 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "sofia.c", 3949
, __PRETTY_FUNCTION__))
;
3950 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile_name);
3951 if (reload == SOFIA_CONFIG_RESCAN) {
3952 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true");
3953 }
3954
3955 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
3956 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3956
, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
3957 status = SWITCH_STATUS_FALSE;
3958 goto done;
3959 }
3960
3961 mod_sofia_globals.auto_restart = SWITCH_TRUE;
3962 mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = SWITCH_FALSE; /* handle backwards compatilibity - by default use new behavior */
3963 mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
3964
3965 if ((settings = switch_xml_child(cfg, "global_settings"))) {
3966 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
3967 char *var = (char *) switch_xml_attr_soft(param, "name");
3968 char *val = (char *) switch_xml_attr_soft(param, "value");
3969 if (!strcasecmp(var, "log-level")) {
3970 su_log_set_level(NULL((void*)0), atoi(val));
3971 } else if (!strcasecmp(var, "tracelevel")) {
3972 mod_sofia_globals.tracelevel = switch_log_str2level(val);
3973 } else if (!strcasecmp(var, "debug-presence")) {
3974 mod_sofia_globals.debug_presence = atoi(val);
3975 } else if (!strcasecmp(var, "debug-sla")) {
3976 mod_sofia_globals.debug_sla = atoi(val);
3977 } else if (!strcasecmp(var, "max-reg-threads") && val) {
3978 int x = atoi(val);
3979
3980 if (x > 0) {
3981 mod_sofia_globals.max_reg_threads = x;
3982 }
3983
3984 } else if (!strcasecmp(var, "auto-restart")) {
3985 mod_sofia_globals.auto_restart = switch_true(val);
3986 } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
3987 mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
3988 if (switch_true(val)) {
3989 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 3989
, ((void*)0)
, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
3990 "deprecated and will be removed - let FS devs know if you think it should stay\n");
3991 }
3992 } else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
3993 if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) {
3994 /* old behaviour */
3995 mod_sofia_globals.rewrite_multicasted_fs_path = 1;
3996 } else if (!strcasecmp(val, "original_server_host")) {
3997 mod_sofia_globals.rewrite_multicasted_fs_path = 2;
3998 } else if (!strcasecmp(val, "original_hostname")) {
3999 mod_sofia_globals.rewrite_multicasted_fs_path = 3;
4000 } else {
4001 mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
4002 }
4003 } else if (!strcasecmp(var, "capture-server")) {
4004 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__, 4004)
;
4005 }
4006 }
4007 }
4008
4009 if ((profiles = switch_xml_child(cfg, "profiles"))) {
4010 for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
4011 char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name");
4012 char *xprofiledomain = (char *) switch_xml_attr(xprofile, "domain");
4013 if (!(settings = switch_xml_child(xprofile, "settings"))) {
4014 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4014
, ((void*)0)
, SWITCH_LOG_ERROR, "No Settings, check the new config!\n");
4015 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4015)
;
4016 } else {
4017 switch_memory_pool_t *pool = NULL((void*)0);
4018
4019 if (!xprofilename) {
4020 xprofilename = "unnamed";
4021 }
4022
4023 if (profile_name) {
4024 if (strcasecmp(profile_name, xprofilename)) {
4025 continue;
4026 } else {
4027 profile_found = 1;
4028 }
4029 }
4030
4031 if (!profile_already_started) {
4032
4033 /* Setup the pool */
4034 if ((status = switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "sofia.c", (const
char *)__func__, 4034)
) != SWITCH_STATUS_SUCCESS) {
4035 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4035
, ((void*)0)
, SWITCH_LOG_CRIT, "Memory Error!\n");
4036 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4036)
;
4037 goto done;
4038 }
4039
4040 if (!(profile = (sofia_profile_t *) switch_core_alloc(pool, sizeof(*profile))switch_core_perform_alloc(pool, sizeof(*profile), "sofia.c", (
const char *)__func__, 4040)
)) {
4041 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4041
, ((void*)0)
, SWITCH_LOG_ERROR, "Memory Error!\n");
4042 sofia_profile_start_failure(NULL, xprofilename)sofia_perform_profile_start_failure(((void*)0), xprofilename,
"sofia.c", 4042)
;
4043 goto done;
4044 }
4045
4046 profile->tls_verify_policy = TPTLS_VERIFY_NONE;
4047 /* lib default */
4048 profile->tls_verify_depth = 2;
4049
4050
4051 switch_mutex_init(&profile->gw_mutex, SWITCH_MUTEX_NESTED0x1, pool);
4052
4053 profile->trans_timeout = 100;
4054
4055 profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
4056
4057 profile->pool = pool;
4058
4059 profile->user_agent = switch_core_sprintf(profile->pool, "FreeSWITCH-mod_sofia/%s", switch_version_full());
4060
4061 profile->sip_user_ping_max = 3;
4062 profile->sip_user_ping_min = 1;
4063
4064 profile->name = switch_core_strdup(profile->pool, xprofilename)switch_core_perform_strdup(profile->pool, xprofilename, "sofia.c"
, (const char *)__func__, 4064)
;
4065 switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
4066
4067 if (xprofiledomain) {
4068 profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain)switch_core_perform_strdup(profile->pool, xprofiledomain, "sofia.c"
, (const char *)__func__, 4068)
;
4069 }
4070
4071 profile->dbname = switch_core_strdup(profile->pool, url)switch_core_perform_strdup(profile->pool, url, "sofia.c", (
const char *)__func__, 4071)
;
4072 switch_core_hash_init(&profile->chat_hash)switch_core_hash_init_case(&profile->chat_hash, SWITCH_TRUE
)
;
4073 switch_core_hash_init(&profile->reg_nh_hash)switch_core_hash_init_case(&profile->reg_nh_hash, SWITCH_TRUE
)
;
4074 switch_core_hash_init(&profile->mwi_debounce_hash)switch_core_hash_init_case(&profile->mwi_debounce_hash
, SWITCH_TRUE)
;
4075 switch_thread_rwlock_create(&profile->rwlock, profile->pool);
4076 switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED0x1, profile->pool);
4077 profile->dtmf_duration = 100;
4078 profile->rtp_digit_delay = 40;
4079 profile->sip_force_expires = 0;
4080 profile->sip_expires_max_deviation = 0;
4081 profile->sip_expires_late_margin = 60;
4082 profile->sip_subscription_max_deviation = 0;
4083 profile->tls_ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
4084 profile->tls_version = SOFIA_TLS_VERSION_TLSv1;
4085 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_1;
4086 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
4087 profile->tls_timeout = 300;
4088 profile->mflags = MFLAG_REFER | MFLAG_REGISTER;
4089 profile->server_rport_level = 1;
4090 profile->client_rport_level = 1;
4091 profile->tls_cert_dir = SWITCH_GLOBAL_dirs.certs_dir;
4092 sofia_set_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 1;
4093 sofia_set_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 1;
4094 profile->auto_restart = 1;
4095 sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 1;
4096 sofia_set_media_flag(profile, SCMF_RENEG_ON_REINVITE)(profile)->media_flags[SCMF_RENEG_ON_REINVITE] = 1;
4097 sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE)(profile)->media_flags[SCMF_RTP_AUTOFLUSH_DURING_BRIDGE] =
1
;
4098 profile->contact_user = SOFIA_DEFAULT_CONTACT_USER"mod_sofia";
4099 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
4100 sofia_set_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 1;
4101 sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 1;
4102 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
1
;
4103 //sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
4104
4105 profile->shutdown_type = "false";
4106 profile->local_network = "localnet.auto";
4107 sofia_set_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 1;
4108 sofia_set_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 1;
4109 profile->mndlb |= SM_NDLB_ALLOW_NONDUP_SDP;
4110 profile->te = 101;
4111 profile->ireg_seconds = IREG_SECONDS30;
4112 profile->iping_seconds = IPING_SECONDS30;
4113 profile->iping_freq = IPING_FREQUENCY1;
4114 profile->paid_type = PAID_DEFAULT;
4115 profile->bind_attempts = 2;
4116 profile->bind_attempt_interval = 5;
4117
4118 profile->tls_verify_policy = TPTLS_VERIFY_NONE;
4119 /* lib default */
4120 profile->tls_verify_depth = 2;
4121 profile->tls_verify_date = SWITCH_TRUE;
4122 } else {
4123
4124 /* you could change profile->foo here if it was a minor change like context or dialplan ... */
4125 profile->acl_count = 0;
4126 profile->nat_acl_count = 0;
4127 profile->reg_acl_count = 0;
4128 profile->proxy_acl_count = 0;
4129 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
4130 profile->ib_calls = 0;
4131 profile->ob_calls = 0;
4132 profile->ib_failed_calls = 0;
4133 profile->ob_failed_calls = 0;
4134 profile->shutdown_type = "false";
4135 profile->rtpip_index = 0;
4136
4137 if (xprofiledomain) {
4138 profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain)switch_core_perform_strdup(profile->pool, xprofiledomain, "sofia.c"
, (const char *)__func__, 4138)
;
4139 }
4140 }
4141
4142 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
4143 char *var = (char *) switch_xml_attr_soft(param, "name");
4144 char *val = (char *) switch_xml_attr_soft(param, "value");
4145
4146 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4146
, ((void*)0)
, SWITCH_LOG_DEBUG, "%s [%s]\n", var, val);
4147
4148 if (!strcasecmp(var, "debug")) {
4149 profile->debug = atoi(val);
4150 } else if (!strcasecmp(var, "parse-invite-tel-params")) {
4151 profile->parse_invite_tel_params = switch_true(val);
4152 } else if (!strcasecmp(var, "keepalive-method")) {
4153 if (!zstr(val)_zstr(val)) {
4154 if (!strcasecmp(val, "info")) {
4155 profile->keepalive = KA_INFO;
4156 } else {
4157 profile->keepalive = KA_MESSAGE;
4158 }
4159 }
4160 } else if (!strcasecmp(var, "bind-attempts") && val) {
4161 int ba = atoi(val) - 1;
4162
4163 if (ba >= 0) {
4164 profile->bind_attempts = ba;
4165 }
4166 } else if (!strcasecmp(var, "bind-attempt-interval") && val) {
4167 int bai = atoi(val);
4168
4169 if (bai >= 0) {
4170 profile->bind_attempt_interval = bai;
4171 }
4172 } else if (!strcasecmp(var, "shutdown-on-fail")) {
4173 profile->shutdown_type = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4173)
;
4174 } else if (!strcasecmp(var, "sip-trace")) {
4175 if (switch_true(val)) {
4176 sofia_set_flag(profile, TFLAG_TPORT_LOG)(profile)->flags[TFLAG_TPORT_LOG] = 1;
4177 } else {
4178 sofia_clear_flag(profile, TFLAG_TPORT_LOG)(profile)->flags[TFLAG_TPORT_LOG] = 0;
4179 }
4180 } else if (!strcasecmp(var, "sip-capture")) {
4181 if (switch_true(val)) {
4182 sofia_set_flag(profile, TFLAG_CAPTURE)(profile)->flags[TFLAG_CAPTURE] = 1;
4183 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);
4184 } else {
4185 sofia_clear_flag(profile, TFLAG_CAPTURE)(profile)->flags[TFLAG_CAPTURE] = 0;
4186 }
4187 } else if (!strcasecmp(var, "socket-tcp-keepalive") && !zstr(val)_zstr(val)) {
4188 profile->socket_tcp_keepalive = atoi(val);
4189 sofia_set_pflag(profile, PFLAG_SOCKET_TCP_KEEPALIVE)(profile)->pflags[PFLAG_SOCKET_TCP_KEEPALIVE] = 1;
4190 } else if (!strcasecmp(var, "tcp-keepalive") && !zstr(val)_zstr(val)) {
4191 profile->tcp_keepalive = atoi(val);
4192 sofia_set_pflag(profile, PFLAG_TCP_KEEPALIVE)(profile)->pflags[PFLAG_TCP_KEEPALIVE] = 1;
4193 } else if (!strcasecmp(var, "tcp-pingpong") && !zstr(val)_zstr(val)) {
4194 profile->tcp_pingpong = atoi(val);
4195 sofia_set_pflag(profile, PFLAG_TCP_PINGPONG)(profile)->pflags[PFLAG_TCP_PINGPONG] = 1;
4196 } else if (!strcasecmp(var, "tcp-ping2pong") && !zstr(val)_zstr(val)) {
4197 profile->tcp_ping2pong = atoi(val);
4198 sofia_set_pflag(profile, PFLAG_TCP_PING2PONG)(profile)->pflags[PFLAG_TCP_PING2PONG] = 1;
4199 } else if ((!strcasecmp(var, "proxy-refer-replaces") || !strcasecmp(var, "proxy-refer")) && !zstr(val)_zstr(val)) {
4200 if (switch_true(val)) {
4201 sofia_set_pflag(profile, PFLAG_PROXY_REFER)(profile)->pflags[PFLAG_PROXY_REFER] = 1;
4202 } else {
4203 sofia_clear_pflag(profile, PFLAG_PROXY_REFER)(profile)->pflags[PFLAG_PROXY_REFER] = 0;
4204 }
4205 } else if (!strcasecmp(var, "sip-messages-respond-200-ok") && !zstr(val)_zstr(val)) {
4206 if (switch_true(val)) {
4207 sofia_set_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK)(profile)->pflags[PFLAG_MESSAGES_RESPOND_200_OK] = 1;
4208 } else {
4209 sofia_clear_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK)(profile)->pflags[PFLAG_MESSAGES_RESPOND_200_OK] = 0;
4210 }
4211 } else if (!strcasecmp(var, "sip-subscribe-respond-200-ok") && !zstr(val)_zstr(val)) {
4212 if (switch_true(val)) {
4213 sofia_set_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK)(profile)->pflags[PFLAG_SUBSCRIBE_RESPOND_200_OK] = 1;
4214 } else {
4215 sofia_clear_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK)(profile)->pflags[PFLAG_SUBSCRIBE_RESPOND_200_OK] = 0;
4216 }
4217 } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)_zstr(val)) {
4218 profile->odbc_dsn = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4218)
;
4219 } else if (!strcasecmp(var, "db-pre-trans-execute") && !zstr(val)_zstr(val)) {
4220 profile->pre_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4220)
;
4221 } else if (!strcasecmp(var, "db-post-trans-execute") && !zstr(val)_zstr(val)) {
4222 profile->post_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4222)
;
4223 } else if (!strcasecmp(var, "db-inner-pre-trans-execute") && !zstr(val)_zstr(val)) {
4224 profile->inner_pre_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4224)
;
4225 } else if (!strcasecmp(var, "db-inner-post-trans-execute") && !zstr(val)_zstr(val)) {
4226 profile->inner_post_trans_execute = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4226)
;
4227 } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) {
4228 if (switch_true(val)) {
4229 sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)(profile)->pflags[PFLAG_FORWARD_MWI_NOTIFY] = 1;
4230 } else {
4231 sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)(profile)->pflags[PFLAG_FORWARD_MWI_NOTIFY] = 0;
4232 }
4233 } else if (!strcasecmp(var, "NDLB-proxy-never-patch-reinvites")) {
4234 if (switch_true(val)) {
4235 profile->mndlb |= SM_NDLB_NEVER_PATCH_REINVITE;
4236 } else {
4237 profile->mndlb &= ~SM_NDLB_NEVER_PATCH_REINVITE;
4238 }
4239 } else if (!strcasecmp(var, "registration-thread-frequency")) {
4240 profile->ireg_seconds = atoi(val);
4241 if (profile->ireg_seconds < 0) {
4242 profile->ireg_seconds = IREG_SECONDS30;
4243 }
4244 } else if (!strcasecmp(var, "ping-mean-interval")) {
4245 profile->iping_seconds = atoi(val);
4246 if (profile->iping_seconds < 0) {
4247 profile->iping_seconds = IPING_SECONDS30;
4248 }
4249 } else if (!strcasecmp(var, "ping-thread-frequency")) {
4250 profile->iping_freq = atoi(val);
4251 if (profile->iping_freq < 0) {
4252 profile->iping_freq = IPING_FREQUENCY1;
4253 }
4254 } else if (!strcasecmp(var, "user-agent-string")) {
4255 profile->user_agent = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4255)
;
4256 } else if (!strcasecmp(var, "auto-restart")) {
4257 profile->auto_restart = switch_true(val);
4258 } else if (!strcasecmp(var, "log-auth-failures")) {
4259 if (switch_true(val)) {
4260 sofia_set_pflag(profile, PFLAG_LOG_AUTH_FAIL)(profile)->pflags[PFLAG_LOG_AUTH_FAIL] = 1;
4261 } else {
4262 sofia_clear_pflag(profile, PFLAG_LOG_AUTH_FAIL)(profile)->pflags[PFLAG_LOG_AUTH_FAIL] = 0;
4263 }
4264 } else if (!strcasecmp(var, "confirm-blind-transfer")) {
4265 if (switch_true(val)) {
4266 sofia_set_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)(profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] = 1;
4267 } else {
4268 sofia_clear_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)(profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] = 0;
4269 }
4270 } else if (!strcasecmp(var, "allow-update")) {
4271 if (switch_true(val)) {
4272 sofia_set_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 1;
4273 } else {
4274 sofia_clear_pflag(profile, PFLAG_ALLOW_UPDATE)(profile)->pflags[PFLAG_ALLOW_UPDATE] = 0;
4275 }
4276 } else if (!strcasecmp(var, "send-display-update")) {
4277 if (switch_true(val)) {
4278 sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 1;
4279 } else {
4280 sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 0;
4281 }
4282 } else if (!strcasecmp(var, "mwi-use-reg-callid")) {
4283 if (switch_true(val)) {
4284 sofia_set_pflag(profile, PFLAG_MWI_USE_REG_CALLID)(profile)->pflags[PFLAG_MWI_USE_REG_CALLID] = 1;
4285 } else {
4286 sofia_clear_pflag(profile, PFLAG_MWI_USE_REG_CALLID)(profile)->pflags[PFLAG_MWI_USE_REG_CALLID] = 0;
4287 }
4288 } else if (!strcasecmp(var, "tcp-unreg-on-socket-close")) {
4289 if (switch_true(val)) {
4290 sofia_set_pflag(profile, PFLAG_TCP_UNREG_ON_SOCKET_CLOSE)(profile)->pflags[PFLAG_TCP_UNREG_ON_SOCKET_CLOSE] = 1;
4291 } else {
4292 sofia_clear_pflag(profile, PFLAG_TCP_UNREG_ON_SOCKET_CLOSE)(profile)->pflags[PFLAG_TCP_UNREG_ON_SOCKET_CLOSE] = 0;
4293 }
4294 } else if (!strcasecmp(var, "tcp-always-nat")) {
4295 if (switch_true(val)) {
4296 sofia_set_pflag(profile, PFLAG_TCP_ALWAYS_NAT)(profile)->pflags[PFLAG_TCP_ALWAYS_NAT] = 1;
4297 } else {
4298 sofia_clear_pflag(profile, PFLAG_TCP_ALWAYS_NAT)(profile)->pflags[PFLAG_TCP_ALWAYS_NAT] = 0;
4299 }
4300 } else if (!strcasecmp(var, "tls-always-nat")) {
4301 if (switch_true(val)) {
4302 sofia_set_pflag(profile, PFLAG_TCP_ALWAYS_NAT)(profile)->pflags[PFLAG_TCP_ALWAYS_NAT] = 1;
4303 } else {
4304 sofia_clear_pflag(profile, PFLAG_TCP_ALWAYS_NAT)(profile)->pflags[PFLAG_TCP_ALWAYS_NAT] = 0;
4305 }
4306 } else if (!strcasecmp(var, "presence-proto-lookup")) {
4307 if (switch_true(val)) {
4308 sofia_set_pflag(profile, PFLAG_PRESENCE_MAP)(profile)->pflags[PFLAG_PRESENCE_MAP] = 1;
4309 } else {
4310 sofia_clear_pflag(profile, PFLAG_PRESENCE_MAP)(profile)->pflags[PFLAG_PRESENCE_MAP] = 0;
4311 }
4312 } else if (!strcasecmp(var, "profile-standby")) {
4313 if (switch_true(val)) {
4314 sofia_set_pflag(profile, PFLAG_STANDBY)(profile)->pflags[PFLAG_STANDBY] = 1;
4315 } else {
4316 sofia_clear_pflag(profile, PFLAG_STANDBY)(profile)->pflags[PFLAG_STANDBY] = 0;
4317 }
4318 } else if (!strcasecmp(var, "liberal-dtmf")) {
4319 if (switch_true(val)) {
4320 sofia_set_pflag(profile, PFLAG_LIBERAL_DTMF)(profile)->pflags[PFLAG_LIBERAL_DTMF] = 1;
4321 } else {
4322 sofia_clear_pflag(profile, PFLAG_LIBERAL_DTMF)(profile)->pflags[PFLAG_LIBERAL_DTMF] = 0;
4323 }
4324 } else if (!strcasecmp(var, "rtp-digit-delay")) {
4325 int delay = atoi(val);
4326 if (delay < 0) {
4327 delay = 0;
4328 }
4329 profile->rtp_digit_delay = (uint32_t) delay;
4330 } else if (!strcasecmp(var, "watchdog-enabled")) {
4331 profile->watchdog_enabled = switch_true(val);
4332 } else if (!strcasecmp(var, "watchdog-step-timeout")) {
4333 profile->step_timeout = atoi(val);
4334 } else if (!strcasecmp(var, "watchdog-event-timeout")) {
4335 profile->event_timeout = atoi(val);
4336
4337 } else if (!strcasecmp(var, "in-dialog-chat")) {
4338 if (switch_true(val)) {
4339 sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT)(profile)->pflags[PFLAG_IN_DIALOG_CHAT] = 1;
4340 } else {
4341 sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT)(profile)->pflags[PFLAG_IN_DIALOG_CHAT] = 0;
4342 }
4343 } else if (!strcasecmp(var, "enable-chat")) {
4344 if (switch_true(val)) {
4345 sofia_set_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 1;
4346 } else {
4347 sofia_clear_pflag(profile, PFLAG_ENABLE_CHAT)(profile)->pflags[PFLAG_ENABLE_CHAT] = 0;
4348 }
4349 } else if (!strcasecmp(var, "fire-message-events")) {
4350 if (switch_true(val)) {
4351 sofia_set_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)(profile)->pflags[PFLAG_FIRE_MESSAGE_EVENTS] = 1;
4352 } else {
4353 sofia_clear_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)(profile)->pflags[PFLAG_FIRE_MESSAGE_EVENTS] = 0;
4354 }
4355 } else if (!strcasecmp(var, "t38-passthru")) {
4356 if (switch_true(val)) {
4357 sofia_set_pflag(profile, PFLAG_T38_PASSTHRU)(profile)->pflags[PFLAG_T38_PASSTHRU] = 1;
4358 } else {
4359 sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU)(profile)->pflags[PFLAG_T38_PASSTHRU] = 0;
4360 }
4361 } else if (!strcasecmp(var, "presence-disable-early")) {
4362 if (switch_true(val)) {
4363 sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY)(profile)->pflags[PFLAG_PRESENCE_DISABLE_EARLY] = 1;
4364 } else {
4365 sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY)(profile)->pflags[PFLAG_PRESENCE_DISABLE_EARLY] = 0;
4366 }
4367 } else if (!strcasecmp(var, "ignore-183nosdp")) {
4368 if (switch_true(val)) {
4369 sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP)(profile)->pflags[PFLAG_IGNORE_183NOSDP] = 1;
4370 } else {
4371 sofia_clear_pflag(profile, PFLAG_IGNORE_183NOSDP)(profile)->pflags[PFLAG_IGNORE_183NOSDP] = 0;
4372 }
4373 } else if (!strcasecmp(var, "renegotiate-codec-on-hold")) {
4374 if (switch_true(val)) {
4375 sofia_set_media_flag(profile, SCMF_RENEG_ON_HOLD)(profile)->media_flags[SCMF_RENEG_ON_HOLD] = 1;
4376 } else {
4377 sofia_clear_media_flag(profile, SCMF_RENEG_ON_HOLD)(profile)->media_flags[SCMF_RENEG_ON_HOLD] = 0;
4378 }
4379 } else if (!strcasecmp(var, "renegotiate-codec-on-reinvite")) {
4380 if (switch_true(val)) {
4381 sofia_set_media_flag(profile, SCMF_RENEG_ON_REINVITE)(profile)->media_flags[SCMF_RENEG_ON_REINVITE] = 1;
4382 } else {
4383 sofia_clear_media_flag(profile, SCMF_RENEG_ON_REINVITE)(profile)->media_flags[SCMF_RENEG_ON_REINVITE] = 0;
4384 }
4385 } else if (!strcasecmp(var, "presence-probe-on-register")) {
4386 if (switch_true(val)) {
4387 sofia_set_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_PROBE_ON_REGISTER] = 1;
4388 } else {
4389 sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_PROBE_ON_REGISTER] = 0;
4390 }
4391 } else if (!strcasecmp(var, "send-presence-on-register")) {
4392 if (switch_true(val) || !strcasecmp(val, "all")) {
4393 sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 1;
4394 } else if (!strcasecmp(val, "first-only")) {
4395 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 0;
4396 sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_FIRST_REGISTER] = 1;
4397 } else {
4398 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_REGISTER] = 0;
4399 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_PRESENCE_ON_FIRST_REGISTER] = 0;
4400 }
4401 } else if (!strcasecmp(var, "cid-in-1xx")) {
4402 if (switch_true(val)) {
4403 sofia_set_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 1;
4404 } else {
4405 sofia_clear_pflag(profile, PFLAG_CID_IN_1XX)(profile)->pflags[PFLAG_CID_IN_1XX] = 0;
4406 }
4407
4408 } else if (!strcasecmp(var, "disable-hold")) {
4409 if (switch_true(val)) {
4410 sofia_set_media_flag(profile, SCMF_DISABLE_HOLD)(profile)->media_flags[SCMF_DISABLE_HOLD] = 1;
4411 } else {
4412 sofia_clear_media_flag(profile, SCMF_DISABLE_HOLD)(profile)->media_flags[SCMF_DISABLE_HOLD] = 0;
4413 }
4414 } else if (!strcasecmp(var, "auto-jitterbuffer-msec")) {
4415 int msec = atoi(val);
4416 if (msec > 19) {
4417 profile->jb_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4417)
;
4418 }
4419 } else if (!strcasecmp(var, "dtmf-type")) {
4420 if (!strcasecmp(val, "rfc2833")) {
4421 profile->dtmf_type = DTMF_2833;
4422 } else if (!strcasecmp(val, "info")) {
4423 profile->dtmf_type = DTMF_INFO;
4424 } else {
4425 profile->dtmf_type = DTMF_NONE;
4426 }
4427 } else if (!strcasecmp(var, "NDLB-force-rport")) {
4428 if (val && !strcasecmp(val, "safe")) {
4429 profile->server_rport_level = 3;
4430 profile->client_rport_level = 1;
4431 } else if (val && !strcasecmp(val, "disabled")) {
4432 profile->server_rport_level = 0;
4433 profile->client_rport_level = 0;
4434 } else if (val && !strcasecmp(val, "client-only")) {
4435 profile->client_rport_level = 1;
4436 } else if (val && !strcasecmp(val, "server-only")) {
4437 profile->client_rport_level = 0;
4438 profile->server_rport_level = 1;
4439 } else if (switch_true(val)) {
4440 profile->server_rport_level = 2;
4441 profile->client_rport_level = 1;
4442 }
4443 } else if (!strcasecmp(var, "auto-rtp-bugs")) {
4444 switch_core_media_parse_rtp_bugs(&profile->auto_rtp_bugs, val);
4445 } else if (!strcasecmp(var, "manual-rtp-bugs")) {
4446 switch_core_media_parse_rtp_bugs(&profile->manual_rtp_bugs, val);
4447 } else if (!strcasecmp(var, "manual-video-rtp-bugs")) {
4448 switch_core_media_parse_rtp_bugs(&profile->manual_video_rtp_bugs, val);
4449 } else if (!strcasecmp(var, "dbname")) {
4450 profile->dbname = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4450)
;
4451 } else if (!strcasecmp(var, "presence-hosts")) {
4452 profile->presence_hosts = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4452)
;
4453 } else if (!strcasecmp(var, "caller-id-type")) {
4454 profile->cid_type = sofia_cid_name2type(val);
4455 } else if (!strcasecmp(var, "record-template")) {
4456 profile->record_template = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4456)
;
4457 } else if (!strcasecmp(var, "record-path")) {
4458 profile->record_path = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4458)
;
4459 } else if ((!strcasecmp(var, "inbound-no-media") || !strcasecmp(var, "inbound-bypass-media"))) {
4460 if (switch_true(val)) {
4461 sofia_set_flag(profile, TFLAG_INB_NOMEDIA)(profile)->flags[TFLAG_INB_NOMEDIA] = 1;
4462 } else {
4463 sofia_clear_flag(profile, TFLAG_INB_NOMEDIA)(profile)->flags[TFLAG_INB_NOMEDIA] = 0;
4464 }
4465 } else if (!strcasecmp(var, "inbound-late-negotiation")) {
4466 if (switch_true(val)) {
4467 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
4468 } else {
4469 sofia_clear_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 0;
4470 }
4471 } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) {
4472 if (switch_true(val)) {
4473 sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)(profile)->pflags[PFLAG_RTP_NOTIMER_DURING_BRIDGE] = 1;
4474 } else {
4475 sofia_clear_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)(profile)->pflags[PFLAG_RTP_NOTIMER_DURING_BRIDGE] = 0;
4476 }
4477 } else if (!strcasecmp(var, "manual-redirect")) {
4478 if (switch_true(val)) {
4479 sofia_set_pflag(profile, PFLAG_MANUAL_REDIRECT)(profile)->pflags[PFLAG_MANUAL_REDIRECT] = 1;
4480 } else {
4481 sofia_clear_pflag(profile, PFLAG_MANUAL_REDIRECT)(profile)->pflags[PFLAG_MANUAL_REDIRECT] = 0;
4482 }
4483 } else if (!strcasecmp(var, "inbound-proxy-media")) {
4484 if (switch_true(val)) {
4485 sofia_set_flag(profile, TFLAG_PROXY_MEDIA)(profile)->flags[TFLAG_PROXY_MEDIA] = 1;
4486 } else {
4487 sofia_clear_flag(profile, TFLAG_PROXY_MEDIA)(profile)->flags[TFLAG_PROXY_MEDIA] = 0;
4488 }
4489 } else if (!strcasecmp(var, "inbound-zrtp-passthru")) {
4490 if (switch_true(val)) {
4491 sofia_set_flag(profile, TFLAG_ZRTP_PASSTHRU)(profile)->flags[TFLAG_ZRTP_PASSTHRU] = 1;
4492 } else {
4493 sofia_clear_flag(profile, TFLAG_ZRTP_PASSTHRU)(profile)->flags[TFLAG_ZRTP_PASSTHRU] = 0;
4494 }
4495 } else if (!strcasecmp(var, "force-subscription-expires")) {
4496 int tmp = atoi(val);
4497 if (tmp > 0) {
4498 profile->force_subscription_expires = tmp;
4499 }
4500 } else if (!strcasecmp(var, "force-publish-expires")) {
4501 int tmp = atoi(val);
4502 if (tmp > 0) {
4503 profile->force_publish_expires = tmp;
4504 }
4505 } else if (!strcasecmp(var, "send-message-query-on-register")) {
4506 if (switch_true(val)) {
4507 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 1;
4508 } else if (!strcasecmp(val, "first-only")) {
4509 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 0;
4510 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
1
;
4511 } else {
4512 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_REGISTER] = 0;
4513 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER)(profile)->pflags[PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER] =
0
;
4514 }
4515 } else if (!strcasecmp(var, "inbound-reg-in-new-thread") && val) {
4516 if (switch_true(val)) {
4517 sofia_set_pflag(profile, PFLAG_THREAD_PER_REG)(profile)->pflags[PFLAG_THREAD_PER_REG] = 1;
4518 } else {
4519 sofia_clear_pflag(profile, PFLAG_THREAD_PER_REG)(profile)->pflags[PFLAG_THREAD_PER_REG] = 0;
4520 }
4521 } else if (!strcasecmp(var, "inbound-use-callid-as-uuid")) {
4522 if (switch_true(val)) {
4523 sofia_set_pflag(profile, PFLAG_CALLID_AS_UUID)(profile)->pflags[PFLAG_CALLID_AS_UUID] = 1;
4524 } else {
4525 sofia_clear_pflag(profile, PFLAG_CALLID_AS_UUID)(profile)->pflags[PFLAG_CALLID_AS_UUID] = 0;
4526 }
4527 } else if (!strcasecmp(var, "outbound-use-uuid-as-callid")) {
4528 if (switch_true(val)) {
4529 sofia_set_pflag(profile, PFLAG_UUID_AS_CALLID)(profile)->pflags[PFLAG_UUID_AS_CALLID] = 1;
4530 } else {
4531 sofia_clear_pflag(profile, PFLAG_UUID_AS_CALLID)(profile)->pflags[PFLAG_UUID_AS_CALLID] = 0;
4532 }
4533 } else if (!strcasecmp(var, "track-calls")) {
4534 if (switch_true(val)) {
4535 sofia_set_pflag(profile, PFLAG_TRACK_CALLS)(profile)->pflags[PFLAG_TRACK_CALLS] = 1;
4536 }
4537 } else if (!strcasecmp(var, "NDLB-received-in-nat-reg-contact")) {
4538 if (switch_true(val)) {
4539 sofia_set_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)(profile)->pflags[PFLAG_RECIEVED_IN_NAT_REG_CONTACT] = 1;
4540 } else {
4541 sofia_clear_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)(profile)->pflags[PFLAG_RECIEVED_IN_NAT_REG_CONTACT] = 0;
4542 }
4543 } else if (!strcasecmp(var, "aggressive-nat-detection")) {
4544 if (switch_true(val)) {
4545 sofia_set_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)(profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] = 1;
4546 } else {
4547 sofia_clear_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)(profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] = 0;
4548 }
4549 } else if (!strcasecmp(var, "disable-rtp-auto-adjust")) {
4550 if (switch_true(val)) {
4551 sofia_set_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ)(profile)->media_flags[SCMF_DISABLE_RTP_AUTOADJ] = 1;
4552 } else {
4553 sofia_clear_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ)(profile)->media_flags[SCMF_DISABLE_RTP_AUTOADJ] = 0;
4554 }
4555 } else if (!strcasecmp(var, "NDLB-support-asterisk-missing-srtp-auth")) {
4556 if (switch_true(val)) {
4557 profile->mndlb |= SM_NDLB_DISABLE_SRTP_AUTH;
4558 } else {
4559 profile->mndlb &= ~SM_NDLB_DISABLE_SRTP_AUTH;
4560 }
4561 } else if (!strcasecmp(var, "user-agent-filter")) {
4562 profile->user_agent_filter = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4562)
;
4563 } else if (!strcasecmp(var, "max-registrations-per-extension")) {
4564 profile->max_registrations_perext = atoi(val);
4565 } else if (!strcasecmp(var, "rfc2833-pt")) {
4566 profile->te = (switch_payload_t) atoi(val);
4567 } else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)((profile)->media_flags[SCMF_SUPPRESS_CNG] ? 1 : 0)) {
4568 profile->cng_pt = (switch_payload_t) atoi(val);
4569 } else if (!strcasecmp(var, "sip-port")) {
4570 if (!strcasecmp(val, "auto")) {
4571 sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_PORT] = 1;
4572 } else {
4573 profile->sip_port = (switch_port_t) atoi(val);
4574 if (!profile->extsipport) profile->extsipport = profile->sip_port;
4575 }
4576 } else if (!strcasecmp(var, "vad")) {
4577 if (!strcasecmp(val, "in")) {
4578 profile->vflags |= VAD_IN;
4579 } else if (!strcasecmp(val, "out")) {
4580 profile->vflags |= VAD_OUT;
4581 } else if (!strcasecmp(val, "both")) {
4582 profile->vflags |= VAD_OUT | VAD_IN;
4583 } else if (strcasecmp(val, "none")) {
4584 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4584
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid option %s for VAD\n", val);
4585 }
4586 } else if (!strcasecmp(var, "ext-rtp-ip")) {
4587 if (!zstr(val)_zstr(val)) {
4588 char *ip = mod_sofia_globals.guess_ip;
4589
4590 if (!strcmp(val, "0.0.0.0")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(val) && __builtin_constant_p ("0.0.0.0") &&
(__s1_len = __builtin_strlen (val), __s2_len = __builtin_strlen
("0.0.0.0"), (!((size_t)(const void *)((val) + 1) - (size_t)
(const void *)(val) == 1) || __s1_len >= 4) && (!(
(size_t)(const void *)(("0.0.0.0") + 1) - (size_t)(const void
*)("0.0.0.0") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(val, "0.0.0.0") : (__builtin_constant_p (val) && ((
size_t)(const void *)((val) + 1) - (size_t)(const void *)(val
) == 1) && (__s1_len = __builtin_strlen (val), __s1_len
< 4) ? (__builtin_constant_p ("0.0.0.0") && ((size_t
)(const void *)(("0.0.0.0") + 1) - (size_t)(const void *)("0.0.0.0"
) == 1) ? __builtin_strcmp (val, "0.0.0.0") : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) ("0.0.0.0"); int __result = (((const unsigned char *) (const
char *) (val))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (val))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (val))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (val))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("0.0.0.0") && ((size_t)(const void *)(("0.0.0.0") +
1) - (size_t)(const void *)("0.0.0.0") == 1) && (__s2_len
= __builtin_strlen ("0.0.0.0"), __s2_len < 4) ? (__builtin_constant_p
(val) && ((size_t)(const void *)((val) + 1) - (size_t
)(const void *)(val) == 1) ? __builtin_strcmp (val, "0.0.0.0"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (val); int __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (val, "0.0.0.0")))); })
) {
4591 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4591
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n",
4592 mod_sofia_globals.guess_ip);
4593 } else if (!strcasecmp(val, "auto-nat")) {
4594 ip = NULL((void*)0);
4595 } else {
4596 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
4597 sofia_clear_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 0;
4598 }
4599 if (ip) {
4600 if (!strncasecmp(ip, "autonat:", 8)) {
4601 profile->extrtpip = switch_core_strdup(profile->pool, ip + 8)switch_core_perform_strdup(profile->pool, ip + 8, "sofia.c"
, (const char *)__func__, 4601)
;
4602 if (zstr(profile->extsipip)_zstr(profile->extsipip)) {
4603 profile->extsipip = switch_core_strdup(profile->pool, profile->extrtpip)switch_core_perform_strdup(profile->pool, profile->extrtpip
, "sofia.c", (const char *)__func__, 4603)
;
4604 }
4605 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
4606 } else {
4607 profile->extrtpip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 4607)
;
4608 }
4609 }
4610 } else {
4611 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4611
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid ext-rtp-ip\n");
4612 }
4613 } else if (!strcasecmp(var, "rtp-ip")) {
4614 char *ip = mod_sofia_globals.guess_ip;
4615 char buf[64];
4616
4617 if (!strcmp(val, "0.0.0.0")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(val) && __builtin_constant_p ("0.0.0.0") &&
(__s1_len = __builtin_strlen (val), __s2_len = __builtin_strlen
("0.0.0.0"), (!((size_t)(const void *)((val) + 1) - (size_t)
(const void *)(val) == 1) || __s1_len >= 4) && (!(
(size_t)(const void *)(("0.0.0.0") + 1) - (size_t)(const void
*)("0.0.0.0") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(val, "0.0.0.0") : (__builtin_constant_p (val) && ((
size_t)(const void *)((val) + 1) - (size_t)(const void *)(val
) == 1) && (__s1_len = __builtin_strlen (val), __s1_len
< 4) ? (__builtin_constant_p ("0.0.0.0") && ((size_t
)(const void *)(("0.0.0.0") + 1) - (size_t)(const void *)("0.0.0.0"
) == 1) ? __builtin_strcmp (val, "0.0.0.0") : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) ("0.0.0.0"); int __result = (((const unsigned char *) (const
char *) (val))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (val))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (val))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (val))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("0.0.0.0") && ((size_t)(const void *)(("0.0.0.0") +
1) - (size_t)(const void *)("0.0.0.0") == 1) && (__s2_len
= __builtin_strlen ("0.0.0.0"), __s2_len < 4) ? (__builtin_constant_p
(val) && ((size_t)(const void *)((val) + 1) - (size_t
)(const void *)(val) == 1) ? __builtin_strcmp (val, "0.0.0.0"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (val); int __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (val, "0.0.0.0")))); })
) {
4618 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4618
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
4619 } else if (!strncasecmp(val, "interface:", 10)) {
4620 char *ifname = val+10;
4621 int family = AF_UNSPEC0;
4622 if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC0; }
4623 if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET2; }
4624 if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET610; }
4625 if (switch_find_interface_ip(buf, sizeof(buf), NULL((void*)0), ifname, family) == SWITCH_STATUS_SUCCESS) {
4626 ip = buf;
4627 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4627
, ((void*)0)
, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for rtp-ip\n", ip, val+10);
4628 } else {
4629 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4629
, ((void*)0)
, SWITCH_LOG_ERROR, "Unknown IP for interface %s for rtp-ip\n", val+10);
4630 }
4631 } else {
4632 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
4633 }
4634 if (profile->rtpip_index < MAX_RTPIP50) {
4635 profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 4635)
;
4636 } else {
4637 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4637
, ((void*)0)
, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
4638 }
4639 } else if (!strcasecmp(var, "sip-ip")) {
4640 char *ip = mod_sofia_globals.guess_ip;
4641 char buf[64];
4642
4643 if (!strcmp(val, "0.0.0.0")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(val) && __builtin_constant_p ("0.0.0.0") &&
(__s1_len = __builtin_strlen (val), __s2_len = __builtin_strlen
("0.0.0.0"), (!((size_t)(const void *)((val) + 1) - (size_t)
(const void *)(val) == 1) || __s1_len >= 4) && (!(
(size_t)(const void *)(("0.0.0.0") + 1) - (size_t)(const void
*)("0.0.0.0") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(val, "0.0.0.0") : (__builtin_constant_p (val) && ((
size_t)(const void *)((val) + 1) - (size_t)(const void *)(val
) == 1) && (__s1_len = __builtin_strlen (val), __s1_len
< 4) ? (__builtin_constant_p ("0.0.0.0") && ((size_t
)(const void *)(("0.0.0.0") + 1) - (size_t)(const void *)("0.0.0.0"
) == 1) ? __builtin_strcmp (val, "0.0.0.0") : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) ("0.0.0.0"); int __result = (((const unsigned char *) (const
char *) (val))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (val))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (val))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (val))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("0.0.0.0") && ((size_t)(const void *)(("0.0.0.0") +
1) - (size_t)(const void *)("0.0.0.0") == 1) && (__s2_len
= __builtin_strlen ("0.0.0.0"), __s2_len < 4) ? (__builtin_constant_p
(val) && ((size_t)(const void *)((val) + 1) - (size_t
)(const void *)(val) == 1) ? __builtin_strcmp (val, "0.0.0.0"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (val); int __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("0.0.0.0"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (val, "0.0.0.0")))); })
) {
4644 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4644
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
4645 } else if (!strncasecmp(val, "interface:", 10)) {
4646 char *ifname = val+10;
4647 int family = AF_UNSPEC0;
4648 if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC0; }
4649 if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET2; }
4650 if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET610; }
4651 if (switch_find_interface_ip(buf, sizeof(buf), NULL((void*)0), ifname, family) == SWITCH_STATUS_SUCCESS) {
4652 ip = buf;
4653 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4653
, ((void*)0)
, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for sip-ip\n", ip, val+10);
4654 } else {
4655 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4655
, ((void*)0)
, SWITCH_LOG_ERROR, "Unknown IP for interface %s for sip-ip\n", val+10);
4656 }
4657 } else {
4658 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
4659 }
4660 profile->sipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 4660)
;
4661 } else if (!strcasecmp(var, "ext-sip-port") && val) {
4662 int tmp = atoi(val);
4663 if (tmp > 0) profile->extsipport = (switch_port_t)tmp;
4664 } else if (!strcasecmp(var, "ext-sip-ip")) {
4665 if (!zstr(val)_zstr(val)) {
4666 char *ip = mod_sofia_globals.guess_ip;
4667 char stun_ip[50] = "";
4668 char *myip = stun_ip;
4669
4670 switch_copy_string(stun_ip, ip, sizeof(stun_ip));
4671
4672 if (!strcasecmp(val, "0.0.0.0")) {
4673 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4673
, ((void*)0)
, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n",
4674 mod_sofia_globals.guess_ip);
4675 } else if (!strcasecmp(val, "auto-nat")) {
4676 ip = NULL((void*)0);
4677 } else if (strcasecmp(val, "auto")) {
4678 if (sofia_glue_ext_address_lookup(profile, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
4679 ip = myip;
4680 sofia_clear_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 0;
4681 } else {
4682 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4682
, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to get external ip.\n");
4683 }
4684 }
4685 if (ip) {
4686 if (!strncasecmp(ip, "autonat:", 8)) {
4687 profile->extsipip = switch_core_strdup(profile->pool, ip + 8)switch_core_perform_strdup(profile->pool, ip + 8, "sofia.c"
, (const char *)__func__, 4687)
;
4688 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
4689 } else {
4690 profile->extsipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 4690)
;
4691 }
4692 }
4693 } else {
4694 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4694
, ((void*)0)
, SWITCH_LOG_ERROR, "Invalid ext-sip-ip\n");
4695 }
4696 } else if (!strcasecmp(var, "local-network-acl")) {
4697 if (!strcasecmp(var, "none")) {
4698 profile->local_network = NULL((void*)0);
4699 } else {
4700 profile->local_network = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4700)
;
4701 }
4702 } else if (!strcasecmp(var, "force-register-domain")) {
4703 profile->reg_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4703)
;
4704 } else if (!strcasecmp(var, "force-register-db-domain")) {
4705 profile->reg_db_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4705)
;
4706 } else if (!strcasecmp(var, "force-subscription-domain")) {
4707 profile->sub_domain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4707)
;
4708 } else if (!strcasecmp(var, "bind-params")) {
4709 profile->bind_params = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4709)
;
4710 } else if (!strcasecmp(var, "sip-domain")) {
4711 profile->sipdomain = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4711)
;
4712 } else if (!strcasecmp(var, "rtp-timer-name")) {
4713 profile->timer_name = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4713)
;
4714 } else if (!strcasecmp(var, "hold-music")) {
4715 profile->hold_music = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4715)
;
4716 } else if (!strcasecmp(var, "outbound-proxy")) {
4717 profile->outbound_proxy = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4717)
;
4718 } else if (!strcasecmp(var, "rtcp-audio-interval-msec")) {
4719 profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4719)
;
4720 } else if (!strcasecmp(var, "rtcp-video-interval-msec")) {
4721 profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4721)
;
4722 } else if (!strcasecmp(var, "session-timeout")) {
4723 int v_session_timeout = atoi(val);
4724 if (v_session_timeout >= 0) {
4725 profile->session_timeout = v_session_timeout;
4726 }
4727 } else if (!strcasecmp(var, "max-proceeding")) {
4728 int v_max_proceeding = atoi(val);
4729 if (v_max_proceeding >= 0) {
4730 profile->max_proceeding = v_max_proceeding;
4731 }
4732 } else if (!strcasecmp(var, "rtp-timeout-sec")) {
4733 int v = atoi(val);
4734 if (v >= 0) {
4735 profile->rtp_timeout_sec = v;
4736 }
4737 } else if (!strcasecmp(var, "rtp-hold-timeout-sec")) {
4738 int v = atoi(val);
4739 if (v >= 0) {
4740 profile->rtp_hold_timeout_sec = v;
4741 }
4742 } else if (!strcasecmp(var, "disable-transfer")) {
4743 if (switch_true(val)) {
4744 profile->mflags &= ~MFLAG_REFER;
4745 } else {
4746 profile->mflags |= MFLAG_REFER;
4747 }
4748 } else if (!strcasecmp(var, "disable-register")) {
4749 if (switch_true(val)) {
4750 profile->mflags &= ~MFLAG_REGISTER;
4751 } else {
4752 profile->mflags |= MFLAG_REGISTER;
4753 }
4754 } else if (!strcasecmp(var, "media-option")) {
4755 if (!strcasecmp(val, "resume-media-on-hold")) {
4756 profile->media_options |= MEDIA_OPT_MEDIA_ON_HOLD;
4757 } else if (!strcasecmp(val, "bypass-media-after-att-xfer")) {
4758 profile->media_options |= MEDIA_OPT_BYPASS_AFTER_ATT_XFER;
4759 } else if (!strcasecmp(val, "bypass-media-after-hold")) {
4760 if (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
4761 profile->media_options |= MEDIA_OPT_BYPASS_AFTER_HOLD;
4762 } else {
4763 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4763
, ((void*)0)
, SWITCH_LOG_ERROR,
4764 "bypass-media-after-hold can be set only with resume-media-on-hold media-option\n");
4765 }
4766 } else if (!strcasecmp(val, "none")) {
4767 profile->media_options = 0;
4768 }
4769 } else if (!strcasecmp(var, "pnp-provision-url")) {
4770 profile->pnp_prov_url = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4770)
;
4771 } else if (!strcasecmp(var, "manage-presence")) {
4772 if (!strcasecmp(val, "passive")) {
4773 profile->pres_type = PRES_TYPE_PASSIVE;
4774
4775 } else if (!strcasecmp(val, "pnp")) {
4776 profile->pres_type = PRES_TYPE_PNP;
4777 } else if (switch_true(val)) {
4778 profile->pres_type = PRES_TYPE_FULL;
4779 } else {
4780 profile->pres_type = 0;
4781 }
4782 } else if (!strcasecmp(var, "presence-hold-state")) {
4783 if (!strcasecmp(val, "confirmed")) {
4784 profile->pres_held_type = PRES_HELD_CONFIRMED;
4785 } else if (!strcasecmp(val, "terminated")) {
4786 profile->pres_held_type = PRES_HELD_TERMINATED;
4787 } else {
4788 profile->pres_held_type = 0;
4789 }
4790 } else if (!strcasecmp(var, "presence-privacy")) {
4791 if (switch_true(val)) {
4792 sofia_set_pflag(profile, PFLAG_PRESENCE_PRIVACY)(profile)->pflags[PFLAG_PRESENCE_PRIVACY] = 1;
4793 } else {
4794 sofia_clear_pflag(profile, PFLAG_PRESENCE_PRIVACY)(profile)->pflags[PFLAG_PRESENCE_PRIVACY] = 0;
4795 }
4796 } else if (!strcasecmp(var, "manage-shared-appearance")) {
4797 if (switch_true(val)) {
4798 sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 1;
4799 profile->pres_type = PRES_TYPE_FULL;
4800 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
4801
4802 } else if (!strcasecmp(val, "sylantro")) {
4803 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 4803
, ((void*)0)
, SWITCH_LOG_ERROR,
4804 "Sylantro support has been removed.\n"
4805 "It was incomplete anyway, and we fully support the broadsoft SCA shared line spec.");
4806 sofia_clear_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 0;
4807 } else {
4808 sofia_clear_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)(profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] = 0;
4809 }
4810 } else if (!strcasecmp(var, "disable-srv")) {
4811 if (switch_true(val)) {
4812 sofia_set_pflag(profile, PFLAG_DISABLE_SRV)(profile)->pflags[PFLAG_DISABLE_SRV] = 1;
4813 } else {
4814 sofia_clear_pflag(profile, PFLAG_DISABLE_SRV)(profile)->pflags[PFLAG_DISABLE_SRV] = 0;
4815 }
4816 } else if (!strcasecmp(var, "disable-naptr")) {
4817 if (switch_true(val)) {
4818 sofia_set_pflag(profile, PFLAG_DISABLE_NAPTR)(profile)->pflags[PFLAG_DISABLE_NAPTR] = 1;
4819 } else {
4820 sofia_clear_pflag(profile, PFLAG_DISABLE_NAPTR)(profile)->pflags[PFLAG_DISABLE_NAPTR] = 0;
4821 }
4822 } else if (!strcasecmp(var, "disable-srv503")) {
4823 if (switch_true(val)) {
4824 sofia_set_pflag(profile, PFLAG_DISABLE_SRV503)(profile)->pflags[PFLAG_DISABLE_SRV503] = 1;
4825 } else {
4826 sofia_clear_pflag(profile, PFLAG_DISABLE_SRV503)(profile)->pflags[PFLAG_DISABLE_SRV503] = 0;
4827 }
4828 } else if (!strcasecmp(var, "unregister-on-options-fail")) {
4829 if (switch_true(val)) {
4830 sofia_set_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)(profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] = 1;
4831 } else {
4832 sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)(profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] = 0;
4833 }
4834 } else if (!strcasecmp(var, "sip-user-ping-max")) {
4835 profile->sip_user_ping_max = atoi(val);
4836 } else if (!strcasecmp(var, "sip-user-ping-min")) {
4837 profile->sip_user_ping_min = atoi(val);
4838 } else if (!strcasecmp(var, "require-secure-rtp")) {
4839 if (switch_true(val)) {
4840 sofia_set_pflag(profile, PFLAG_SECURE)(profile)->pflags[PFLAG_SECURE] = 1;
4841 } else {
4842 sofia_clear_pflag(profile, PFLAG_SECURE)(profile)->pflags[PFLAG_SECURE] = 0;
4843 }
4844 } else if (!strcasecmp(var, "multiple-registrations")) {
4845 if (!strcasecmp(val, "call-id")) {
4846 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
4847 } else if (!strcasecmp(val, "contact") || switch_true(val)) {
4848 sofia_set_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 1;
4849 sofia_set_pflag(profile, PFLAG_MULTIREG_CONTACT)(profile)->pflags[PFLAG_MULTIREG_CONTACT] = 1;
4850 } else if (!switch_true(val)) {
4851 sofia_clear_pflag(profile, PFLAG_MULTIREG)(profile)->pflags[PFLAG_MULTIREG] = 0;
4852 sofia_clear_pflag(profile, PFLAG_MULTIREG_CONTACT)(profile)->pflags[PFLAG_MULTIREG_CONTACT] = 0;
4853 }
4854 } else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) {
4855 if (switch_true(val)) {
4856 sofia_set_media_flag(profile, SCMF_SUPPRESS_CNG)(profile)->media_flags[SCMF_SUPPRESS_CNG] = 1;
4857 profile->cng_pt = 0;
4858 } else {
4859 sofia_clear_media_flag(profile, SCMF_SUPPRESS_CNG)(profile)->media_flags[SCMF_SUPPRESS_CNG] = 0;
4860 }
4861 } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
4862 if (switch_true(val)) {
4863 profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH;
4864 } else {
4865 profile->ndlb &= ~PFLAG_NDLB_BROKEN_AUTH_HASH;
4866 }
4867 } else if (!strcasecmp(var, "NDLB-sendrecv-in-session")) {
4868 if (switch_true(val)) {
4869 profile->mndlb |= SM_NDLB_SENDRECV_IN_SESSION;
4870 } else {
4871 profile->mndlb &= ~SM_NDLB_SENDRECV_IN_SESSION;
4872 }
4873 } else if (!strcasecmp(var, "NDLB-allow-bad-iananame")) {
4874 if (switch_true(val)) {
4875 profile->mndlb |= SM_NDLB_ALLOW_BAD_IANANAME;
4876 } else {
4877 profile->mndlb &= ~SM_NDLB_ALLOW_BAD_IANANAME;
4878 }
4879 } else if (!strcasecmp(var, "NDLB-expires-in-register-response")) {
4880 if (switch_true(val)) {
4881 profile->ndlb |= PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE;
4882 } else {
4883 profile->ndlb &= ~PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE;
4884 }
4885 } else if (!strcasecmp(var, "NDLB-allow-crypto-in-avp")) {
4886 if (switch_true(val)) {
4887 profile->mndlb |= SM_NDLB_ALLOW_CRYPTO_IN_AVP;
4888 } else {
4889 profile->mndlb &= ~SM_NDLB_ALLOW_CRYPTO_IN_AVP;
4890 }
4891 } else if (!strcasecmp(var, "NDLB-allow-nondup-sdp")) {
4892 if (switch_true(val)) {
4893 profile->mndlb |= SM_NDLB_ALLOW_NONDUP_SDP;
4894 } else {
4895 profile->mndlb &= ~SM_NDLB_ALLOW_NONDUP_SDP;
4896 }
4897 } else if (!strcasecmp(var, "pass-rfc2833")) {
4898 if (switch_true(val)) {
4899 sofia_set_pflag(profile, PFLAG_PASS_RFC2833)(profile)->pflags[PFLAG_PASS_RFC2833] = 1;
4900 } else {
4901 sofia_clear_pflag(profile, PFLAG_PASS_RFC2833)(profile)->pflags[PFLAG_PASS_RFC2833] = 0;
4902 }
4903 } else if (!strcasecmp(var, "rtp-autofix-timing")) {
4904 if (switch_true(val)) {
4905 sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 1;
4906 } else {
4907 sofia_clear_media_flag(profile, SCMF_AUTOFIX_TIMING)(profile)->media_flags[SCMF_AUTOFIX_TIMING] = 0;
4908 }
4909 } else if (!strcasecmp(var, "contact-user")) {
4910 profile->contact_user = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 4910)
;
4911 } else if (!strcasecmp(var, "nat-options-ping")) {
4912 if (!strcasecmp(val, "udp-only")) {
4913 sofia_set_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_UDP_NAT_OPTIONS_PING] = 1;
4914 } else if (switch_true(val)) {
4915 sofia_set_pflag(profile, PFLAG_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_NAT_OPTIONS_PING] = 1;
4916 } else {
4917 sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_NAT_OPTIONS_PING] = 0;
4918 sofia_clear_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING)(profile)->pflags[PFLAG_UDP_NAT_OPTIONS_PING] = 0;
4919 }
4920 } else if (!strcasecmp(var, "all-reg-options-ping")) {
4921 if (switch_true(val)) {
4922 sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)(profile)->pflags[PFLAG_ALL_REG_OPTIONS_PING] = 1;
4923 } else {
4924 sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)(profile)->pflags[PFLAG_ALL_REG_OPTIONS_PING] = 0;
4925 }
4926 } else if (!strcasecmp(var, "inbound-codec-negotiation")) {
4927 if (!strcasecmp(val, "greedy")) {
4928 sofia_set_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 1;
4929 } else if (!strcasecmp(val, "scrooge")) {
4930 sofia_set_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 1;
4931 sofia_set_media_flag(profile, SCMF_CODEC_SCROOGE)(profile)->media_flags[SCMF_CODEC_SCROOGE] = 1;
4932 } else {
4933 sofia_clear_media_flag(profile, SCMF_CODEC_SCROOGE)(profile)->media_flags[SCMF_CODEC_SCROOGE] = 0;
4934 sofia_clear_media_flag(profile, SCMF_CODEC_GREEDY)(profile)->media_flags[SCMF_CODEC_GREEDY] = 0;
4935 }
4936 } else if (!strcasecmp(var, "disable-transcoding")) {
4937 if (switch_true(val)) {
4938 sofia_set_media_flag(profile, SCMF_DISABLE_TRANSCODING)(profile)->media_flags[SCMF_DISABLE_TRANSCODING] = 1;
4939 } else {
4940 sofia_clear_media_flag(profile, SCMF_DISABLE_TRANSCODING)(profile)->media_flags[SCMF_DISABLE_TRANSCODING] = 0;
4941 }
4942 } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) {
4943 if (switch_true(val)) {
4944 sofia_set_media_flag(profile, SCMF_REWRITE_TIMESTAMPS)(profile)->media_flags[SCMF_REWRITE_TIMESTAMPS] = 1;
4945 } else {
4946 sofia_clear_media_flag(profile, SCMF_REWRITE_TIMESTAMPS)(profile)->media_flags[SCMF_REWRITE_TIMESTAMPS] = 0;
4947 }
4948 } else if (!strcasecmp(var, "auth-calls")) {
4949 if (switch_true(val)) {
4950 sofia_set_pflag(profile, PFLAG_AUTH_CALLS)(profile)->pflags[PFLAG_AUTH_CALLS] = 1;
4951 } else {
4952 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS)(profile)->pflags[PFLAG_AUTH_CALLS] = 0;
4953 }
4954 } else if (!strcasecmp(var, "auth-messages")) {
4955 if (switch_true(val)) {
4956 sofia_set_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 1;
4957 } else {
4958 sofia_clear_pflag(profile, PFLAG_AUTH_MESSAGES)(profile)->pflags[PFLAG_AUTH_MESSAGES] = 0;
4959 }
4960 } else if (!strcasecmp(var, "auth-subscriptions")) {
4961 if (switch_true(val)) {
4962 sofia_set_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 1;
4963 } else {
4964 sofia_clear_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)(profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] = 0;
4965 }
4966 } else if (!strcasecmp(var, "extended-info-parsing")) {
4967 if (switch_true(val)) {
4968 sofia_set_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)(profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] = 1;
4969 } else {
4970 sofia_clear_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)(profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] = 0;
4971 }
4972 } else if (!strcasecmp(var, "nonce-ttl")) {
4973 profile->nonce_ttl = atoi(val);
4974 } else if (!strcasecmp(var, "accept-blind-reg")) {
4975 if (switch_true(val)) {
4976 sofia_set_pflag(profile, PFLAG_BLIND_REG)(profile)->pflags[PFLAG_BLIND_REG] = 1;
4977 } else {
4978 sofia_clear_pflag(profile, PFLAG_BLIND_REG)(profile)->pflags[PFLAG_BLIND_REG] = 0;
4979 }
4980 } else if (!strcasecmp(var, "3pcc-reinvite-bridged-on-ack")) {
4981 if (switch_true(val)) {
4982 sofia_set_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)(profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] = 1;
4983 } else {
4984 sofia_clear_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)(profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] = 0;
4985 }
4986 } else if (!strcasecmp(var, "enable-3pcc")) {
4987 if (switch_true(val)) {
4988 sofia_set_pflag(profile, PFLAG_3PCC)(profile)->pflags[PFLAG_3PCC] = 1;
4989 } else if (!strcasecmp(val, "proxy")) {
4990 sofia_set_pflag(profile, PFLAG_3PCC_PROXY)(profile)->pflags[PFLAG_3PCC_PROXY] = 1;
4991 }
4992 } else if (!strcasecmp(var, "accept-blind-auth")) {
4993 if (switch_true(val)) {
4994 sofia_set_pflag(profile, PFLAG_BLIND_AUTH)(profile)->pflags[PFLAG_BLIND_AUTH] = 1;
4995 } else {
4996 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH)(profile)->pflags[PFLAG_BLIND_AUTH] = 0;
4997 }
4998 } else if (!strcasecmp(var, "auth-all-packets")) {
4999 if (switch_true(val)) {
5000 sofia_set_pflag(profile, PFLAG_AUTH_ALL)(profile)->pflags[PFLAG_AUTH_ALL] = 1;
5001 } else {
5002 sofia_clear_pflag(profile, PFLAG_AUTH_ALL)(profile)->pflags[PFLAG_AUTH_ALL] = 0;
5003 }
5004 } else if (!strcasecmp(var, "full-id-in-dialplan")) {
5005 if (switch_true(val)) {
5006 sofia_set_pflag(profile, PFLAG_FULL_ID)(profile)->pflags[PFLAG_FULL_ID] = 1;
5007 } else {
5008 sofia_clear_pflag(profile, PFLAG_FULL_ID)(profile)->pflags[PFLAG_FULL_ID] = 0;
5009 }
5010 } else if (!strcasecmp(var, "inbound-reg-force-matching-username")) {
5011 if (switch_true(val)) {
5012 sofia_set_pflag(profile, PFLAG_CHECKUSER)(profile)->pflags[PFLAG_CHECKUSER] = 1;
5013 } else {
5014 sofia_clear_pflag(profile, PFLAG_CHECKUSER)(profile)->pflags[PFLAG_CHECKUSER] = 0;
5015 }
5016 } else if (!strcasecmp(var, "enable-timer")) {
5017 if (!switch_true(val)) {
5018 sofia_set_pflag(profile, PFLAG_DISABLE_TIMER)(profile)->pflags[PFLAG_DISABLE_TIMER] = 1;
5019 } else {
5020 sofia_clear_pflag(profile, PFLAG_DISABLE_TIMER)(profile)->pflags[PFLAG_DISABLE_TIMER] = 0;
5021 }
5022 } else if (!strcasecmp(var, "enable-rfc-5626")) {
5023 if (switch_true(val)) {
5024 sofia_set_pflag(profile, PFLAG_ENABLE_RFC5626)(profile)->pflags[PFLAG_ENABLE_RFC5626] = 1;
5025 } else {
5026 sofia_clear_pflag(profile, PFLAG_ENABLE_RFC5626)(profile)->pflags[PFLAG_ENABLE_RFC5626] = 0;
5027 }
5028 } else if (!strcasecmp(var, "minimum-session-expires")) {
5029 profile->minimum_session_expires = atoi(val);
5030 /* per RFC 4028: minimum_session_expires must be > 90 */
5031 if (profile->minimum_session_expires < 90) {
5032 profile->minimum_session_expires = 90;
5033 }
5034 } else if (!strcasecmp(var, "enable-100rel")) {
5035 if (switch_true(val)) {
5036 sofia_clear_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 0;
5037 } else {
5038 sofia_set_pflag(profile, PFLAG_DISABLE_100REL)(profile)->pflags[PFLAG_DISABLE_100REL] = 1;
5039 }
5040 } else if (!strcasecmp(var, "enable-compact-headers")) {
5041 if (switch_true(val)) {
5042 sofia_set_pflag(profile, PFLAG_SIPCOMPACT)(profile)->pflags[PFLAG_SIPCOMPACT] = 1;
5043 } else {
5044 sofia_clear_pflag(profile, PFLAG_SIPCOMPACT)(profile)->pflags[PFLAG_SIPCOMPACT] = 0;
5045 }
5046 } else if (!strcasecmp(var, "pass-callee-id")) {
5047 if (switch_true(val)) {
5048 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 1;
5049 } else {
5050 sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID)(profile)->pflags[PFLAG_PASS_CALLEE_ID] = 0;
5051 }
5052 } else if (!strcasecmp(var, "enable-soa")) {
5053 if (switch_true(val)) {
5054 sofia_set_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 1;
5055 } else {
5056 sofia_clear_flag(profile, TFLAG_ENABLE_SOA)(profile)->flags[TFLAG_ENABLE_SOA] = 0;
5057 }
5058 } else if (!strcasecmp(var, "parse-all-invite-headers")) {
5059 if (switch_true(val)) {
5060 sofia_set_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)(profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] = 1;
5061 } else {
5062 sofia_clear_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)(profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] = 0;
5063 }
5064 } else if (!strcasecmp(var, "bitpacking")) {
5065 if (!strcasecmp(val, "aal2")) {
5066 profile->codec_flags = SWITCH_CODEC_FLAG_AAL2;
5067 } else {
5068 profile->codec_flags = 0;
5069 }
5070 } else if (!strcasecmp(var, "username")) {
5071 profile->sdp_username = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5071)
;
5072 } else if (!strcasecmp(var, "context")) {
5073 profile->context = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5073)
;
5074 } else if (!strcasecmp(var, "apply-nat-acl")) {
5075 if (!strcasecmp(val,"none")) {
5076 profile->nat_acl_count = 0;
5077 } else if (profile->nat_acl_count < SOFIA_MAX_ACL100) {
5078 if (!profile->extsipip && profile->sipip && switch_check_network_list_ip(profile->sipip, val)switch_check_network_list_ip_token(profile->sipip, val, ((
void*)0))
) {
5079 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5079
, ((void*)0)
, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val);
5080 } else {
5081 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__, 5081)
;
5082 }
5083 } else {
5084 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5084
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5085 }
5086 } else if (!strcasecmp(var, "apply-inbound-acl")) {
5087 if (!strcasecmp(val,"none")) {
5088 profile->acl_count = 0;
5089 } else if (profile->acl_count < SOFIA_MAX_ACL100) {
5090 char *list, *pass = NULL((void*)0), *fail = NULL((void*)0);
5091
5092 list = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5092)
;
5093
5094 if ((pass = strchr(list, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(list) && (':') == '\0' ? (char *) __rawmemchr (list
, ':') : __builtin_strchr (list, ':')))
)) {
5095 *pass++ = '\0';
5096 if ((fail = strchr(pass, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(pass) && (':') == '\0' ? (char *) __rawmemchr (pass
, ':') : __builtin_strchr (pass, ':')))
)) {
5097 *fail++ = '\0';
5098 }
5099
5100 if (zstr(pass)_zstr(pass)) pass = NULL((void*)0);
5101 if (zstr(fail)_zstr(fail)) fail = NULL((void*)0);
5102
5103 profile->acl_pass_context[profile->acl_count] = pass;
5104 profile->acl_fail_context[profile->acl_count] = fail;
5105 }
5106
5107 profile->acl[profile->acl_count++] = list;
5108
5109 } else {
5110 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5110
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5111 }
5112 } else if (!strcasecmp(var, "apply-proxy-acl")) {
5113 if (!strcasecmp(val,"none")) {
5114 profile->proxy_acl_count = 0;
5115 } else if (profile->proxy_acl_count < SOFIA_MAX_ACL100) {
5116 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__, 5116)
;
5117 } else {
5118 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5118
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5119 }
5120 } else if (!strcasecmp(var, "apply-register-acl")) {
5121 if (!strcasecmp(val,"none")) {
5122 profile->reg_acl_count = 0;
5123 } else if (profile->reg_acl_count < SOFIA_MAX_ACL100) {
5124 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__, 5124)
;
5125 } else {
5126 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5126
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL100);
5127 }
5128
5129 } else if (!strcasecmp(var, "apply-candidate-acl")) {
5130 if (!strcasecmp(val,"none")) {
5131 profile->cand_acl_count = 0;
5132 } else if (profile->cand_acl_count < SWITCH_MAX_CAND_ACL25) {
5133 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__, 5133)
;
5134 } else {
5135 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5135
, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SWITCH_MAX_CAND_ACL25);
5136 }
5137 } else if (!strcasecmp(var, "alias")) {
5138 sip_alias_node_t *node;
5139 if (zstr(val)_zstr(val)) {
5140 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5140
, ((void*)0)
, SWITCH_LOG_DEBUG, "Alias Param has no data...\n");
5141 } else {
5142 if ((node = switch_core_alloc(profile->pool, sizeof(*node))switch_core_perform_alloc(profile->pool, sizeof(*node), "sofia.c"
, (const char *)__func__, 5142)
)) {
5143 if ((node->url = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5143)
)) {
5144 node->next = profile->aliases;
5145 profile->aliases = node;
5146 }
5147 }
5148 }
5149 } else if (!strcasecmp(var, "dialplan")) {
5150 profile->dialplan = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5150)
;
5151 } else if (!strcasecmp(var, "max-calls")) {
5152 profile->max_calls = atoi(val);
5153 } else if (!strcasecmp(var, "codec-prefs")) {
5154 profile->inbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5154)
;
5155 profile->outbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5155)
;
5156 } else if (!strcasecmp(var, "inbound-codec-prefs")) {
5157 profile->inbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5157)
;
5158 } else if (!strcasecmp(var, "outbound-codec-prefs")) {
5159 profile->outbound_codec_string = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5159)
;
5160 } else if (!strcasecmp(var, "challenge-realm")) {
5161 profile->challenge_realm = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5161)
;
5162 } else if (!strcasecmp(var, "dtmf-duration")) {
5163 uint32_t dur = atoi(val);
5164 if (dur >= switch_core_min_dtmf_duration(0) && dur <= switch_core_max_dtmf_duration(0)) {
5165 profile->dtmf_duration = dur;
5166 } else {
5167 profile->dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION2000;
5168 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5168
, ((void*)0)
, SWITCH_LOG_DEBUG, "Duration out of bounds, using default of %d!\n",
5169 SWITCH_DEFAULT_DTMF_DURATION2000);
5170 }
5171
5172 } else if (!strcasecmp(var, "ws-binding") && !zstr(val)_zstr(val)) {
5173 int tmp;
5174 char *p;
5175
5176 profile->ws_ip = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5176)
;
5177 if ((p = strrchr(profile->ws_ip, ':'))) {
5178 *p++ = '\0';
5179
5180 if (p && (tmp = atol(p)) && tmp > 0) {
5181 profile->ws_port = (switch_port_t) tmp;
5182 }
5183 }
5184
5185 } else if (!strcasecmp(var, "wss-binding") && !zstr(val)_zstr(val)) {
5186 int tmp;
5187 char *p;
5188
5189 profile->wss_ip = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5189)
;
5190 if ((p = strrchr(profile->wss_ip, ':'))) {
5191 *p++ = '\0';
5192
5193 if (p && (tmp = atol(p)) && tmp > 0) {
5194 profile->wss_port = (switch_port_t) tmp;
5195 }
5196 }
5197
5198 /*
5199 * handle TLS params #1
5200 */
5201 } else if (!strcasecmp(var, "tls")) {
5202 if (switch_true(val)) {
5203 sofia_set_pflag(profile, PFLAG_TLS)(profile)->pflags[PFLAG_TLS] = 1;
5204 if (profile->tls_bind_params) {
5205 if (!switch_stristr("transport=tls", profile->tls_bind_params)) {
5206 profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", profile->tls_bind_params);
5207 }
5208 } else {
5209 profile->tls_bind_params = switch_core_strdup(profile->pool, "transport=tls")switch_core_perform_strdup(profile->pool, "transport=tls",
"sofia.c", (const char *)__func__, 5209)
;
5210 }
5211 } else {
5212 sofia_clear_pflag(profile, PFLAG_TLS)(profile)->pflags[PFLAG_TLS] = 0;
5213 }
5214 } else if (!strcasecmp(var, "tls-bind-params")) {
5215 if (switch_stristr("transport=tls", val)) {
5216 profile->tls_bind_params = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5216)
;
5217 } else {
5218 profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", val);
5219 }
5220 } else if (!strcasecmp(var, "tls-only")) {
5221 profile->tls_only = switch_true(val);
5222 } else if (!strcasecmp(var, "tls-verify-date")) {
5223 profile->tls_verify_date = switch_true(val);
5224 } else if (!strcasecmp(var, "tls-verify-depth")) {
5225 profile->tls_verify_depth = atoi(val);
5226 } else if (!strcasecmp(var, "tls-verify-policy")) {
5227 profile->tls_verify_policy = sofia_glue_str2tls_verify_policy(val);
5228 } else if (!strcasecmp(var, "tls-sip-port")) {
5229 if (!strcasecmp(val, "auto")) {
5230 sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] = 1;
5231 } else {
5232 sofia_clear_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)(profile)->pflags[PFLAG_AUTO_ASSIGN_TLS_PORT] = 0;
5233 profile->tls_sip_port = (switch_port_t) atoi(val);
5234 }
5235 } else if (!strcasecmp(var, "tls-cert-dir") && !zstr(val)_zstr(val)) {
5236 profile->tls_cert_dir = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5236)
;
5237 } else if (!strcasecmp(var, "tls-passphrase") && !zstr(val)_zstr(val)) {
5238 profile->tls_passphrase = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5238)
;
5239 } else if (!strcasecmp(var, "tls-verify-in-subjects") && !zstr(val)_zstr(val)) {
5240 profile->tls_verify_in_subjects_str = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5240)
;
5241 } else if (!strcasecmp(var, "tls-ciphers") && !zstr(val)_zstr(val)) {
5242 profile->tls_ciphers = switch_core_strdup(profile->pool, val)switch_core_perform_strdup(profile->pool, val, "sofia.c", (
const char *)__func__, 5242)
;
5243 } else if (!strcasecmp(var, "tls-version") && !zstr(val)_zstr(val)) {
5244 char *ps = val, *pe = val;
5245 profile->tls_version = 0;
5246 while (ps && *pe) {
5247 int n;
5248 pe = strchr(ps,',')(__extension__ (__builtin_constant_p (',') && !__builtin_constant_p
(ps) && (',') == '\0' ? (char *) __rawmemchr (ps, ','
) : __builtin_strchr (ps, ',')))
;
5249 if (!pe && !(pe = memchr(ps,0,1024))) break;
5250 n = (int)(pe-ps);
5251 if (n==5 && !strncasecmp(ps, "sslv2", n))
5252 profile->tls_version |= SOFIA_TLS_VERSION_SSLv2;
5253 if (n==5 && !strncasecmp(ps, "sslv3", n))
5254 profile->tls_version |= SOFIA_TLS_VERSION_SSLv3;
5255 if (n==6 && !strncasecmp(ps, "sslv23", n))
5256 profile->tls_version |= SOFIA_TLS_VERSION_SSLv2 | SOFIA_TLS_VERSION_SSLv3;
5257 if (n==5 && !strncasecmp(ps, "tlsv1", n))
5258 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1;
5259 if (n==7 && !strncasecmp(ps, "tlsv1.1", n))
5260 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_1;
5261 if (n==7 && !strncasecmp(ps, "tlsv1.2", n))
5262 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
5263 ps=pe+1;
5264 }
5265 } else if (!strcasecmp(var, "tls-timeout")) {
5266 int v = atoi(val);
5267 profile->tls_timeout = v > 0 ? (unsigned int)v : 300;
5268 } else if (!strcasecmp(var, "timer-T1")) {
5269 int v = atoi(val);
5270 if (v > 0) {
5271 profile->timer_t1 = v;
5272 } else {
5273 profile->timer_t1 = 500;
5274 }
5275 } else if (!strcasecmp(var, "timer-T1X64")) {
5276 int v = atoi(val);
5277 if (v > 0) {
5278 profile->timer_t1x64 = v;
5279 } else {
5280 profile->timer_t1x64 = 32000;
5281 }
5282 } else if (!strcasecmp(var, "timer-T2")) {
5283 int v = atoi(val);
5284 if (v > 0) {
5285 profile->timer_t2 = v;
5286 } else {
5287 profile->timer_t2 = 4000;
5288 }
5289 } else if (!strcasecmp(var, "timer-T4")) {
5290 int v = atoi(val);
5291 if (v > 0) {
5292 profile->timer_t4 = v;
5293 } else {
5294 profile->timer_t4 = 4000;
5295 }
5296 } else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) {
5297 if (switch_true(val)) {
5298 sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)(profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] = 1;
5299 } else {
5300 sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)(profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] = 0;
5301 }
5302 } else if (!strcasecmp(var, "sip-expires-late-margin")) {
5303 int32_t sip_expires_late_margin = atoi(val);
5304 if (sip_expires_late_margin >= 0) {
5305 profile->sip_expires_late_margin = sip_expires_late_margin;
5306 } else {
5307 profile->sip_expires_late_margin = 60;
5308 }
5309 } else if (!strcasecmp(var, "sip-force-expires")) {
5310 int32_t sip_force_expires = atoi(val);
5311 if (sip_force_expires >= 0) {
5312 profile->sip_force_expires = sip_force_expires;
5313 } else {
5314 profile->sip_force_expires = 0;
5315 }
5316 } else if (!strcasecmp(var, "sip-expires-max-deviation")) {
5317 int32_t sip_expires_max_deviation = atoi(val);
5318 if (sip_expires_max_deviation >= 0) {
5319 profile->sip_expires_max_deviation = sip_expires_max_deviation;
5320 } else {
5321 profile->sip_expires_max_deviation = 0;
5322 }
5323 } else if (!strcasecmp(var, "sip-subscription-max-deviation")) {
5324 int32_t sip_subscription_max_deviation = atoi(val);
5325 if (sip_subscription_max_deviation >= 0) {
5326 profile->sip_subscription_max_deviation = sip_subscription_max_deviation;
5327 } else {
5328 profile->sip_subscription_max_deviation = 0;
5329 }
5330 } else if (!strcasecmp(var, "reuse-connections")) {
5331 switch_bool_t value = switch_true(val);
5332 if (!value) {
5333 sofia_set_pflag(profile, PFLAG_NO_CONNECTION_REUSE)(profile)->pflags[PFLAG_NO_CONNECTION_REUSE] = 1;
5334 } else {
5335 sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE)(profile)->pflags[PFLAG_NO_CONNECTION_REUSE] = 0;
5336 }
5337 } else if (!strcasecmp(var, "p-asserted-id-parse")) {
5338 if (!strncasecmp(val, "default", 7)) {
5339 profile->paid_type = PAID_DEFAULT;
5340 } else if (!strncasecmp(val, "user-only", 9)) {
5341 profile->paid_type = PAID_USER;
5342 } else if (!strncasecmp(val, "user-domain", 11)) {
5343 profile->paid_type = PAID_USER_DOMAIN;
5344 } else if (!strncasecmp(val, "verbatim", 8)) {
5345 profile->paid_type = PAID_VERBATIM;
5346 } else {
5347 profile->paid_type = PAID_DEFAULT;
5348 }
5349 }
5350 }
5351
5352 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)) {
5353 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5353
, ((void*)0)
, SWITCH_LOG_WARNING, "ZRTP passthrough implictly enables inbound-late-negotiation\n");
5354 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
5355 }
5356
5357 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)) {
5358 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5358
, ((void*)0)
, SWITCH_LOG_WARNING, "send-display-update=true is set, but we can't comply because allow-update=false\n");
5359 sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)(profile)->pflags[PFLAG_SEND_DISPLAY_UPDATE] = 0;
5360 }
5361
5362 if ((!profile->cng_pt) && (!sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)((profile)->media_flags[SCMF_SUPPRESS_CNG] ? 1 : 0))) {
5363 profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD13;
5364 }
5365
5366 if (!profile->sipip) {
5367 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__, 5367)
;
5368 }
5369
5370 if (!profile->rtpip[0]) {
5371 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__, 5371)
;
5372 }
5373
5374 if (switch_nat_get_type()) {
5375 char *ip = switch_core_get_variable_dup("nat_public_addr");
5376 if (ip && !strchr(profile->sipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(profile->sipip) && (':') == '\0' ? (char *) __rawmemchr
(profile->sipip, ':') : __builtin_strchr (profile->sipip
, ':')))
) {
5377 if (!profile->extrtpip) {
5378 profile->extrtpip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5378)
;
5379 }
5380 if (!profile->extsipip) {
5381 profile->extsipip = switch_core_strdup(profile->pool, ip)switch_core_perform_strdup(profile->pool, ip, "sofia.c", (
const char *)__func__, 5381)
;
5382 }
5383 sofia_set_pflag(profile, PFLAG_AUTO_NAT)(profile)->pflags[PFLAG_AUTO_NAT] = 1;
5384 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5384
, ((void*)0)
, SWITCH_LOG_NOTICE, "NAT detected setting external ip to %s\n", ip);
5385 }
5386 switch_safe_free(ip)if (ip) {free(ip);ip=((void*)0);};
5387 }
5388
5389 if (profile->nonce_ttl < 60) {
5390 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5390
, ((void*)0)
, SWITCH_LOG_INFO, "Setting nonce TTL to 60 seconds\n");
5391 profile->nonce_ttl = 60;
5392 }
5393
5394 if (!profile->sdp_username) {
5395 profile->sdp_username = switch_core_strdup(profile->pool, "FreeSWITCH")switch_core_perform_strdup(profile->pool, "FreeSWITCH", "sofia.c"
, (const char *)__func__, 5395)
;
5396 }
5397
5398 if (!profile->rtpip[0]) {
5399 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5399
, ((void*)0)
, SWITCH_LOG_WARNING, "Setting ip to '127.0.0.1'\n");
5400 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__, 5400)
;
5401 }
5402
5403 if (!profile->sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)((profile)->pflags[PFLAG_AUTO_ASSIGN_PORT] ? 1 : 0)) {
5404 profile->sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_PORT"5060");
5405 if (!profile->extsipport) profile->extsipport = profile->sip_port;
5406 }
5407
5408 if (!profile->dialplan) {
5409 profile->dialplan = switch_core_strdup(profile->pool, "XML")switch_core_perform_strdup(profile->pool, "XML", "sofia.c"
, (const char *)__func__, 5409)
;
5410 }
5411
5412 if (!profile->context) {
5413 profile->context = switch_core_strdup(profile->pool, "default")switch_core_perform_strdup(profile->pool, "default", "sofia.c"
, (const char *)__func__, 5413)
;
5414 }
5415
5416 if (!profile->sipdomain) {
5417 profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip)switch_core_perform_strdup(profile->pool, profile->sipip
, "sofia.c", (const char *)__func__, 5417)
;
5418 }
5419
5420 if (profile->pres_type == PRES_TYPE_PNP) {
5421 if (!profile->pnp_prov_url) {
5422 profile->pnp_prov_url = switch_core_sprintf(profile->pool, "http://%s/provision/", mod_sofia_globals.guess_ip);
5423 }
5424
5425 if (!profile->pnp_notify_profile) {
5426 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__, 5426)
;
5427 }
5428
5429 if (!profile->extsipip) {
5430 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__, 5430)
;
5431 }
5432
5433 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5433
, ((void*)0)
, SWITCH_LOG_INFO, "we're configured to provision to [%s] on profile [%s]\n",
5434 profile->pnp_prov_url, profile->pnp_notify_profile);
5435 }
5436
5437 config_sofia_profile_urls(profile);
5438
5439 if (profile->tls_cert_dir) {
5440 if (profile->wss_ip) {
5441 char *key, *cert;
5442 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.key");
5443 if (switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS) key = NULL((void*)0);
5444 cert = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.crt");
5445 if (switch_file_exists(cert, profile->pool) != SWITCH_STATUS_SUCCESS) cert = NULL((void*)0);
5446 if ( !key || !cert) {
5447 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
5448 if ( switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS ) {
5449 switch_core_gen_certs(key);
5450 }
5451 }
5452 }
5453 if (sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0)) {
5454 char *key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "agent.pem");
5455 char *ca = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "cafile.pem");;
5456 if (switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS) key = NULL((void*)0);
5457 if (switch_file_exists(ca, profile->pool) != SWITCH_STATUS_SUCCESS) ca = NULL((void*)0);
5458 if ( !key || !ca ) {
5459 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "tls.pem");
5460 if ( switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS ) {
5461 switch_core_gen_certs(key);
5462 }
5463 }
5464 }
5465 }
5466 }
5467
5468 if (profile) {
5469 if (profile_already_started) {
5470 switch_xml_t gateways_tag, domain_tag, domains_tag, aliases_tag, alias_tag;
5471
5472 if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)((profile)->flags[TFLAG_ZRTP_PASSTHRU] ? 1 : 0)) {
5473 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION)(profile)->flags[TFLAG_LATE_NEGOTIATION] = 1;
5474 }
5475
5476 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
5477 parse_gateways(profile, gateways_tag);
5478 }
5479
5480 status = SWITCH_STATUS_SUCCESS;
5481
5482 if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
5483 switch_event_t *xml_params;
5484 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 5484, &xml_params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
5485 switch_assert(xml_params)((xml_params) ? (void) (0) : __assert_fail ("xml_params", "sofia.c"
, 5485, __PRETTY_FUNCTION__))
;
5486 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways");
5487 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
5488
5489 for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
5490 switch_xml_t droot, x_domain_tag;
5491 const char *dname = switch_xml_attr_soft(domain_tag, "name");
5492 const char *parse = switch_xml_attr_soft(domain_tag, "parse");
5493 const char *alias = switch_xml_attr_soft(domain_tag, "alias");
5494
5495 if (!zstr(dname)_zstr(dname)) {
5496 if (!strcasecmp(dname, "all")) {
5497 switch_xml_t xml_root, x_domains;
5498 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) {
5499 for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
5500 dname = switch_xml_attr_soft(x_domain_tag, "name");
5501 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
5502 }
5503 switch_xml_free(xml_root);
5504 }
5505 } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) {
5506 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
5507 switch_xml_free(droot);
5508 }
5509 }
5510 }
5511
5512 switch_event_destroy(&xml_params);
5513 }
5514
5515 if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
5516 for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
5517 char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
5518 if (!zstr(aname)_zstr(aname)) {
5519
5520 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname)switch_core_perform_strdup(profile->pool, aname, "sofia.c"
, (const char *)__func__, 5520)
, profile) == SWITCH_STATUS_SUCCESS) {
5521 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5521
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
5522 } else {
5523 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5523
, ((void*)0)
, SWITCH_LOG_WARNING, "Alias [%s] for profile [%s] (already exists)\n",
5524 aname, profile->name);
5525 }
5526 }
5527 }
5528 }
5529
5530 } else {
5531 switch_xml_t aliases_tag, alias_tag;
5532
5533 if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
5534 for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
5535 char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
5536 if (!zstr(aname)_zstr(aname)) {
5537
5538 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname)switch_core_perform_strdup(profile->pool, aname, "sofia.c"
, (const char *)__func__, 5538)
, profile) == SWITCH_STATUS_SUCCESS) {
5539 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5539
, ((void*)0)
, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
5540 } else {
5541 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5541
, ((void*)0)
, SWITCH_LOG_ERROR, "Error Adding Alias [%s] for profile [%s] (name in use)\n",
5542 aname, profile->name);
5543 }
5544 }
5545 }
5546 }
5547
5548 if (profile->sipip) {
5549 switch_event_t *s_event;
5550 if (!profile->extsipport) profile->extsipport = profile->sip_port;
5551
5552 launch_sofia_profile_thread(profile);
5553 if (profile->odbc_dsn) {
5554 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5554
, ((void*)0)
, SWITCH_LOG_NOTICE, "Connecting ODBC Profile %s [%s]\n", profile->name, url);
5555 switch_yield(1000000)switch_sleep(1000000);;
5556 } else {
5557 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5557
, ((void*)0)
, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url);
5558 }
5559 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__, 5559, &s_event, SWITCH_EVENT_CUSTOM
, "sofia::profile_start")
== SWITCH_STATUS_SUCCESS)) {
5560 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
5561 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
5562 if (profile) {
5563 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
5564 }
5565 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 5565, &s_event, ((void*)0))
;
5566 }
5567 } else {
5568 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5568
, ((void*)0)
, SWITCH_LOG_NOTICE, "Unable to start Profile %s due to no configured sip-ip\n", profile->name);
5569 sofia_profile_start_failure(profile, profile->name)sofia_perform_profile_start_failure(profile, profile->name
, "sofia.c", 5569)
;
5570 }
5571 profile = NULL((void*)0);
5572 }
5573 if (profile_found) {
5574 break;
5575 }
5576 }
5577 }
5578 }
5579 done:
5580
5581 if (profile_already_started) {
5582 sofia_glue_release_profile(profile_already_started)sofia_glue_release_profile__("sofia.c", (const char *)__func__
, 5582, profile_already_started)
;
5583 }
5584
5585 switch_event_destroy(&params);
5586
5587 if (xml) {
5588 switch_xml_free(xml);
5589 }
5590
5591 if (profile_name && !profile_found) {
5592 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5592
, ((void*)0)
, SWITCH_LOG_WARNING, "No Such Profile '%s'\n", profile_name);
5593 status = SWITCH_STATUS_FALSE;
5594 }
5595
5596 return status;
5597}
5598
5599const char *sofia_gateway_status_name(sofia_gateway_status_t status)
5600{
5601 static const char *status_names[] = { "DOWN", "UP", NULL((void*)0) };
5602
5603 if (status < SOFIA_GATEWAY_INVALID) {
5604 return status_names[status];
5605 } else {
5606 return "INVALID";
5607 }
5608}
5609
5610const char *sofia_sip_user_status_name(sofia_sip_user_status_t status)
5611{
5612 static const char *status_names[] = { "UNREACHABLE", "REACHABLE", NULL((void*)0) };
5613
5614 if (status < SOFIA_REG_INVALID) {
5615 return status_names[status];
5616 } else {
5617 return "INVALID";
5618 }
5619}
5620
5621struct cb_helper_sip_user_status {
5622 char *status;
5623 size_t status_len;
5624
5625 char *contact;
5626 size_t contact_len;
5627
5628 int count;
5629};
5630
5631int sofia_sip_user_status_callback(void *pArg, int argc, char **argv, char **columnNames)
5632{
5633 struct cb_helper_sip_user_status *cbt = (struct cb_helper_sip_user_status *) pArg;
5634
5635 if (argc != 3) {
5636 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5636
, ((void*)0)
, SWITCH_LOG_ERROR, "expected 3 arguments from query, instead got %d\n", argc);
5637 return 0;
5638 }
5639
5640 switch_copy_string(cbt->status, argv[0], cbt->status_len);
5641 cbt->count = (argv[1] && switch_is_number(argv[1])) ? atoi(argv[1]) : 0;
5642
5643 switch_copy_string(cbt->contact, argv[2], cbt->contact_len);
5644
5645 return 1;
5646}
5647
5648static void sofia_handle_sip_r_options(switch_core_session_t *session, int status,
5649 char const *phrase,
5650 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
5651 sofia_dispatch_event_t *de,
5652 tagi_t tags[])
5653{
5654 sofia_gateway_t *gateway = NULL((void*)0);
5655 switch_bool_t do_fire_gateway_state_event = SWITCH_FALSE;
5656
5657 if (sofia_private && !zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
5658 gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 5658
, sofia_private->gateway_name)
;
5659 sofia_private->destroy_me = 1;
5660 }
5661
5662 if (gateway) {
5663 if (status >= 200 && status < 600 && status != 408 && status != 503) {
5664 if (gateway->state == REG_STATE_FAILED) {
5665 gateway->state = REG_STATE_UNREGED;
5666 }
5667
5668 if (gateway->ping_count < 0) {
5669 gateway->ping_count = 0;
5670 }
5671
5672 if (gateway->ping_count < gateway->ping_max) {
5673 gateway->ping_count++;
5674
5675 if (gateway->ping_count >= gateway->ping_min && gateway->status != SOFIA_GATEWAY_UP) {
5676 gateway->status = SOFIA_GATEWAY_UP;
5677 gateway->uptime = switch_time_now();
5678 do_fire_gateway_state_event = SWITCH_TRUE;
5679 }
5680
5681 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5681, (const char*)(session)
, SWITCH_LOG_WARNING,
5682 "Ping succeeded %s with code %d - count %d/%d/%d, state %s\n",
5683 gateway->name, status, gateway->ping_min, gateway->ping_count, gateway->ping_max, sofia_gateway_status_name(gateway->status));
5684 }
5685 if (gateway->ping_sent) {
5686 gateway->ping_time = (float)(switch_time_now() - gateway->ping_sent) / 1000;
5687 gateway->ping_sent = 0;
5688 }
5689 } else {
5690 if (gateway->state == REG_STATE_REGED) {
5691 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5691, (const char*)(session)
, SWITCH_LOG_WARNING, "Unregister %s\n", gateway->name);
5692 gateway->state = REG_STATE_FAILED;
5693 gateway->ping_time = 0;
5694 }
5695
5696 if (gateway->ping_count > 0) {
5697 gateway->ping_count--;
5698 }
5699
5700 if (gateway->ping_count < gateway->ping_min && gateway->status != SOFIA_GATEWAY_DOWN) {
5701 gateway->status = SOFIA_GATEWAY_DOWN;
5702 do_fire_gateway_state_event = SWITCH_TRUE;
5703 gateway->ping_time = 0;
5704 }
5705
5706 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5706, (const char*)(session)
, SWITCH_LOG_WARNING,
5707 "Ping failed %s with code %d - count %d/%d/%d, state %s\n",
5708 gateway->name, status, gateway->ping_min, gateway->ping_count, gateway->ping_max, sofia_gateway_status_name(gateway->status));
5709 }
5710 if (gateway->ping_monitoring || do_fire_gateway_state_event) {
5711 sofia_reg_fire_custom_gateway_state_event(gateway, status, phrase);
5712 }
5713
5714 gateway->ping = switch_epoch_time_now(NULL((void*)0)) + gateway->ping_freq;
5715 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 5715, gateway);
;
5716 gateway->pinging = 0;
5717 } else if (sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')(__extension__ (__builtin_constant_p ('_') && !__builtin_constant_p
(sip->sip_call_id->i_id) && ('_') == '\0' ? (char
*) __rawmemchr (sip->sip_call_id->i_id, '_') : __builtin_strchr
(sip->sip_call_id->i_id, '_')))
) {
5718 const char *call_id = strchr(sip->sip_call_id->i_id, '_')(__extension__ (__builtin_constant_p ('_') && !__builtin_constant_p
(sip->sip_call_id->i_id) && ('_') == '\0' ? (char
*) __rawmemchr (sip->sip_call_id->i_id, '_') : __builtin_strchr
(sip->sip_call_id->i_id, '_')))
+ 1;
5719 char *sql;
5720 struct cb_helper_sip_user_status sip_user_status;
5721 char ping_status[255] = "";
5722 char sip_contact[1024] = "";
5723 int sip_user_ping_min = profile->sip_user_ping_min;
5724 int sip_user_ping_max = profile->sip_user_ping_max;
5725
5726 char *sip_user = switch_mprintf("%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
5727
5728 sip_user_status.status = ping_status;
5729 sip_user_status.status_len = sizeof(ping_status);
5730 sip_user_status.contact = sip_contact;
5731 sip_user_status.contact_len = sizeof(sip_contact);
5732 sql = switch_mprintf("select ping_status, ping_count, contact from sip_registrations where sip_user='%s' and sip_host='%s' and call_id='%q'",
5733 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
5734 sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sip_user_status_callback, &sip_user_status);
5735 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
5736
5737 if (status != 200 && status != 486) {
5738 sip_user_status.count--;
5739 if (sip_user_status.count >= 0) {
5740 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5740, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' failed with code %d - count %d, state %s\n",
5741 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
5742 sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count,
5743 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
5744 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
5745 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
5746 }
5747 if (sip_user_status.count < sip_user_ping_min) {
5748 if (strcmp(sip_user_status.status, "Unreachable")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(sip_user_status.status) && __builtin_constant_p ("Unreachable"
) && (__s1_len = __builtin_strlen (sip_user_status.status
), __s2_len = __builtin_strlen ("Unreachable"), (!((size_t)(const
void *)((sip_user_status.status) + 1) - (size_t)(const void *
)(sip_user_status.status) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("Unreachable") + 1) - (size_t)(const
void *)("Unreachable") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(sip_user_status.status, "Unreachable") : (__builtin_constant_p
(sip_user_status.status) && ((size_t)(const void *)(
(sip_user_status.status) + 1) - (size_t)(const void *)(sip_user_status
.status) == 1) && (__s1_len = __builtin_strlen (sip_user_status
.status), __s1_len < 4) ? (__builtin_constant_p ("Unreachable"
) && ((size_t)(const void *)(("Unreachable") + 1) - (
size_t)(const void *)("Unreachable") == 1) ? __builtin_strcmp
(sip_user_status.status, "Unreachable") : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
("Unreachable"); int __result = (((const unsigned char *) (const
char *) (sip_user_status.status))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (sip_user_status.status))[1] - __s2[1
]); if (__s1_len > 1 && __result == 0) { __result =
(((const unsigned char *) (const char *) (sip_user_status.status
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (sip_user_status
.status))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("Unreachable") && ((size_t)(const void *)(("Unreachable"
) + 1) - (size_t)(const void *)("Unreachable") == 1) &&
(__s2_len = __builtin_strlen ("Unreachable"), __s2_len < 4
) ? (__builtin_constant_p (sip_user_status.status) &&
((size_t)(const void *)((sip_user_status.status) + 1) - (size_t
)(const void *)(sip_user_status.status) == 1) ? __builtin_strcmp
(sip_user_status.status, "Unreachable") : (- (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) (sip_user_status.status); int __result = (((const unsigned
char *) (const char *) ("Unreachable"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("Unreachable"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("Unreachable"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("Unreachable"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (sip_user_status.status, "Unreachable"
)))); })
) {
5749 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5749, (const char*)(session)
, SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Unreachable\n",
5750 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
5751 sql = switch_mprintf("update sip_registrations set ping_status='Unreachable' where sip_user='%s' and sip_host='%s' and call_id='%q'",
5752 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
5753 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
5754 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
5755 sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
5756 sip->sip_to->a_url->url_host, call_id, SOFIA_REG_REACHABLE, status, phrase);
5757
5758 if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)((profile)->pflags[PFLAG_UNREG_OPTIONS_FAIL] ? 1 : 0)) {
5759 time_t now = switch_epoch_time_now(NULL((void*)0));
5760 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5760, (const char*)(session)
, SWITCH_LOG_WARNING, "Expire sip user '%s@%s' due to options failure\n",
5761 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
5762
5763 sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' and call_id='%q'",
5764 (long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
5765 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
5766 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
5767 }
5768 }
5769 }
5770 } else {
5771 sip_user_status.count++;
5772 if (sip_user_status.count <= sip_user_ping_max) {
5773 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5773, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' succeeded with code %d - count %d, state %s\n",
5774 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
5775 sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count,
5776 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
5777 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
5778 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
5779 }
5780 if (sip_user_status.count >= sip_user_ping_min) {
5781 if (strcmp(sip_user_status.status, "Reachable")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(sip_user_status.status) && __builtin_constant_p ("Reachable"
) && (__s1_len = __builtin_strlen (sip_user_status.status
), __s2_len = __builtin_strlen ("Reachable"), (!((size_t)(const
void *)((sip_user_status.status) + 1) - (size_t)(const void *
)(sip_user_status.status) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("Reachable") + 1) - (size_t)(const
void *)("Reachable") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(sip_user_status.status, "Reachable") : (__builtin_constant_p
(sip_user_status.status) && ((size_t)(const void *)(
(sip_user_status.status) + 1) - (size_t)(const void *)(sip_user_status
.status) == 1) && (__s1_len = __builtin_strlen (sip_user_status
.status), __s1_len < 4) ? (__builtin_constant_p ("Reachable"
) && ((size_t)(const void *)(("Reachable") + 1) - (size_t
)(const void *)("Reachable") == 1) ? __builtin_strcmp (sip_user_status
.status, "Reachable") : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) ("Reachable")
; int __result = (((const unsigned char *) (const char *) (sip_user_status
.status))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
sip_user_status.status))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (sip_user_status.status))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (sip_user_status.status))[3] - __s2[3
]); } } __result; }))) : (__builtin_constant_p ("Reachable") &&
((size_t)(const void *)(("Reachable") + 1) - (size_t)(const void
*)("Reachable") == 1) && (__s2_len = __builtin_strlen
("Reachable"), __s2_len < 4) ? (__builtin_constant_p (sip_user_status
.status) && ((size_t)(const void *)((sip_user_status.
status) + 1) - (size_t)(const void *)(sip_user_status.status)
== 1) ? __builtin_strcmp (sip_user_status.status, "Reachable"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (sip_user_status.status); int __result
= (((const unsigned char *) (const char *) ("Reachable"))[0]
- __s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("Reachable"))[1]
- __s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("Reachable"))[2]
- __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("Reachable"))[3]
- __s2[3]); } } __result; })))) : __builtin_strcmp (sip_user_status
.status, "Reachable")))); })
) {
5782 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5782, (const char*)(session)
, SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Reachable\n",
5783 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
5784 sql = switch_mprintf("update sip_registrations set ping_status='Reachable' where sip_user='%s' and sip_host='%s' and call_id='%q'",
5785 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
5786 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
5787 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
5788 sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
5789 sip->sip_to->a_url->url_host, call_id, SOFIA_REG_UNREACHABLE, status, phrase);
5790 }
5791 }
5792 }
5793
5794 switch_safe_free(sip_user)if (sip_user) {free(sip_user);sip_user=((void*)0);};
5795
5796 }
5797}
5798
5799static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
5800 char const *phrase,
5801 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
5802 sofia_dispatch_event_t *de,
5803 tagi_t tags[])
5804{
5805 char *call_info = NULL((void*)0);
5806
5807 if (sip && session) {
5808 switch_channel_t *channel = switch_core_session_get_channel(session);
5809 const char *uuid;
5810 switch_core_session_t *other_session;
5811 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
5812 char network_ip[80];
5813 int network_port = 0;
5814 switch_caller_profile_t *caller_profile = NULL((void*)0);
5815 int has_t38 = 0;
5816
5817 switch_channel_clear_flag(channel, CF_REQ_MEDIA);
5818
5819 if (status >= 900) {
5820 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5820, (const char*)(session)
, SWITCH_LOG_ERROR, "%s status %d received.\n",
5821 switch_channel_get_name(channel), status);
5822 return;
5823 }
5824
5825 if (status > 299) {
5826 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_refuse")switch_channel_set_variable_var_check(channel, "sip_hangup_disposition"
, "recv_refuse", SWITCH_TRUE)
;
5827 }
5828
5829 if (status >= 400) {
5830 char status_str[5];
5831 switch_snprintf(status_str, sizeof(status_str), "%d", status);
5832 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)
;
5833 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)
;
5834 }
5835
5836 if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
5837 || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
5838 || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
5839 tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
5840 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5840, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote Reason: %d\n", tech_pvt->q850_cause);
5841 }
5842
5843 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
5844
5845 switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
5846 switch_channel_set_variable(channel, "sip_reply_host", network_ip)switch_channel_set_variable_var_check(channel, "sip_reply_host"
, network_ip, SWITCH_TRUE)
;
5847 switch_channel_set_variable_printf(channel, "sip_reply_port", "%d", network_port);
5848
5849 switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip);
5850 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
5851
5852 if ((caller_profile = switch_channel_get_caller_profile(channel))) {
5853 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__, 5853)
;
5854 }
5855
5856 tech_pvt->mparams.last_sdp_response = NULL((void*)0);
5857 if (sip->sip_payload && sip->sip_payload->pl_data) {
5858 switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE);
5859 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__, 5859)
;
5860 }
5861
5862 if (status > 299 && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ)) {
5863 switch_channel_set_private(channel, "t38_options", NULL((void*)0));
5864 switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
5865 switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ);
5866 switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_FAIL);
5867 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5867, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s T38 invite failed\n", switch_channel_get_name(tech_pvt->channel));
5868 }
5869
5870
5871 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
5872 if (channel && sip->sip_call_info) {
5873 char *p;
5874 call_info = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info);
5875
5876 if (switch_stristr("appearance", call_info)) {
5877 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)
;
5878 if ((p = strchr(call_info, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(call_info) && (';') == '\0' ? (char *) __rawmemchr (
call_info, ';') : __builtin_strchr (call_info, ';')))
)) {
5879 switch_channel_set_variable(channel, "presence_call_info", p + 1)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p + 1, SWITCH_TRUE)
;
5880 }
5881 }
5882 } else if ((status == 180 || status == 183 || status == 200)) {
5883 char buf[128] = "";
5884 char *sql;
5885 char *state = "active";
5886
5887 if (status != 200) {
5888 state = "progressing";
5889 }
5890
5891 if (sip &&
5892 sip->sip_from && sip->sip_from->a_url && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
5893 sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
5894 sql =
5895 switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
5896 "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
5897 sip->sip_from->a_url->url_host);
5898 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
5899
5900 if (mod_sofia_globals.debug_sla > 1) {
5901 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5901
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
5902 }
5903 free(sql);
5904
5905 if (!zstr(buf)_zstr(buf)) {
5906 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
5907 "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
5908
5909 if (mod_sofia_globals.debug_sla > 1) {
5910 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 5910
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
5911 }
5912
5913 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
5914
5915 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
5915, (const char*)(session)
, SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
5916 sip->sip_from->a_url->url_host, buf);
5917 switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
5918 switch_channel_set_variable(channel, "presence_call_info", buf)switch_channel_set_variable_var_check(channel, "presence_call_info"
, buf, SWITCH_TRUE)
;
5919 }
5920 }
5921 }
5922 }
5923
5924#if 0
5925 if (status == 200 && switch_channel_test_flag(channel, CF_PROXY_MEDIA) &&
5926 sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(tech_pvt->iananame, "PROXY")) {
5927 switch_core_session_t *other_session;
5928
5929 switch_core_media_proxy_codec(session, sip->sip_payload->pl_data);
5930
5931 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 5931)
== SWITCH_STATUS_SUCCESS) {
5932 if (switch_core_session_compare(session, other_session)) {
5933 switch_core_media_proxy_codec(other_session, sip->sip_payload->pl_data);
5934 }
5935 switch_core_session_rwunlock(other_session);
5936 }
5937 }
5938#endif
5939
5940
5941
5942 if ((status == 180 || status == 183 || status > 199)) {
5943 const char *vval;
5944
5945 if (status > 199) {
5946 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_RESPONSE_HEADER_PREFIX"sip_rh_");
5947 } else {
5948 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_PROGRESS_HEADER_PREFIX"sip_ph_");
5949 }
5950
5951
5952 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)) {
5953 switch_core_session_t *other_session;
5954
5955 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 5955)
== SWITCH_STATUS_SUCCESS) {
5956 if (status > 199) {
5957 switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_RESPONSE_HEADER_PREFIX_T"~sip_rh_");
5958 } else {
5959 switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_PROGRESS_HEADER_PREFIX_T"~sip_ph_");
5960 }
5961 switch_core_session_rwunlock(other_session);
5962 }
5963 }
5964 }
5965
5966 if ((status == 180 || status == 183 || status == 200)) {
5967 const char *x_freeswitch_support;
5968
5969 switch_channel_set_flag(channel, CF_MEDIA_ACK)switch_channel_set_flag_value(channel, CF_MEDIA_ACK, 1);
5970
5971 if ((x_freeswitch_support = sofia_glue_get_unknown_header(sip, "X-FS-Support"))) {
5972 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__, 5972)
;
5973 }
5974
5975 if (sip->sip_user_agent && sip->sip_user_agent->g_string) {
5976 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)
;
5977 } else if (sip->sip_server && sip->sip_server->g_string) {
5978 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)
;
5979 }
5980
5981 sofia_update_callee_id(session, profile, sip, SWITCH_FALSE);
5982
5983 if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)((tech_pvt->profile)->media_flags[SCMF_AUTOFIX_TIMING] ?
1 : 0)
) {
5984 switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
5985 }
5986
5987 }
5988
5989 if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
5990 sip_contact_t *p_contact = sip->sip_contact;
5991 int i = 0;
5992 char var_name[80];
5993 const char *diversion_header;
5994 char *full_contact = NULL((void*)0);
5995 char *invite_contact;
5996 const char *br;
5997 const char *v;
5998
5999 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)) {
6000 switch_channel_hangup(channel, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6000, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL)
;
6001 goto end;
6002 }
6003
6004 if (!p_contact) {
6005 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6005, (const char*)(session)
, SWITCH_LOG_ERROR, "Missing contact header in redirect request\n");
6006 goto end;
6007 }
6008
6009 if ((br = switch_channel_get_partner_uuid(channel))) {
6010 switch_xml_t root = NULL((void*)0), domain = NULL((void*)0);
6011 switch_core_session_t *a_session;
6012 switch_channel_t *a_channel;
6013
6014 const char *sip_redirect_profile, *sip_redirect_context, *sip_redirect_dialplan, *sip_redirect_fork;
6015
6016 if ((a_session = switch_core_session_locate(br)switch_core_session_perform_locate(br, "sofia.c", (const char
*)__func__, 6016)
) && (a_channel = switch_core_session_get_channel(a_session))) {
6017 switch_stream_handle_t stream = { 0 };
6018 char separator[2] = "|";
6019 char *redirect_dialstring;
6020 su_home_t *home = su_home_new(sizeof(*home));
6021 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6021, __PRETTY_FUNCTION__))
;
6022
6023 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 6023, __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
;
6024
6025 if (!(sip_redirect_profile = switch_channel_get_variable(channel, "sip_redirect_profile")switch_channel_get_variable_dup(channel, "sip_redirect_profile"
, SWITCH_TRUE, -1)
)) {
6026 sip_redirect_profile = profile->name;
6027 }
6028 if (!(sip_redirect_context = switch_channel_get_variable(channel, "sip_redirect_context")switch_channel_get_variable_dup(channel, "sip_redirect_context"
, SWITCH_TRUE, -1)
)) {
6029 sip_redirect_context = "redirected";
6030 }
6031 if (!(sip_redirect_dialplan = switch_channel_get_variable(channel, "sip_redirect_dialplan")switch_channel_get_variable_dup(channel, "sip_redirect_dialplan"
, SWITCH_TRUE, -1)
)) {
6032 sip_redirect_dialplan = "XML";
6033 }
6034
6035 sip_redirect_fork = switch_channel_get_variable(channel, "sip_redirect_fork")switch_channel_get_variable_dup(channel, "sip_redirect_fork",
SWITCH_TRUE, -1)
;
6036
6037 if (switch_true(sip_redirect_fork)) {
6038 *separator = ',';
6039 }
6040
6041 for (p_contact = sip->sip_contact; p_contact; p_contact = p_contact->m_next) {
6042 if (p_contact->m_url) {
6043 full_contact = sip_header_as_string(home, (void *) p_contact);
6044 invite_contact = sofia_glue_strip_uri(full_contact);
6045
6046 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_%d", i);
6047 switch_channel_set_variable(a_channel, var_name, full_contact)switch_channel_set_variable_var_check(a_channel, var_name, full_contact
, SWITCH_TRUE)
;
6048
6049 if (i == 0) {
6050 switch_channel_set_variable(channel, "sip_redirected_to", full_contact)switch_channel_set_variable_var_check(channel, "sip_redirected_to"
, full_contact, SWITCH_TRUE)
;
6051 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)
;
6052 }
6053
6054 if (p_contact->m_url->url_user) {
6055 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_user_%d", i);
6056 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)
;
6057 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)
;
6058 }
6059 if (p_contact->m_url->url_host) {
6060 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_host_%d", i);
6061 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)
;
6062 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)
;
6063 }
6064 if (p_contact->m_url->url_params) {
6065 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_params_%d", i);
6066 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)
;
6067 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)
;
6068 }
6069
6070 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_dialstring_%d", i);
6071 switch_channel_set_variable_printf(channel, var_name, "sofia/%s/%s", sip_redirect_profile, invite_contact);
6072 switch_channel_set_variable_printf(a_channel, var_name, "sofia/%s/%s", sip_redirect_profile, invite_contact);
6073 stream.write_function(&stream, "%ssofia/%s/%s", i ? separator : "", sip_redirect_profile, invite_contact);
6074 free(invite_contact);
6075 i++;
6076 }
6077 }
6078
6079 redirect_dialstring = stream.data;
6080
6081 switch_channel_set_variable_printf(channel, "sip_redirect_count", "%d", i);
6082 switch_channel_set_variable(channel, "sip_redirect_dialstring", redirect_dialstring)switch_channel_set_variable_var_check(channel, "sip_redirect_dialstring"
, redirect_dialstring, SWITCH_TRUE)
;
6083 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)
;
6084
6085 p_contact = sip->sip_contact;
6086 full_contact = sip_header_as_string(home, (void *) sip->sip_contact);
6087
6088 if ((diversion_header = sofia_glue_get_unknown_header(sip, "diversion"))) {
6089 switch_channel_set_variable(channel, "sip_redirected_by", diversion_header)switch_channel_set_variable_var_check(channel, "sip_redirected_by"
, diversion_header, SWITCH_TRUE)
;
6090 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)
;
6091 }
6092
6093 if (sofia_test_pflag(profile, PFLAG_MANUAL_REDIRECT)((profile)->pflags[PFLAG_MANUAL_REDIRECT] ? 1 : 0)) {
6094 if (!(v = switch_channel_get_variable(channel, "outbound_redirect_info")switch_channel_get_variable_dup(channel, "outbound_redirect_info"
, SWITCH_TRUE, -1)
)) {
6095 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6095, (const char*)(session)
, SWITCH_LOG_DEBUG, "Redirect: Transfering to %s %s %s\n",
6096 p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
6097
6098 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
6099 switch_core_media_bug_transfer_recordings(session, a_session);
6100 }
6101
6102 switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
6103 }
6104 switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6104, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION
)
;
6105 } else if ((!strcmp(profile->sipip, p_contact->m_url->url_host)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(profile->sipip) && __builtin_constant_p (p_contact
->m_url->url_host) && (__s1_len = __builtin_strlen
(profile->sipip), __s2_len = __builtin_strlen (p_contact->
m_url->url_host), (!((size_t)(const void *)((profile->sipip
) + 1) - (size_t)(const void *)(profile->sipip) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((p_contact->
m_url->url_host) + 1) - (size_t)(const void *)(p_contact->
m_url->url_host) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(profile->sipip, p_contact->m_url->url_host) : (__builtin_constant_p
(profile->sipip) && ((size_t)(const void *)((profile
->sipip) + 1) - (size_t)(const void *)(profile->sipip) ==
1) && (__s1_len = __builtin_strlen (profile->sipip
), __s1_len < 4) ? (__builtin_constant_p (p_contact->m_url
->url_host) && ((size_t)(const void *)((p_contact->
m_url->url_host) + 1) - (size_t)(const void *)(p_contact->
m_url->url_host) == 1) ? __builtin_strcmp (profile->sipip
, p_contact->m_url->url_host) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(p_contact->m_url->url_host); int __result = (((const unsigned
char *) (const char *) (profile->sipip))[0] - __s2[0]); if
(__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (profile->sipip))[1] - __s2
[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (profile->sipip
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (profile
->sipip))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(p_contact->m_url->url_host) && ((size_t)(const
void *)((p_contact->m_url->url_host) + 1) - (size_t)(const
void *)(p_contact->m_url->url_host) == 1) && (
__s2_len = __builtin_strlen (p_contact->m_url->url_host
), __s2_len < 4) ? (__builtin_constant_p (profile->sipip
) && ((size_t)(const void *)((profile->sipip) + 1)
- (size_t)(const void *)(profile->sipip) == 1) ? __builtin_strcmp
(profile->sipip, p_contact->m_url->url_host) : (- (
__extension__ ({ const unsigned char *__s2 = (const unsigned char
*) (const char *) (profile->sipip); int __result = (((const
unsigned char *) (const char *) (p_contact->m_url->url_host
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (p_contact
->m_url->url_host))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (p_contact->m_url->url_host))[2] - __s2[2]); if
(__s2_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (p_contact->m_url->url_host
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (profile
->sipip, p_contact->m_url->url_host)))); })
)
6106 || (profile->extsipip && !strcmp(profile->extsipip, p_contact->m_url->url_host)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(profile->extsipip) && __builtin_constant_p (p_contact
->m_url->url_host) && (__s1_len = __builtin_strlen
(profile->extsipip), __s2_len = __builtin_strlen (p_contact
->m_url->url_host), (!((size_t)(const void *)((profile->
extsipip) + 1) - (size_t)(const void *)(profile->extsipip)
== 1) || __s1_len >= 4) && (!((size_t)(const void
*)((p_contact->m_url->url_host) + 1) - (size_t)(const void
*)(p_contact->m_url->url_host) == 1) || __s2_len >=
4)) ? __builtin_strcmp (profile->extsipip, p_contact->
m_url->url_host) : (__builtin_constant_p (profile->extsipip
) && ((size_t)(const void *)((profile->extsipip) +
1) - (size_t)(const void *)(profile->extsipip) == 1) &&
(__s1_len = __builtin_strlen (profile->extsipip), __s1_len
< 4) ? (__builtin_constant_p (p_contact->m_url->url_host
) && ((size_t)(const void *)((p_contact->m_url->
url_host) + 1) - (size_t)(const void *)(p_contact->m_url->
url_host) == 1) ? __builtin_strcmp (profile->extsipip, p_contact
->m_url->url_host) : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (p_contact->
m_url->url_host); int __result = (((const unsigned char *)
(const char *) (profile->extsipip))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (profile->extsipip))[1] - __s2[1])
; if (__s1_len > 1 && __result == 0) { __result = (
((const unsigned char *) (const char *) (profile->extsipip
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (profile
->extsipip))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(p_contact->m_url->url_host) && ((size_t)(const
void *)((p_contact->m_url->url_host) + 1) - (size_t)(const
void *)(p_contact->m_url->url_host) == 1) && (
__s2_len = __builtin_strlen (p_contact->m_url->url_host
), __s2_len < 4) ? (__builtin_constant_p (profile->extsipip
) && ((size_t)(const void *)((profile->extsipip) +
1) - (size_t)(const void *)(profile->extsipip) == 1) ? __builtin_strcmp
(profile->extsipip, p_contact->m_url->url_host) : (
- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (profile->extsipip); int __result =
(((const unsigned char *) (const char *) (p_contact->m_url
->url_host))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (p_contact->m_url->url_host))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (p_contact->m_url->url_host
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (p_contact
->m_url->url_host))[3] - __s2[3]); } } __result; })))) :
__builtin_strcmp (profile->extsipip, p_contact->m_url->
url_host)))); })
)
6107 || (switch_xml_locate_domain(p_contact->m_url->url_host, NULL((void*)0), &root, &domain) == SWITCH_STATUS_SUCCESS)) {
6108 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6108, (const char*)(session)
, SWITCH_LOG_DEBUG, "Redirect: Transfering to %s\n",
6109 p_contact->m_url->url_user);
6110
6111 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
6112 switch_core_media_bug_transfer_recordings(session, a_session);
6113 }
6114
6115 switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, NULL((void*)0), NULL((void*)0));
6116 switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6116, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION
)
;
6117 switch_xml_free(root);
6118 } else {
6119 invite_contact = sofia_glue_strip_uri(full_contact);
6120 tech_pvt->redirected = switch_core_session_strdup(session, invite_contact)switch_core_perform_session_strdup(session, invite_contact, "sofia.c"
, (const char *)__func__, 6120)
;
6121 free(invite_contact);
6122 }
6123
6124 if (home) {
6125 su_home_unref(home);
6126 home = NULL((void*)0);
6127 }
6128
6129 free(stream.data);
6130
6131 switch_core_session_rwunlock(a_session);
6132 }
6133 } else {
6134 su_home_t *home = su_home_new(sizeof(*home));
6135 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6135, __PRETTY_FUNCTION__))
;
6136 full_contact = sip_header_as_string(home, (void *) sip->sip_contact);
6137 invite_contact = sofia_glue_strip_uri(full_contact);
6138
6139 switch_channel_set_variable(channel, "sip_redirected_to", invite_contact)switch_channel_set_variable_var_check(channel, "sip_redirected_to"
, invite_contact, SWITCH_TRUE)
;
6140 tech_pvt->redirected = switch_core_session_strdup(session, invite_contact)switch_core_perform_session_strdup(session, invite_contact, "sofia.c"
, (const char *)__func__, 6140)
;
6141
6142 free(invite_contact);
6143
6144 if (home) {
6145 su_home_unref(home);
6146 home = NULL((void*)0);
6147 }
6148 }
6149 }
6150
6151
6152 if (sip->sip_payload && sip->sip_payload->pl_data && switch_stristr("m=image", sip->sip_payload->pl_data)) {
6153 has_t38 = 1;
6154 }
6155
6156 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
6157 switch_channel_clear_flag(channel, CF_T38_PASSTHRU);
6158 has_t38 = 0;
6159 }
6160
6161 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && has_t38) {
6162 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
6163 switch_core_media_udptl_mode(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
6164
6165 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__, 6165)
)) {
6166 if (switch_core_session_compare(session, other_session)) {
6167 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
6168 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
6169 switch_core_media_udptl_mode(other_tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
6170 }
6171 }
6172 switch_core_session_rwunlock(other_session);
6173 }
6174 }
6175
6176 has_t38 = 0;
6177 }
6178
6179 if (status > 199 && (switch_channel_test_flag(channel, CF_PROXY_MODE) ||
6180 switch_channel_test_flag(channel, CF_PROXY_MEDIA) ||
6181 (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && (has_t38 || status > 299)))) {
6182
6183 if (sofia_test_flag(tech_pvt, TFLAG_SENT_UPDATE)((tech_pvt)->flags[TFLAG_SENT_UPDATE] ? 1 : 0)) {
6184 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
);
;
6185
6186 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__, 6186)
)) {
6187 const char *r_sdp = NULL((void*)0);
6188 switch_core_session_message_t *msg;
6189 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
6190 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
6191
6192 if (sip->sip_payload && sip->sip_payload->pl_data &&
6193 sip->sip_content_type && sip->sip_content_type->c_subtype && switch_stristr("sdp", sip->sip_content_type->c_subtype)) {
6194 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__, 6194
)
;
6195 r_sdp = tech_pvt->mparams.remote_sdp_str;
6196 switch_core_media_proxy_remote_addr(session, NULL((void*)0));
6197 }
6198
6199 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6199, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n", status, phrase);
6200
6201 if (status == 491 && (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) ||
6202 switch_channel_test_flag(channel, CF_PROXY_MODE))) {
6203 nua_respond(other_tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending, TAG_END()(tag_type_t)0, (tag_value_t)0);
6204 switch_core_session_rwunlock(other_session);
6205 goto end;
6206 } else if (status > 299) {
6207 switch_channel_set_private(channel, "t38_options", NULL((void*)0));
6208 switch_channel_set_private(other_channel, "t38_options", NULL((void*)0));
6209 switch_channel_clear_flag(channel, CF_T38_PASSTHRU);
6210 switch_channel_clear_flag(other_channel, CF_T38_PASSTHRU);
6211 switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38);
6212 switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38_REQ);
6213 switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_FAIL);
6214 } else if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) &&
6215 has_t38 && sip->sip_payload && sip->sip_payload->pl_data) {
6216 switch_t38_options_t *t38_options = switch_core_media_extract_t38_options(session, sip->sip_payload->pl_data);
6217
6218 if (!t38_options) {
6219 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6219, (const char*)(session)
, SWITCH_LOG_WARNING, "Could not parse T.38 options from sdp.\n");
6220 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)
;
6221 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6221, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
6222 switch_core_session_rwunlock(other_session);
6223 goto end;
6224 } else {
6225 switch_core_media_process_t38_passthru(session, other_session, t38_options);
6226 }
6227 }
6228
6229
6230 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 6230)
;
6231 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
6232 msg->from = __FILE__"sofia.c";
6233 msg->numeric_arg = status;
6234 msg->string_arg = switch_core_session_strdup(other_session, phrase)switch_core_perform_session_strdup(other_session, phrase, "sofia.c"
, (const char *)__func__, 6234)
;
6235
6236 if (status == 200 && switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && has_t38) {
6237 msg->pointer_arg = switch_core_session_strdup(other_session, "t38")switch_core_perform_session_strdup(other_session, "t38", "sofia.c"
, (const char *)__func__, 6237)
;
6238 } else if (r_sdp) {
6239 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__, 6239)
;
6240 msg->pointer_arg_size = strlen(r_sdp);
6241 }
6242
6243 if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) && has_t38) {
6244 if (switch_core_media_ready(session, SWITCH_MEDIA_TYPE_AUDIO) &&
6245 switch_core_media_ready(other_session, SWITCH_MEDIA_TYPE_AUDIO)) {
6246 switch_channel_clear_flag(channel, CF_NOTIMER_DURING_BRIDGE);
6247 switch_core_media_udptl_mode(session, SWITCH_MEDIA_TYPE_AUDIO);
6248 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6248, (const char*)(session)
, SWITCH_LOG_INFO, "Activating T38 Passthru\n");
6249 }
6250 }
6251
6252 switch_core_session_queue_message(other_session, msg);
6253
6254 switch_core_session_rwunlock(other_session);
6255 }
6256 goto end;
6257 }
6258 }
6259
6260 if ((status == 180 || status == 183 || status == 200)) {
6261 const char *astate = "early";
6262 url_t *from = NULL((void*)0), *to = NULL((void*)0), *contact = NULL((void*)0);
6263
6264 if (sip->sip_to) {
6265 to = sip->sip_to->a_url;
6266 }
6267 if (sip->sip_from) {
6268 from = sip->sip_from->a_url;
6269 }
6270 if (sip->sip_contact) {
6271 contact = sip->sip_contact->m_url;
6272 }
6273
6274 if (status == 200) {
6275 astate = "confirmed";
6276 }
6277
6278 if ((!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED) &&
6279 !switch_channel_test_flag(channel, CF_RING_READY)) || switch_channel_test_flag(channel, CF_RECOVERING)) {
6280 const char *from_user = "", *from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
6281 const char *user_agent = "", *call_id = "";
6282 const char *to_tag = "";
6283 const char *from_tag = "";
6284 char *sql = NULL((void*)0);
6285
6286 if (sip->sip_user_agent) {
6287 user_agent = switch_str_nil(sip->sip_user_agent->g_string)(sip->sip_user_agent->g_string ? sip->sip_user_agent
->g_string : "")
;
6288 }
6289
6290 if (sip->sip_call_id) {
6291 call_id = switch_str_nil(sip->sip_call_id->i_id)(sip->sip_call_id->i_id ? sip->sip_call_id->i_id :
"")
;
6292 }
6293
6294 if (to) {
6295 from_user = switch_str_nil(to->url_user)(to->url_user ? to->url_user : "");
6296 from_tag = switch_str_nil(sip->sip_to->a_tag)(sip->sip_to->a_tag ? sip->sip_to->a_tag : "");
6297 }
6298
6299 if (from) {
6300 from_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
6301 to_user = switch_str_nil(from->url_user)(from->url_user ? from->url_user : "");
6302 to_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
6303 to_tag = switch_str_nil(sip->sip_from->a_tag)(sip->sip_from->a_tag ? sip->sip_from->a_tag : ""
)
;
6304 }
6305
6306 if (contact) {
6307 contact_user = switch_str_nil(contact->url_user)(contact->url_user ? contact->url_user : "");
6308 contact_host = switch_str_nil(contact->url_host)(contact->url_host ? contact->url_host : "");
6309 }
6310
6311 if (profile->pres_type) {
6312 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
6313 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
6314 char *full_contact = NULL((void*)0);
6315 char *p = NULL((void*)0);
6316 time_t now;
6317
6318 if (sip->sip_contact) {
6319 full_contact = sip_header_as_string(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), (void *) sip->sip_contact);
6320 }
6321
6322 if (call_info && (p = strchr(call_info, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(call_info) && (';') == '\0' ? (char *) __rawmemchr (
call_info, ';') : __builtin_strchr (call_info, ';')))
)) {
6323 p++;
6324 }
6325
6326 now = switch_epoch_time_now(NULL((void*)0));
6327
6328 sql = switch_mprintf("insert into sip_dialogs "
6329 "(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
6330 "contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
6331 "call_info,rcd,call_info_state) "
6332 "values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
6333 call_id,
6334 switch_core_session_get_uuid(session),
6335 to_user, to_host, to_tag, from_user, from_host, from_tag, contact_user,
6336 contact_host, astate, "outbound", user_agent,
6337 profile->name, mod_sofia_globals.hostname, switch_str_nil(full_contact)(full_contact ? full_contact : ""),
6338 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);
6339 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 6339, __PRETTY_FUNCTION__
))
;
6340
6341 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
6342
6343 if ( full_contact ) {
6344 su_free(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), full_contact);
6345 }
6346 }
6347 } else if (status == 200 && (profile->pres_type)) {
6348 char *sql = NULL((void*)0);
6349 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
6350 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
6351
6352 sql = switch_mprintf("update sip_dialogs set state='%q',presence_id='%q',presence_data='%q' "
6353 "where uuid='%s';\n", astate, switch_str_nil(presence_id)(presence_id ? presence_id : ""), switch_str_nil(presence_data)(presence_data ? presence_data : ""),
6354 switch_core_session_get_uuid(session));
6355 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 6355, __PRETTY_FUNCTION__
))
;
6356 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
6357 }
6358
6359 extract_header_vars(profile, sip, session, nh);
6360 extract_vars(profile, sip, session);
6361 switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING);
6362 }
6363
6364 }
6365
6366 end:
6367
6368 if (call_info) {
6369 su_free(nua_handle_home(nh)((su_home_t *)(nh)), call_info);
6370 }
6371
6372 if (!session && (status == 180 || status == 183 || status == 200)) {
6373 /* nevermind */
6374 nua_handle_bind(nh, NULL((void*)0));
6375 nua_handle_destroy(nh);
6376 }
6377}
6378
6379/* Pure black magic, if you can't understand this code you are lucky.........*/
6380void *SWITCH_THREAD_FUNC media_on_hold_thread_run(switch_thread_t *thread, void *obj)
6381{
6382 switch_core_session_t *other_session = NULL((void*)0), *session = (switch_core_session_t *) obj;
6383 const char *uuid;
6384
6385 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
6386 switch_channel_t *channel = switch_core_session_get_channel(session);
6387 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
6388
6389 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__, 6389)
)) {
6390 if (switch_core_session_compare(session, other_session)) {
6391 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
6392 sofia_set_flag_locked(tech_pvt, TFLAG_HOLD_LOCK)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 6392, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_HOLD_LOCK] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
6393
6394 switch_yield(250000)switch_sleep(250000);;
6395 switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
6396 switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL((void*)0));
6397
6398 switch_ivr_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE|SMF_REPLYONLY_B);
6399
6400 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
6401 switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
6402 }
6403
6404 switch_core_media_toggle_hold(session, 1);
6405 }
6406 switch_core_session_rwunlock(other_session);
6407 }
6408
6409 switch_core_session_rwunlock(session);
6410 }
6411
6412 return NULL((void*)0);
6413}
6414
6415static void launch_media_on_hold(switch_core_session_t *session)
6416{
6417 switch_thread_t *thread;
6418 switch_threadattr_t *thd_attr = NULL((void*)0);
6419
6420 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
6421 switch_threadattr_detach_set(thd_attr, 1);
6422 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
6423 switch_thread_create(&thread, thd_attr, media_on_hold_thread_run, session, switch_core_session_get_pool(session));
6424}
6425
6426
6427
6428static void mark_transfer_record(switch_core_session_t *session, const char *br_a, const char *br_b)
6429{
6430 switch_core_session_t *br_b_session, *br_a_session;
6431 switch_channel_t *channel;
6432 const char *uvar1, *dvar1, *uvar2, *dvar2;
6433
6434 channel = switch_core_session_get_channel(session);
6435
6436 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
6437 uvar1 = "sip_from_user";
6438 dvar1 = "sip_from_host";
6439 } else {
6440 uvar1 = "sip_to_user";
6441 dvar1 = "sip_to_host";
6442 }
6443
6444
6445 if ((br_b_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 6445)
) ) {
6446 switch_channel_t *br_b_channel = switch_core_session_get_channel(br_b_session);
6447 switch_caller_profile_t *cp = switch_channel_get_caller_profile(br_b_channel);
6448
6449 if (switch_channel_direction(br_b_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
6450 uvar2 = "sip_from_user";
6451 dvar2 = "sip_from_host";
6452 } else {
6453 uvar2 = "sip_to_user";
6454 dvar2 = "sip_to_host";
6455 }
6456
6457 cp->transfer_source = switch_core_sprintf(cp->pool,
6458 "%ld:%s:att_xfer:%s@%s/%s@%s",
6459 (long) switch_epoch_time_now(NULL((void*)0)),
6460 cp->uuid_str,
6461 switch_channel_get_variable(channel, uvar1)switch_channel_get_variable_dup(channel, uvar1, SWITCH_TRUE, -
1)
,
6462 switch_channel_get_variable(channel, dvar1)switch_channel_get_variable_dup(channel, dvar1, SWITCH_TRUE, -
1)
,
6463 switch_channel_get_variable(br_b_channel, uvar2)switch_channel_get_variable_dup(br_b_channel, uvar2, SWITCH_TRUE
, -1)
,
6464 switch_channel_get_variable(br_b_channel, dvar2)switch_channel_get_variable_dup(br_b_channel, dvar2, SWITCH_TRUE
, -1)
);
6465
6466 switch_channel_add_variable_var_check(br_b_channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history", cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
6467 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)
;
6468
6469 switch_core_session_rwunlock(br_b_session);
6470 }
6471
6472
6473
6474 if ((br_a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 6474)
) ) {
6475 switch_channel_t *br_a_channel = switch_core_session_get_channel(br_a_session);
6476 switch_caller_profile_t *cp = switch_channel_get_caller_profile(br_a_channel);
6477
6478 if (switch_channel_direction(br_a_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
6479 uvar2 = "sip_from_user";
6480 dvar2 = "sip_from_host";
6481 } else {
6482 uvar2 = "sip_to_user";
6483 dvar2 = "sip_to_host";
6484 }
6485
6486 cp->transfer_source = switch_core_sprintf(cp->pool,
6487 "%ld:%s:att_xfer:%s@%s/%s@%s",
6488 (long) switch_epoch_time_now(NULL((void*)0)),
6489 cp->uuid_str,
6490 switch_channel_get_variable(channel, uvar1)switch_channel_get_variable_dup(channel, uvar1, SWITCH_TRUE, -
1)
,
6491 switch_channel_get_variable(channel, dvar1)switch_channel_get_variable_dup(channel, dvar1, SWITCH_TRUE, -
1)
,
6492 switch_channel_get_variable(br_a_channel, uvar2)switch_channel_get_variable_dup(br_a_channel, uvar2, SWITCH_TRUE
, -1)
,
6493 switch_channel_get_variable(br_a_channel, dvar2)switch_channel_get_variable_dup(br_a_channel, dvar2, SWITCH_TRUE
, -1)
);
6494
6495 switch_channel_add_variable_var_check(br_a_channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history", cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
6496 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)
;
6497
6498 switch_core_session_rwunlock(br_a_session);
6499 }
6500
6501
6502}
6503
6504
6505static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
6506 char const *phrase,
6507 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
6508 sofia_dispatch_event_t *de,
6509 tagi_t tags[])
6510{
6511 const char *l_sdp = NULL((void*)0), *r_sdp = NULL((void*)0);
6512 int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
6513 int ss_state = nua_callstate_init;
6514 switch_channel_t *channel = NULL((void*)0);
6515 private_object_t *tech_pvt = NULL((void*)0);
6516 const char *replaces_str = NULL((void*)0);
6517 switch_core_session_t *other_session = NULL((void*)0);
6518 switch_channel_t *other_channel = NULL((void*)0);
6519 //private_object_t *other_tech_pvt = NULL;
6520 char st[80] = "";
6521 int is_dup_sdp = 0;
6522 switch_event_t *s_event = NULL((void*)0);
6523 char *p;
6524 char *patched_sdp = NULL((void*)0);
6525
6526 tl_gets(tags,
6527 NUTAG_CALLSTATE_REF(ss_state)nutag_callstate_ref, tag_int_vr(&(ss_state)),
6528 NUTAG_OFFER_RECV_REF(offer_recv)nutag_offer_recv_ref, tag_bool_vr(&(offer_recv)),
6529 NUTAG_ANSWER_RECV_REF(answer_recv)nutag_answer_recv_ref, tag_bool_vr(&(answer_recv)),
6530 NUTAG_OFFER_SENT_REF(offer_sent)nutag_offer_sent_ref, tag_bool_vr(&(offer_sent)),
6531 NUTAG_ANSWER_SENT_REF(answer_sent)nutag_answer_sent_ref, tag_bool_vr(&(answer_sent)),
6532 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);
6533
6534 if (session) {
6535 channel = switch_core_session_get_channel(session);
6536 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
6537
6538 if (!tech_pvt || !tech_pvt->nh) {
6539 goto done;
6540 }
6541
6542 if (!r_sdp && (status == 100 || status == 200)) {
6543 if (ss_state == nua_callstate_completing) {
6544 if (tech_pvt->mparams.last_sdp_response) {
6545 r_sdp = tech_pvt->mparams.last_sdp_response;
6546 }
6547 } else if (ss_state == nua_callstate_received) {
6548 if (tech_pvt->mparams.last_sdp_str) {
6549 r_sdp = tech_pvt->mparams.last_sdp_str;
6550 }
6551 }
6552 }
6553 tech_pvt->mparams.last_sdp_str = NULL((void*)0);
6554 tech_pvt->mparams.last_sdp_response = NULL((void*)0);
6555
6556 if (r_sdp && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) {
6557 const char *var;
6558
6559 if ((var = switch_channel_get_variable(channel, "bypass_media_sdp_filter")switch_channel_get_variable_dup(channel, "bypass_media_sdp_filter"
, SWITCH_TRUE, -1)
)) {
6560 if ((patched_sdp = switch_core_media_process_sdp_filter(r_sdp, var, session))) {
6561 r_sdp = patched_sdp;
6562 }
6563 }
6564 }
6565
6566 if ((switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) ||
6567 (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))) {
6568
6569 /* This marr in our code brought to you by people who can't read........ */
6570 if (profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME && r_sdp && (p = (char *) switch_stristr("g729a/8000", r_sdp))) {
6571 p += 4;
6572 *p++ = '/';
6573 *p++ = '8';
6574 *p++ = '0';
6575 *p++ = '0';
6576 *p++ = '0';
6577 *p++ = ' ';
6578 }
6579 }
6580 }
6581
6582
6583 if (ss_state == nua_callstate_terminated) {
6584
6585 if ((status == 300 || status == 301 || status == 302 || status == 305) && session) {
6586 channel = switch_core_session_get_channel(session);
6587 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
6588
6589 if (!tech_pvt || !tech_pvt->nh) {
6590 goto done;
6591 }
6592
6593
6594 if (tech_pvt->redirected) {
6595 sofia_glue_do_invite(session);
6596 goto done;
6597 }
6598 }
6599
6600 if (sofia_private) {
6601 sofia_private->destroy_me = 1;
6602 }
6603 }
6604
6605 if (session) {
6606 if (switch_channel_test_flag(channel, CF_ANSWERED) && (status == 180 || status == 183) && !r_sdp) {
6607 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6607, (const char*)(session)
, SWITCH_LOG_DEBUG, "Channel %s skipping state [%s][%d]\n",
6608 switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
6609 goto done;
6610 } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (status == 180 || status == 183) && r_sdp) {
6611 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
6612 }
6613
6614 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6614, (const char*)(session)
, SWITCH_LOG_DEBUG, "Channel %s entering state [%s][%d]\n",
6615 switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
6616
6617 if (r_sdp) {
6618 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)
;
6619
6620 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)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tech_pvt->mparams.remote_sdp_str) && __builtin_constant_p
(r_sdp) && (__s1_len = __builtin_strlen (tech_pvt->
mparams.remote_sdp_str), __s2_len = __builtin_strlen (r_sdp),
(!((size_t)(const void *)((tech_pvt->mparams.remote_sdp_str
) + 1) - (size_t)(const void *)(tech_pvt->mparams.remote_sdp_str
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)((r_sdp) + 1) - (size_t)(const void *)(r_sdp) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (tech_pvt->mparams.remote_sdp_str
, r_sdp) : (__builtin_constant_p (tech_pvt->mparams.remote_sdp_str
) && ((size_t)(const void *)((tech_pvt->mparams.remote_sdp_str
) + 1) - (size_t)(const void *)(tech_pvt->mparams.remote_sdp_str
) == 1) && (__s1_len = __builtin_strlen (tech_pvt->
mparams.remote_sdp_str), __s1_len < 4) ? (__builtin_constant_p
(r_sdp) && ((size_t)(const void *)((r_sdp) + 1) - (size_t
)(const void *)(r_sdp) == 1) ? __builtin_strcmp (tech_pvt->
mparams.remote_sdp_str, r_sdp) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (r_sdp);
int __result = (((const unsigned char *) (const char *) (tech_pvt
->mparams.remote_sdp_str))[0] - __s2[0]); if (__s1_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (tech_pvt->mparams.remote_sdp_str))[1] -
__s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (tech_pvt->mparams
.remote_sdp_str))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tech_pvt->mparams.remote_sdp_str))[3] - __s2[3]); } }
__result; }))) : (__builtin_constant_p (r_sdp) && ((
size_t)(const void *)((r_sdp) + 1) - (size_t)(const void *)(r_sdp
) == 1) && (__s2_len = __builtin_strlen (r_sdp), __s2_len
< 4) ? (__builtin_constant_p (tech_pvt->mparams.remote_sdp_str
) && ((size_t)(const void *)((tech_pvt->mparams.remote_sdp_str
) + 1) - (size_t)(const void *)(tech_pvt->mparams.remote_sdp_str
) == 1) ? __builtin_strcmp (tech_pvt->mparams.remote_sdp_str
, r_sdp) : (- (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) (tech_pvt->mparams.remote_sdp_str
); int __result = (((const unsigned char *) (const char *) (r_sdp
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (r_sdp
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (r_sdp
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (r_sdp)
)[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (tech_pvt
->mparams.remote_sdp_str, r_sdp)))); })
)) {
6621 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6621, (const char*)(session)
, SWITCH_LOG_DEBUG, "Duplicate SDP\n%s\n", r_sdp);
6622 is_dup_sdp = 1;
6623 } else {
6624 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6624, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
6625 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__, 6625)
;
6626
6627 //if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
6628 // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE);
6629 //}
6630
6631 sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
6632 sofia_set_flag(tech_pvt, TFLAG_NEW_SDP)(tech_pvt)->flags[TFLAG_NEW_SDP] = 1;
6633
6634 }
6635 }
6636 }
6637
6638 if (status == 988) {
6639 goto done;
6640 }
6641
6642 if (status == 183 && !r_sdp) {
6643 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)) {
6644 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6644, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s Ignoring 183 w/o sdp\n", channel ? switch_channel_get_name(channel) : "None");
6645 goto done;
6646 }
6647 status = 180;
6648 }
6649
6650 if (status == 180 && r_sdp) {
6651 status = 183;
6652 }
6653
6654 if (channel && profile->pres_type && ss_state == nua_callstate_ready && status == 200) {
6655 const char* to_tag = "";
6656 char *sql = NULL((void*)0);
6657 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) : "")
;
6658 sql = switch_mprintf("update sip_dialogs set sip_to_tag='%q' "
6659 "where uuid='%q' and sip_to_tag = ''", to_tag, switch_core_session_get_uuid(session));
6660
6661 if (mod_sofia_globals.debug_presence > 1) {
6662 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 6662
, ((void*)0)
, SWITCH_LOG_DEBUG, "QUERY SQL %s\n", sql);
6663 }
6664 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
6665 }
6666
6667 if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
6668 const char *full_to = NULL((void*)0);
6669 const char *val;
6670 if ((val = switch_channel_get_variable(channel, "sip_auto_answer")switch_channel_get_variable_dup(channel, "sip_auto_answer", SWITCH_TRUE
, -1)
) && switch_true(val)) {
6671 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) : "")
;
6672
6673 nua_notify(nh,
6674 NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1),
6675 NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
6676 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
6677 TAG_IF((full_to), SIPTAG_TO_STR(full_to))!((full_to)) ? tag_skip : siptag_to_str, tag_str_v(full_to),
6678 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
6679 SIPTAG_EVENT_STR("talk")siptag_event_str, tag_str_v("talk"),
6680 TAG_END()(tag_type_t)0, (tag_value_t)0);
6681 }
6682 }
6683
6684
6685
6686 state_process:
6687
6688 switch ((enum nua_callstate) ss_state) {
6689 case nua_callstate_terminated:
6690 case nua_callstate_terminating:
6691 case nua_callstate_ready:
6692 case nua_callstate_completed:
6693 case nua_callstate_received:
6694 case nua_callstate_proceeding:
6695 case nua_callstate_completing:
6696 case nua_callstate_calling:
6697 if (!(session && channel && tech_pvt))
6698 goto done;
6699 default:
6700 break;
6701 }
6702
6703 switch ((enum nua_callstate) ss_state) {
6704 case nua_callstate_init:
6705 break;
6706 case nua_callstate_authenticating:
6707 break;
6708 case nua_callstate_calling:
6709 tech_pvt->sent_last_invite = 1;
6710 tech_pvt->sent_invites++;
6711 break;
6712 case nua_callstate_proceeding:
6713
6714 switch (status) {
6715 case 180:
6716 switch_channel_mark_ring_ready(channel)switch_channel_perform_mark_ring_ready_value(channel, SWITCH_RING_READY_RINGING
, "sofia.c", (const char *)__func__, 6716)
;
6717 break;
6718 case 182:
6719 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__, 6719)
;
6720 break;
6721 default:
6722 break;
6723 }
6724
6725 if (r_sdp) {
6726 if (switch_channel_test_flag(channel, CF_PROXY_MODE) && r_sdp) {
6727 char ibuf[35] = "", pbuf[35] = "";
6728 const char *ptr;
6729
6730 if ((ptr = switch_stristr("c=IN IP4", r_sdp))) {
6731 int i = 0;
6732
6733 ptr += 8;
6734
6735 while(*ptr == ' ') {
6736 ptr++;
6737 }
6738 while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
6739 ibuf[i++] = *ptr++;
6740 }
6741
6742 switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, ibuf)switch_channel_set_variable_var_check(channel, "remote_media_ip"
, ibuf, SWITCH_TRUE)
;
6743 }
6744
6745 if ((ptr = switch_stristr("m=audio", r_sdp))) {
6746 int i = 0;
6747
6748 ptr += 7;
6749
6750 while(*ptr == ' ') {
6751 ptr++;
6752 }
6753 while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
6754 pbuf[i++] = *ptr++;
6755 }
6756
6757 switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, pbuf)switch_channel_set_variable_var_check(channel, "remote_media_port"
, pbuf, SWITCH_TRUE)
;
6758 }
6759
6760 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
6761 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
6762 }
6763 sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 6763, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_EARLY_MEDIA] = 1;switch_mutex_unlock(tech_pvt->
flag_mutex);
;
6764 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 6764)
;
6765 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
6766 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) || switch_channel_test_flag(channel, CF_REINVITE)) {
6767 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
6768 goto done;
6769 }
6770 }
6771 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 6771)
== SWITCH_STATUS_SUCCESS) {
6772 other_channel = switch_core_session_get_channel(other_session);
6773 switch_channel_pass_sdp(channel, other_channel, r_sdp);
6774
6775 //switch_channel_pre_answer(other_channel);
6776 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_PROGRESS);
6777 switch_core_session_rwunlock(other_session);
6778 }
6779 goto done;
6780 } else {
6781 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) {
6782 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "DELAYED NEGOTIATION", SWITCH_TRUE)
;
6783 } else if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
6784 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
6785 switch_core_media_patch_sdp(tech_pvt->session);
6786 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
6787 nua_respond(nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable, TAG_END()(tag_type_t)0, (tag_value_t)0);
6788 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6788, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
6789 } else{
6790 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 6790)
;
6791 }
6792
6793 } else {
6794 if (sofia_media_tech_media(tech_pvt, (char *) r_sdp) != SWITCH_STATUS_SUCCESS) {
6795 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)
;
6796 nua_respond(nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable, TAG_END()(tag_type_t)0, (tag_value_t)0);
6797 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6797, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
6798 }
6799 }
6800 goto done;
6801 }
6802 }
6803 break;
6804 case nua_callstate_completing:
6805 {
6806 int send_ack = 1;
6807
6808 if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
6809 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)
;
6810
6811 if (switch_true(wait_for_ack)) {
6812 switch_core_session_t *other_session;
6813
6814 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 6814)
== SWITCH_STATUS_SUCCESS) {
6815 if (switch_core_session_compare(session, other_session)) {
6816 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
6817 sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK)(other_tech_pvt)->flags[TFLAG_PASS_ACK] = 1;
6818 send_ack = 0;
6819 }
6820 switch_core_session_rwunlock(other_session);
6821 }
6822 }
6823 }
6824
6825 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)) {
6826 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
6827 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 6827)
== SWITCH_STATUS_SUCCESS) {
6828 other_channel = switch_core_session_get_channel(other_session);
6829 //other_tech_pvt = switch_core_session_get_private(other_session);
6830
6831 switch_channel_pass_sdp(channel, other_channel, r_sdp);
6832 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
6833 switch_core_session_rwunlock(other_session);
6834 }
6835 goto done;
6836
6837 }
6838
6839 if (send_ack) {
6840 tech_send_ack(nh, tech_pvt);
6841 } else {
6842 ss_state = nua_callstate_ready;
6843 goto state_process;
6844 }
6845
6846 }
6847 goto done;
6848 case nua_callstate_received:
6849 tech_pvt->recv_invites++;
6850 tech_pvt->sent_last_invite = 0;
6851 if (!sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
6852 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 6852)
== SWITCH_STATUS_SUCCESS) {
6853 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
6854 int r = sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)((other_tech_pvt)->flags[TFLAG_REINVITED] ? 1 : 0);
6855 switch_core_session_rwunlock(other_session);
6856
6857 if (r) {
6858 /* Due to a race between simultaneous reinvites to both legs of a bridge,
6859 an earlier call to nua_invite silently failed.
6860 So we reject the incoming invite with a 491 and redo the failed outgoing invite. */
6861
6862 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6862, (const char*)(session)
, SWITCH_LOG_DEBUG,
6863 "Other leg already handling a reinvite, so responding with 491\n");
6864
6865 nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending, TAG_END()(tag_type_t)0, (tag_value_t)0);
6866 sofia_glue_do_invite(session);
6867 goto done;
6868 }
6869 }
6870
6871 if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
6872 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
6873 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOMEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOMEDIA", SWITCH_TRUE)
;
6874 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 6874, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
6875 if (switch_channel_get_state(channel) == CS_NEW) {
6876 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 6876, CS_INIT)
;
6877 }
6878 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
6879 goto done;
6880 } else if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
6881 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "PROXY MEDIA", SWITCH_TRUE)
;
6882 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 6882, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
6883 if (switch_channel_get_state(channel) == CS_NEW) {
6884 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 6884, CS_INIT)
;
6885 }
6886 } else if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)((tech_pvt)->flags[TFLAG_LATE_NEGOTIATION] ? 1 : 0)) {
6887 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "DELAYED NEGOTIATION", SWITCH_TRUE)
;
6888 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 6888, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
6889 if (switch_channel_get_state(channel) == CS_NEW) {
6890 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 6890, CS_INIT)
;
6891 }
6892 } else {
6893 uint8_t match = 0;
6894
6895 if (tech_pvt->mparams.num_codecs) {
6896 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
6897 }
6898
6899 if (!match) {
6900 if (switch_channel_get_state(channel) != CS_NEW) {
6901 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable, TAG_END()(tag_type_t)0, (tag_value_t)0);
6902 }
6903 } else {
6904 nua_handle_t *bnh;
6905 sip_replaces_t *replaces;
6906 su_home_t *home = NULL((void*)0);
6907 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED", SWITCH_TRUE)
;
6908 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 6908, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
6909 if (switch_channel_get_state(channel) == CS_NEW) {
6910 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 6910, CS_INIT)
;
6911 } else {
6912 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, TAG_END()(tag_type_t)0, (tag_value_t)0);
6913 }
6914 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
6915 if (replaces_str) {
6916 home = su_home_new(sizeof(*home));
6917 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 6917, __PRETTY_FUNCTION__))
;
6918 if ((replaces = sip_replaces_make(home, replaces_str))
6919 && (bnh = nua_handle_by_replaces(nua, replaces))) {
6920 sofia_private_t *b_private;
6921
6922 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6922, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing Replaces Attended Transfer\n");
6923 while (switch_channel_get_state(channel) < CS_EXECUTE) {
6924 switch_yield(10000)switch_sleep(10000);;
6925 }
6926
6927 if ((b_private = nua_handle_magic(bnh))) {
6928 const char *br_b = switch_channel_get_partner_uuid(channel);
6929 char *br_a = b_private->uuid;
6930
6931
6932 if (br_b) {
6933 switch_core_session_t *tmp;
6934
6935 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
) &&
6936 (tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 6936)
)) {
6937 switch_core_media_bug_transfer_recordings(session, tmp);
6938 switch_core_session_rwunlock(tmp);
6939 }
6940
6941 switch_channel_set_variable_printf(channel, "transfer_to", "att:%s", br_b);
6942
6943 mark_transfer_record(session, br_a, br_b);
6944 switch_ivr_uuid_bridge(br_a, br_b);
6945 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "ATTENDED_TRANSFER", SWITCH_TRUE)
;
6946 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
);
;
6947 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
6948 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
);
;
6949 switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6949, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
6950 } else {
6951 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)
;
6952 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6952, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
6953 }
6954 } else {
6955 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)
;
6956 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6956, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
6957 }
6958 nua_handle_unref(bnh);
6959 }
6960 su_home_unref(home);
6961 home = NULL((void*)0);
6962 }
6963
6964 goto done;
6965 }
6966
6967 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "NO CODECS", SWITCH_TRUE)
;
6968 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6968, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
6969 }
6970 } else {
6971 if (sofia_test_pflag(profile, PFLAG_3PCC)((profile)->pflags[PFLAG_3PCC] ? 1 : 0)) {
6972 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
6973 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
6973, (const char*)(session)
, SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc=yes cannot work with bypass or proxy media, hanging up.\n");
6974 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "3PCC DISABLED", SWITCH_TRUE)
;
6975 switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 6975, SWITCH_CAUSE_MANDATORY_IE_MISSING)
;
6976 } else {
6977 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOSDP", SWITCH_TRUE)
;
6978 switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
6979 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
6980 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 6980, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
6981 switch_channel_set_state(channel, CS_HIBERNATE)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 6981, CS_HIBERNATE)
;
6982 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
6983 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
6984 SIPTAG_CONTACT_STR(tech_pvt->profile->url)siptag_contact_str, tag_str_v(tech_pvt->profile->url),
6985 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
6986 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
6987 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
6988 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)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
6989 } else {
6990 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
6991 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
6992 SIPTAG_CONTACT_STR(tech_pvt->profile->url)siptag_contact_str, tag_str_v(tech_pvt->profile->url),
6993 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
)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
6994 }
6995 }
6996 } else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
6997 //3PCC proxy mode delays the 200 OK until the call is answered
6998 // 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...
6999 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "RECEIVED_NOSDP", SWITCH_TRUE)
;
7000 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7000, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7001 //switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
7002 //switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
7003 sofia_set_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)(tech_pvt)->flags[TFLAG_LATE_NEGOTIATION] = 1;
7004 //Moves into CS_INIT so call moves forward into the dialplan
7005 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7005, CS_INIT)
;
7006 } else {
7007 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7007, (const char*)(session)
, SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc not enabled, hanging up.\n");
7008 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "3PCC DISABLED", SWITCH_TRUE)
;
7009 switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7009, SWITCH_CAUSE_MANDATORY_IE_MISSING)
;
7010 }
7011 goto done;
7012 }
7013
7014 } else if (tech_pvt && sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0) && !r_sdp) {
7015 sofia_set_flag_locked(tech_pvt, TFLAG_NOSDP_REINVITE)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7015, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_NOSDP_REINVITE] = 1;switch_mutex_unlock(tech_pvt->
flag_mutex);
;
7016 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)) {
7017 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7017, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_3PCC] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7018 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7018)
== SWITCH_STATUS_SUCCESS) {
7019 switch_core_session_message_t *msg;
7020 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 7020)
;
7021 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
7022 msg->from = __FILE__"sofia.c";
7023 msg->string_arg = NULL((void*)0);
7024 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7024, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing NOSDP to other leg.\n");
7025 switch_core_session_queue_message(other_session, msg);
7026 switch_core_session_rwunlock(other_session);
7027 } else {
7028 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7028, (const char*)(session)
, SWITCH_LOG_WARNING,
7029 "NOSDP Re-INVITE to a proxy mode channel that is not in a bridge.\n");
7030 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7030, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7031 }
7032 goto done;
7033 }
7034 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, TAG_END()(tag_type_t)0, (tag_value_t)0);
7035 goto done;
7036 } else {
7037 ss_state = nua_callstate_completed;
7038 goto state_process;
7039 }
7040
7041 break;
7042 case nua_callstate_early:
7043 if (answer_recv) {
7044 uint8_t match = 0;
7045 sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7045, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_EARLY_MEDIA] = 1;switch_mutex_unlock(tech_pvt->
flag_mutex);
;
7046 switch_channel_mark_pre_answered(channel)switch_channel_perform_mark_pre_answered(channel, "sofia.c", (
const char *)__func__, 7046)
;
7047 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7048
7049 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)) {
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, "3PCC-PROXY, Got my PRACK\n");
7051 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
7052 }
7053
7054 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
7055 if (match) {
7056 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
7057 goto done;
7058 }
7059
7060 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
7061
7062 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7063 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7063, (const char*)(session)
, SWITCH_LOG_ERROR, "Early Media RTP Error!\n");
7064 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7064, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7065 }
7066 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7066, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
7067 } else {
7068 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7068, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7069 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7069, (const char*)(session)
, SWITCH_LOG_ERROR, "Early Media Codec Error!\n");
7070 }
7071 }
7072 break;
7073 case nua_callstate_completed:
7074 if (r_sdp) {
7075 const char *var;
7076 uint8_t match = 0, is_ok = 1, is_t38 = 0;
7077 tech_pvt->mparams.hold_laps = 0;
7078
7079 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)) {
7080 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7080, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ignoring Re-invite\n");
7081 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, TAG_END()(tag_type_t)0, (tag_value_t)0);
7082 goto done;
7083 }
7084
7085 if (switch_stristr("m=image", r_sdp)) {
7086 is_t38 = 1;
7087 }
7088
7089 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7090 if ((sofia_test_media_flag(profile, SCMF_DISABLE_HOLD)((profile)->media_flags[SCMF_DISABLE_HOLD] ? 1 : 0)
7091 || ((var = switch_channel_get_variable(channel, "rtp_disable_hold")switch_channel_get_variable_dup(channel, "rtp_disable_hold", SWITCH_TRUE
, -1)
) && switch_true(var)))
7092 && ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) || tech_pvt->mparams.hold_laps)) {
7093 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, TAG_END()(tag_type_t)0, (tag_value_t)0);
7094
7095 if (tech_pvt->mparams.hold_laps) {
7096 tech_pvt->mparams.hold_laps = 0;
7097 } else {
7098 tech_pvt->mparams.hold_laps = 1;
7099 }
7100
7101 goto done;
7102 }
7103
7104 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7104)
== SWITCH_STATUS_SUCCESS) {
7105 switch_core_session_message_t *msg;
7106 private_object_t *other_tech_pvt;
7107 int media_on_hold = switch_true(switch_channel_get_variable_dup(channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1));
7108
7109 if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 &&
7110 ((profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) || media_on_hold)) {
7111 if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) {
7112 tech_pvt->mparams.hold_laps = 1;
7113 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)
;
7114 switch_channel_clear_flag(channel, CF_PROXY_MODE);
7115 switch_core_media_set_local_sdp(tech_pvt->session, NULL((void*)0), SWITCH_FALSE);
7116
7117 if (!switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) {
7118 if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7119 //const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
7120
7121
7122 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
7123 if (sofia_media_tech_media(tech_pvt, r_sdp) != SWITCH_STATUS_SUCCESS) {
7124 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)
;
7125 status = SWITCH_STATUS_FALSE;
7126 switch_core_session_rwunlock(other_session);
7127 goto done;
7128 }
7129 }
7130 }
7131
7132
7133 if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
7134 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
7135 if ((status = switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0)) != SWITCH_STATUS_SUCCESS) {
7136 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7136, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7137 switch_core_session_rwunlock(other_session);
7138 goto done;
7139 }
7140 }
7141 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 1);
7142
7143 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
7144 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
7145 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7146 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
7147 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
7148 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7149 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)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
7150 } else {
7151 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
7152 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
7153 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7154 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
)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
7155 }
7156
7157 switch_channel_set_flag(channel, CF_PROXY_MODE)switch_channel_set_flag_value(channel, CF_PROXY_MODE, 1);
7158 switch_yield(250000)switch_sleep(250000);;
7159 launch_media_on_hold(session);
7160
7161 switch_core_session_rwunlock(other_session);
7162 goto done;
7163 }
7164 }
7165
7166 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && !(tech_pvt->profile->mndlb & SM_NDLB_NEVER_PATCH_REINVITE)) {
7167 if (switch_core_media_proxy_remote_addr(session, r_sdp) == SWITCH_STATUS_SUCCESS && !is_t38) {
7168 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, TAG_END()(tag_type_t)0, (tag_value_t)0);
7169 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7169, (const char*)(session)
, SWITCH_LOG_DEBUG, "Audio params changed, NOT proxying re-invite.\n");
7170 switch_core_session_rwunlock(other_session);
7171 goto done;
7172 }
7173 }
7174
7175 other_tech_pvt = switch_core_session_get_private(other_session)switch_core_session_get_private_class(other_session, SWITCH_PVT_PRIMARY
)
;
7176 if(sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)((other_tech_pvt)->flags[TFLAG_REINVITED] ? 1 : 0)) {
7177 /* The other leg won the reinvite race */
7178 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7178, (const char*)(session)
, SWITCH_LOG_DEBUG, "Other leg already handling reinvite, so responding with 491\n");
7179 nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING491, sip_491_Request_pending, TAG_END()(tag_type_t)0, (tag_value_t)0);
7180 switch_core_session_rwunlock(other_session);
7181 goto done;
7182 }
7183 sofia_set_flag(tech_pvt, TFLAG_REINVITED)(tech_pvt)->flags[TFLAG_REINVITED] = 1;
7184
7185 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 7185)
;
7186 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
7187 msg->from = __FILE__"sofia.c";
7188 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__, 7188)
;
7189 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7189, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing SDP to other leg.\n%s\n", r_sdp);
7190
7191 if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt)->flags[TFLAG_SIP_HOLD] ? 1 : 0)) {
7192 if (!switch_stristr("sendonly", r_sdp)) {
7193 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
);
;
7194 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
7195 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__, 7195
)
;
7196 }
7197 } else if (switch_stristr("sendonly", r_sdp)) {
7198 const char *msg = "hold";
7199
7200 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
7201 const char *info = switch_channel_get_variable(channel, "presence_call_info")switch_channel_get_variable_dup(channel, "presence_call_info"
, SWITCH_TRUE, -1)
;
7202 if (info) {
7203 if (switch_stristr("private", info)) {
7204 msg = "hold-private";
7205 }
7206 }
7207 }
7208
7209 sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7209, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_SIP_HOLD] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7210 switch_channel_set_flag(channel, CF_LEG_HOLDING)switch_channel_set_flag_value(channel, CF_LEG_HOLDING, 1);
7211 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__, 7211)
;
7212 }
7213
7214 switch_core_session_queue_message(other_session, msg);
7215
7216 switch_core_session_rwunlock(other_session);
7217 } else {
7218 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7218, (const char*)(session)
, SWITCH_LOG_WARNING,
7219 "Re-INVITE to a no-media channel that is not in a bridge.\n");
7220 is_ok = 0;
7221 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7221, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7222 }
7223 goto done;
7224 } else {
7225 if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) {
7226 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, TAG_END()(tag_type_t)0, (tag_value_t)0);
7227 goto done;
7228 }
7229
7230 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
7231
7232 if (tech_pvt->mparams.num_codecs) {
7233 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
7234 }
7235
7236
7237 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7238 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, TAG_END()(tag_type_t)0, (tag_value_t)0);
7239 goto done;
7240 }
7241
7242 if (match && sofia_test_flag(tech_pvt, TFLAG_NOREPLY)((tech_pvt)->flags[TFLAG_NOREPLY] ? 1 : 0)) {
7243 sofia_clear_flag(tech_pvt, TFLAG_NOREPLY)(tech_pvt)->flags[TFLAG_NOREPLY] = 0;
7244 goto done;
7245 }
7246
7247 if (match) {
7248 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
7249 goto done;
7250 }
7251
7252 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
7253
7254 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7255 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7255, (const char*)(session)
, SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
7256 is_ok = 0;
7257 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7257, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7258 }
7259 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7259, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
7260 } else {
7261 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7262 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK, TAG_END()(tag_type_t)0, (tag_value_t)0);
7263 goto done;
7264 }
7265
7266 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
7267 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7267, (const char*)(session)
, SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
7268 is_ok = 0;
7269 }
7270 }
7271
7272
7273 if (is_ok) {
7274
7275 if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
7276 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
7277 }
7278 if (sofia_use_soa(tech_pvt)((tech_pvt)->flags[TFLAG_ENABLE_SOA] ? 1 : 0)) {
7279 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
7280 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7281 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)soatag_user_sdp_str, tag_str_v(tech_pvt->mparams.local_sdp_str
)
,
7282 SOATAG_REUSE_REJECTED(1)soatag_reuse_rejected, tag_bool_v(1),
7283 SOATAG_AUDIO_AUX("cn telephone-event")soatag_audio_aux, tag_str_v("cn telephone-event"),
7284 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)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
7285 } else {
7286 nua_respond(tech_pvt->nh, SIP_200_OK200, sip_200_OK,
7287 NUTAG_MEDIA_ENABLE(0)nutag_media_enable, tag_bool_v(0),
7288 SIPTAG_CONTACT_STR(tech_pvt->reply_contact)siptag_contact_str, tag_str_v(tech_pvt->reply_contact),
7289 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
)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
7290 }
7291 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__, 7291, &s_event, SWITCH_EVENT_CUSTOM
, "sofia::reinvite")
== SWITCH_STATUS_SUCCESS) {
7292 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
7293 switch_event_fire(&s_event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 7293, &s_event, ((void*)0))
;
7294 }
7295 } else {
7296 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable, TAG_END()(tag_type_t)0, (tag_value_t)0);
7297 }
7298 }
7299 break;
7300 case nua_callstate_ready:
7301 if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA) &&
7302 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)) {
7303 /* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */
7304 uint8_t match = 0;
7305
7306 sofia_clear_flag(tech_pvt, TFLAG_NEW_SDP)(tech_pvt)->flags[TFLAG_NEW_SDP] = 0;
7307 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
7308
7309 if (tech_pvt->mparams.num_codecs) {
7310 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
7311 }
7312 if (match) {
7313 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
7314 goto done;
7315 }
7316 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL((void*)0), 0, NULL((void*)0), 0);
7317
7318 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7318, (const char*)(session)
, SWITCH_LOG_DEBUG, "Processing updated SDP\n");
7319 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
7320
7321 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7322 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7322, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
7323 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7323, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7324 goto done;
7325 }
7326 } else {
7327 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
7328 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7328, (const char*)(session)
, SWITCH_LOG_ERROR, "Codec Error! %s\n", r_sdp);
7329 goto done;
7330
7331 }
7332 }
7333
7334 if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)((tech_pvt)->flags[TFLAG_NOSDP_REINVITE] ? 1 : 0)) {
7335 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);
;
7336 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7337 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7338 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7339 goto done;
7340 }
7341 }
7342
7343 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7343)
== SWITCH_STATUS_SUCCESS) {
7344 other_channel = switch_core_session_get_channel(other_session);
7345 switch_channel_pass_sdp(channel, other_channel, r_sdp);
7346
7347 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)) {
7348 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7348, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
7349 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
7350 } else {
7351 switch_core_session_message_t *msg;
7352
7353 if (sofia_test_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)((profile)->pflags[PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK] ? 1
: 0)
) {
7354 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 7354)
;
7355 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
7356 msg->from = __FILE__"sofia.c";
7357 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__, 7357)
;
7358 switch_core_session_queue_message(other_session, msg);
7359 }
7360
7361 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
7362 }
7363
7364 switch_core_session_rwunlock(other_session);
7365 }
7366 } else {
7367 uint8_t match = 0;
7368 int is_ok = 1;
7369
7370 if (tech_pvt->mparams.num_codecs) {
7371 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
7372 }
7373
7374 if (match) {
7375 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
7376 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7377 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7377, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
7378 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)
;
7379 is_ok = 0;
7380 }
7381 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
7382 } else {
7383 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)
;
7384 is_ok = 0;
7385 }
7386
7387 if (!is_ok) {
7388 nua_respond(nh, SIP_488_NOT_ACCEPTABLE488, sip_488_Not_acceptable, TAG_END()(tag_type_t)0, (tag_value_t)0);
7389 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 7389, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION
)
;
7390 }
7391 }
7392 goto done;
7393 }
7394
7395 if (channel) {
7396 switch_channel_clear_flag(channel, CF_REQ_MEDIA);
7397 }
7398 if (tech_pvt && nh == tech_pvt->nh2) {
7399 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7399, (const char*)(session)
, SWITCH_LOG_DEBUG, "Cheater Reinvite!\n");
7400 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE)switch_channel_set_flag_value(tech_pvt->channel, CF_REINVITE
, 1)
;
7401 tech_pvt->nh = tech_pvt->nh2;
7402 tech_pvt->nh2 = NULL((void*)0);
7403 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) == SWITCH_STATUS_SUCCESS) {
7404 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7405 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7405, (const char*)(session)
, SWITCH_LOG_ERROR, "Cheater Reinvite RTP Error!\n");
7406 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7406, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7407 }
7408 }
7409 goto done;
7410 }
7411
7412 if (channel) {
7413 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)) {
7414 sofia_set_flag_locked(tech_pvt, TFLAG_ANS)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7414, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7415 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7416 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 7416)
;
7417
7418 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7419 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7419)
== SWITCH_STATUS_SUCCESS) {
7420 //other_channel = switch_core_session_get_channel(other_session);
7421 //switch_channel_answer(other_channel);
7422 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
7423 switch_core_session_rwunlock(other_session);
7424 }
7425 }
7426 goto done;
7427 }
7428
7429 if (!r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
7430 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)
;
7431 }
7432
7433 if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)((tech_pvt)->flags[TFLAG_SDP] ? 1 : 0)) {
7434 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7435 sofia_set_flag_locked(tech_pvt, TFLAG_ANS)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7435, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7436 sofia_set_flag_locked(tech_pvt, TFLAG_SDP)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7436, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_SDP] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7437 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 7437)
;
7438
7439 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7440 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7441 goto done;
7442 }
7443 }
7444
7445 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7445)
== SWITCH_STATUS_SUCCESS) {
7446 other_channel = switch_core_session_get_channel(other_session);
7447 switch_channel_pass_sdp(channel, other_channel, r_sdp);
7448
7449 //switch_channel_answer(other_channel);
7450 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
7451
7452 switch_core_session_rwunlock(other_session);
7453 }
7454
7455 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)) {
7456 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7456, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
7457 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
7458 }
7459
7460 goto done;
7461 } else {
7462 uint8_t match = 0;
7463
7464 if (tech_pvt->mparams.num_codecs) {
7465 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
7466 }
7467
7468 sofia_set_flag_locked(tech_pvt, TFLAG_ANS)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7468, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_ANS] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7469
7470 if (match) {
7471 switch_channel_check_zrtp(channel);
7472
7473 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) == SWITCH_STATUS_SUCCESS) {
7474 if (sofia_media_activate_rtp(tech_pvt) == SWITCH_STATUS_SUCCESS) {
7475 switch_channel_mark_answered(channel)switch_channel_perform_mark_answered(channel, "sofia.c", (const
char *)__func__, 7475)
;
7476 } else {
7477 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7477, (const char*)(session)
, SWITCH_LOG_ERROR, "RTP Error!\n");
7478 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7478, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)
;
7479 }
7480
7481 if (sofia_test_flag(tech_pvt, TFLAG_3PCC)((tech_pvt)->flags[TFLAG_3PCC] ? 1 : 0)) {
7482 /* Check if we are in 3PCC proxy mode, if so then set the flag to indicate we received the ack */
7483 if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)((profile)->pflags[PFLAG_3PCC_PROXY] ? 1 : 0)) {
7484 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7484, (const char*)(session)
, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
7485 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)(tech_pvt)->flags[TFLAG_3PCC_HAS_ACK] = 1;
7486 } else if (switch_channel_get_state(channel) == CS_HIBERNATE) {
7487 sofia_set_flag_locked(tech_pvt, TFLAG_READY)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7487, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_READY] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7488 switch_channel_set_state(channel, CS_INIT)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 7488, CS_INIT)
;
7489 sofia_set_flag(tech_pvt, TFLAG_SDP)(tech_pvt)->flags[TFLAG_SDP] = 1;
7490 }
7491 }
7492 goto done;
7493 }
7494 }
7495
7496 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "NO CODECS", SWITCH_TRUE)
;
7497 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7497, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)
;
7498 }
7499 }
7500 }
7501
7502 break;
7503 case nua_callstate_terminating:
7504 if (status == 488 || switch_channel_get_state(channel) == CS_HIBERNATE) {
7505 tech_pvt->q850_cause = SWITCH_CAUSE_MANDATORY_IE_MISSING;
7506 }
7507 case nua_callstate_terminated:
7508 sofia_set_flag_locked(tech_pvt, TFLAG_BYE)((tech_pvt->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("tech_pvt->flag_mutex != ((void*)0)", "sofia.c", 7508, __PRETTY_FUNCTION__
));switch_mutex_lock(tech_pvt->flag_mutex);(tech_pvt)->
flags[TFLAG_BYE] = 1;switch_mutex_unlock(tech_pvt->flag_mutex
);
;
7509 if (sofia_test_flag(tech_pvt, TFLAG_NOHUP)((tech_pvt)->flags[TFLAG_NOHUP] ? 1 : 0)) {
7510 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
);
;
7511 } else if (switch_channel_up(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) < CS_HANGUP)
) {
7512 int cause;
7513 if (tech_pvt->q850_cause) {
7514 cause = tech_pvt->q850_cause;
7515 } else {
7516 cause = sofia_glue_sip_cause_to_freeswitch(status);
7517 }
7518 if (status) {
7519 switch_snprintf(st, sizeof(st), "%d", status);
7520 switch_channel_set_variable(channel, "sip_term_status", st)switch_channel_set_variable_var_check(channel, "sip_term_status"
, st, SWITCH_TRUE)
;
7521 switch_snprintf(st, sizeof(st), "sip:%d", status);
7522 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)
;
7523 if (phrase) {
7524 switch_channel_set_variable_partner(channel, "sip_hangup_phrase", phrase)switch_channel_set_variable_partner_var_check(channel, "sip_hangup_phrase"
, phrase, SWITCH_TRUE)
;
7525 }
7526 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_BYE_HEADER_PREFIX"sip_bye_h_");
7527 }
7528 switch_snprintf(st, sizeof(st), "%d", cause);
7529 switch_channel_set_variable(channel, "sip_term_cause", st)switch_channel_set_variable_var_check(channel, "sip_term_cause"
, st, SWITCH_TRUE)
;
7530 switch_channel_hangup(channel, cause)switch_channel_perform_hangup(channel, "sofia.c", (const char
*)__func__, 7530, cause)
;
7531 ss_state = nua_callstate_terminated;
7532 }
7533
7534
7535 if (ss_state == nua_callstate_terminated) {
7536 if (tech_pvt->sofia_private) {
7537 tech_pvt->sofia_private = NULL((void*)0);
7538 }
7539
7540 tech_pvt->nh = NULL((void*)0);
7541
7542 if (nh) {
7543 nua_handle_bind(nh, NULL((void*)0));
7544 nua_handle_destroy(nh);
7545 }
7546 }
7547
7548 break;
7549 }
7550
7551 done:
7552
7553 switch_safe_free(patched_sdp)if (patched_sdp) {free(patched_sdp);patched_sdp=((void*)0);};
7554
7555 if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) {
7556 sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY)(tech_pvt)->flags[TFLAG_SIMPLIFY] = 1;
7557 }
7558
7559
7560 return;
7561}
7562
7563typedef struct {
7564 char *exten;
7565 char *exten_with_params;
7566 char *event;
7567 char *reply_uuid;
7568 char *bridge_to_uuid;
7569 switch_event_t *vars;
7570 switch_memory_pool_t *pool;
7571} nightmare_xfer_helper_t;
7572
7573void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void *obj)
7574{
7575 nightmare_xfer_helper_t *nhelper = (nightmare_xfer_helper_t *) obj;
7576 switch_memory_pool_t *pool;
7577 switch_status_t status = SWITCH_STATUS_FALSE;
7578 switch_core_session_t *session, *a_session;
7579
7580 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__, 7580)
)) {
7581 switch_core_session_t *tsession = NULL((void*)0);
7582 switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
7583 uint32_t timeout = 60;
7584 char *tuuid_str;
7585
7586 if ((session = switch_core_session_locate(nhelper->reply_uuid)switch_core_session_perform_locate(nhelper->reply_uuid, "sofia.c"
, (const char *)__func__, 7586)
)) {
7587 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
7588 switch_channel_t *channel_a = switch_core_session_get_channel(session);
7589
7590 if ((status = switch_ivr_originate(NULL((void*)0), &tsession, &cause, nhelper->exten_with_params, timeout, NULL((void*)0), NULL((void*)0), NULL((void*)0),
7591 switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL((void*)0))) == SWITCH_STATUS_SUCCESS) {
7592 if (switch_channel_up(channel_a)(switch_channel_check_signal(channel_a, SWITCH_TRUE) || switch_channel_get_state
(channel_a) < CS_HANGUP)
) {
7593
7594 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)
)) {
7595 switch_core_media_bug_transfer_recordings(session, a_session);
7596 }
7597
7598
7599 tuuid_str = switch_core_session_get_uuid(tsession);
7600 switch_channel_set_variable_printf(channel_a, "transfer_to", "att:%s", tuuid_str);
7601 mark_transfer_record(session, nhelper->bridge_to_uuid, tuuid_str);
7602 switch_ivr_uuid_bridge(nhelper->bridge_to_uuid, tuuid_str);
7603 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)
;
7604 } else {
7605 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__, 7605, SWITCH_CAUSE_ORIGINATOR_CANCEL
)
;
7606 status = SWITCH_STATUS_FALSE;
7607 }
7608 switch_core_session_rwunlock(tsession);
7609 }
7610
7611 if (status == SWITCH_STATUS_SUCCESS) {
7612 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7612, (const char*)(session)
, SWITCH_LOG_DEBUG, "The nightmare is over.....\n");
7613 } else {
7614 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7614, (const char*)(session)
, SWITCH_LOG_DEBUG, "1 .. 2 .. Freddie's commin' for you...\n");
7615 }
7616
7617 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"),
7618 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"
)
,
7619 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")
7620 "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), TAG_END()(tag_type_t)0, (tag_value_t)0);
7621
7622 switch_core_session_rwunlock(session);
7623 }
7624
7625 switch_core_session_rwunlock(a_session);
7626 }
7627
7628 switch_event_destroy(&nhelper->vars);
7629
7630 pool = nhelper->pool;
7631 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia.c",
(const char *)__func__, 7631)
;
7632
7633 return NULL((void*)0);
7634}
7635
7636static void launch_nightmare_xfer(nightmare_xfer_helper_t *nhelper)
7637{
7638 switch_thread_t *thread;
7639 switch_threadattr_t *thd_attr = NULL((void*)0);
7640
7641 switch_threadattr_create(&thd_attr, nhelper->pool);
7642 switch_threadattr_detach_set(thd_attr, 1);
7643 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
7644 switch_thread_create(&thread, thd_attr, nightmare_xfer_thread_run, nhelper, nhelper->pool);
7645}
7646
7647/*---------------------------------------*/
7648
7649static switch_status_t xfer_hanguphook(switch_core_session_t *session)
7650{
7651 switch_channel_t *channel = switch_core_session_get_channel(session);
7652 switch_channel_state_t state = switch_channel_get_state(channel);
7653
7654 if (state == CS_HANGUP) {
7655 switch_core_session_t *ksession;
7656 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)
;
7657
7658 if (uuid && (ksession = switch_core_session_force_locate(uuid)switch_core_session_perform_force_locate(uuid, "sofia.c", (const
char *)__func__, 7658)
)) {
7659 switch_channel_t *kchannel = switch_core_session_get_channel(ksession);
7660
7661 switch_channel_clear_flag(kchannel, CF_XFER_ZOMBIE);
7662 switch_channel_clear_flag(kchannel, CF_TRANSFER);
7663 if (switch_channel_up(kchannel)(switch_channel_check_signal(kchannel, SWITCH_TRUE) || switch_channel_get_state
(kchannel) < CS_HANGUP)
) {
7664 switch_channel_hangup(kchannel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(kchannel, "sofia.c", (const char
*)__func__, 7664, SWITCH_CAUSE_NORMAL_CLEARING)
;
7665 }
7666
7667 switch_core_session_rwunlock(ksession);
7668 }
7669
7670 switch_core_event_hook_remove_state_change(session, xfer_hanguphook);
7671
7672 }
7673
7674 return SWITCH_STATUS_SUCCESS;
7675}
7676
7677nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces)
7678{
7679 nua_handle_t *nh = NULL((void*)0);
7680 switch_hash_index_t *hi;
7681 const void *var;
7682 void *val;
7683 sofia_profile_t *profile;
7684
7685 switch_mutex_lock(mod_sofia_globals.hash_mutex);
7686 if (mod_sofia_globals.profile_hash) {
7687 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)) {
7688 switch_core_hash_this(hi, &var, NULL((void*)0), &val);
7689 if ((profile = (sofia_profile_t *) val)) {
7690 if (!(nh = nua_handle_by_replaces(profile->nua, replaces))) {
7691 nh = nua_handle_by_call_id(profile->nua, replaces->rp_call_id);
7692 }
7693 if (nh)
7694 break;
7695 }
7696 }
7697 switch_safe_free(hi)if (hi) {free(hi);hi=((void*)0);};
7698 }
7699 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
7700
7701 return nh;
7702
7703}
7704
7705void 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,
7706 sofia_dispatch_event_t *de, tagi_t tags[])
7707{
7708 /* Incoming refer */
7709 sip_from_t const *from;
7710 //sip_to_t const *to;
7711 sip_refer_to_t const *refer_to;
7712 private_object_t *tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
7713 char *etmp = NULL((void*)0), *exten = NULL((void*)0);
7714 switch_channel_t *channel_a = switch_core_session_get_channel(session);
7715 switch_channel_t *channel_b = NULL((void*)0);
7716 su_home_t *home = NULL((void*)0);
7717 char *full_ref_by = NULL((void*)0);
7718 char *full_ref_to = NULL((void*)0);
7719 nightmare_xfer_helper_t *nightmare_xfer_helper;
7720 switch_memory_pool_t *npool;
7721
7722 if (!(profile->mflags & MFLAG_REFER)) {
7723 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);
7724 goto done;
7725 }
7726
7727 if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
7728 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7728, (const char*)(session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
7729 goto done;
7730 }
7731
7732 if ((refer_to = sip->sip_refer_to)) {
7733 full_ref_to = sip_header_as_string(home, (void *) sip->sip_refer_to);
7734 }
7735
7736
7737 if (sofia_test_pflag(profile, PFLAG_PROXY_REFER)((profile)->pflags[PFLAG_PROXY_REFER] ? 1 : 0)) {
7738 switch_core_session_t *other_session;
7739
7740 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 7740)
== SWITCH_STATUS_SUCCESS) {
7741 switch_core_session_message_t *msg;
7742
7743 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "sofia.c", (const char *)__func__, 7743)
;
7744 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 7744
;
7745 msg->message_id = SWITCH_MESSAGE_INDICATE_DEFLECT;
7746 msg->string_arg = switch_core_session_strdup(other_session, full_ref_to)switch_core_perform_session_strdup(other_session, full_ref_to
, "sofia.c", (const char *)__func__, 7746)
;
7747 msg->from = __FILE__"sofia.c";
7748 switch_core_session_queue_message(other_session, msg);
7749 switch_core_session_rwunlock(other_session);
7750
7751 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"), TAG_END()(tag_type_t)0, (tag_value_t)0);
7752 goto done;
7753 }
7754 }
7755
7756
7757 from = sip->sip_from;
7758 //to = sip->sip_to;
7759
7760 home = su_home_new(sizeof(*home));
7761 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia.c", 7761, __PRETTY_FUNCTION__))
;
7762
7763 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"), TAG_END()(tag_type_t)0, (tag_value_t)0);
7764
7765
7766 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)
;
7767
7768 if (sip->sip_referred_by) {
7769 full_ref_by = sip_header_as_string(home, (void *) sip->sip_referred_by);
7770 }
7771
7772 if (refer_to) {
7773 char *rep = NULL((void*)0);
7774
7775 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
7776 exten = switch_core_session_sprintf(session, "%s@%s", (char *) refer_to->r_url->url_user, (char *) refer_to->r_url->url_host);
7777 } else {
7778 exten = (char *) refer_to->r_url->url_user;
7779 }
7780
7781 if (refer_to->r_url->url_params) {
7782 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)
;
7783 }
7784
7785 switch_core_session_queue_indication(session, SWITCH_MESSAGE_REFER_EVENT);
7786 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7786, (const char*)(session)
, SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
7787
7788 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)
;
7789
7790
7791 if (refer_to->r_url && refer_to->r_url->url_headers) {
7792 rep = (char *) switch_stristr("Replaces=", refer_to->r_url->url_headers);
7793 }
7794
7795
7796 if (rep) {
7797 sip_replaces_t *replaces;
7798 nua_handle_t *bnh = NULL((void*)0);
7799
7800 if (rep) {
7801 const char *br_a = NULL((void*)0), *br_b = NULL((void*)0);
7802 char *buf;
7803 char *p;
7804
7805 rep = switch_core_session_strdup(session, rep + 9)switch_core_perform_session_strdup(session, rep + 9, "sofia.c"
, (const char *)__func__, 7805)
;
7806
7807 if ((buf = switch_core_session_alloc(session, strlen(rep) + 1)switch_core_perform_session_alloc(session, strlen(rep) + 1, "sofia.c"
, (const char *)__func__, 7807)
)) {
7808 rep = url_unescape(buf, (const char *) rep);
7809 if ((p = strchr(rep, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(rep) && (';') == '\0' ? (char *) __rawmemchr (rep, ';'
) : __builtin_strchr (rep, ';')))
)) {
7810 *p = '\0';
7811 }
7812 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7812, (const char*)(session)
, SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep);
7813 } else {
7814 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7814, (const char*)(session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
7815 goto done;
7816 }
7817
7818 if ((replaces = sip_replaces_make(home, rep))) {
7819 if (!(bnh = nua_handle_by_replaces(nua, replaces))) {
7820 if (!(bnh = nua_handle_by_call_id(nua, replaces->rp_call_id))) {
7821 bnh = sofia_global_nua_handle_by_replaces(replaces);
7822 }
7823 }
7824 }
7825
7826 if (bnh) {
7827 sofia_private_t *b_private = NULL((void*)0);
7828 private_object_t *b_tech_pvt = NULL((void*)0);
7829 switch_core_session_t *b_session = NULL((void*)0);
7830
7831
7832 switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep)switch_channel_set_variable_var_check(channel_a, "_sofia_replaces_"
, rep, SWITCH_TRUE)
;
7833 if ((b_private = nua_handle_magic(bnh))) {
7834 int deny_refer_requests = 0;
7835
7836 if (!(b_session = switch_core_session_locate(b_private->uuid)switch_core_session_perform_locate(b_private->uuid, "sofia.c"
, (const char *)__func__, 7836)
)) {
7837 goto done;
7838 }
7839 b_tech_pvt = (private_object_t *) switch_core_session_get_private(b_session)switch_core_session_get_private_class(b_session, SWITCH_PVT_PRIMARY
)
;
7840 channel_b = switch_core_session_get_channel(b_session);
7841
7842 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)
;
7843 switch_channel_set_variable(channel_b, "transfer_disposition", "replaced")switch_channel_set_variable_var_check(channel_b, "transfer_disposition"
, "replaced", SWITCH_TRUE)
;
7844
7845 br_a = switch_channel_get_partner_uuid(channel_a);
7846 br_b = switch_channel_get_partner_uuid(channel_b);
7847
7848 if (!switch_ivr_uuid_exists(br_a)) {
7849 br_a = NULL((void*)0);
7850 }
7851
7852 if (!switch_ivr_uuid_exists(br_b)) {
7853 br_b = NULL((void*)0);
7854 }
7855
7856 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)
)) {
7857 deny_refer_requests = 1;
7858 }
7859
7860 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)
)) {
7861 deny_refer_requests = 1;
7862 }
7863
7864 if (!deny_refer_requests && br_a) {
7865 switch_core_session_t *a_session;
7866 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 7866)
)) {
7867 switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
7868
7869 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)
)) {
7870 deny_refer_requests = 1;
7871 }
7872 switch_core_session_rwunlock(a_session);
7873 }
7874 }
7875
7876 if (!deny_refer_requests && br_b) {
7877 switch_core_session_t *b_session;
7878 if ((b_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 7878)
)) {
7879 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
7880
7881 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)
)) {
7882 deny_refer_requests = 1;
7883 }
7884 switch_core_session_rwunlock(b_session);
7885 }
7886 }
7887
7888 if (deny_refer_requests) {
7889 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7889, (const char*)(session)
, SWITCH_LOG_NOTICE, "Denying Attended Transfer, variable [deny_refer_requests] was set to true\n");
7890
7891 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"
)
,
7892 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"
)
,
7893 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);
7894
7895 } else if (switch_channel_test_flag(channel_b, CF_ORIGINATOR)) {
7896 switch_core_session_t *a_session;
7897
7898 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7898, (const char*)(session)
, SWITCH_LOG_NOTICE,
7899 "Attended Transfer on originating session %s\n", switch_core_session_get_uuid(b_session));
7900
7901
7902
7903 switch_channel_set_variable_printf(channel_b, "transfer_to", "satt:%s", br_a);
7904
7905 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)
;
7906
7907
7908 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);
;
7909 switch_channel_clear_flag(channel_b, CF_LEG_HOLDING);
7910 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
);
;
7911
7912 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)
;
7913 switch_channel_set_flag(channel_b, CF_XFER_ZOMBIE)switch_channel_set_flag_value(channel_b, CF_XFER_ZOMBIE, 1);
7914 switch_channel_set_flag(channel_b, CF_TRANSFER)switch_channel_set_flag_value(channel_b, CF_TRANSFER, 1);
7915
7916
7917 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 7917)
)) {
7918 const char *moh = profile->hold_music;
7919 switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
7920 switch_caller_profile_t *prof = switch_channel_get_caller_profile(channel_b);
7921 const char *tmp;
7922
7923 switch_core_event_hook_add_state_change(a_session, xfer_hanguphook);
7924 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)
;
7925 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)
;
7926 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)
;
7927 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)
;
7928
7929 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) {
7930 switch_channel_set_flag(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
7931 }
7932
7933
7934 if ((tmp = switch_channel_get_hold_music(a_channel))) {
7935 moh = tmp;
7936 }
7937
7938 if (!zstr(moh)_zstr(moh) && !strcasecmp(moh, "silence")) {
7939 moh = NULL((void*)0);
7940 }
7941
7942 if (moh) {
7943 char *xdest;
7944 xdest = switch_core_session_sprintf(a_session, "endless_playback:%s,park", moh);
7945 switch_ivr_session_transfer(a_session, xdest, "inline", NULL((void*)0));
7946 } else {
7947 switch_ivr_session_transfer(a_session, "park", "inline", NULL((void*)0));
7948 }
7949
7950 switch_core_session_rwunlock(a_session);
7951
7952 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"
)
,
7953 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),
7954 TAG_END()(tag_type_t)0, (tag_value_t)0);
7955
7956 if (b_tech_pvt && !sofia_test_flag(b_tech_pvt, TFLAG_BYE)((b_tech_pvt)->flags[TFLAG_BYE] ? 1 : 0)) {
7957 char *q850 = NULL((void*)0);
7958 const char *val = NULL((void*)0);
7959
7960 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 != ((void*)0)", "sofia.c", 7960,
__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);
;
7961 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)
;
7962 if (!val || switch_true(val)) {
7963 q850 = switch_core_session_sprintf(a_session, "Q.850;cause=16;text=\"normal_clearing\"");
7964 }
7965 nua_bye(b_tech_pvt->nh,
7966 SIPTAG_CONTACT(SIP_NONE)siptag_contact, siptag_contact_v(((void const *)-1L)),
7967 TAG_IF(!zstr(q850), SIPTAG_REASON_STR(q850))!(!_zstr(q850)) ? tag_skip : siptag_reason_str, tag_str_v(q850
)
,
7968 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)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
7969
7970 }
7971 } else {
7972 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"
)
,
7973 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"
)
,
7974 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);
7975 }
7976
7977 } else if (br_a && br_b) {
7978 switch_core_session_t *tmp = NULL((void*)0);
7979
7980 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
7980, (const char*)(session)
, SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n",
7981 switch_str_nil(br_a)(br_a ? br_a : ""), switch_str_nil(br_b)(br_b ? br_b : ""));
7982
7983 if ((tmp = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 7983)
)) {
7984 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
7985
7986 if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER)) {
7987 switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
7988 }
7989
7990 switch_channel_set_variable(tchannel, "transfer_disposition", "bridge")switch_channel_set_variable_var_check(tchannel, "transfer_disposition"
, "bridge", SWITCH_TRUE)
;
7991
7992 switch_channel_set_flag(tchannel, CF_ATTENDED_TRANSFER)switch_channel_set_flag_value(tchannel, CF_ATTENDED_TRANSFER,
1)
;
7993 switch_core_session_rwunlock(tmp);
7994 }
7995
7996 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__, 7996)
)) {
7997 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
7998 switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE)switch_channel_set_flag_value(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE
, 1)
;
7999 switch_core_session_rwunlock(tmp);
8000 }
8001
8002
8003 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)
) &&
8004 (tmp = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 8004)
)) {
8005 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)
;
8006 switch_core_media_bug_transfer_recordings(session, tmp);
8007 switch_core_session_rwunlock(tmp);
8008 }
8009
8010
8011 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)
) &&
8012 (tmp = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 8012)
)) {
8013 switch_core_media_bug_transfer_recordings(b_session, tmp);
8014 switch_core_session_rwunlock(tmp);
8015 }
8016
8017 switch_channel_set_variable_printf(channel_a, "transfer_to", "att:%s", br_b);
8018
8019 mark_transfer_record(session, br_a, br_b);
8020
8021 switch_ivr_uuid_bridge(br_a, br_b);
8022 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)
;
8023 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"
)
,
8024 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),
8025 TAG_END()(tag_type_t)0, (tag_value_t)0);
8026
8027 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);
;
8028 switch_channel_clear_flag(channel_b, CF_LEG_HOLDING);
8029 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
);
;
8030 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)
;
8031 switch_channel_set_state(channel_b, CS_PARK)switch_channel_perform_set_state(channel_b, "sofia.c", (const
char *)__func__, 8031, CS_PARK)
;
8032
8033 } else {
8034 if (!br_a && !br_b) {
8035 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8035, (const char*)(session)
, SWITCH_LOG_WARNING,
8036 "Cannot transfer channels that are not in a bridge.\n");
8037 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"
)
,
8038 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"),
8039 SIPTAG_EVENT_STR(etmp)siptag_event_str, tag_str_v(etmp), TAG_END()(tag_type_t)0, (tag_value_t)0);
8040 } else {
8041 switch_core_session_t *t_session, *hup_session;
8042 switch_channel_t *hup_channel;
8043 const char *ext;
8044
8045 if (br_a && !br_b) {
8046 t_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 8046)
;
8047 hup_channel = channel_b;
8048 hup_session = b_session;
8049 } else {
8050 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
)
;
8051 t_session = switch_core_session_locate(br_b)switch_core_session_perform_locate(br_b, "sofia.c", (const char
*)__func__, 8051)
;
8052 hup_channel = channel_a;
8053 hup_session = session;
8054 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
);
;
8055 switch_channel_clear_flag(tech_pvt->channel, CF_LEG_HOLDING);
8056 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);
;
8057 switch_channel_clear_flag(h_tech_pvt->channel, CF_LEG_HOLDING);
8058 switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(channel_b, "sofia.c", (const char
*)__func__, 8058, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
8059 }
8060
8061 if (t_session) {
8062 switch_channel_t *t_channel = switch_core_session_get_channel(t_session);
8063 const char *idest = switch_channel_get_variable(hup_channel, "inline_destination")switch_channel_get_variable_dup(hup_channel, "inline_destination"
, SWITCH_TRUE, -1)
;
8064 ext = switch_channel_get_variable(hup_channel, "destination_number")switch_channel_get_variable_dup(hup_channel, "destination_number"
, SWITCH_TRUE, -1)
;
8065
8066 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
8067 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)
;
8068 }
8069
8070 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
8071 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)
;
8072 }
8073
8074
8075 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)
)) {
8076 switch_core_media_bug_transfer_recordings(hup_session, t_session);
8077 }
8078
8079 if (idest) {
8080 switch_ivr_session_transfer(t_session, idest, "inline", NULL((void*)0));
8081 } else {
8082 switch_ivr_session_transfer(t_session, ext, NULL((void*)0), NULL((void*)0));
8083 }
8084
8085 nua_notify(tech_pvt->nh,
8086 NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1),
8087 SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0")siptag_content_type_str, tag_str_v("message/sipfrag;version=2.0"
)
,
8088 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"
)
,
8089 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
8090 switch_core_session_rwunlock(t_session);
8091 switch_channel_hangup(hup_channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(hup_channel, "sofia.c", (const char
*)__func__, 8091, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
8092 } else {
8093 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8093, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session to transfer to not found.\n");
8094 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"
)
,
8095 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"
)
,
8096 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);
8097 }
8098 }
8099 }
8100 if (b_session) {
8101 switch_core_session_rwunlock(b_session);
8102 }
8103 }
8104 nua_handle_unref(bnh);
8105 } else { /* the other channel is on a different box, we have to go find them */
8106 if (exten && (br_a = switch_channel_get_partner_uuid(channel_a))) {
8107 switch_core_session_t *a_session;
8108 switch_channel_t *channel = switch_core_session_get_channel(session);
Value stored to 'channel' during its initialization is never read
8109
8110 if ((a_session = switch_core_session_locate(br_a)switch_core_session_perform_locate(br_a, "sofia.c", (const char
*)__func__, 8110)
)) {
8111 const char *port = NULL((void*)0);
8112 const char *rep_h = NULL((void*)0);
8113
8114 if (refer_to && refer_to->r_url && refer_to->r_url->url_port) {
8115 port = refer_to->r_url->url_port;
8116 }
8117
8118 channel = switch_core_session_get_channel(a_session);
8119
8120 exten = switch_core_session_sprintf(session, "sofia/%s/sip:%s@%s%s%s",
8121 profile->name, refer_to->r_url->url_user,
8122 refer_to->r_url->url_host, port ? ":" : "", port ? port : "");
8123
8124 switch_core_new_memory_pool(&npool)switch_core_perform_new_memory_pool(&npool, "sofia.c", (const
char *)__func__, 8124)
;
8125 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__, 8125)
;
8126 nightmare_xfer_helper->exten = switch_core_strdup(npool, exten)switch_core_perform_strdup(npool, exten, "sofia.c", (const char
*)__func__, 8126)
;
8127
8128 if (refer_to->r_url && (refer_to->r_url->url_params || refer_to->r_url->url_headers)) {
8129 if (refer_to->r_url->url_headers) {
8130 nightmare_xfer_helper->exten_with_params = switch_core_sprintf(npool,
8131 "{sip_invite_params=%s?%s}%s",
8132 refer_to->r_url->url_params ? refer_to->r_url->
8133 url_params : "", refer_to->r_url->url_headers, exten);
8134 } else {
8135 nightmare_xfer_helper->exten_with_params = switch_core_sprintf(npool,
8136 "{sip_invite_params=%s}%s", refer_to->r_url->url_params,
8137 exten);
8138 }
8139 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8139
, ((void*)0)
, SWITCH_LOG_DEBUG, "INVITE RURI '%s'\n", nightmare_xfer_helper->exten_with_params);
8140 } else {
8141 nightmare_xfer_helper->exten_with_params = nightmare_xfer_helper->exten;
8142 }
8143
8144 nightmare_xfer_helper->event = switch_core_strdup(npool, etmp)switch_core_perform_strdup(npool, etmp, "sofia.c", (const char
*)__func__, 8144)
;
8145 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__, 8145)
;
8146 nightmare_xfer_helper->bridge_to_uuid = switch_core_strdup(npool, br_a)switch_core_perform_strdup(npool, br_a, "sofia.c", (const char
*)__func__, 8146)
;
8147 nightmare_xfer_helper->pool = npool;
8148
8149 if (refer_to->r_url && refer_to->r_url->url_headers) {
8150 char *h, *v, *hp;
8151 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__, 8151)
;
8152 while (p && *p) {
8153 h = p;
8154 if ((p = strchr(p, '=')(__extension__ (__builtin_constant_p ('=') && !__builtin_constant_p
(p) && ('=') == '\0' ? (char *) __rawmemchr (p, '=')
: __builtin_strchr (p, '=')))
)) {
8155 *p++ = '\0';
8156 v = p;
8157 if ((p = strchr(p, '&')(__extension__ (__builtin_constant_p ('&') && !__builtin_constant_p
(p) && ('&') == '\0' ? (char *) __rawmemchr (p, '&'
) : __builtin_strchr (p, '&')))
)) {
8158 *p++ = '\0';
8159 }
8160
8161 url_unescape(h, (const char *) h);
8162 url_unescape(v, (const char *) v);
8163 if (strcasecmp("Replaces", h)) {
8164 hp = switch_core_session_sprintf(session, "%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", h);
8165 switch_channel_set_variable(channel, hp, v)switch_channel_set_variable_var_check(channel, hp, v, SWITCH_TRUE
)
;
8166 } else {
8167 // use this one instead of rep value from above to keep all parameters
8168 switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, v)switch_channel_set_variable_var_check(channel, "_sofia_replaces_"
, v, SWITCH_TRUE)
;
8169 }
8170 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8170, (const char*)(session)
, SWITCH_LOG_DEBUG, "Exporting replaces URL header [%s:%s]\n",
8171 h, v);
8172 }
8173 }
8174 }
8175
8176
8177 switch_event_create(&nightmare_xfer_helper->vars, SWITCH_EVENT_CHANNEL_DATA)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 8177, &nightmare_xfer_helper->
vars, SWITCH_EVENT_CHANNEL_DATA, ((void*)0))
;
8178
8179 rep_h = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER)switch_channel_get_variable_dup(channel, "_sofia_replaces_", SWITCH_TRUE
, -1)
;
8180 if (rep_h) {
8181 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REPLACES_HEADER"_sofia_replaces_", rep_h);
8182 } else {
8183 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REPLACES_HEADER"_sofia_replaces_", rep);
8184 }
8185
8186
8187 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
8188 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "Referred-By", full_ref_by);
8189 }
8190
8191 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
8192 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REFER_TO_VARIABLE"sip_refer_to", full_ref_to);
8193 }
8194
8195 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8195, (const char*)(session)
, SWITCH_LOG_DEBUG, "Good Luck, you'll need it......\n");
8196 launch_nightmare_xfer(nightmare_xfer_helper);
8197
8198 switch_core_session_rwunlock(a_session);
8199
8200 } else {
8201 goto error;
8202 }
8203
8204 } else {
8205 error:
8206 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8206, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid Transfer! [%s]\n", br_a);
8207 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)
;
8208 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"
)
,
8209 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),
8210 TAG_END()(tag_type_t)0, (tag_value_t)0);
8211 }
8212 }
8213 } else {
8214 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8214, (const char*)(session)
, SWITCH_LOG_ERROR, "Cannot parse Replaces!\n");
8215 }
8216 goto done;
8217 }
8218
8219 } else {
8220 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8220, (const char*)(session)
, SWITCH_LOG_ERROR, "Missing Refer-To\n");
8221 goto done;
8222 }
8223
8224 if (exten) {
8225 switch_channel_t *channel = switch_core_session_get_channel(session);
8226 const char *br = switch_channel_get_partner_uuid(channel);
8227 switch_core_session_t *b_session;
8228
8229 switch_channel_set_variable_printf(channel, "transfer_to", "blind:%s", br ? br : exten);
8230
8231 if (!zstr(br)_zstr(br) && (b_session = switch_core_session_locate(br)switch_core_session_perform_locate(br, "sofia.c", (const char
*)__func__, 8231)
)) {
8232 const char *var;
8233 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
8234
8235 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)
;
8236 if (!zstr(full_ref_by)_zstr(full_ref_by)) {
8237 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)
;
8238 }
8239
8240 if (!zstr(full_ref_to)_zstr(full_ref_to)) {
8241 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)
;
8242 }
8243
8244 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")switch_channel_get_variable_dup(channel, "recording_follow_transfer"
, SWITCH_TRUE, -1)
)) {
8245 switch_core_media_bug_transfer_recordings(session, b_session);
8246 }
8247
8248 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "BLIND_TRANSFER")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "BLIND_TRANSFER", SWITCH_TRUE)
;
8249
8250 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)) ||
8251 sofia_test_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)((profile)->pflags[PFLAG_CONFIRM_BLIND_TRANSFER] ? 1 : 0)) {
8252
8253 switch_channel_set_state_flag(b_channel, CF_CONFIRM_BLIND_TRANSFER);
8254 switch_channel_set_variable(channel, "sip_blind_transfer_event", etmp)switch_channel_set_variable_var_check(channel, "sip_blind_transfer_event"
, etmp, SWITCH_TRUE)
;
8255 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)
;
8256 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)
;
8257
8258 switch_channel_set_variable(channel, "park_timeout", "600:blind_transfer")switch_channel_set_variable_var_check(channel, "park_timeout"
, "600:blind_transfer", SWITCH_TRUE)
;
8259 switch_channel_set_state(channel, CS_PARK)switch_channel_perform_set_state(channel, "sofia.c", (const char
*)__func__, 8259, CS_PARK)
;
8260 } else {
8261 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"
)
,
8262 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
8263 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
8264 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
8265 }
8266
8267 if (refer_to->r_url->url_params) {
8268 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)
;
8269 }
8270
8271 switch_ivr_session_transfer(b_session, exten, NULL((void*)0), NULL((void*)0));
8272 switch_core_session_rwunlock(b_session);
8273 } else {
8274 switch_event_t *event;
8275
8276 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 8276, &event, SWITCH_EVENT_CUSTOM
, "sofia::error")
== SWITCH_STATUS_SUCCESS) {
8277 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Error-Type", "blind_transfer");
8278 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Transfer-Exten", exten);
8279 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Full-Refer-To", full_ref_to);
8280 switch_channel_event_set_data(channel, event);
8281 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 8281, &event, ((void*)0))
;
8282 }
8283
8284 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8284, (const char*)(session)
, SWITCH_LOG_ERROR, "Cannot Blind Transfer 1 Legged calls\n");
8285 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)
;
8286 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"
)
,
8287 NUTAG_SUBSTATE(nua_substate_terminated)nutag_substate, tag_int_v(nua_substate_terminated),
8288 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource")siptag_subscription_state_str, tag_str_v("terminated;reason=noresource"
)
,
8289 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);
8290 }
8291 }
8292
8293 done:
8294 if (home) {
8295 su_home_unref(home);
8296 home = NULL((void*)0);
8297 }
8298
8299 if (etmp) {
8300 switch_safe_free(etmp)if (etmp) {free(etmp);etmp=((void*)0);};
8301 }
8302}
8303
8304
8305static switch_status_t create_info_event(sip_t const *sip,
8306 nua_handle_t *nh, switch_event_t **revent)
8307{
8308 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
))
;
8309 switch_event_t *event;
8310
8311 if (!(sip && switch_event_create(&event, SWITCH_EVENT_RECV_INFO)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 8311, &event, SWITCH_EVENT_RECV_INFO
, ((void*)0))
== SWITCH_STATUS_SUCCESS)) {
8312 return SWITCH_STATUS_FALSE;
8313 }
8314
8315 if (sip && sip->sip_content_type) {
8316 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Content-Type", sip->sip_content_type->c_type);
8317 }
8318
8319 if (sip->sip_from && sip->sip_from->a_url) {
8320 if (sip->sip_from->a_url->url_user) {
8321 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-From-User", sip->sip_from->a_url->url_user);
8322 }
8323
8324 if (sip->sip_from->a_url->url_host) {
8325 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-From-Host", sip->sip_from->a_url->url_host);
8326 }
8327 }
8328
8329 if (sip->sip_to && sip->sip_to->a_url) {
8330 if (sip->sip_to->a_url->url_user) {
8331 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-To-User", sip->sip_to->a_url->url_user);
8332 }
8333
8334 if (sip->sip_to->a_url->url_host) {
8335 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-To-Host", sip->sip_to->a_url->url_host);
8336 }
8337 }
8338
8339
8340 if (sip->sip_contact && sip->sip_contact->m_url) {
8341 if (sip->sip_contact->m_url->url_user) {
8342 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Contact-User", sip->sip_contact->m_url->url_user);
8343 }
8344
8345 if (sip->sip_contact->m_url->url_host) {
8346 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Contact-Host", sip->sip_contact->m_url->url_host);
8347 }
8348 }
8349
8350
8351 if (sip->sip_call_info) {
8352 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Call-Info",
8353 sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info));
8354 }
8355
8356 if (alert_info) {
8357 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));
8358 }
8359
8360
8361 if (sip->sip_payload && sip->sip_payload->pl_data) {
8362 switch_event_add_body(event, "%s", sip->sip_payload->pl_data);
8363 }
8364
8365 *revent = event;
8366
8367 return SWITCH_STATUS_SUCCESS;
8368}
8369
8370void 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,
8371 sofia_dispatch_event_t *de, tagi_t tags[])
8372{
8373 /* placeholder for string searching */
8374 const char *signal_ptr;
8375 const char *rec_header;
8376 const char *clientcode_header;
8377 switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), 0, SWITCH_DTMF_ENDPOINT };
8378 switch_event_t *event;
8379 private_object_t *tech_pvt = NULL((void*)0);
8380 switch_channel_t *channel = NULL((void*)0);
8381
8382 if (session) {
8383 tech_pvt = (private_object_t *) switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8384 channel = switch_core_session_get_channel(session);
8385 }
8386
8387 if (sofia_test_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)((profile)->pflags[PFLAG_EXTENDED_INFO_PARSING] ? 1 : 0)) {
8388 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
8389 sip->sip_payload && sip->sip_payload->pl_data) {
8390
8391 if (!strncasecmp(sip->sip_content_type->c_type, "freeswitch", 10)) {
8392
8393 if (!strcasecmp(sip->sip_content_type->c_subtype, "session-event")) {
8394 if (session) {
8395 if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
8396 if (switch_core_session_queue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
8397 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8397, (const char*)(session)
, SWITCH_LOG_DEBUG, "queued freeswitch event for INFO\n");
8398 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"
)
,
8399 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
8400 } else {
8401 switch_event_destroy(&event);
8402 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"
)
,
8403 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
8404 }
8405 }
8406
8407 } else {
8408 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"
)
,
8409 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
8410
8411 }
8412
8413 return;
8414
8415 } else if (!strcasecmp(sip->sip_content_type->c_subtype, "api-request")) {
8416 char *cmd = strdup(sip->sip_payload->pl_data)(__extension__ (__builtin_constant_p (sip->sip_payload->
pl_data) && ((size_t)(const void *)((sip->sip_payload
->pl_data) + 1) - (size_t)(const void *)(sip->sip_payload
->pl_data) == 1) ? (((const char *) (sip->sip_payload->
pl_data))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1
) : ({ size_t __len = strlen (sip->sip_payload->pl_data
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, sip->
sip_payload->pl_data, __len); __retval; })) : __strdup (sip
->sip_payload->pl_data)))
;
8417 char *arg;
8418 switch_stream_handle_t stream = { 0 };
8419 switch_status_t status;
8420
8421 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia.c", 8421, __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
;
8422 switch_assert(stream.data)((stream.data) ? (void) (0) : __assert_fail ("stream.data", "sofia.c"
, 8422, __PRETTY_FUNCTION__))
;
8423
8424 if ((arg = strchr(cmd, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(cmd) && (':') == '\0' ? (char *) __rawmemchr (cmd, ':'
) : __builtin_strchr (cmd, ':')))
)) {
8425 *arg++ = '\0';
8426 }
8427
8428 if ((status = switch_api_execute(cmd, arg, NULL((void*)0), &stream)) == SWITCH_STATUS_SUCCESS) {
8429 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"),
8430 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
8431 } else {
8432 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"),
8433 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
8434 }
8435
8436 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
8437 switch_safe_free(cmd)if (cmd) {free(cmd);cmd=((void*)0);};
8438 return;
8439 }
8440
8441 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_END()(tag_type_t)0, (tag_value_t)0);
8442
8443 return;
8444 }
8445 }
8446 }
8447
8448 if (session) {
8449 const char *vval;
8450
8451 /* Barf if we didn't get our private */
8452 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_class(session, SWITCH_PVT_PRIMARY)"
, "sofia.c", 8452, __PRETTY_FUNCTION__))
;
8453
8454 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_INFO_HEADER_PREFIX"sip_info_h_");
8455
8456
8457
8458 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && !strcasecmp(sip->sip_content_type->c_type, "freeswitch/data")) {
8459 char *data = NULL((void*)0);
8460
8461 if (sip->sip_payload && sip->sip_payload->pl_data) {
8462 data = sip->sip_payload->pl_data;
8463 }
8464
8465 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)) {
8466 switch_core_session_t *nsession = NULL((void*)0);
8467
8468 switch_core_session_get_partner(session, &nsession)switch_core_session_perform_get_partner(session, &nsession
, "sofia.c", (const char *)__func__, 8468)
;
8469
8470 if (nsession) {
8471 switch_core_session_message_t *msg;
8472
8473 switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_INFO_HEADER_PREFIX_T"~sip_info_h_");
8474 msg = switch_core_session_alloc(nsession, sizeof(*msg))switch_core_perform_session_alloc(nsession, sizeof(*msg), "sofia.c"
, (const char *)__func__, 8474)
;
8475 MESSAGE_STAMP_FFL(msg)msg->_file = "sofia.c"; msg->_func = (const char *)__func__
; msg->_line = 8475
;
8476 msg->message_id = SWITCH_MESSAGE_INDICATE_INFO;
8477
8478 msg->string_array_arg[2] = switch_core_session_strdup(nsession, data)switch_core_perform_session_strdup(nsession, data, "sofia.c",
(const char *)__func__, 8478)
;
8479
8480 msg->from = __FILE__"sofia.c";
8481 switch_core_session_queue_message(nsession, msg);
8482
8483 switch_core_session_rwunlock(nsession);
8484 }
8485 }
8486 }
8487
8488 if (sip && sip->sip_content_type && sip->sip_content_type->c_subtype && sip->sip_content_type->c_type &&
8489 !strncasecmp(sip->sip_content_type->c_type, "message", 7) &&
8490 !strcasecmp(sip->sip_content_type->c_subtype, "update_display")) {
8491 sofia_update_callee_id(session, profile, sip, SWITCH_TRUE);
8492 goto end;
8493 }
8494
8495 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
8496 sip->sip_payload && sip->sip_payload->pl_data) {
8497 if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) {
8498 switch_core_session_t *other_session;
8499
8500 if (switch_channel_test_flag(channel, CF_VIDEO)) {
8501 if (switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "sofia.c", (const char *)__func__, 8501)
== SWITCH_STATUS_SUCCESS) {
8502 sofia_glue_build_vid_refresh_message(other_session, sip->sip_payload->pl_data);
8503 switch_core_session_rwunlock(other_session);
8504 } else {
8505 switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ)switch_channel_set_flag_value(channel, CF_VIDEO_REFRESH_REQ, 1
)
;
8506 }
8507 }
8508
8509 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) &&
8510 !strcasecmp(sip->sip_content_type->c_subtype, "vnd.nortelnetworks.digits")) {
8511 int tmp;
8512 if ((signal_ptr = switch_stristr("d=", sip->sip_payload->pl_data))) {
8513 signal_ptr = signal_ptr + 2;
8514
8515 while (*signal_ptr && *signal_ptr == ' ') {
8516 signal_ptr++;
8517 }
8518
8519 if (*signal_ptr && (*signal_ptr == '*' || *signal_ptr == '#' || *signal_ptr == 'A' || *signal_ptr == 'B'
8520 || *signal_ptr == 'C' || *signal_ptr == 'D')) {
8521 dtmf.digit = *signal_ptr;
8522 } else {
8523 tmp = atoi(signal_ptr);
8524 dtmf.digit = switch_rfc2833_to_char(tmp);
8525 }
8526
8527 dtmf.duration = 100;
8528 } else {
8529 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8529, (const char*)(session)
, SWITCH_LOG_DEBUG, "Bad signal\n");
8530 goto end;
8531 }
8532 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) {
8533 /* Try and find signal information in the payload */
8534 if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) {
8535 int tmp;
8536 /* move signal_ptr where we need it (right past Signal=) */
8537 signal_ptr = signal_ptr + 7;
8538
8539 /* handle broken devices with spaces after the = (cough) VegaStream (cough) */
8540 while (*signal_ptr && *signal_ptr == ' ')
8541 signal_ptr++;
8542
8543 if (*signal_ptr
8544 && (*signal_ptr == '*' || *signal_ptr == '#' || *signal_ptr == 'A' || *signal_ptr == 'B' || *signal_ptr == 'C'
8545 || *signal_ptr == 'D')) {
8546 dtmf.digit = *signal_ptr;
8547 } else {
8548 tmp = atoi(signal_ptr);
8549 dtmf.digit = switch_rfc2833_to_char(tmp);
8550 }
8551 } else {
8552 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8552, (const char*)(session)
, SWITCH_LOG_DEBUG, "Bad signal\n");
8553 goto end;
8554 }
8555
8556 if ((signal_ptr = switch_stristr("Duration=", sip->sip_payload->pl_data))) {
8557 int tmp;
8558 signal_ptr += 9;
8559
8560 /* handle broken devices with spaces after the = (cough) VegaStream (cough) */
8561 while (*signal_ptr && *signal_ptr == ' ')
8562 signal_ptr++;
8563
8564 if ((tmp = atoi(signal_ptr)) <= 0) {
8565 tmp = switch_core_default_dtmf_duration(0);
8566 }
8567 dtmf.duration = tmp * 8;
8568 }
8569 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf")) {
8570 int tmp = atoi(sip->sip_payload->pl_data);
8571 dtmf.digit = switch_rfc2833_to_char(tmp);
8572 } else {
8573 goto end;
8574 }
8575
8576 if (dtmf.digit) {
8577 if (tech_pvt->mparams.dtmf_type == DTMF_INFO ||
8578 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)) {
8579 /* queue it up */
8580 switch_channel_queue_dtmf(channel, &dtmf);
8581
8582 /* print debug info */
8583 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8583, (const char*)(session)
, SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit);
8584
8585 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
8586 const char *uuid;
8587 switch_core_session_t *session_b;
8588
8589 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__, 8589)
)) {
8590 while (switch_channel_has_dtmf(channel)) {
8591 switch_dtmf_t idtmf = { 0, 0 };
8592 if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) {
8593 switch_core_session_send_dtmf(session_b, &idtmf);
8594 }
8595 }
8596
8597 switch_core_session_rwunlock(session_b);
8598 }
8599 }
8600
8601 /* Send 200 OK response */
8602 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_END()(tag_type_t)0, (tag_value_t)0);
8603 } else {
8604 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8604, (const char*)(session)
, SWITCH_LOG_WARNING,
8605 "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
8606 }
8607 }
8608 goto end;
8609 }
8610
8611 if ((clientcode_header = sofia_glue_get_unknown_header(sip, "x-clientcode"))) {
8612 if (!zstr(clientcode_header)_zstr(clientcode_header)) {
8613 switch_channel_set_variable(channel, "call_clientcode", clientcode_header)switch_channel_set_variable_var_check(channel, "call_clientcode"
, clientcode_header, SWITCH_TRUE)
;
8614 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8614, (const char*)(session)
, SWITCH_LOG_NOTICE, "Setting CMC to %s\n", clientcode_header);
8615 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_END()(tag_type_t)0, (tag_value_t)0);
8616 }
8617 goto end;
8618 }
8619
8620 if ((rec_header = sofia_glue_get_unknown_header(sip, "record"))) {
8621 if (zstr(profile->record_template)_zstr(profile->record_template)) {
8622 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8622, (const char*)(session)
, SWITCH_LOG_WARNING, "Record attempted but no template defined.\n");
8623 nua_respond(nh, 488, "Recording not enabled", 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);
8624 } else {
8625 if (!strcasecmp(rec_header, "on")) {
8626 char *file = NULL((void*)0), *tmp = NULL((void*)0);
8627
8628 if (switch_true(switch_channel_get_variable(channel, "sip_disable_recording")switch_channel_get_variable_dup(channel, "sip_disable_recording"
, SWITCH_TRUE, -1)
)) {
8629 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8629, (const char*)(session)
, SWITCH_LOG_WARNING, "Record attempted but is disabled by sip_disable_recording variable.\n");
8630 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), TAG_END()(tag_type_t)0, (tag_value_t)0);
8631 } else {
8632
8633 tmp = switch_mprintf("%s%s%s", profile->record_path ? profile->record_path : "${recordings_dir}",
8634 SWITCH_PATH_SEPARATOR"/", profile->record_template);
8635 file = switch_channel_expand_variables(channel, tmp)switch_channel_expand_variables_check(channel, tmp, ((void*)0
), ((void*)0), 0)
;
8636 switch_ivr_record_session(session, file, 0, NULL((void*)0));
8637 switch_channel_set_variable(channel, "sofia_record_file", file)switch_channel_set_variable_var_check(channel, "sofia_record_file"
, file, SWITCH_TRUE)
;
8638 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8638, (const char*)(session)
, SWITCH_LOG_NOTICE, "Recording %s to %s\n", switch_channel_get_name(channel),
8639 file);
8640 switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);};
8641 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_END()(tag_type_t)0, (tag_value_t)0);
8642 if (file != profile->record_template) {
8643 free(file);
8644 file = NULL((void*)0);
8645 }
8646 }
8647 } else {
8648 const char *file;
8649
8650 if ((file = switch_channel_get_variable(channel, "sofia_record_file")switch_channel_get_variable_dup(channel, "sofia_record_file",
SWITCH_TRUE, -1)
)) {
8651 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8651, (const char*)(session)
, SWITCH_LOG_NOTICE, "Done recording %s to %s\n",
8652 switch_channel_get_name(channel), file);
8653 switch_ivr_stop_record_session(session, file);
8654 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_END()(tag_type_t)0, (tag_value_t)0);
8655 } else {
8656 nua_respond(nh, 488, "Nothing to stop", 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);
8657 }
8658 }
8659 }
8660 }
8661 }
8662
8663 end:
8664
8665 if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
8666 if (channel) {
8667 switch_channel_event_set_data(channel, event);
8668 }
8669 switch_event_fire(&event)switch_event_fire_detailed("sofia.c", (const char * )(const char
*)__func__, 8669, &event, ((void*)0))
;
8670 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8670, (const char*)(session)
, SWITCH_LOG_DEBUG, "dispatched freeswitch event for INFO\n");
8671 }
8672
8673 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_END()(tag_type_t)0, (tag_value_t)0);
8674
8675 return;
8676
8677}
8678
8679void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
8680 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
8681 sofia_dispatch_event_t *de,
8682 tagi_t tags[])
8683{
8684 char *call_info = NULL((void*)0);
8685 switch_channel_t *channel = NULL((void*)0);
8686 private_object_t *tech_pvt = NULL((void*)0);
8687
8688 if (session) {
8689 channel = switch_core_session_get_channel(session);
8690 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8691 }
8692
8693 if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)((profile)->pflags[PFLAG_TRACK_CALLS] ? 1 : 0)) {
8694 switch_channel_t *channel = switch_core_session_get_channel(session);
8695 private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8696 char network_ip[80];
8697 int network_port = 0;
8698 char via_space[2048];
8699 char branch[16] = "";
8700
8701 sofia_clear_flag(tech_pvt, TFLAG_GOT_ACK)(tech_pvt)->flags[TFLAG_GOT_ACK] = 0;
8702
8703 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
8704 switch_stun_random_string(branch, sizeof(branch) - 1, "0123456789abcdef");
8705
8706 switch_snprintf(via_space, sizeof(via_space), "SIP/2.0/UDP %s;rport=%d;branch=%s", network_ip, network_port, branch);
8707 switch_channel_set_variable(channel, "sip_full_via", via_space)switch_channel_set_variable_var_check(channel, "sip_full_via"
, via_space, SWITCH_TRUE)
;
8708 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
8709 switch_channel_set_variable_printf(channel, "sip_recieved_port", "%d", network_port);
8710 switch_channel_set_variable_printf(channel, "sip_via_rport", "%d", network_port);
8711
8712 switch_core_recovery_track(session);
8713 }
8714
8715 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
8716 if (channel && sip->sip_call_info) {
8717 char *p;
8718 if ((call_info = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) sip->sip_call_info))) {
8719 if (switch_stristr("appearance", call_info)) {
8720 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)
;
8721 if ((p = strchr(call_info, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(call_info) && (';') == '\0' ? (char *) __rawmemchr (
call_info, ';') : __builtin_strchr (call_info, ';')))
)) {
8722 switch_channel_set_variable(channel, "presence_call_info", p + 1)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p + 1, SWITCH_TRUE)
;
8723 }
8724 }
8725 su_free(nua_handle_home(nh)((su_home_t *)(nh)), call_info);
8726 }
8727 }
8728 }
8729
8730 if (channel) {
8731 tech_pvt->mparams.last_sdp_str = NULL((void*)0);
8732 if (sip->sip_payload && sip->sip_payload->pl_data) {
8733 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)
;
8734 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__, 8734)
;
8735 }
8736 switch_channel_execute_on(channel, "execute_on_sip_reinvite");
8737 }
8738
8739}
8740
8741void 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[])
8742{
8743 char key[128] = "";
8744 sip_unknown_t *un;
8745 sip_remote_party_id_t *rpid = NULL((void*)0);
8746 sip_p_asserted_identity_t *passerted = NULL((void*)0);
8747 sip_p_preferred_identity_t *ppreferred = NULL((void*)0);
8748 sip_privacy_t *privacy = NULL((void*)0);
8749 sip_alert_info_t *alert_info = NULL((void*)0);
8750 sip_call_info_t *call_info = NULL((void*)0);
8751 private_object_t *tech_pvt = NULL((void*)0);
8752 switch_channel_t *channel = NULL((void*)0);
8753 //const char *channel_name = NULL;
8754 const char *displayname = NULL((void*)0);
8755 const char *destination_number = NULL((void*)0);
8756 const char *from_user = NULL((void*)0), *from_host = NULL((void*)0);
8757 const char *referred_by_user = NULL((void*)0);//, *referred_by_host = NULL;
8758 const char *context = NULL((void*)0);
8759 const char *dialplan = NULL((void*)0);
8760 char network_ip[80];
8761 char proxied_client_ip[80];
8762 switch_event_t *v_event = NULL((void*)0);
8763 switch_xml_t x_user = NULL((void*)0);
8764 uint32_t sess_count = switch_core_session_count();
8765 uint32_t sess_max = switch_core_session_limit(0);
8766 int is_auth = 0, calling_myself = 0;
8767 int network_port = 0;
8768 char *is_nat = NULL((void*)0);
8769 char *aniii = NULL((void*)0);
8770 char acl_token[512] = "";
8771 sofia_transport_t transport;
8772 const char *gw_name = NULL((void*)0);
8773 const char *gw_param_name = NULL((void*)0);
8774 char *call_info_str = NULL((void*)0);
8775 nua_handle_t *bnh = NULL((void*)0);
8776 char sip_acl_authed_by[512] = "";
8777 char sip_acl_token[512] = "";
8778 const char *dialog_from_user = "", *dialog_from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
8779 const char *user_agent = "", *call_id = "";
8780 url_t *from = NULL((void*)0), *to = NULL((void*)0), *contact = NULL((void*)0);
8781 const char *to_tag = "";
8782 const char *from_tag = "";
8783 char *sql = NULL((void*)0);
8784 char *acl_context = NULL((void*)0);
8785 const char *r_sdp = NULL((void*)0);
8786 int is_tcp = 0, is_tls = 0;
8787 const char *uparams = NULL((void*)0);
8788 char *name_params = NULL((void*)0);
8789
8790
8791 if (sip && sip->sip_contact && sip->sip_contact->m_url && sip->sip_contact->m_url->url_params) {
8792 uparams = sip->sip_contact->m_url->url_params;
8793 } else {
8794 uparams = NULL((void*)0);
8795 }
8796
8797
8798 if (uparams) {
8799 if (switch_stristr("transport=tcp", uparams)) {
8800 is_tcp = 1;
8801 } else if (switch_stristr("transport=tls", uparams)) {
8802 is_tls = 1;
8803 }
8804 }
8805
8806 profile->ib_calls++;
8807
8808 if (sip->sip_payload && sip->sip_payload->pl_data) {
8809 r_sdp = sip->sip_payload->pl_data;
8810 }
8811
8812 if (!session || (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0))) {
8813 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);
8814 goto fail;
8815 }
8816
8817 tech_pvt = switch_core_session_get_private(session)switch_core_session_get_private_class(session, SWITCH_PVT_PRIMARY
)
;
8818
8819 if (!sip || !sip->sip_request || !sip->sip_request->rq_method_name) {
8820 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8820
, ((void*)0)
, SWITCH_LOG_ERROR, "Received an invalid packet!\n");
8821 nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE503, sip_503_Service_unavailable, TAG_END()(tag_type_t)0, (tag_value_t)0);
8822 goto fail;
8823 }
8824
8825 if (!(sip->sip_contact && sip->sip_contact->m_url)) {
8826 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8826
, ((void*)0)
, SWITCH_LOG_ERROR, "NO CONTACT!\n");
8827 nua_respond(nh, 400, "Missing Contact Header", TAG_END()(tag_type_t)0, (tag_value_t)0);
8828 goto fail;
8829 }
8830
8831
8832 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
8833
8834 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
8834, (const char*)(tech_pvt->session)
, SWITCH_LOG_DEBUG, "%s receiving invite from %s:%d version: %s\n",
8835 switch_channel_get_name(tech_pvt->channel), network_ip, network_port, switch_version_full_human());
8836
8837
8838 if (sip && sip->sip_via && sip->sip_via->v_protocol && switch_stristr("sip/2.0/ws", sip->sip_via->v_protocol)) {
8839 is_nat = "websockets";
8840 }
8841
8842
8843 if (r_sdp) {
8844 switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
8845 }
8846
8847
8848 if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)((profile)->pflags[PFLAG_AGGRESSIVE_NAT_DETECTION] ? 1 : 0
)
||
8849 (sofia_test_pflag(profile, PFLAG_TLS_ALWAYS_NAT)((profile)->pflags[PFLAG_TLS_ALWAYS_NAT] ? 1 : 0) && (is_tcp || is_tls)) ||
8850 (!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))
) &&
8851 profile->server_rport_level >= 2 && sip->sip_user_agent &&
8852 sip->sip_user_agent->g_string &&
8853 (!strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7) || !strncasecmp(sip->sip_user_agent->g_string, "KIRK Wireless Server", 20)))
8854 ) {
8855 if (sip && sip->sip_via) {
8856 const char *port = sip->sip_via->v_port;
8857 const char *host = sip->sip_via->v_host;
8858
8859 if (host && sip->sip_via->v_received) {
8860 is_nat = "via received";
8861 } else if (host && strcmp(network_ip, host)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(network_ip) && __builtin_constant_p (host) &&
(__s1_len = __builtin_strlen (network_ip), __s2_len = __builtin_strlen
(host), (!((size_t)(const void *)((network_ip) + 1) - (size_t
)(const void *)(network_ip) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((host) + 1) - (size_t)(const void *
)(host) == 1) || __s2_len >= 4)) ? __builtin_strcmp (network_ip
, host) : (__builtin_constant_p (network_ip) && ((size_t
)(const void *)((network_ip) + 1) - (size_t)(const void *)(network_ip
) == 1) && (__s1_len = __builtin_strlen (network_ip),
__s1_len < 4) ? (__builtin_constant_p (host) && (
(size_t)(const void *)((host) + 1) - (size_t)(const void *)(host
) == 1) ? __builtin_strcmp (network_ip, host) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (host); int __result = (((const unsigned char *) (const
char *) (network_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (network_ip))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (network_ip))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (network_ip))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(host) && ((size_t)(const void *)((host) + 1) - (size_t
)(const void *)(host) == 1) && (__s2_len = __builtin_strlen
(host), __s2_len < 4) ? (__builtin_constant_p (network_ip
) && ((size_t)(const void *)((network_ip) + 1) - (size_t
)(const void *)(network_ip) == 1) ? __builtin_strcmp (network_ip
, host) : (- (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (network_ip); int __result =
(((const unsigned char *) (const char *) (host))[0] - __s2[0
]); if (__s2_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (host))[1] - __s2[1
]); if (__s2_len > 1 && __result == 0) { __result =
(((const unsigned char *) (const char *) (host))[2] - __s2[2
]); if (__s2_len > 2 && __result == 0) __result = (
((const unsigned char *) (const char *) (host))[3] - __s2[3])
; } } __result; })))) : __builtin_strcmp (network_ip, host)))
); })
) {
8862 is_nat = "via host";
8863 } else if (port && atoi(port) != network_port) {
8864 is_nat = "via port";
8865 }
8866 }
8867 }
8868
8869 if (!is_nat && profile->nat_acl_count) {
8870 uint32_t x = 0;
8871 int contact_private_ip = 1;
8872 int network_private_ip = 0;
8873 char *last_acl = NULL((void*)0);
8874 const char *contact_host = NULL((void*)0);
8875
8876 if (sip && sip->sip_contact && sip->sip_contact->m_url) {
8877 contact_host = sip->sip_contact->m_url->url_host;
8878 }
8879
8880 if (!zstr(contact_host)_zstr(contact_host)) {
8881 /* NAT mode double check logic and examples.
8882
8883 Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point
8884 is most likely behind nat with us so we need to veto that decision to turn on nat processing.
8885
8886 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
8887 the remote endpoint is likely behind a remote nat traversing the public internet.
8888
8889 This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net
8890 in cases where we don't really need to be doing this.
8891
8892 Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind
8893 remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process.
8894
8895 */
8896
8897 for (x = 0; x < profile->nat_acl_count; x++) {
8898 last_acl = profile->nat_acl[x];
8899 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))
)) {
8900 break;
8901 }
8902 }
8903 if (contact_private_ip) {
8904 for (x = 0; x < profile->nat_acl_count; x++) {
8905 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))
)) {
8906 break;
8907 }
8908 }
8909 }
8910
8911 if (contact_private_ip && !network_private_ip) {
8912 is_nat = last_acl;
8913 }
8914 }
8915 }
8916
8917 if (profile->acl_count) {
8918 uint32_t x = 0;
8919 int ok = 1;
8920 char *last_acl = NULL((void*)0);
8921 const char *token = NULL((void*)0);
8922
8923 for (x = 0; x < profile->acl_count; x++) {
8924 last_acl = profile->acl[x];
8925 if ((ok = switch_check_network_list_ip_token(network_ip, last_acl, &token))) {
8926
8927 if (profile->acl_pass_context[x]) {
8928 acl_context = profile->acl_pass_context[x];
8929 }
8930
8931 break;
8932 }
8933
8934 if (profile->acl_fail_context[x]) {
8935 acl_context = profile->acl_fail_context[x];
8936 } else {
8937 acl_context = NULL((void*)0);
8938 }
8939 }
8940
8941 if (ok) {
8942 if (token) {
8943 switch_set_string(acl_token, token)switch_copy_string(acl_token, token, sizeof(acl_token));
8944 }
8945 if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
8946 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8946
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
8947 network_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""), acl_token);
8948 switch_set_string(sip_acl_authed_by, last_acl)switch_copy_string(sip_acl_authed_by, last_acl, sizeof(sip_acl_authed_by
))
;
8949 switch_set_string(sip_acl_token, acl_token)switch_copy_string(sip_acl_token, acl_token, sizeof(sip_acl_token
))
;
8950 is_auth = 1;
8951 }
8952 } else {
8953 int network_ip_is_proxy = 0;
8954 /* Check if network_ip is a proxy allowed to send us calls */
8955 if (profile->proxy_acl_count) {
8956 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8956
, ((void*)0)
, SWITCH_LOG_DEBUG, "%d acls to check for proxy\n", profile->proxy_acl_count);
8957 }
8958
8959 for (x = 0; x < profile->proxy_acl_count; x++) {
8960 last_acl = profile->proxy_acl[x];
8961 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8961
, ((void*)0)
, SWITCH_LOG_DEBUG, "checking %s against acl %s\n", network_ip, last_acl);
8962 if (switch_check_network_list_ip_token(network_ip, last_acl, &token)) {
8963 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8963
, ((void*)0)
, SWITCH_LOG_INFO, "%s is a proxy according to the %s acl\n", network_ip, last_acl);
8964 network_ip_is_proxy = 1;
8965 break;
8966 }
8967 }
8968 /*
8969 * if network_ip is a proxy allowed to send calls, check for auth
8970 * ip header and see if it matches against the inbound acl
8971 */
8972 if (network_ip_is_proxy) {
8973 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8973
, ((void*)0)
, SWITCH_LOG_DEBUG, "network ip is a proxy\n");
8974
8975 for (un = sip->sip_unknown; un; un = un->un_next) {
8976 if (!strcasecmp(un->un_name, "X-AUTH-IP")) {
8977 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8977
, ((void*)0)
, SWITCH_LOG_DEBUG, "found auth ip [%s] header of [%s]\n", un->un_name, un->un_value);
8978 if (!zstr(un->un_value)_zstr(un->un_value)) {
8979 for (x = 0; x < profile->acl_count; x++) {
8980 last_acl = profile->acl[x];
8981 if ((ok = switch_check_network_list_ip_token(un->un_value, last_acl, &token))) {
8982 switch_copy_string(proxied_client_ip, un->un_value, sizeof(proxied_client_ip));
8983 break;
8984 }
8985 }
8986 }
8987 }
8988 }
8989 }
8990
8991 if (!ok) {
8992
8993 if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
8994 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 8994
, ((void*)0)
, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", network_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""));
8995
8996 if (!acl_context) {
8997 nua_respond(nh, SIP_403_FORBIDDEN403, sip_403_Forbidden, TAG_END()(tag_type_t)0, (tag_value_t)0);
8998 goto fail;
8999 }
9000 } else {
9001 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 9001
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
9002 network_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""));
9003 }
9004 } else {
9005 if (token) {
9006 switch_set_string(acl_token, token)switch_copy_string(acl_token, token, sizeof(acl_token));
9007 }
9008 if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)) {
9009 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 9009
, ((void*)0)
, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
9010 proxied_client_ip, switch_str_nil(last_acl)(last_acl ? last_acl : ""), acl_token);
9011 switch_set_string(sip_acl_authed_by, last_acl)switch_copy_string(sip_acl_authed_by, last_acl, sizeof(sip_acl_authed_by
))
;
9012 switch_set_string(sip_acl_token, acl_token)switch_copy_string(sip_acl_token, acl_token, sizeof(sip_acl_token
))
;
9013
9014 is_auth = 1;
9015
9016 }
9017 }
9018 }
9019 }
9020
9021 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)) {
9022 char *user;
9023
9024 if (!strcmp(network_ip, profile->sipip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(network_ip) && __builtin_constant_p (profile->sipip
) && (__s1_len = __builtin_strlen (network_ip), __s2_len
= __builtin_strlen (profile->sipip), (!((size_t)(const void
*)((network_ip) + 1) - (size_t)(const void *)(network_ip) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
((profile->sipip) + 1) - (size_t)(const void *)(profile->
sipip) == 1) || __s2_len >= 4)) ? __builtin_strcmp (network_ip
, profile->sipip) : (__builtin_constant_p (network_ip) &&
((size_t)(const void *)((network_ip) + 1) - (size_t)(const void
*)(network_ip) == 1) && (__s1_len = __builtin_strlen
(network_ip), __s1_len < 4) ? (__builtin_constant_p (profile
->sipip) && ((size_t)(const void *)((profile->sipip
) + 1) - (size_t)(const void *)(profile->sipip) == 1) ? __builtin_strcmp
(network_ip, profile->sipip) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (profile
->sipip); int __result = (((const unsigned char *) (const char
*) (network_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (network_ip))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (network_ip))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (network_ip))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(profile->sipip) && ((size_t)(const void *)((profile
->sipip) + 1) - (size_t)(const void *)(profile->sipip) ==
1) && (__s2_len = __builtin_strlen (profile->sipip
), __s2_len < 4) ? (__builtin_constant_p (network_ip) &&
((size_t)(const void *)((network_ip) + 1) - (size_t)(const void
*)(network_ip) == 1) ? __builtin_strcmp (network_ip, profile
->sipip) : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (network_ip); int __result
= (((const unsigned char *) (const char *) (profile->sipip
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (profile
->sipip))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
profile->sipip))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (profile->sipip))[3] - __s2[3]); } } __result; })))) :
__builtin_strcmp (network_ip, profile->sipip)))); })
&& network_port == profile->sip_port) {
9025 calling_myself++;
9026 }
9027
9028 if (sip && sip->sip_from) {
9029 user = switch_core_session_sprintf(session, "%s@%s", sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host);
9030 switch_ivr_set_user(session, user);
9031 }
9032
9033 is_auth++;
9034 }
9035
9036 if (!is_auth &&
9037 (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)((profile)->pflags[PFLAG_AUTH_CALLS] ? 1 : 0)
9038 || (!sofia_test_pflag(profile, PFLAG_BLIND_AUTH)((profile)->pflags[PFLAG_BLIND_AUTH] ? 1 : 0) && (sip->sip_proxy_authorization || sip->sip_authorization)))) {
9039 if (!strcmp(network_ip, profile->sipip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(network_ip) && __builtin_constant_p (profile->sipip
) && (__s1_len = __builtin_strlen (network_ip), __s2_len
= __builtin_strlen (profile->sipip), (!((size_t)(const void
*)((network_ip) + 1) - (size_t)(const void *)(network_ip) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
((profile->sipip) + 1) - (size_t)(const void *)(profile->
sipip) == 1) || __s2_len >= 4)) ? __builtin_strcmp (network_ip
, profile->sipip) : (__builtin_constant_p (network_ip) &&
((size_t)(const void *)((network_ip) + 1) - (size_t)(const void
*)(network_ip) == 1) && (__s1_len = __builtin_strlen
(network_ip), __s1_len < 4) ? (__builtin_constant_p (profile
->sipip) && ((size_t)(const void *)((profile->sipip
) + 1) - (size_t)(const void *)(profile->sipip) == 1) ? __builtin_strcmp
(network_ip, profile->sipip) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (profile
->sipip); int __result = (((const unsigned char *) (const char
*) (network_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (network_ip))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (network_ip))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (network_ip))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(profile->sipip) && ((size_t)(const void *)((profile
->sipip) + 1) - (size_t)(const void *)(profile->sipip) ==
1) && (__s2_len = __builtin_strlen (profile->sipip
), __s2_len < 4) ? (__builtin_constant_p (network_ip) &&
((size_t)(const void *)((network_ip) + 1) - (size_t)(const void
*)(network_ip) == 1) ? __builtin_strcmp (network_ip, profile
->sipip) : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (network_ip); int __result
= (((const unsigned char *) (const char *) (profile->sipip
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (profile
->sipip))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
profile->sipip))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (profile->sipip))[3] - __s2[3]); } } __result; })))) :
__builtin_strcmp (network_ip, profile->sipip)))); })
&& network_port == profile->sip_port) {
9040 calling_myself++;
9041 } else {
9042 switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("sofia.c", (const char *
)(const char *)__func__, 9042, &v_event, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
9043
9044 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))
) {
9045 if (v_event) {
9046 switch_event_destroy(&v_event);
9047 }
9048 if (x_user) {
9049 switch_xml_free(x_user);
9050 }
9051
9052 if (sip->sip_authorization || sip->sip_proxy_authorization) {
9053 goto fail;
9054 }
9055
9056 return;
9057 }
9058 }
9059 is_auth++;
9060 }
9061
9062
9063
9064 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__, 9064)
;
9065 tech_pvt->mparams.remote_port = network_port;
9066
9067 channel = tech_pvt->channel = switch_core_session_get_channel(session);
9068
9069 switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
9070 switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip);
9071 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
9072
9073 if (*acl_token) {
9074 switch_channel_set_variable(channel, "acl_token", acl_token)switch_channel_set_variable_var_check(channel, "acl_token", acl_token
, SWITCH_TRUE)
;
9075 if (strchr(acl_token, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(acl_token) && ('@') == '\0' ? (char *) __rawmemchr (
acl_token, '@') : __builtin_strchr (acl_token, '@')))
) {
9076 if (switch_ivr_set_user(session, acl_token) == SWITCH_STATUS_SUCCESS) {
9077 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9077, (const char*)(session)
, SWITCH_LOG_DEBUG, "Authenticating user %s\n", acl_token);
9078 } else {
9079 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9079, (const char*)(session)
, SWITCH_LOG_WARNING, "Error Authenticating user %s\n", acl_token);
9080 }
9081 }
9082 }
9083
9084 if (sip->sip_via || (sip->sip_contact && sip->sip_contact->m_url)) {
9085 char tmp[35] = "";
9086 const char *ipv6 = strchr(tech_pvt->mparams.remote_ip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(tech_pvt->mparams.remote_ip) && (':') == '\0' ? (
char *) __rawmemchr (tech_pvt->mparams.remote_ip, ':') : __builtin_strchr
(tech_pvt->mparams.remote_ip, ':')))
;
9087
9088 if (sip->sip_via) {
9089 transport = sofia_glue_via2transport(sip->sip_via);
9090 } else {
9091 transport = sofia_glue_url2transport(sip->sip_contact->m_url);
9092 }
9093
9094
9095 tech_pvt->record_route =
9096 switch_core_session_sprintf(session,
9097 "sip:%s%s%s:%d;transport=%s",
9098 ipv6 ? "[" : "", tech_pvt->mparams.remote_ip, ipv6 ? "]" : "",
9099 tech_pvt->mparams.remote_port, sofia_glue_transport2str(transport));
9100
9101 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)
;
9102 snprintf(tmp, sizeof(tmp), "%d", tech_pvt->mparams.remote_port);
9103 switch_channel_set_variable(channel, "sip_received_port", tmp)switch_channel_set_variable_var_check(channel, "sip_received_port"
, tmp, SWITCH_TRUE)
;
9104 }
9105
9106 if (sip->sip_via) {
9107 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)
;
9108 }
9109
9110 if (*key != '\0') {
9111 tech_pvt->key = switch_core_session_strdup(session, key)switch_core_perform_session_strdup(session, key, "sofia.c", (
const char *)__func__, 9111)
;
9112 }
9113
9114
9115 if (is_auth) {
9116 switch_channel_set_variable(channel, "sip_authorized", "true")switch_channel_set_variable_var_check(channel, "sip_authorized"
, "true", SWITCH_TRUE)
;
9117
9118 if (!zstr(sip_acl_authed_by)_zstr(sip_acl_authed_by)) {
9119 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)
;
9120 }
9121
9122 if (!zstr(sip_acl_token)_zstr(sip_acl_token)) {
9123 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)
;
9124 }
9125
9126 }
9127
9128 if (calling_myself) {
9129 switch_channel_set_variable(channel, "sip_looped_call", "true")switch_channel_set_variable_var_check(channel, "sip_looped_call"
, "true", SWITCH_TRUE)
;
9130 }
9131
9132 tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
9133 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));
9134 switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
9135
9136 if (x_user) {
9137 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");
9138
9139 if (v_event) {
9140 switch_event_header_t *hp;
9141
9142 for (hp = v_event->headers; hp; hp = hp->next) {
9143 switch_channel_set_variable(channel, hp->name, hp->value)switch_channel_set_variable_var_check(channel, hp->name, hp
->value, SWITCH_TRUE)
;
9144 }
9145
9146 ruser = switch_event_get_header(v_event, "username")switch_event_get_header_idx(v_event, "username", -1);
9147 rdomain = switch_event_get_header(v_event, "domain_name")switch_event_get_header_idx(v_event, "domain_name", -1);
9148
9149 switch_channel_set_variable(channel, "requested_user_name", ruser)switch_channel_set_variable_var_check(channel, "requested_user_name"
, ruser, SWITCH_TRUE)
;
9150 switch_channel_set_variable(channel, "requested_domain_name", rdomain)switch_channel_set_variable_var_check(channel, "requested_domain_name"
, rdomain, SWITCH_TRUE)
;
9151 }
9152
9153 if (!user) user = ruser;
9154 if (!domain) domain = rdomain;
9155
9156 switch_ivr_set_user_xml(session, NULL((void*)0), user, domain, x_user);
9157 switch_xml_free(x_user);
9158 x_user = NULL((void*)0);
9159 }
9160
9161 if (v_event) {
9162 switch_event_destroy(&v_event);
9163 }
9164
9165 if (sip->sip_from && sip->sip_from->a_url) {
9166 from_user = sip->sip_from->a_url->url_user;
9167 from_host = sip->sip_from->a_url->url_host;
9168 //channel_name = url_set_chanvars(session, sip->sip_from->a_url, sip_from);
9169
9170 if (sip->sip_from->a_url->url_params) {
9171 aniii = switch_find_parameter(sip->sip_from->a_url->url_params, "isup-oli", switch_core_session_get_pool(session));
9172 }
9173
9174 if (!zstr(from_user)_zstr(from_user)) {
9175 if (*from_user == '+') {
9176 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)
;
9177 } else {
9178 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)
;
9179 }
9180 }
9181
9182 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)
;
9183
9184 if (sip->sip_from->a_params) {
9185 set_variable_sip_param(channel, "from", sip->sip_from->a_params);
9186 }
9187
9188 switch_channel_set_variable(channel, "sofia_profile_name", profile->name)switch_channel_set_variable_var_check(channel, "sofia_profile_name"
, profile->name, SWITCH_TRUE)
;
9189 switch_channel_set_variable(channel, "recovery_profile_name", profile->name)switch_channel_set_variable_var_check(channel, "recovery_profile_name"
, profile->name, SWITCH_TRUE)
;
9190 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)
;
9191
9192 if (!zstr(sip->sip_from->a_display)_zstr(sip->sip_from->a_display)) {
9193 displayname = sip->sip_from->a_display;
9194 } else {
9195 displayname = zstr(from_user)_zstr(from_user) ? "unknown" : from_user;
9196 }
9197 }
9198
9199 if ((rpid = sip_remote_party_id(sip)((sip_remote_party_id_t *)msg_header_access((msg_pub_t*)(sip)
, sip_remote_party_id_class))
)) {
9200 if (rpid->rpid_url && rpid->rpid_url->url_user) {
9201 char *full_rpid_header = sip_header_as_string(nh->nh_home, (void *) rpid);
9202 from_user = rpid->rpid_url->url_user;
9203 if (!zstr(full_rpid_header)_zstr(full_rpid_header)) {
9204 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)
;
9205 }
9206
9207 }
9208 if (!zstr(rpid->rpid_display)_zstr(rpid->rpid_display)) {
9209 displayname = rpid->rpid_display;
9210 }
9211 switch_channel_set_variable(channel, "sip_cid_type", "rpid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "rpid", SWITCH_TRUE)
;
9212 tech_pvt->cid_type = CID_TYPE_RPID;
9213 }
9214
9215 if ((passerted = sip_p_asserted_identity(sip)((sip_p_asserted_identity_t *)msg_header_access((msg_pub_t*)(
sip), sip_p_asserted_identity_class))
)) {
9216 if (passerted->paid_url && passerted->paid_url->url_user) {
9217 char *full_paid_header = sip_header_as_string(nh->nh_home, (void *) passerted);
9218 //char *full_paid_header = (char *)(passerted->paid_common->h_data);
9219 from_user = passerted->paid_url->url_user;
9220 if (!zstr(full_paid_header)_zstr(full_paid_header)) {
9221 if (profile->paid_type == PAID_DEFAULT || profile->paid_type == PAID_USER) {
9222 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)
;
9223 } else if (profile->paid_type == PAID_USER_DOMAIN) {
9224 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
)
9225 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
)
;
9226 } else if (profile->paid_type == PAID_VERBATIM) {
9227 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)
;
9228 }
9229 }
9230 }
9231 if (!zstr(passerted->paid_display)_zstr(passerted->paid_display)) {
9232 displayname = passerted->paid_display;
9233 }
9234 switch_channel_set_variable(channel, "sip_cid_type", "pid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "pid", SWITCH_TRUE)
;
9235 tech_pvt->cid_type = CID_TYPE_PID;
9236 }
9237
9238 if ((ppreferred = sip_p_preferred_identity(sip)((sip_p_preferred_identity_t *)msg_header_access((msg_pub_t*)
(sip), sip_p_preferred_identity_class))
)) {
9239 if (ppreferred->ppid_url && ppreferred->ppid_url->url_user) {
9240 char *full_ppid_header = sip_header_as_string(nh->nh_home, (void *) ppreferred);
9241 from_user = ppreferred->ppid_url->url_user;
9242 if (!zstr(full_ppid_header)_zstr(full_ppid_header)) {
9243 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)
;
9244 }
9245
9246 }
9247 if (!zstr(ppreferred->ppid_display)_zstr(ppreferred->ppid_display)) {
9248 displayname = ppreferred->ppid_display;
9249 }
9250 switch_channel_set_variable(channel, "sip_cid_type", "pid")switch_channel_set_variable_var_check(channel, "sip_cid_type"
, "pid", SWITCH_TRUE)
;
9251 tech_pvt->cid_type = CID_TYPE_PID;
9252 }
9253
9254 if (from_user) {
9255 check_decode(from_user, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 9255, __PRETTY_FUNCTION__)); if (!_zstr(from_user)) { int d
= 0; char *p; if ((__extension__ (__builtin_constant_p ('%')
&& !__builtin_constant_p (from_user) && ('%'
) == '\0' ? (char *) __rawmemchr (from_user, '%') : __builtin_strchr
(from_user, '%')))) { char *tmp = switch_core_perform_session_strdup
(session, from_user, "sofia.c", (const char *)__func__, 9255)
; switch_url_decode(tmp); from_user = tmp; d++; } if ((p = (__extension__
(__builtin_constant_p ('"') && !__builtin_constant_p
(from_user) && ('"') == '\0' ? (char *) __rawmemchr (
from_user, '"') : __builtin_strchr (from_user, '"'))))) { if (
!d) { char *tmp = switch_core_perform_session_strdup(session,
from_user, "sofia.c", (const char *)__func__, 9255); from_user
= tmp; } if ((p = (__extension__ (__builtin_constant_p ('"')
&& !__builtin_constant_p (from_user) && ('"'
) == '\0' ? (char *) __rawmemchr (from_user, '"') : __builtin_strchr
(from_user, '"'))))) { from_user = p+1; } if ((p = strrchr(from_user
, '"'))) { *p = '\0'; } } } if (session) break; } while(!session
)
;
9256
9257 if ((name_params = strchr(from_user, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(from_user) && (';') == '\0' ? (char *) __rawmemchr (
from_user, ';') : __builtin_strchr (from_user, ';')))
)) {
9258 *name_params++ = '\0';
9259 switch_channel_set_variable(channel, "sip_name_params", name_params)switch_channel_set_variable_var_check(channel, "sip_name_params"
, name_params, SWITCH_TRUE)
;
9260 }
9261 }
9262
9263 extract_header_vars(profile, sip, session, nh);
9264
9265 if (sip->sip_request->rq_url) {
9266 const char *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")
;
9267 char *user = NULL((void*)0);
9268 if (sip->sip_request->rq_url->url_user) {
9269
9270 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__, 9270
)
;
9271 if (profile->parse_invite_tel_params) {
9272 if (strchr(user, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(user) && (';') == '\0' ? (char *) __rawmemchr (user
, ';') : __builtin_strchr (user, ';')))
) {
9273 int argc1, x1 = 0;
9274 char *argv1[32] = { 0 };
9275
9276 if ((argc1 = switch_separate_string(user, ';', argv1, (sizeof(argv1) / sizeof(argv1[0]))))) {
9277 for (x1 = 0; x1 < argc1; x1++) {
9278 if (x1 == 0) {
9279 switch_channel_set_variable(channel, "sip_req_user", argv1[0])switch_channel_set_variable_var_check(channel, "sip_req_user"
, argv1[0], SWITCH_TRUE)
;
9280 } else {
9281 int argc2 = 0;
9282 char *argv2[2] = { 0 };
9283 if ((argc2 = switch_separate_string(argv1[x1], '=', argv2, (sizeof(argv2) / sizeof(argv2[0])))) == 2) {
9284 char *var_name = NULL((void*)0);
9285 var_name = switch_mprintf("sip_invite_%s", argv2[0]);
9286 switch_channel_set_variable(channel, var_name, argv2[1])switch_channel_set_variable_var_check(channel, var_name, argv2
[1], SWITCH_TRUE)
;
9287 switch_safe_free( var_name )if (var_name) {free(var_name);var_name=((void*)0);};
9288 } else {
9289 char *var_name = NULL((void*)0);
9290 var_name = switch_mprintf("sip_invite_%s", argv1[x1]);
9291 switch_channel_set_variable(channel, var_name, "true")switch_channel_set_variable_var_check(channel, var_name, "true"
, SWITCH_TRUE)
;
9292 switch_safe_free( var_name )if (var_name) {free(var_name);var_name=((void*)0);};
9293 }
9294 }
9295 }
9296 }
9297 }
9298 }
9299 }
9300
9301 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
9302 destination_number = req_uri;
9303 } else {
9304 destination_number = user;
9305 }
9306 if (sip->sip_request->rq_url->url_params && (sofia_glue_find_parameter(sip->sip_request->rq_url->url_params, "intercom=true"))) {
9307 switch_channel_set_variable(channel, "sip_auto_answer_detected", "true")switch_channel_set_variable_var_check(channel, "sip_auto_answer_detected"
, "true", SWITCH_TRUE)
;
9308 }
9309 }
9310
9311 if (!destination_number && sip->sip_to && sip->sip_to->a_url) {
9312 destination_number = sip->sip_to->a_url->url_user;
9313 }
9314
9315 /* The human network, OH THE HUMANITY!!! lets send invites with no number! */
9316 if (!destination_number && sip->sip_from && sip->sip_from->a_url) {
9317 destination_number = sip->sip_from->a_url->url_user;
9318 }
9319
9320 if (destination_number) {
9321 check_decode(destination_number, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 9321, __PRETTY_FUNCTION__)); if (!_zstr(destination_number)
) { int d = 0; char *p; if ((__extension__ (__builtin_constant_p
('%') && !__builtin_constant_p (destination_number) &&
('%') == '\0' ? (char *) __rawmemchr (destination_number, '%'
) : __builtin_strchr (destination_number, '%')))) { char *tmp
= switch_core_perform_session_strdup(session, destination_number
, "sofia.c", (const char *)__func__, 9321); switch_url_decode
(tmp); destination_number = tmp; d++; } if ((p = (__extension__
(__builtin_constant_p ('"') && !__builtin_constant_p
(destination_number) && ('"') == '\0' ? (char *) __rawmemchr
(destination_number, '"') : __builtin_strchr (destination_number
, '"'))))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, destination_number, "sofia.c", (const char *)__func__
, 9321); destination_number = tmp; } if ((p = (__extension__ (
__builtin_constant_p ('"') && !__builtin_constant_p (
destination_number) && ('"') == '\0' ? (char *) __rawmemchr
(destination_number, '"') : __builtin_strchr (destination_number
, '"'))))) { destination_number = p+1; } if ((p = strrchr(destination_number
, '"'))) { *p = '\0'; } } } if (session) break; } while(!session
)
;
9322 } else {
9323 destination_number = "service";
9324 }
9325
9326 if (sip->sip_to && sip->sip_to->a_url) {
9327 const char *host, *user;
9328 int port, check_nat = 0;
9329 url_t *transport_url;
9330
9331 if (sip->sip_record_route && sip->sip_record_route->r_url) {
9332 transport_url = sip->sip_record_route->r_url;
9333 } else {
9334 transport_url = sip->sip_contact->m_url;
9335 }
9336
9337 transport = sofia_glue_url2transport(transport_url);
9338 tech_pvt->transport = transport;
9339
9340 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")
;
9341 if (switch_channel_get_variable(channel, "sip_to_uri")switch_channel_get_variable_dup(channel, "sip_to_uri", SWITCH_TRUE
, -1)
) {
9342 const char *ipv6;
9343 const char *tmp, *at, *url = NULL((void*)0);
9344
9345 host = switch_channel_get_variable(channel, "sip_to_host")switch_channel_get_variable_dup(channel, "sip_to_host", SWITCH_TRUE
, -1)
;
9346 user = switch_channel_get_variable(channel, "sip_to_user")switch_channel_get_variable_dup(channel, "sip_to_user", SWITCH_TRUE
, -1)
;
9347
9348 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)
;
9349
9350 if (sip->sip_to->a_params) {
9351 set_variable_sip_param(channel, "to", sip->sip_to->a_params);
9352 }
9353
9354 if (sip->sip_contact->m_url->url_port) {
9355 port = atoi(sip->sip_contact->m_url->url_port);
9356 } else {
9357 port = sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->extsipport;
9358 }
9359
9360 ipv6 = strchr(host, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(host) && (':') == '\0' ? (char *) __rawmemchr (host
, ':') : __builtin_strchr (host, ':')))
;
9361 tech_pvt->to_uri =
9362 switch_core_session_sprintf(session,
9363 "sip:%s@%s%s%s:%d;transport=%s",
9364 user, ipv6 ? "[" : "", host, ipv6 ? "]" : "", port, sofia_glue_transport2str(transport));
9365
9366 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
9367 url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url;
9368 check_nat = 1;
9369 } else {
9370 url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url;
9371 }
9372
9373 if (!url) {
9374 if (check_nat) {
9375 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9375, (const char*)(session)
, SWITCH_LOG_WARNING, "Nat detected but no external address configured.\n");
9376 }
9377 url = profile->url;
9378 }
9379
9380 if (!url) {
9381 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 9381, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
9382 }
9383
9384 tmp = sofia_overcome_sip_uri_weakness(session, url, transport, SWITCH_TRUE, NULL((void*)0), NULL((void*)0));
9385
9386 if ((at = strchr(tmp, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(tmp) && ('@') == '\0' ? (char *) __rawmemchr (tmp, '@'
) : __builtin_strchr (tmp, '@')))
)) {
9387 url = switch_core_session_sprintf(session, "sip:%s%s", user, at);
9388 }
9389
9390 if (url) {
9391 const char *brackets = NULL((void*)0);
9392 const char *proto = NULL((void*)0);
9393
9394 brackets = strchr(url, '>')(__extension__ (__builtin_constant_p ('>') && !__builtin_constant_p
(url) && ('>') == '\0' ? (char *) __rawmemchr (url
, '>') : __builtin_strchr (url, '>')))
;
9395 proto = switch_stristr("transport=", url);
9396 tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s%s%s%s%s",
9397 brackets ? "" : "<", url,
9398 proto ? "" : ";transport=",
9399 proto ? "" : sofia_glue_transport2str(transport), brackets ? "" : ">");
9400 } else {
9401 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 9401, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
9402 }
9403
9404 } else {
9405 const char *url = NULL((void*)0);
9406 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
9407 url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url;
9408 } else {
9409 url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url;
9410 }
9411
9412 if (url) {
9413 const char *brackets = NULL((void*)0);
9414 const char *proto = NULL((void*)0);
9415
9416 brackets = strchr(url, '>')(__extension__ (__builtin_constant_p ('>') && !__builtin_constant_p
(url) && ('>') == '\0' ? (char *) __rawmemchr (url
, '>') : __builtin_strchr (url, '>')))
;
9417 proto = switch_stristr("transport=", url);
9418 tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s%s%s%s%s",
9419 brackets ? "" : "<", url,
9420 proto ? "" : ";transport=",
9421 proto ? "" : sofia_glue_transport2str(transport), brackets ? "" : ">");
9422 } else {
9423 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(tech_pvt->channel, "sofia.c"
, (const char *)__func__, 9423, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
9424 }
9425 }
9426 }
9427
9428 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
9429 tech_pvt->user_via = sofia_glue_create_external_via(session, profile, tech_pvt->transport);
9430 nua_set_hparams(tech_pvt->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);
9431 }
9432
9433 if (sip->sip_contact && sip->sip_contact->m_url) {
9434 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")
;
9435 }
9436
9437 if (sip->sip_referred_by) {
9438 referred_by_user = sip->sip_referred_by->b_url->url_user;
9439 //referred_by_host = sip->sip_referred_by->b_url->url_host;
9440 //channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by);
9441
9442 check_decode(referred_by_user, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 9442, __PRETTY_FUNCTION__)); if (!_zstr(referred_by_user)) {
int d = 0; char *p; if ((__extension__ (__builtin_constant_p
('%') && !__builtin_constant_p (referred_by_user) &&
('%') == '\0' ? (char *) __rawmemchr (referred_by_user, '%')
: __builtin_strchr (referred_by_user, '%')))) { char *tmp = switch_core_perform_session_strdup
(session, referred_by_user, "sofia.c", (const char *)__func__
, 9442); switch_url_decode(tmp); referred_by_user = tmp; d++;
} if ((p = (__extension__ (__builtin_constant_p ('"') &&
!__builtin_constant_p (referred_by_user) && ('"') ==
'\0' ? (char *) __rawmemchr (referred_by_user, '"') : __builtin_strchr
(referred_by_user, '"'))))) { if (!d) { char *tmp = switch_core_perform_session_strdup
(session, referred_by_user, "sofia.c", (const char *)__func__
, 9442); referred_by_user = tmp; } if ((p = (__extension__ (__builtin_constant_p
('"') && !__builtin_constant_p (referred_by_user) &&
('"') == '\0' ? (char *) __rawmemchr (referred_by_user, '"')
: __builtin_strchr (referred_by_user, '"'))))) { referred_by_user
= p+1; } if ((p = strrchr(referred_by_user, '"'))) { *p = '\0'
; } } } if (session) break; } while(!session)
;
9443
9444 if (!zstr(referred_by_user)_zstr(referred_by_user)) {
9445 if (*referred_by_user == '+') {
9446 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)
;
9447 } else {
9448 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)
;
9449 }
9450 }
9451
9452 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)
;
9453
9454 if (sip->sip_referred_by->b_params) {
9455 set_variable_sip_param(channel, "referred_by", sip->sip_referred_by->b_params);
9456 }
9457 }
9458
9459 //sofia_glue_set_name(tech_pvt, channel_name);
9460 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
9461
9462 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "INBOUND CALL")switch_channel_set_variable_var_check(channel, "endpoint_disposition"
, "INBOUND CALL", SWITCH_TRUE)
;
9463
9464 if (sofia_test_flag(tech_pvt, TFLAG_INB_NOMEDIA)((tech_pvt)->flags[TFLAG_INB_NOMEDIA] ? 1 : 0)) {
9465 switch_channel_set_flag(channel, CF_PROXY_MODE)switch_channel_set_flag_value(channel, CF_PROXY_MODE, 1);
9466 }
9467
9468 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_HOLD) {
9469 switch_channel_set_flag(channel, CF_BYPASS_MEDIA_AFTER_HOLD)switch_channel_set_flag_value(channel, CF_BYPASS_MEDIA_AFTER_HOLD
, 1)
;
9470 }
9471
9472 if (sofia_test_flag(tech_pvt, TFLAG_PROXY_MEDIA)((tech_pvt)->flags[TFLAG_PROXY_MEDIA] ? 1 : 0)) {
9473 switch_channel_set_flag(channel, CF_PROXY_MEDIA)switch_channel_set_flag_value(channel, CF_PROXY_MEDIA, 1);
9474 }
9475
9476 if (sofia_test_flag(tech_pvt, TFLAG_ZRTP_PASSTHRU)((tech_pvt)->flags[TFLAG_ZRTP_PASSTHRU] ? 1 : 0)) {
9477 switch_channel_set_flag(channel, CF_ZRTP_PASSTHRU_REQ)switch_channel_set_flag_value(channel, CF_ZRTP_PASSTHRU_REQ, 1
)
;
9478 }
9479
9480 if (sip->sip_subject && sip->sip_subject->g_string) {
9481 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)
;
9482 }
9483
9484 if (sip->sip_user_agent && !zstr(sip->sip_user_agent->g_string)_zstr(sip->sip_user_agent->g_string)) {
9485 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)
;
9486 }
9487
9488 if (sip->sip_via) {
9489 if (sip->sip_via->v_host) {
9490 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)
;
9491 }
9492 if (sip->sip_via->v_port) {
9493 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)
;
9494 }
9495 if (sip->sip_via->v_rport) {
9496 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)
;
9497 }
9498 }
9499
9500
9501 if (sip->sip_multipart) {
9502 msg_multipart_t *mp;
9503
9504 for (mp = sip->sip_multipart; mp; mp = mp->mp_next) {
9505 if (mp->mp_payload && mp->mp_payload->pl_data && mp->mp_content_type && mp->mp_content_type->c_type) {
9506 char *val = switch_core_session_sprintf(session, "%s:%s", mp->mp_content_type->c_type, mp->mp_payload->pl_data);
9507 switch_channel_add_variable_var_check(channel, "sip_multipart", val, SWITCH_FALSE, SWITCH_STACK_PUSH);
9508 }
9509 }
9510 }
9511
9512 if (sip->sip_max_forwards) {
9513 char max_forwards[32];
9514 switch_snprintf(max_forwards, sizeof(max_forwards), "%lu", sip->sip_max_forwards->mf_count);
9515 switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards)switch_channel_set_variable_var_check(channel, "max_forwards"
, max_forwards, SWITCH_TRUE)
;
9516 }
9517
9518 if (acl_context) context = acl_context;
9519
9520 if (!context) {
9521 context = switch_channel_get_variable(channel, "user_context")switch_channel_get_variable_dup(channel, "user_context", SWITCH_TRUE
, -1)
;
9522 }
9523
9524 if (!context) {
9525 if (profile->context && !strcasecmp(profile->context, "_domain_")) {
9526 context = from_host;
9527 } else {
9528 context = profile->context;
9529 }
9530 }
9531
9532 if (!(dialplan = switch_channel_get_variable(channel, "inbound_dialplan")switch_channel_get_variable_dup(channel, "inbound_dialplan", SWITCH_TRUE
, -1)
)) {
9533 dialplan = profile->dialplan;
9534 }
9535
9536 if ((alert_info = sip_alert_info(sip)((sip_alert_info_t *)msg_header_access((msg_pub_t*)(sip), sip_alert_info_class
))
)) {
9537 char *tmp = sip_header_as_string(nh->nh_home, (void *) alert_info);
9538 switch_channel_set_variable(channel, "alert_info", tmp)switch_channel_set_variable_var_check(channel, "alert_info", tmp
, SWITCH_TRUE)
;
9539 su_free(nh->nh_home, tmp);
9540 }
9541
9542 if ((call_info = sip_call_info(sip)((sip_call_info_t *)msg_header_access((msg_pub_t*)(sip), sip_call_info_class
))
)) {
9543 call_info_str = sip_header_as_string(nh->nh_home, (void *) call_info);
9544
9545 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
&& switch_stristr("appearance", call_info_str)) {
9546 char *p;
9547
9548 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)
;
9549 if ((p = strchr(call_info_str, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(call_info_str) && (';') == '\0' ? (char *) __rawmemchr
(call_info_str, ';') : __builtin_strchr (call_info_str, ';')
))
)) {
9550 p++;
9551 switch_channel_set_variable(channel, "presence_call_info", p)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p, SWITCH_TRUE)
;
9552 }
9553 }
9554
9555 if (call_info->ci_params && (msg_params_find(call_info->ci_params, "answer-after=0"))) {
9556 switch_channel_set_variable(channel, "sip_auto_answer_detected", "true")switch_channel_set_variable_var_check(channel, "sip_auto_answer_detected"
, "true", SWITCH_TRUE)
;
9557 }
9558
9559 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)
;
9560
9561 call_info = call_info->ci_next;
9562
9563 while (call_info) {
9564 call_info_str = sip_header_as_string(nh->nh_home, (void *) call_info);
9565 switch_channel_add_variable_var_check(channel, "sip_call_info", call_info_str, SWITCH_FALSE, SWITCH_STACK_PUSH);
9566 call_info = call_info->ci_next;
9567 }
9568
9569 call_info = sip_call_info(sip)((sip_call_info_t *)msg_header_access((msg_pub_t*)(sip), sip_call_info_class
))
;
9570
9571 } else if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)((profile)->pflags[PFLAG_MANAGE_SHARED_APPEARANCE] ? 1 : 0
)
) {
9572 char buf[128] = "";
9573 char *sql;
9574 char *state = "progressing";
9575
9576 if (sip &&
9577 sip->sip_from && sip->sip_from->a_url && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
9578 sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
9579 sql =
9580 switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
9581 "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
9582 sip->sip_from->a_url->url_host);
9583 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
9584
9585 if (mod_sofia_globals.debug_sla > 1) {
9586 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 9586
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
9587 }
9588 free(sql);
9589
9590 if (!zstr(buf)_zstr(buf)) {
9591 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
9592 "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
9593
9594 if (mod_sofia_globals.debug_sla > 1) {
9595 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 9595
, ((void*)0)
, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
9596 }
9597
9598 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
9599
9600
9601 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9601, (const char*)(session)
, SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
9602 sip->sip_from->a_url->url_host, buf);
9603
9604 switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
9605 switch_channel_set_variable(channel, "presence_call_info", buf)switch_channel_set_variable_var_check(channel, "presence_call_info"
, buf, SWITCH_TRUE)
;
9606 call_info_str = switch_core_session_sprintf(session, "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
9607 }
9608 }
9609 }
9610
9611
9612 if (profile->pres_type) {
9613 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
9614 if (zstr(presence_id)_zstr(presence_id)) {
9615 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 : "")
;
9616 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 : "")
;
9617 char *tmp = switch_mprintf("%s@%s", user, host);
9618 switch_assert(tmp)((tmp) ? (void) (0) : __assert_fail ("tmp", "sofia.c", 9618, __PRETTY_FUNCTION__
))
;
9619 switch_channel_set_variable(channel, "presence_id", tmp)switch_channel_set_variable_var_check(channel, "presence_id",
tmp, SWITCH_TRUE)
;
9620 free(tmp);
9621 }
9622 }
9623
9624
9625 if (sip->sip_request->rq_url->url_params) {
9626 gw_param_name = switch_find_parameter(sip->sip_request->rq_url->url_params, "gw", switch_core_session_get_pool(session));
9627 }
9628
9629 if (strstr(destination_number, "gw+")) {
9630 if (sofia_test_pflag(profile, PFLAG_FULL_ID)((profile)->pflags[PFLAG_FULL_ID] ? 1 : 0)) {
9631 char *tmp;
9632 gw_name = switch_core_session_strdup(session, destination_number + 3)switch_core_perform_session_strdup(session, destination_number
+ 3, "sofia.c", (const char *)__func__, 9632)
;
9633 if ((tmp = strchr(gw_name, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(gw_name) && ('@') == '\0' ? (char *) __rawmemchr (gw_name
, '@') : __builtin_strchr (gw_name, '@')))
)) {
9634 *tmp = '\0';
9635 }
9636 } else {
9637 gw_name = destination_number + 3;
9638 }
9639 }
9640
9641 if (gw_name || gw_param_name) {
9642 sofia_gateway_t *gateway = NULL((void*)0);
9643 char *extension = NULL((void*)0);
9644
9645 if (gw_name && ((gateway = sofia_reg_find_gateway(gw_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 9645
, gw_name)
))) {
9646 gw_param_name = NULL((void*)0);
9647 extension = gateway->extension;
9648 }
9649
9650 if (!gateway && gw_param_name) {
9651 if ((gateway = sofia_reg_find_gateway(gw_param_name)sofia_reg_find_gateway__("sofia.c", (const char *)__func__, 9651
, gw_param_name)
)) {
9652 extension = gateway->real_extension;
9653 }
9654 }
9655
9656 if (gateway) {
9657 context = switch_core_session_strdup(session, gateway->register_context)switch_core_perform_session_strdup(session, gateway->register_context
, "sofia.c", (const char *)__func__, 9657)
;
9658 switch_channel_set_variable(channel, "sip_gateway", gateway->name)switch_channel_set_variable_var_check(channel, "sip_gateway",
gateway->name, SWITCH_TRUE)
;
9659
9660 if (!zstr(extension)_zstr(extension)) {
9661 if (!strcasecmp(extension, "auto_to_user")) {
9662 destination_number = sip->sip_to->a_url->url_user;
9663 } else if (!strcasecmp(extension, "auto")) {
9664 if (gw_name) {
9665 destination_number = sip->sip_to->a_url->url_user;
9666 }
9667 } else {
9668 destination_number = switch_core_session_strdup(session, extension)switch_core_perform_session_strdup(session, extension, "sofia.c"
, (const char *)__func__, 9668)
;
9669 }
9670 } else if (!gw_param_name) {
9671 destination_number = sip->sip_to->a_url->url_user;
9672 }
9673
9674 gateway->ib_calls++;
9675
9676 if (gateway->ib_vars) {
9677 switch_event_header_t *hp;
9678 for (hp = gateway->ib_vars->headers; hp; hp = hp->next) {
9679 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9679, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n",
9680 switch_channel_get_name(channel), hp->name, hp->value);
9681 switch_channel_set_variable(channel, hp->name, hp->value)switch_channel_set_variable_var_check(channel, hp->name, hp
->value, SWITCH_TRUE)
;
9682 }
9683 }
9684
9685 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia.c", (const char *)__func__
, 9685, gateway);
;
9686 }
9687 }
9688
9689 if (call_info_str) {
9690 char *sql;
9691 char cid[512] = "";
9692 char *str;
9693 char *p = NULL((void*)0);
9694 const char *user = NULL((void*)0), *host = NULL((void*)0), *from_user = NULL((void*)0), *from_host = NULL((void*)0);
9695
9696 if (sip->sip_to && sip->sip_to->a_url) {
9697 user = sip->sip_to->a_url->url_user;
9698 host = sip->sip_to->a_url->url_host;
9699 }
9700
9701 if (sip->sip_from && sip->sip_from->a_url) {
9702 from_user = sip->sip_from->a_url->url_user;
9703 from_host = sip->sip_from->a_url->url_host;
9704 }
9705
9706 if (!user) user = from_user;
9707 if (!host) user = from_host;
9708
9709 if (user && host && from_user && !strcmp(user, from_user)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(user) && __builtin_constant_p (from_user) &&
(__s1_len = __builtin_strlen (user), __s2_len = __builtin_strlen
(from_user), (!((size_t)(const void *)((user) + 1) - (size_t
)(const void *)(user) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((from_user) + 1) - (size_t)(const void
*)(from_user) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(user, from_user) : (__builtin_constant_p (user) && (
(size_t)(const void *)((user) + 1) - (size_t)(const void *)(user
) == 1) && (__s1_len = __builtin_strlen (user), __s1_len
< 4) ? (__builtin_constant_p (from_user) && ((size_t
)(const void *)((from_user) + 1) - (size_t)(const void *)(from_user
) == 1) ? __builtin_strcmp (user, from_user) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (from_user); int __result = (((const unsigned char *
) (const char *) (user))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (user))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (user))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (user))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(from_user) && ((size_t)(const void *)((from_user) +
1) - (size_t)(const void *)(from_user) == 1) && (__s2_len
= __builtin_strlen (from_user), __s2_len < 4) ? (__builtin_constant_p
(user) && ((size_t)(const void *)((user) + 1) - (size_t
)(const void *)(user) == 1) ? __builtin_strcmp (user, from_user
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (user); int __result = (((const unsigned
char *) (const char *) (from_user))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (from_user))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (from_user))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (from_user))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (user, from_user)))); })
) {
9710 if ((p = strchr(call_info_str, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(call_info_str) && (';') == '\0' ? (char *) __rawmemchr
(call_info_str, ';') : __builtin_strchr (call_info_str, ';')
))
)) {
9711 p++;
9712 }
9713
9714 sql =
9715 switch_mprintf
9716 ("select call_id from sip_dialogs where call_info='%q' and ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
9717 "and call_id is not null",
9718 switch_str_nil(p)(p ? p : ""), user, host, user, host);
9719
9720 if ((str = sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, cid, sizeof(cid)))) {
9721 bnh = nua_handle_by_call_id(nua, str);
9722 }
9723
9724 if (mod_sofia_globals.debug_sla > 1) {
9725 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia.c", (const char *)__func__, 9725
, ((void*)0)
, SWITCH_LOG_ERROR, "PICK SQL %s [%s] [%s] %d\n", sql, str, cid, !!bnh);
9726 }
9727
9728 free(sql);
9729 }
9730 }
9731
9732
9733 check_decode(displayname, session)do { ((session) ? (void) (0) : __assert_fail ("session", "sofia.c"
, 9733, __PRETTY_FUNCTION__)); if (!_zstr(displayname)) { int
d = 0; char *p; if ((__extension__ (__builtin_constant_p ('%'
) && !__builtin_constant_p (displayname) && (
'%') == '\0' ? (char *) __rawmemchr (displayname, '%') : __builtin_strchr
(displayname, '%')))) { char *tmp = switch_core_perform_session_strdup
(session, displayname, "sofia.c", (const char *)__func__, 9733
); switch_url_decode(tmp); displayname = tmp; d++; } if ((p =
(__extension__ (__builtin_constant_p ('"') && !__builtin_constant_p
(displayname) && ('"') == '\0' ? (char *) __rawmemchr
(displayname, '"') : __builtin_strchr (displayname, '"')))))
{ if (!d) { char *tmp = switch_core_perform_session_strdup(session
, displayname, "sofia.c", (const char *)__func__, 9733); displayname
= tmp; } if ((p = (__extension__ (__builtin_constant_p ('"')
&& !__builtin_constant_p (displayname) && ('"'
) == '\0' ? (char *) __rawmemchr (displayname, '"') : __builtin_strchr
(displayname, '"'))))) { displayname = p+1; } if ((p = strrchr
(displayname, '"'))) { *p = '\0'; } } } if (session) break; }
while(!session)
;
9734
9735 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__, 9735)));} else { tech_pvt->caller_profile
->username = ""; }
;
9736 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__, 9736)));} else { tech_pvt->caller_profile
->dialplan = ""; }
;
9737 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__, 9737)));} else { tech_pvt->caller_profile
->caller_id_name = ""; }
;
9738 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__, 9738)));} else { tech_pvt->caller_profile
->caller_id_number = ""; }
;
9739 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__, 9739)));} else { tech_pvt->caller_profile
->orig_caller_id_name = ""; }
;
9740 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__, 9740)));} else { tech_pvt->caller_profile
->orig_caller_id_number = ""; }
;
9741 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__, 9741)));} else { tech_pvt->caller_profile
->network_addr = ""; }
;
9742 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__, 9742)));} else { tech_pvt->caller_profile
->ani = ""; }
;
9743 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__
, 9743)));} else { tech_pvt->caller_profile->aniii = ""
; }
;
9744 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__, 9744)));} else { tech_pvt->caller_profile
->context = ""; }
;
9745 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__, 9745
)));} else { tech_pvt->caller_profile->destination_number
= ""; }
;
9746
9747 if (!bnh && sip->sip_replaces) {
9748 if (!(bnh = nua_handle_by_replaces(nua, sip->sip_replaces))) {
9749 if (!(bnh = nua_handle_by_call_id(nua, sip->sip_replaces->rp_call_id))) {
9750 bnh = sofia_global_nua_handle_by_replaces(sip->sip_replaces);
9751 }
9752 }
9753 }
9754
9755 if (bnh) {
9756 sofia_private_t *b_private = NULL((void*)0);
9757 if ((b_private = nua_handle_magic(bnh))) {
9758 switch_core_session_t *b_session = NULL((void*)0);
9759
9760 if ((b_session = switch_core_session_locate(b_private->uuid)switch_core_session_perform_locate(b_private->uuid, "sofia.c"
, (const char *)__func__, 9760)
)) {
9761 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
9762 const char *bridge_uuid;
9763 switch_caller_profile_t *orig_cp, *cp;
9764 //const char *sent_name, *sent_number;
9765 orig_cp = switch_channel_get_caller_profile(b_channel);
9766 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__
, 9766)
;
9767 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__
, 9767)
;
9768
9769 if (!call_info) {
9770 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__
, 9770)
;
9771 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__
, 9771)
;
9772 }
9773
9774 if (orig_cp) {
9775 cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool, orig_cp);
9776 switch_channel_set_originator_caller_profile(channel, cp);
9777 }
9778
9779#if 0
9780 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)
;
9781 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)
;
9782
9783 if (!zstr(sent_name)_zstr(sent_name) && !zstr(sent_number)_zstr(sent_number)) {
9784 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__, 9784)
;
9785 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__, 9785)
;
9786 } else {
9787 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
9788 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__
, 9788)
;
9789 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__
, 9789)
;
9790 } else {
9791 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__
, 9791)
;
9792 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__
, 9792)
;
9793 }
9794 }
9795#endif
9796
9797 if (is_nat) {
9798 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9798, (const char*)(session)
, SWITCH_LOG_CRIT, "Setting NAT mode based on %s\n", is_nat);
9799 }
9800
9801 tech_pvt->caller_profile->dialplan = "inline";
9802
9803 bridge_uuid = switch_channel_get_partner_uuid(b_channel);
9804
9805 if (call_info) {
9806 const char *olu;
9807 switch_core_session_t *os;
9808 switch_codec_implementation_t read_impl = { 0 };
9809 char *codec_str = "";
9810
9811 if (!zstr(bridge_uuid)_zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) {
9812 olu = bridge_uuid;
9813 } else {
9814 olu = b_private->uuid;
9815 }
9816
9817 if ((os = switch_core_session_locate(olu)switch_core_session_perform_locate(olu, "sofia.c", (const char
*)__func__, 9817)
)) {
9818 switch_core_session_get_real_read_impl(os, &read_impl);
9819 switch_core_session_rwunlock(os);
9820
9821 codec_str = switch_core_session_sprintf(session, "set:absolute_codec_string=%s@%di,", read_impl.iananame,
9822 read_impl.microseconds_per_packet / 1000);
9823 }
9824
9825 if (!zstr(bridge_uuid)_zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) {
9826 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)
;
9827
9828 if (b_call_id) {
9829 char *sql = switch_mprintf("update sip_dialogs set call_info_state='idle' where call_id='%q'", b_call_id);
9830 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
9830, (const char*)(session)
, SWITCH_LOG_CRIT, "SQL: %s\n", sql);
9831 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
9832
9833 switch_channel_presence(b_channel, "unknown", "idle", NULL)switch_channel_perform_presence(b_channel, "unknown", "idle",
((void*)0), "sofia.c", (const char *)__func__, 9833)
;
9834 }
9835 switch_channel_set_flag(tech_pvt->channel, CF_SLA_INTERCEPT)switch_channel_set_flag_value(tech_pvt->channel, CF_SLA_INTERCEPT
, 1)
;
9836 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
9837 "%sanswer,intercept:%s", codec_str, bridge_uuid);
9838 } else {
9839 switch_caller_profile_t *bcp = switch_channel_get_caller_profile(b_channel);
9840
9841 if (switch_channel_test_flag(b_channel, CF_BRIDGE_ORIGINATOR)) {
9842 switch_channel_set_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR)switch_channel_set_flag_value(tech_pvt->channel, CF_BRIDGE_ORIGINATOR
, 1)
;
9843 }
9844
9845 if (!zstr(bcp->callee_id_name)_zstr(bcp->callee_id_name)) {
9846 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__, 9846
)
;
9847 }
9848
9849 if (!zstr(bcp->callee_id_number)_zstr(bcp->callee_id_number)) {
9850 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__
, 9850)
;
9851 }
9852
9853
9854 if (!zstr(bcp->caller_id_name)_zstr(bcp->caller_id_name)) {
9855 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__, 9855
)
;
9856 }
9857
9858 if (!zstr(bcp->caller_id_number)_zstr(bcp->caller_id_number)) {
9859 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__
, 9859)
;
9860 }
9861
9862 if (bcp->originatee_caller_profile) {
9863 switch_caller_profile_t *cp;
9864
9865 cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool,
9866 bcp->originatee_caller_profile);
9867
9868 switch_channel_set_originatee_caller_profile(tech_pvt->channel, cp);
9869 }
9870
9871 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
9872 "%sanswer,sofia_sla:%s", codec_str, b_private->uuid);
9873 }
9874 } else {
9875 if (!zstr(bridge_uuid)_zstr(bridge_uuid)) {
9876 switch_channel_mark_hold(b_channel, SWITCH_FALSE);
9877 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid);
9878 } else {
9879 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)
;
9880 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)
;
9881
9882 if (b_data && b_app) {
9883 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s:%s", b_app, b_data);
9884 } else if (b_app) {
9885 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s", b_app);
9886 }
9887
9888
9889 switch_channel_hangup(b_channel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(b_channel, "sofia.c", (const char
*)__func__, 9889, SWITCH_CAUSE_ATTENDED_TRANSFER)
;
9890 }
9891 }
9892
9893 switch_core_session_rwunlock(b_session);
9894 }
9895 }
9896 nua_handle_unref(bnh);
9897 }
9898
9899
9900
9901 if (tech_pvt->caller_profile) {
9902
9903 int first_history_info = 1;
9904
9905 if (rpid) {
9906 if (rpid->rpid_privacy) {
9907 if (!strcasecmp(rpid->rpid_privacy, "yes")) {
9908 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)
;
9909 } else if (!strcasecmp(rpid->rpid_privacy, "full")) {
9910 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)
;
9911 } else if (!strcasecmp(rpid->rpid_privacy, "name")) {
9912 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NAME
)
;
9913 } else if (!strcasecmp(rpid->rpid_privacy, "number")) {
9914 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags |= (SWITCH_CPF_HIDE_NUMBER
)
;
9915 } else {
9916 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_HIDE_NAME
)
;
9917 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_HIDE_NUMBER
)
;
9918 }
9919 }
9920
9921 if (rpid->rpid_screen && !strcasecmp(rpid->rpid_screen, "no")) {
9922 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN)(tech_pvt->caller_profile)->flags &= ~(SWITCH_CPF_SCREEN
)
;
9923 }
9924 }
9925
9926 if ((privacy = sip_privacy(sip)((sip_privacy_t *)msg_header_access((msg_pub_t*)(sip), sip_privacy_class
))
)) {
9927 char *full_priv_header = sip_header_as_string(nh->nh_home, (void *) privacy);
9928 if (!zstr(full_priv_header)_zstr(full_priv_header)) {
9929 switch_channel_set_variable(channel, "sip_Privacy", full_priv_header)switch_channel_set_variable_var_check(channel, "sip_Privacy",
full_priv_header, SWITCH_TRUE)
;
9930 }
9931 if (msg_params_find(privacy->priv_values, "id")) {
9932 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)
;
9933 }
9934 }
9935
9936 /* Loop thru unknown Headers Here so we can do something with them */
9937 for (un = sip->sip_unknown; un; un = un->un_next) {
9938 if (!strncasecmp(un->un_name, "Accept-Language", 15)) {
9939 if (!zstr(un->un_value)_zstr(un->un_value)) {
9940 char *tmp_name;
9941 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name))) {
9942 switch_channel_set_variable(channel, tmp_name, un->un_value)switch_channel_set_variable_var_check(channel, tmp_name, un->
un_value, SWITCH_TRUE)
;
9943 free(tmp_name);
9944 }
9945 }
9946 } else if (!strncasecmp(un->un_name, "Diversion", 9)) {
9947 /* Basic Diversion Support for Diversion Indication in SIP */
9948 /* draft-levy-sip-diversion-08 */
9949 if (!zstr(un->un_value)_zstr(un->un_value)) {
9950 char *tmp_name;
9951 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name))) {
9952 switch_channel_set_variable(channel, tmp_name, un->un_value)switch_channel_set_variable_var_check(channel, tmp_name, un->
un_value, SWITCH_TRUE)
;
9953 free(tmp_name);
9954 }
9955 }
9956 } else if (!strncasecmp(un->un_name, "History-Info", 12)) {
9957 if (first_history_info) {
9958 /* If the header exists first time, make sure to remove old info and re-set the variable */
9959 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)
;
9960 first_history_info = 0;
9961 } else {
9962 /* Append the History-Info into one long string */
9963 const char *history_var = switch_channel_get_variable(channel, "sip_history_info")switch_channel_get_variable_dup(channel, "sip_history_info", SWITCH_TRUE
, -1)
;
9964 if (!zstr(history_var)_zstr(history_var)) {
9965 char *tmp_str;
9966 if ((tmp_str = switch_mprintf("%s, %s", history_var, un->un_value))) {
9967 switch_channel_set_variable(channel, "sip_history_info", tmp_str)switch_channel_set_variable_var_check(channel, "sip_history_info"
, tmp_str, SWITCH_TRUE)
;
9968 free(tmp_str);
9969 } else {
9970 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)
;
9971 }
9972 } else {
9973 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)
;
9974 }
9975 }
9976 } else if (!strcasecmp(un->un_name, "X-FS-Channel-Name") && !zstr(un->un_value)_zstr(un->un_value)) {
9977 switch_channel_set_name(channel, un->un_value);
9978 switch_channel_set_variable(channel, "push_channel_name", "true")switch_channel_set_variable_var_check(channel, "push_channel_name"
, "true", SWITCH_TRUE)
;
9979 } else if (!strcasecmp(un->un_name, "X-FS-Support")) {
9980 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__, 9980)
;
9981 } else if (!strcasecmp(un->un_name, "Geolocation")) {
9982 switch_channel_set_variable(channel, "sip_geolocation", un->un_value)switch_channel_set_variable_var_check(channel, "sip_geolocation"
, un->un_value, SWITCH_TRUE)
;
9983 } else if (!strcasecmp(un->un_name, "Geolocation-Error")) {
9984 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)
;
9985 } else if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2) || !strcasecmp(un->un_name, "User-to-User")) {
9986 if (!zstr(un->un_value)_zstr(un->un_value)) {
9987 char new_name[512] = "";
9988 int reps = 0;
9989 for (;;) {
9990 char postfix[25] = "";
9991 if (reps > 0) {
9992 switch_snprintf(postfix, sizeof(postfix), "-%d", reps);
9993 }
9994 reps++;
9995 switch_snprintf(new_name, sizeof(new_name), "%s%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name, postfix);
9996
9997 if (switch_channel_get_variable(channel, new_name)switch_channel_get_variable_dup(channel, new_name, SWITCH_TRUE
, -1)
) {
9998 continue;
9999 }
10000
10001 switch_channel_set_variable(channel, new_name, un->un_value)switch_channel_set_variable_var_check(channel, new_name, un->
un_value, SWITCH_TRUE)
;
10002 break;
10003 }
10004 }
10005 }
10006 }
10007
10008 }
10009
10010 tech_pvt->sofia_private = sofia_private;
10011 tech_pvt->nh = nh;
10012
10013 if (profile->pres_type && sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)((profile)->pflags[PFLAG_IN_DIALOG_CHAT] ? 1 : 0)) {
10014 sofia_presence_set_chat_hash(tech_pvt, sip);
10015 }
10016
10017 if (sofia_test_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)((profile)->pflags[PFLAG_PARSE_ALL_INVITE_HEADERS] ? 1 : 0
)
) {
10018 sofia_parse_all_invite_headers(sip, session, nh);
10019 }
10020
10021 if (sip->sip_to) {
10022 to = sip->sip_to->a_url;
10023 }
10024 if (sip->sip_from) {
10025 from = sip->sip_from->a_url;
10026 }
10027 if (sip->sip_contact) {
10028 contact = sip->sip_contact->m_url;
10029 }
10030
10031 if (sip->sip_user_agent) {
10032 user_agent = switch_str_nil(sip->sip_user_agent->g_string)(sip->sip_user_agent->g_string ? sip->sip_user_agent
->g_string : "")
;
10033 }
10034
10035 if (sip->sip_call_id) {
10036 call_id = switch_str_nil(sip->sip_call_id->i_id)(sip->sip_call_id->i_id ? sip->sip_call_id->i_id :
"")
;
10037 }
10038
10039 if (to) {
10040 to_user = switch_str_nil(to->url_user)(to->url_user ? to->url_user : "");
10041 to_host = switch_str_nil(to->url_host)(to->url_host ? to->url_host : "");
10042 to_tag = switch_str_nil(sip->sip_to->a_tag)(sip->sip_to->a_tag ? sip->sip_to->a_tag : "");
10043 }
10044
10045 if (from) {
10046 dialog_from_user = switch_str_nil(from->url_user)(from->url_user ? from->url_user : "");
10047 dialog_from_host = switch_str_nil(from->url_host)(from->url_host ? from->url_host : "");
10048 from_tag = switch_str_nil(sip->sip_from->a_tag)(sip->sip_from->a_tag ? sip->sip_from->a_tag : ""
)
;
10049 }
10050
10051 if (contact) {
10052 contact_user = switch_str_nil(contact->url_user)(contact->url_user ? contact->url_user : "");
10053 contact_host = switch_str_nil(contact->url_host)(contact->url_host ? contact->url_host : "");
10054 }
10055
10056 if (profile->pres_type) {
10057 const char *presence_data = switch_channel_get_variable(channel, "presence_data")switch_channel_get_variable_dup(channel, "presence_data", SWITCH_TRUE
, -1)
;
10058 const char *presence_id = switch_channel_get_variable(channel, "presence_id")switch_channel_get_variable_dup(channel, "presence_id", SWITCH_TRUE
, -1)
;
10059 char *full_contact = "";
10060 char *p = NULL((void*)0);
10061 time_t now;
10062
10063 if (sip->sip_contact) {
10064 full_contact = sip_header_as_string(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), (void *) sip->sip_contact);
10065 }
10066
10067 if (call_info_str && switch_stristr("appearance", call_info_str)) {
10068 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)
;
10069 if ((p = strchr(call_info_str, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(call_info_str) && (';') == '\0' ? (char *) __rawmemchr
(call_info_str, ';') : __builtin_strchr (call_info_str, ';')
))
)) {
10070 p++;
10071 switch_channel_set_variable(channel, "presence_call_info", p)switch_channel_set_variable_var_check(channel, "presence_call_info"
, p, SWITCH_TRUE)
;
10072 }
10073 }
10074
10075 now = switch_epoch_time_now(NULL((void*)0));
10076
10077 sql = switch_mprintf("insert into sip_dialogs "
10078 "(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
10079 "contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
10080 "call_info,rcd,call_info_state) "
10081 "values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
10082 call_id,
10083 tech_pvt->sofia_private->uuid,
10084 to_user, to_host, to_tag, dialog_from_user, dialog_from_host, from_tag,
10085 contact_user, contact_host, "confirmed", "inbound", user_agent,
10086 profile->name, mod_sofia_globals.hostname, switch_str_nil(full_contact)(full_contact ? full_contact : ""),
10087 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);
10088
10089 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia.c", 10089,
__PRETTY_FUNCTION__))
;
10090
10091 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
10092
10093 if ( full_contact ) {
10094 su_free(nua_handle_home(tech_pvt->nh)((su_home_t *)(tech_pvt->nh)), full_contact);
10095 }
10096 }
10097
10098 if (is_nat) {
10099 sofia_set_flag(tech_pvt, TFLAG_NAT)(tech_pvt)->flags[TFLAG_NAT] = 1;
10100 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "sofia.c", (const char *)__func__,
10100, (const char*)(session)
, SWITCH_LOG_DEBUG, "Setting NAT mode based on %s\n", is_nat);
10101 switch_channel_set_variable(channel, "sip_nat_detected", "true")switch_channel_set_variable_var_check(channel, "sip_nat_detected"
, "true", SWITCH_TRUE)
;
10102 }
10103
10104 return;
10105
10106 fail:
10107 profile->ib_failed_calls++;
10108
10109 return;
10110
10111}
10112
10113void sofia_handle_sip_i_options(int status,
10114 char const *phrase,
10115 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
10116 sofia_dispatch_event_t *de,
10117 tagi_t tags[])
10118{
10119 uint32_t sess_count = switch_core_session_count();
10120 uint32_t sess_max = switch_core_session_limit(0);
10121
10122 if (sofia_test_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY)((profile)->pflags[PFLAG_OPTIONS_RESPOND_503_ON_BUSY] ? 1 :
0)
&&
10123 (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)((profile)->pflags[PFLAG_RUNNING] ? 1 : 0) || !switch_core_ready_inbound())) {
10124 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);
10125 } else {
10126 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),
10127 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);
10128 }
10129
10130}
10131
10132/*
10133 * This subroutine will take the a_params of a sip_addr_s structure and spin through them.
10134 * Each param will be used to create a channel variable.
10135 * In the SIP RFC's, this data is called generic-param.
10136 * Note that the tag-param is also included in the a_params list.
10137 *
10138 * From: "John Doe" <sip:5551212@1.2.3.4>;tag=ed23266b52cbb17eo2;ref=101;mbid=201
10139 *
10140 * For example, the header above will produce an a_params list with three entries
10141 * tag=ed23266b52cbb17eo2
10142 * ref=101
10143 * mbid=201
10144 *
10145 * The a_params list is parsed and the lvalue is used to create the channel variable name while the
10146 * rvalue is used to create the channel variable value.
10147 *
10148 * If no equal (=) sign is found during parsing, a channel variable name is created with the param and
10149 * the value is set to NULL.
10150 *
10151 * Pointers are used for copying the sip_header_name for performance reasons. There are no calls to
10152 * any string functions and no memory is allocated/dealocated. The only limiter is the size of the
10153 * sip_header_name array.
10154*/
10155static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params)
10156{
10157 char sip_header_name[128] = "";
10158 char var1[] = "sip_";
10159 char *cp, *sh, *sh_end, *sh_save;
10160
10161 /* Build the static part of the sip_header_name variable from */
10162 /* the header_type. If the header type is "referred_by" then */
10163 /* sip_header_name = "sip_referred_by_". */
10164 sh = sip_header_name;
10165 sh_end = sh + sizeof(sip_header_name) - 1;
10166 for (cp = var1; *cp; cp++, sh++) {
10167 *sh = *cp;
10168 }
10169 *sh = '\0';
10170
10171 /* Copy the header_type to the sip_header_name. Before copying */
10172 /* each character, check that we aren't going to overflow the */
10173 /* the sip_header_name buffer. We have to account for the */
10174 /* trailing underscore and NULL that will be added to the end. */
10175 for (cp = header_type; (*cp && (sh < (sh_end - 1))); cp++, sh++) {
10176 *sh = *cp;
10177 }
10178 *sh++ = '_';
10179 *sh = '\0';
10180
10181 /* sh now points to the NULL at the end of the partially built */
10182 /* sip_header_name variable. This is also the start of the */
10183 /* variable part of the sip_header_name built from the lvalue */
10184 /* of the params data. */
10185 sh_save = sh;
10186
10187 while (params && params[0]) {
10188
10189 /* Copy the params data to the sip_header_name variable until */
10190 /* the end of the params string is reached, an '=' is detected */
10191 /* or until the sip_header_name buffer has been exhausted. */
10192 for (cp = (char *) (*params); ((*cp != '=') && *cp && (sh < sh_end)); cp++, sh++) {
10193 *sh = *cp;
10194 }
10195
10196 /* cp now points to either the end of the params data or the */
10197 /* equal (=) sign separating the lvalue and rvalue. */
10198 if (*cp == '=')
10199 cp++;
10200 *sh = '\0';
10201 switch_channel_set_variable(channel, sip_header_name, cp)switch_channel_set_variable_var_check(channel, sip_header_name
, cp, SWITCH_TRUE)
;
10202
10203 /* Bump pointer to next param in the list. Also reset the */
10204 /* sip_header_name pointer to the beginning of the dynamic area */
10205 params++;
10206 sh = sh_save;
10207 }
10208}
10209
10210/* For Emacs:
10211 * Local Variables:
10212 * mode:c
10213 * indent-tabs-mode:t
10214 * tab-width:4
10215 * c-basic-offset:4
10216 * End:
10217 * For VIM:
10218 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
10219 */