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
45 extern su_log_t tport_log[];
46 extern su_log_t iptsec_log[];
47 extern su_log_t nea_log[];
48 extern su_log_t nta_log[];
49 extern su_log_t nth_client_log[];
50 extern su_log_t nth_server_log[];
51 extern su_log_t nua_log[];
52 extern su_log_t soa_log[];
53 extern su_log_t sresolv_log[];
54 #ifdef HAVE_SOFIA_STUN
55 extern su_log_t stun_log[];
56 #endif
57 extern su_log_t su_log_default[];
58
59 static void config_sofia_profile_urls(sofia_profile_t * profile);
60 static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag, const char *gwname);
61 static void parse_domain_tag(sofia_profile_t *profile, switch_xml_t x_domain_tag, const char *dname, const char *parse, const char *alias);
62
63 void 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
68 static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params);
69
70
71
72 static 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
78 static 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[]);
83 static 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
sofia_set_accept_language_channel_variable(switch_channel_t * channel,sip_t const * sip)87 static void sofia_set_accept_language_channel_variable(switch_channel_t *channel, sip_t const *sip)
88 {
89 if (sip->sip_accept_language) {
90 sip_accept_language_t *sip_accept_language = NULL;
91 int count = 0;
92
93 for(sip_accept_language = sip->sip_accept_language; sip_accept_language; sip_accept_language = sip_accept_language->aa_next) {
94 char var_name[64] = "";
95
96 if (zstr(sip_accept_language->aa_value)) {
97 continue;
98
99 }
100 if (count == 0) {
101 switch_channel_set_variable(channel, "sip_accept_language", sip_accept_language->aa_value);
102 }
103
104 switch_snprintf(var_name, sizeof(var_name), "sip_accept_language_%d_value", count);
105 switch_channel_set_variable(channel, var_name, sip_accept_language->aa_value);
106
107 if (!zstr(sip_accept_language->aa_q)) {
108 switch_snprintf(var_name, sizeof(var_name), "sip_accept_language_%d_q", count);
109 switch_channel_set_variable(channel, var_name, sip_accept_language->aa_q);
110 }
111
112 count++;
113 }
114 switch_channel_set_variable_printf(channel, "sip_accept_language_count", "%d", count);
115 }
116 }
117
sofia_handle_sip_r_notify(switch_core_session_t * session,int status,char const * phrase,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[])118 void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
119 char const *phrase,
120 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
121 sofia_dispatch_event_t *de, tagi_t tags[])
122 {
123 private_object_t *tech_pvt = switch_core_session_get_private(session);
124 switch_core_session_t *other_session;
125
126 if (tech_pvt->proxy_refer_uuid && (other_session = switch_core_session_locate(tech_pvt->proxy_refer_uuid))) {
127 switch_core_session_message_t *msg;
128
129 msg = switch_core_session_alloc(other_session, sizeof(*msg));
130 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
131 msg->from = __FILE__;
132 msg->numeric_arg = status;
133 msg->string_arg = switch_core_session_strdup(other_session, phrase);
134 switch_core_session_queue_message(other_session, msg);
135 switch_core_session_rwunlock(other_session);
136 } else {
137 tech_pvt->proxy_refer_uuid = NULL;
138 }
139
140
141 if (status == 481 && sip && !sip->sip_retry_after && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) {
142 char *sql;
143
144 sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", sip->sip_call_id->i_id);
145 switch_assert(sql != NULL);
146 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
147 nua_handle_destroy(nh);
148 }
149
150 }
151
152 #define url_set_chanvars(session, url, varprefix) _url_set_chanvars(session, url, #varprefix "_user", #varprefix "_host", #varprefix "_port", #varprefix "_uri", #varprefix "_params")
153
_url_set_chanvars(switch_core_session_t * session,url_t * url,const char * user_var,const char * host_var,const char * port_var,const char * uri_var,const char * params_var)154 static const char *_url_set_chanvars(switch_core_session_t *session, url_t *url, const char *user_var,
155 const char *host_var, const char *port_var, const char *uri_var, const char *params_var)
156 {
157 const char *user = NULL, *host = NULL, *port = NULL;
158 char *uri = NULL;
159 switch_channel_t *channel = switch_core_session_get_channel(session);
160 char new_port[25] = "";
161
162 if (url) {
163 user = url->url_user;
164 host = url->url_host;
165 port = url->url_port;
166 if (!zstr(url->url_params)) {
167 switch_channel_set_variable(channel, params_var, url->url_params);
168 }
169 }
170
171 if (zstr(user)) {
172 user = "nobody";
173 }
174
175 if (zstr(host)) {
176 host = "nowhere";
177 }
178
179 check_decode(user, session);
180
181 if (user) {
182 switch_channel_set_variable(channel, user_var, user);
183 }
184
185
186 if (port) {
187 switch_snprintf(new_port, sizeof(new_port), ":%s", port);
188 }
189
190 switch_channel_set_variable(channel, port_var, port);
191 if (host) {
192 if (user) {
193 uri = switch_core_session_sprintf(session, "%s@%s%s", user, host, new_port);
194 } else {
195 uri = switch_core_session_sprintf(session, "%s%s", host, new_port);
196 }
197 switch_channel_set_variable(channel, uri_var, uri);
198 switch_channel_set_variable(channel, host_var, host);
199 }
200
201 return uri;
202 }
203
strip_quotes(const char * in)204 static char *strip_quotes(const char *in)
205 {
206 char *t = (char *) in;
207 char *r = (char *) in;
208
209 if (t && *t == '"') {
210 t++;
211
212 if (end_of(t) == '"') {
213 r = strdup(t);
214 switch_assert(r);
215 end_of(r) = '\0';
216 }
217 }
218
219 return r;
220 }
221
extract_header_vars(sofia_profile_t * profile,sip_t const * sip,switch_core_session_t * session,nua_handle_t * nh)222 static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip,
223 switch_core_session_t *session, nua_handle_t *nh)
224 {
225 switch_channel_t *channel = switch_core_session_get_channel(session);
226 char *full;
227
228 if (sip) {
229 if (sip->sip_route) {
230 const char *v = switch_channel_get_variable(channel, "sip_full_route");
231
232 if (!v) {
233 sip_route_t *rp;
234 switch_stream_handle_t stream = { 0 };
235 int x = 0;
236
237 SWITCH_STANDARD_STREAM(stream);
238
239 for (rp = sip->sip_route; rp; rp = rp->r_next) {
240 char *route = sip_header_as_string(nh->nh_home, (void *) rp);
241 stream.write_function(&stream, x == 0 ? "%s" : ",%s", route);
242 su_free(nh->nh_home, route);
243 x++;
244 }
245 switch_channel_set_variable(channel, "sip_full_route", stream.data);
246 free(stream.data);
247 }
248 }
249
250 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
251 if (sip->sip_contact) {
252 char *c = sip_header_as_string(nh->nh_home, (void *) sip->sip_contact);
253 switch_channel_set_variable(channel, "sip_recover_contact", c);
254 su_free(nh->nh_home, c);
255 }
256 }
257
258 if (sip->sip_record_route) {
259 sip_record_route_t *rrp;
260 switch_stream_handle_t forward_stream = { 0 };
261 switch_stream_handle_t reverse_stream = { 0 };
262 int x = 0;
263 char *tmp[128] = { 0 };
264 int y = 0;
265
266 SWITCH_STANDARD_STREAM(forward_stream);
267 SWITCH_STANDARD_STREAM(reverse_stream);
268
269 for(rrp = sip->sip_record_route; rrp; rrp = rrp->r_next) {
270 char *rr = sip_header_as_string(nh->nh_home, (void *) rrp);
271 forward_stream.write_function(&forward_stream, x == 0 ? "%s" : ",%s", rr);
272 tmp[y++] = rr;
273 if (y == 127) break;
274 x++;
275 }
276
277 y--;
278
279 x = 0;
280
281 while(y >= 0) {
282 reverse_stream.write_function(&reverse_stream, x == 0 ? "%s" : ",%s", tmp[y]);
283 su_free(nh->nh_home, tmp[y]);
284 y--;
285 x++;
286 }
287
288 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND || switch_channel_test_flag(channel, CF_RECOVERED)) {
289 switch_channel_set_variable(channel, "sip_invite_route_uri", (char *)reverse_stream.data);
290 switch_channel_set_variable(channel, "sip_invite_record_route", (char *)forward_stream.data);
291 } else {
292 switch_channel_set_variable(channel, "sip_invite_route_uri", (char *)forward_stream.data);
293 switch_channel_set_variable(channel, "sip_invite_record_route", (char *)reverse_stream.data);
294 }
295
296 free(reverse_stream.data);
297 free(forward_stream.data);
298 }
299
300 if (sip->sip_via) {
301 sip_via_t *vp;
302 switch_stream_handle_t stream = { 0 };
303 int x = 0;
304
305 SWITCH_STANDARD_STREAM(stream);
306
307 for(vp = sip->sip_via; vp; vp = vp->v_next) {
308 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
309
310 stream.write_function(&stream, x == 0 ? "%s" : ",%s", v);
311 su_free(nh->nh_home, v);
312
313 x++;
314 }
315
316 switch_channel_set_variable(channel, "sip_full_via", (char *)stream.data);
317
318 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND || switch_stristr("TCP", (char *)stream.data)) {
319 switch_channel_set_variable(channel, "sip_recover_via", (char *)stream.data);
320 }
321
322 free(stream.data);
323
324 }
325
326 if (sip->sip_from) {
327 char *p = strip_quotes(sip->sip_from->a_display);
328
329 if (p) {
330 switch_channel_set_variable(channel, "sip_from_display", p);
331 }
332 if (p != sip->sip_from->a_display) free(p);
333 if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_from))) {
334 switch_channel_set_variable(channel, "sip_full_from", full);
335 su_free(nh->nh_home, full);
336 }
337 }
338
339 if (sip->sip_to) {
340 char *p = strip_quotes(sip->sip_to->a_display);
341
342 if (p) {
343 switch_channel_set_variable(channel, "sip_to_display", p);
344 }
345
346 if (p != sip->sip_to->a_display) free(p);
347
348 if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_to))) {
349 switch_channel_set_variable(channel, "sip_full_to", full);
350 su_free(nh->nh_home, full);
351 }
352 }
353
354 }
355 }
356
extract_vars(sofia_profile_t * profile,sip_t const * sip,switch_core_session_t * session)357 static void extract_vars(sofia_profile_t *profile, sip_t const *sip,
358 switch_core_session_t *session)
359 {
360 switch_channel_t *channel = switch_core_session_get_channel(session);
361
362 if (sip) {
363 if (sip->sip_from)
364 url_set_chanvars(session, sip->sip_from->a_url, sip_from);
365 if (sip->sip_request)
366 url_set_chanvars(session, sip->sip_request->rq_url, sip_req);
367 if (sip->sip_to)
368 url_set_chanvars(session, sip->sip_to->a_url, sip_to);
369 if (sip->sip_contact)
370 url_set_chanvars(session, sip->sip_contact->m_url, sip_contact);
371 if (sip->sip_referred_by)
372 url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by);
373 if (sip->sip_to && sip->sip_to->a_tag) {
374 switch_channel_set_variable(channel, "sip_to_tag", sip->sip_to->a_tag);
375 }
376 if (sip->sip_from && sip->sip_from->a_tag) {
377 switch_channel_set_variable(channel, "sip_from_tag", sip->sip_from->a_tag);
378 }
379 if (sip->sip_cseq && sip->sip_cseq->cs_seq) {
380 char sip_cseq[40] = "";
381 switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq);
382 switch_channel_set_variable(channel, "sip_cseq", sip_cseq);
383 }
384 if (sip->sip_call_id && sip->sip_call_id->i_id) {
385 switch_channel_set_variable(channel, "sip_call_id", sip->sip_call_id->i_id);
386 }
387 }
388 }
389
390 /**
391 * Add a specific SIP INVITE header to the channel variables, prefixed with "sip_i_"
392 */
sofia_add_invite_header_to_chanvars(switch_channel_t * channel,nua_handle_t * nh,void * sip_header,const char * var)393 static void sofia_add_invite_header_to_chanvars(switch_channel_t *channel, nua_handle_t *nh, void *sip_header, const char *var)
394 {
395 switch_assert(channel);
396 switch_assert(nh);
397 switch_assert(var);
398
399 if (sip_header) {
400 char *full;
401 if ((full = sip_header_as_string(nh->nh_home, sip_header))) {
402 switch_channel_set_variable(channel, var, full);
403 su_free(nh->nh_home, full);
404 }
405 }
406 }
407
408 /**
409 * Deep search into the SIP message to recreate the original headers, including multiple Diversions, etc.
410 * Finally sets the "sip_invite_headers" to a string containing the 'original' SIP headers, except that the order may have changed.
411 * Multiple headers will have the original internal order, though.
412 *
413 * @param sip A sip_t struct containing the parsed message
414 * @param session A call session
415 * @param nh A NUA handle for string allocation
416 */
sofia_parse_all_invite_headers(sip_t const * sip,switch_core_session_t * session,nua_handle_t * nh)417 static void sofia_parse_all_invite_headers(sip_t const *sip, switch_core_session_t *session, nua_handle_t *nh)
418 {
419 switch_channel_t *channel = switch_core_session_get_channel(session);
420 sip_unknown_t *un;
421 sip_p_asserted_identity_t *passerted;
422 sip_p_preferred_identity_t *ppreferred;
423 sip_remote_party_id_t *rpid;
424 sip_reply_to_t *reply_to;
425 sip_alert_info_t *alert_info;
426
427 if (!sip) return;
428
429 /* Add simple (unique) headers first */
430 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_from, "sip_i_from");
431 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_to, "sip_i_to");
432 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_call_id, "sip_i_call_id");
433 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_cseq, "sip_i_cseq");
434 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_route, "sip_i_route");
435 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_max_forwards, "sip_i_max_forwards");
436 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_proxy_require, "sip_i_proxy_require");
437 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_contact, "sip_i_contact");
438 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_user_agent, "sip_i_user_agent");
439 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_subject, "sip_i_subject");
440 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_priority, "sip_i_priority");
441 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_organization, "sip_i_organization");
442 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_in_reply_to, "sip_i_in_reply_to");
443 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_accept_encoding, "sip_i_accept_encoding");
444 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_accept_language, "sip_i_accept_language");
445 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_i_allow");
446 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_require, "sip_i_require");
447 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_supported, "sip_i_supported");
448 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_date, "sip_i_date");
449 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_timestamp, "sip_i_timestamp");
450 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_expires, "sip_i_expires");
451 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_min_expires, "sip_i_min_expires");
452 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_session_expires, "sip_i_session_expires");
453 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_min_se, "sip_i_min_se");
454 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_privacy, "sip_i_privacy");
455 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_mime_version, "sip_i_mime_version");
456 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_type, "sip_i_content_type");
457 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_encoding, "sip_i_content_encoding");
458 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_language, "sip_i_content_language");
459 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_disposition, "sip_i_content_disposition");
460 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_content_length, "sip_i_content_length");
461
462 /* Add all other headers - which might exist more than once */
463
464 if (sip->sip_via) {
465 sip_via_t *vp;
466 for (vp = sip->sip_via; vp; vp = vp->v_next) {
467 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
468 switch_channel_add_variable_var_check(channel, "sip_i_via", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
469 su_free(nh->nh_home, v);
470 }
471 }
472
473 if (sip->sip_record_route) {
474 sip_record_route_t *rrp;
475 for (rrp = sip->sip_record_route; rrp; rrp = rrp->r_next) {
476 char *rr = sip_header_as_string(nh->nh_home, (void *) rrp);
477 switch_channel_add_variable_var_check(channel, "sip_i_record_route", rr, SWITCH_FALSE, SWITCH_STACK_PUSH);
478 su_free(nh->nh_home, rr);
479 }
480 }
481
482 if (sip->sip_proxy_authorization) {
483 sip_proxy_authorization_t *vp;
484 for (vp = sip->sip_proxy_authorization; vp; vp = vp->au_next) {
485 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
486 switch_channel_add_variable_var_check(channel, "sip_i_proxy_authorization", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
487 su_free(nh->nh_home, v);
488 }
489 }
490
491 if (sip->sip_call_info) {
492 sip_call_info_t *vp;
493 for (vp = sip->sip_call_info; vp; vp = vp->ci_next) {
494 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
495 switch_channel_add_variable_var_check(channel, "sip_i_call_info", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
496 su_free(nh->nh_home, v);
497 }
498 }
499
500 if (sip->sip_accept) {
501 sip_accept_t *vp;
502 for (vp = sip->sip_accept; vp; vp = vp->ac_next) {
503 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
504 switch_channel_add_variable_var_check(channel, "sip_i_accept", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
505 su_free(nh->nh_home, v);
506 }
507 }
508
509 if (sip->sip_authorization) {
510 sip_authorization_t *vp;
511 for (vp = sip->sip_authorization; vp; vp = vp->au_next) {
512 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
513 switch_channel_add_variable_var_check(channel, "sip_i_authorization", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
514 su_free(nh->nh_home, v);
515 }
516 }
517
518 if ((alert_info = sip_alert_info(sip))) {
519 sip_alert_info_t *vp;
520 for (vp = alert_info; vp; vp = vp->ai_next) {
521 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
522 switch_channel_add_variable_var_check(channel, "sip_i_alert_info", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
523 su_free(nh->nh_home, v);
524 }
525 }
526
527 if ((passerted = sip_p_asserted_identity(sip))) {
528 sip_p_asserted_identity_t *vp;
529 for (vp = passerted; vp; vp = vp->paid_next) {
530 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
531 switch_channel_add_variable_var_check(channel, "sip_i_p_asserted_identity", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
532 su_free(nh->nh_home, v);
533 }
534 }
535
536 if ((ppreferred = sip_p_preferred_identity(sip))) {
537 sip_p_preferred_identity_t *vp;
538 for (vp = ppreferred; vp; vp = vp->ppid_next) {
539 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
540 switch_channel_add_variable_var_check(channel, "sip_i_p_preferred_identity", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
541 su_free(nh->nh_home, v);
542 }
543 }
544
545 if ((rpid = sip_remote_party_id(sip))) {
546 sip_remote_party_id_t *vp;
547 for (vp = rpid; vp; vp = vp->rpid_next) {
548 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
549 switch_channel_add_variable_var_check(channel, "sip_i_remote_party_id", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
550 su_free(nh->nh_home, v);
551 }
552 }
553
554 if ((reply_to = sip_reply_to(sip))) {
555 sip_reply_to_t *vp;
556 for (vp = reply_to; vp; vp = vp->rplyto_next) {
557 char *v = sip_header_as_string(nh->nh_home, (void *) vp);
558 switch_channel_add_variable_var_check(channel, "sip_i_reply_to", v, SWITCH_FALSE, SWITCH_STACK_PUSH);
559 su_free(nh->nh_home, v);
560 }
561 }
562
563 /* Loop through the unknown headers */
564 for (un = sip->sip_unknown; un; un = un->un_next) {
565 if (!zstr(un->un_name) && !zstr(un->un_value)) {
566 char *parsed_name;
567 if ((parsed_name = switch_mprintf("sip_i_%s", un->un_name))) {
568 char *p, *x = parsed_name;
569 switch_tolower_max(x);
570 while ((p = strchr(x, '-'))) {
571 *p = '_';
572 x = ++p;
573 }
574 switch_channel_add_variable_var_check(channel, parsed_name, un->un_value, SWITCH_FALSE, SWITCH_STACK_PUSH);
575 free(parsed_name);
576 }
577 }
578 }
579 }
580
sofia_pass_notify(switch_core_session_t * session,const char * uuid,const char * payload)581 static switch_status_t sofia_pass_notify(switch_core_session_t *session, const char *uuid, const char *payload)
582 {
583 switch_core_session_t *other_session;
584
585 if ((other_session = switch_core_session_locate(uuid))) {
586 switch_core_session_message_t *msg;
587
588 msg = switch_core_session_alloc(other_session, sizeof(*msg));
589 MESSAGE_STAMP_FFL(msg);
590 msg->message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE;
591 msg->string_arg = switch_core_session_strdup(other_session, payload);
592 msg->from = __FILE__;
593 switch_core_session_queue_message(other_session, msg);
594 switch_core_session_rwunlock(other_session);
595 return SWITCH_STATUS_SUCCESS;
596 }
597
598 return SWITCH_STATUS_FALSE;
599 }
600
601
sofia_handle_sip_i_notify(switch_core_session_t * session,int status,char const * phrase,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[])602 void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
603 char const *phrase,
604 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
605 sofia_dispatch_event_t *de, tagi_t tags[])
606 {
607 switch_channel_t *channel = NULL;
608 private_object_t *tech_pvt = NULL;
609 switch_event_t *s_event = NULL;
610 sofia_gateway_subscription_t *gw_sub_ptr;
611 int sub_state;
612 sofia_gateway_t *gateway = NULL;
613 const char *session_id_header = sofia_glue_session_id_header(session, profile);
614
615 tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
616
617 /* make sure we have a proper event */
618 if (!sip || !sip->sip_event) {
619 goto error;
620 }
621
622 /* Automatically return a 200 OK for Event: keep-alive */
623 if (!strcasecmp(sip->sip_event->o_type, "keep-alive")) {
624 /* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */
625 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
626 goto end;
627 }
628
629 if (session) {
630 channel = switch_core_session_get_channel(session);
631 switch_assert(channel != NULL);
632 tech_pvt = switch_core_session_get_private(session);
633 switch_assert(tech_pvt != NULL);
634 }
635
636
637 if (tech_pvt && tech_pvt->proxy_refer_uuid && sofia_test_pflag(profile, PFLAG_PROXY_REFER) && sip->sip_payload && sip->sip_payload->pl_data &&
638 sip->sip_content_type && sip->sip_content_type->c_type && switch_stristr("sipfrag", sip->sip_content_type->c_type)) {
639
640 if (sofia_pass_notify(session, tech_pvt->proxy_refer_uuid, sip->sip_payload->pl_data) == SWITCH_STATUS_SUCCESS) {
641 if (tech_pvt->proxy_refer_msg) {
642 msg_ref_destroy(tech_pvt->proxy_refer_msg);
643 tech_pvt->proxy_refer_msg = NULL;
644 }
645 tech_pvt->proxy_refer_msg = msg_ref_create(de->data->e_msg);
646 //nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
647 } else {
648 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
649 }
650
651 goto end;
652 }
653
654 /* For additional NOTIFY event packages see http://www.iana.org/assignments/sip-events. */
655 if (sip->sip_content_type &&
656 sip->sip_content_type->c_type && sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(sip->sip_event->o_type, "refer")) {
657 if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_NOTIFY_REFER) == SWITCH_STATUS_SUCCESS) {
658 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "content-type", sip->sip_content_type->c_type);
659 switch_event_add_body(s_event, "%s", sip->sip_payload->pl_data);
660 }
661 }
662
663 /* add common headers for the NOTIFY to the switch_event and fire if it exists */
664 if (s_event != NULL) {
665 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event-package", sip->sip_event->o_type);
666 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event-id", sip->sip_event->o_id);
667
668 if (sip->sip_contact) {
669 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s@%s",
670 sip->sip_contact->m_url->url_user, sip->sip_contact->m_url->url_host);
671 }
672
673 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);
674 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-tag", sip->sip_from->a_tag);
675 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);
676 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-tag", sip->sip_to->a_tag);
677
678 if (sip->sip_call_id && sip->sip_call_id->i_id) {
679 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", sip->sip_call_id->i_id);
680 }
681 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_substate) {
682 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-substate", sip->sip_subscription_state->ss_substate);
683 }
684 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_reason) {
685 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-reason", sip->sip_subscription_state->ss_reason);
686 }
687 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_retry_after) {
688 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-retry-after", sip->sip_subscription_state->ss_retry_after);
689 }
690 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_expires) {
691 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "subscription-expires", sip->sip_subscription_state->ss_expires);
692 }
693 if (session) {
694 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "UniqueID", switch_core_session_get_uuid(session));
695 }
696 switch_event_fire(&s_event);
697 }
698
699 if (!strcasecmp(sip->sip_event->o_type, "refer")) {
700 if (session && channel && tech_pvt) {
701 if (sip->sip_payload && sip->sip_payload->pl_data) {
702 char *p;
703 int status_val = 0;
704 if ((p = strchr(sip->sip_payload->pl_data, ' '))) {
705 p++;
706 status_val = atoi(p);
707 }
708 if (!status_val || status_val >= 200) {
709 switch_channel_set_variable(channel, "sip_refer_reply", sip->sip_payload->pl_data);
710 if (status_val == 200) {
711 switch_channel_hangup(channel, SWITCH_CAUSE_BLIND_TRANSFER);
712 }
713 if ((int)tech_pvt->want_event == 9999) {
714 tech_pvt->want_event = 0;
715 }
716 }
717 }
718 }
719 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
720 }
721
722 /* if no session, assume it could be an incoming notify from a gateway subscription */
723 if (session) {
724 if (!zstr(profile->proxy_notify_events) && (!strcasecmp(profile->proxy_notify_events, "all") || strstr(profile->proxy_notify_events, sip->sip_event->o_type))) {
725 switch_core_session_t *other_session;
726 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
727 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
728 const char *full_to = NULL;
729 char *pl = NULL;
730 char *unknown = NULL;
731
732 full_to = switch_str_nil(switch_channel_get_variable(switch_core_session_get_channel(other_session), "sip_full_to"));
733 if (sip->sip_payload && sip->sip_payload->pl_data) {
734 pl = switch_core_session_strdup(other_session, (char*)sip->sip_payload->pl_data);
735 }
736 unknown = sofia_glue_get_non_extra_unknown_headers(sip);
737 nua_notify(other_tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active),
738 TAG_IF((full_to), SIPTAG_TO_STR(full_to)), SIPTAG_SUBSCRIPTION_STATE_STR("active"),
739 SIPTAG_EVENT_STR(sip->sip_event->o_type), TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)),
740 TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)),
741 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
742 TAG_END());
743 switch_safe_free(unknown);
744 switch_core_session_rwunlock(other_session);
745 }
746 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
747 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
748 goto end;
749 }
750 /* make sure we have a proper "talk" event */
751 if (strcasecmp(sip->sip_event->o_type, "talk")) {
752 goto error;
753 }
754
755 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
756 switch_channel_answer(channel);
757 switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number"));
758 switch_ivr_session_transfer(session, "auto_answer", NULL, NULL);
759 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
760 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
761 goto end;
762 }
763 }
764
765 if (!sofia_private || zstr(sofia_private->gateway_name)) {
766 if (profile->debug) {
767 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Gateway information missing Subscription Event: %s\n",
768 sip->sip_event->o_type);
769 }
770 goto error;
771 }
772
773
774 if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) {
775 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Gateway information missing\n");
776 goto error;
777 }
778
779 /* find the corresponding gateway subscription (if any) */
780 if (!(gw_sub_ptr = sofia_find_gateway_subscription(gateway, sip->sip_event->o_type))) {
781 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
782 "Could not find gateway subscription. Gateway: %s. Subscription Event: %s\n",
783 gateway->name, sip->sip_event->o_type);
784 goto error;
785 }
786
787 if (!(gw_sub_ptr->state == SUB_STATE_SUBED || gw_sub_ptr->state == SUB_STATE_SUBSCRIBE)) {
788 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Ignoring notify due to subscription state: %d\n", gw_sub_ptr->state);
789 goto error;
790 }
791
792 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_expires) {
793 int delta = atoi(sip->sip_subscription_state->ss_expires);
794
795 delta /= 2;
796
797 if (delta < 1) {
798 delta = 1;
799 }
800 gw_sub_ptr->expires = switch_epoch_time_now(NULL) + delta;
801 }
802
803 /* dispatch freeswitch event */
804 if (switch_event_create(&s_event, SWITCH_EVENT_NOTIFY_IN) == SWITCH_STATUS_SUCCESS) {
805 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event", sip->sip_event->o_type);
806 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "pl_data", sip->sip_payload ? sip->sip_payload->pl_data : "");
807 if ( sip->sip_content_type != NULL )
808 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_content_type", sip->sip_content_type->c_type);
809 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", gateway->profile->sip_port);
810 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
811 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", gateway->profile->name);
812 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", gateway->profile->url);
813 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "gateway_name", gateway->name);
814 if ( sip->sip_call_info != NULL ) {
815 sip_call_info_t *call_info = sip->sip_call_info;
816 char *nua_hold = sip_header_as_string(nua_handle_home(nh), (void *) call_info);
817 size_t cur_len = strlen(nua_hold);
818 char *hold = strdup(nua_hold);
819 su_free(nua_handle_home(nh), nua_hold);
820
821 while ((call_info = call_info->ci_next) != NULL) {
822 char *tmp = sip_header_as_string(nua_handle_home(nh), (void *) call_info);
823 size_t tmp_len = strlen(tmp);
824 char *tmp_hold = realloc(hold, cur_len + tmp_len + 2);
825 if (!tmp_hold) {
826 /* Avoid leak if realloc failed */
827 free(hold);
828 }
829 switch_assert(tmp_hold);
830 hold = tmp_hold;
831 strncpy(hold + cur_len, ",", 2);
832 strncpy(hold + cur_len + 1, tmp, tmp_len +1);
833 su_free(nua_handle_home(nh), tmp);
834 cur_len = cur_len + tmp_len + 2;
835 }
836 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Call-Info", hold);
837 switch_safe_free(hold);
838 }
839 switch_event_fire(&s_event);
840 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "dispatched freeswitch event for message-summary NOTIFY\n");
841 } else {
842 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to create event\n");
843 goto error;
844 }
845
846 goto end;
847
848 error:
849
850
851 if (sip && sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "message-summary")) {
852 /* unsolicited mwi, just say ok */
853 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
854 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
855
856 if (sofia_test_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)) {
857 const char *mwi_status = NULL;
858 char network_ip[80];
859 uint32_t x = 0;
860 int acl_ok = 1;
861 char *last_acl = NULL;
862
863 if (sip->sip_to && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host
864 && sip->sip_payload && sip->sip_payload->pl_data ) {
865
866 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL);
867 for (x = 0; x < profile->acl_count; x++) {
868 last_acl = profile->acl[x];
869 if (!(acl_ok = switch_check_network_list_ip(network_ip, last_acl))) {
870 break;
871 }
872 }
873
874 if ( acl_ok )
875 {
876 mwi_status = switch_stristr("Messages-Waiting: ", sip->sip_payload->pl_data);
877
878 if ( mwi_status ) {
879 char *mwi_stat;
880 mwi_status += strlen( "Messages-Waiting: " );
881 mwi_stat = switch_strip_whitespace( mwi_status );
882
883 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
884 "Forwarding unsolicited MWI ( %s : %s@%s )\n",
885 mwi_stat, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
886 if (switch_event_create(&s_event, SWITCH_EVENT_MESSAGE_WAITING) == SWITCH_STATUS_SUCCESS) {
887 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", mwi_stat );
888 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM,
889 "MWI-Message-Account", "%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
890 switch_event_fire(&s_event);
891 }
892 switch_safe_free(mwi_stat);
893 }
894 } else {
895 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Dropping unsolicited MWI ( %s@%s ) because of ACL\n",
896 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host );
897 };
898
899 }
900 }
901
902 } else {
903 nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS_MSG(de->data->e_msg),
904 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
905 }
906
907 end:
908
909 if (!gateway && sub_state == nua_substate_terminated && sofia_private && sofia_private != &mod_sofia_globals.destroy_private &&
910 sofia_private != &mod_sofia_globals.keep_private) {
911 sofia_private->destroy_nh = 1;
912 sofia_private->destroy_me = 1;
913 }
914
915 if (gateway) {
916 sofia_reg_release_gateway(gateway);
917 }
918
919 }
920
921 /*
922 * This will fire an event containing X-headers from the BYE response
923 */
sofia_handle_sip_r_bye(switch_core_session_t * session,int status,char const * phrase,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[])924 void sofia_handle_sip_r_bye(switch_core_session_t *session, int status,
925 char const *phrase,
926 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
927 sofia_dispatch_event_t *de, tagi_t tags[])
928 {
929 if (profile && sofia_test_pflag(profile, PFLAG_FIRE_BYE_RESPONSE_EVENTS) && sip && sip->sip_call_id && !zstr(sip->sip_call_id->i_id) && sofia_private && !zstr_buf(sofia_private->uuid_str)) {
930 switch_event_t *bye_response_event = NULL;
931 sip_unknown_t *un;
932 if (switch_event_create_subclass(&bye_response_event, SWITCH_EVENT_CUSTOM, MY_EVENT_BYE_RESPONSE) == SWITCH_STATUS_SUCCESS) {
933 switch_event_add_header(bye_response_event, SWITCH_STACK_BOTTOM, "call-id", "%s", sip->sip_call_id->i_id);
934 switch_event_add_header(bye_response_event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", sofia_private->uuid_str);
935 for (un = sip->sip_unknown; un; un = un->un_next) {
936 if (!zstr(un->un_value)) {
937 switch_event_add_header(bye_response_event, SWITCH_STACK_BOTTOM, un->un_name, "%s", un->un_value);
938 }
939 }
940 switch_event_fire(&bye_response_event);
941 }
942 }
943 }
944
sofia_handle_sip_i_bye(switch_core_session_t * session,int status,char const * phrase,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[])945 void sofia_handle_sip_i_bye(switch_core_session_t *session, int status,
946 char const *phrase,
947 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
948 sofia_dispatch_event_t *de, tagi_t tags[])
949 {
950 const char *tmp;
951 switch_channel_t *channel;
952 private_object_t *tech_pvt;
953 char *extra_headers;
954 const char *call_info = NULL;
955 const char *vval = NULL;
956 const char *session_id_header = sofia_glue_session_id_header(session, profile);
957 #ifdef MANUAL_BYE
958 int cause;
959 char st[80] = "";
960 #endif
961
962 if (!session) {
963 return;
964 }
965
966 channel = switch_core_session_get_channel(session);
967 tech_pvt = switch_core_session_get_private(session);
968
969 #ifdef MANUAL_BYE
970 status = 200;
971 phrase = "OK";
972
973 if (switch_channel_test_flag(tech_pvt->channel, CF_SLA_BARGING)) {
974 const char *bargee_uuid = switch_channel_get_variable(channel, "sip_barging_uuid");
975 switch_core_session_t *bargee_session;
976 uint32_t ttl = 0;
977
978 if ((bargee_session = switch_core_session_locate(bargee_uuid))) {
979 //switch_channel_t *bargee_channel = switch_core_session_get_channel(bargee_session);
980 if ((ttl = switch_core_media_bug_count(bargee_session, "eavesdrop")) == 1) {
981 if (switch_core_session_check_interface(bargee_session, sofia_endpoint_interface)) {
982 switch_channel_clear_flag(switch_core_session_get_channel(bargee_session), CF_SLA_BARGE);
983 }
984 }
985 switch_core_session_rwunlock(bargee_session);
986 }
987 }
988
989 if (switch_channel_test_flag(tech_pvt->channel, CF_SLA_BARGE)) {
990 switch_core_session_t *new_session, *other_session;
991 const char *other_uuid = switch_channel_get_partner_uuid(tech_pvt->channel);
992 char *cmd = NULL;
993
994 if (!zstr(other_uuid) && (other_session = switch_core_session_locate(other_uuid))) {
995 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
996
997 switch_mutex_lock(profile->ireg_mutex);
998 if (switch_ivr_eavesdrop_pop_eavesdropper(session, &new_session) == SWITCH_STATUS_SUCCESS) {
999 switch_channel_t *new_channel = switch_core_session_get_channel(new_session);
1000 const char *new_uuid = switch_core_session_get_uuid(new_session);
1001 switch_caller_profile_t *cp = switch_channel_get_caller_profile(new_channel);
1002
1003 cp->caller_id_name = cp->orig_caller_id_name;
1004 cp->caller_id_number = cp->orig_caller_id_number;
1005
1006
1007 switch_channel_set_variable(new_channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL);
1008
1009 switch_channel_set_flag(other_channel, CF_REDIRECT);
1010
1011 switch_channel_set_state(new_channel, CS_RESET);
1012
1013 switch_ivr_uuid_bridge(new_uuid, other_uuid);
1014 cmd = switch_core_session_sprintf(session, "sleep:500,sofia_sla:%s inline", new_uuid);
1015
1016 switch_channel_clear_flag(other_channel, CF_REDIRECT);
1017
1018 switch_core_session_rwunlock(new_session);
1019 }
1020 switch_mutex_unlock(profile->ireg_mutex);
1021
1022 switch_core_session_rwunlock(other_session);
1023 }
1024
1025 if (!zstr(cmd)) {
1026 switch_ivr_eavesdrop_exec_all(session, "transfer", cmd);
1027 }
1028 }
1029
1030 sofia_set_flag_locked(tech_pvt, TFLAG_BYE);
1031 call_info = switch_channel_get_variable(channel, "presence_call_info_full");
1032
1033 if (sip->sip_reason) {
1034 char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason);
1035
1036 if (!zstr(reason_header)) {
1037 switch_channel_set_variable(channel, "sip_reason", reason_header);
1038 switch_channel_set_variable_partner(channel, "sip_reason", reason_header);
1039 }
1040 }
1041
1042 if (sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
1043 || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
1044 || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
1045 tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
1046 cause = tech_pvt->q850_cause;
1047 } else {
1048 cause = sofia_glue_sip_cause_to_freeswitch(status);
1049 }
1050
1051 if (sip->sip_content_type && sip->sip_content_type->c_type) {
1052 switch_channel_set_variable(channel, "sip_bye_content_type", sip->sip_content_type->c_type);
1053 }
1054
1055 if (sip->sip_payload && sip->sip_payload->pl_data) {
1056 switch_channel_set_variable(channel, "sip_bye_payload", sip->sip_payload->pl_data);
1057 }
1058
1059 switch_snprintf(st, sizeof(st), "%d", status);
1060 switch_channel_set_variable(channel, "sip_term_status", st);
1061 switch_snprintf(st, sizeof(st), "sip:%d", status);
1062 switch_channel_set_variable(channel, SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE, st);
1063
1064 switch_channel_set_variable_partner(channel, "sip_hangup_phrase", phrase);
1065
1066 switch_snprintf(st, sizeof(st), "%d", cause);
1067 switch_channel_set_variable(channel, "sip_term_cause", st);
1068
1069 extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_BYE_HEADER_PREFIX);
1070 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_BYE_HEADER_PREFIX);
1071
1072 if (!(vval = switch_channel_get_variable(channel, "sip_copy_custom_headers")) || switch_true(vval)) {
1073 switch_core_session_t *nsession = NULL;
1074
1075 switch_core_session_get_partner(session, &nsession);
1076
1077 if (nsession) {
1078 const char *vval;
1079 switch_channel_t *nchannel = switch_core_session_get_channel(nsession);
1080
1081 if (!(vval = switch_channel_get_variable(nchannel, "sip_copy_custom_headers")) || switch_true(vval)) {
1082 switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_BYE_HEADER_PREFIX_T);
1083 }
1084 switch_core_session_rwunlock(nsession);
1085 }
1086 }
1087
1088
1089 switch_channel_hangup(channel, cause);
1090 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
1091 TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
1092 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
1093
1094 switch_safe_free(extra_headers);
1095
1096 if (sofia_private) {
1097 sofia_private->destroy_me = 1;
1098 sofia_private->destroy_nh = 1;
1099 }
1100 #endif
1101
1102
1103 if (sip->sip_user_agent && !zstr(sip->sip_user_agent->g_string)) {
1104 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_user_agent->g_string);
1105 } else if (sip->sip_server && !zstr(sip->sip_server->g_string)) {
1106 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_server->g_string);
1107 }
1108
1109 sofia_set_accept_language_channel_variable(channel, sip);
1110
1111 if ((tmp = sofia_glue_get_unknown_header(sip, "rtp-txstat"))) {
1112 switch_channel_set_variable(channel, "sip_rtp_txstat", tmp);
1113 }
1114 if ((tmp = sofia_glue_get_unknown_header(sip, "rtp-rxstat"))) {
1115 switch_channel_set_variable(channel, "sip_rtp_rxstat", tmp);
1116 }
1117 if ((tmp = sofia_glue_get_unknown_header(sip, "P-RTP-Stat"))) {
1118 switch_channel_set_variable(channel, "sip_p_rtp_stat", tmp);
1119 }
1120
1121 tech_pvt->got_bye = 1;
1122 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_bye");
1123
1124 return;
1125 }
1126
sofia_handle_sip_r_message(int status,sofia_profile_t * profile,nua_handle_t * nh,sip_t const * sip)1127 void sofia_handle_sip_r_message(int status, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip)
1128 {
1129 const char *call_id;
1130 int *mstatus;
1131
1132 if (!(sip && sip->sip_call_id)) {
1133 nua_handle_destroy(nh);
1134 return;
1135 }
1136
1137 call_id = sip->sip_call_id->i_id;
1138
1139
1140
1141 switch_mutex_lock(profile->flag_mutex);
1142 mstatus = switch_core_hash_find(profile->chat_hash, call_id);
1143 switch_mutex_unlock(profile->flag_mutex);
1144
1145 if (mstatus) {
1146 *mstatus = status;
1147 }
1148
1149 }
1150
sofia_wait_for_reply(struct private_object * tech_pvt,nua_event_t event,uint32_t timeout)1151 void sofia_wait_for_reply(struct private_object *tech_pvt, nua_event_t event, uint32_t timeout)
1152 {
1153 time_t exp = switch_epoch_time_now(NULL) + timeout;
1154
1155 tech_pvt->want_event = event;
1156
1157 while (switch_channel_ready(tech_pvt->channel) && tech_pvt->want_event && switch_epoch_time_now(NULL) < exp) {
1158 switch_yield(100000);
1159 }
1160
1161 }
1162
sofia_send_callee_id(switch_core_session_t * session,const char * name,const char * number)1163 void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number)
1164 {
1165 const char *uuid;
1166 switch_core_session_t *session_b;
1167 switch_channel_t *channel = switch_core_session_get_channel(session);
1168 switch_caller_profile_t *caller_profile = switch_channel_get_caller_profile(channel);
1169
1170
1171 if (switch_channel_inbound_display(channel)) {
1172 if (zstr(name)) {
1173 name = caller_profile->caller_id_name;
1174 }
1175
1176 if (zstr(number)) {
1177 number = caller_profile->caller_id_number;
1178 }
1179
1180 if (zstr(name)) {
1181 name = number;
1182 }
1183
1184 if (zstr(number)) {
1185 name = number = "UNKNOWN";
1186 }
1187
1188 if (!zstr(name) && !strcmp(name,"_undef_")) {
1189 name = "";
1190 }
1191 } else {
1192 if (zstr(name)) {
1193 name = caller_profile->callee_id_name;
1194 }
1195
1196 if (zstr(number)) {
1197 number = caller_profile->callee_id_number;
1198 }
1199
1200 if (zstr(name)) {
1201 name = number;
1202 }
1203
1204 if (zstr(number)) {
1205 number = caller_profile->destination_number;
1206 }
1207
1208 if (!zstr(name) && !strcmp(name,"_undef_")) {
1209 name = "";
1210 }
1211 }
1212
1213 if ((uuid = switch_channel_get_partner_uuid(channel)) && (session_b = switch_core_session_locate(uuid))) {
1214 switch_core_session_message_t *msg;
1215 //switch_channel_t *channel_b = switch_core_session_get_channel(session_b);
1216
1217 //switch_channel_set_profile_var(channel_b, "callee_id_name", name);
1218 //switch_channel_set_profile_var(channel_b, "callee_id_number", number);
1219
1220 msg = switch_core_session_alloc(session_b, sizeof(*msg));
1221 MESSAGE_STAMP_FFL(msg);
1222 msg->message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
1223 msg->string_array_arg[0] = switch_core_session_strdup(session_b, name);
1224 msg->string_array_arg[1] = switch_core_session_strdup(session_b, number);
1225 msg->from = __FILE__;
1226 switch_core_session_queue_message(session_b, msg);
1227 switch_core_session_rwunlock(session_b);
1228 }
1229 }
1230
sofia_update_callee_id(switch_core_session_t * session,sofia_profile_t * profile,sip_t const * sip,switch_bool_t send)1231 void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip,
1232 switch_bool_t send)
1233 {
1234 switch_channel_t *channel = switch_core_session_get_channel(session);
1235 sip_p_asserted_identity_t *passerted = NULL;
1236 char *name = NULL;
1237 const char *number = "unknown", *tmp;
1238 switch_caller_profile_t *caller_profile;
1239 char *dup = NULL;
1240 switch_event_t *event;
1241 const char *val;
1242 int fs = 0, lazy = 0, att = 0;
1243 const char *name_var = "callee_id_name";
1244 const char *num_var = "callee_id_number";
1245
1246 if (switch_true(switch_channel_get_variable(channel, SWITCH_IGNORE_DISPLAY_UPDATES_VARIABLE)) || !sofia_test_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE)) {
1247 return;
1248 }
1249
1250
1251 if (switch_channel_inbound_display(channel)) {
1252 name_var = "caller_id_name";
1253 num_var = "caller_id_number";
1254 }
1255
1256
1257 number = (char *) switch_channel_get_variable(channel, num_var);
1258 name = (char *) switch_channel_get_variable(channel, name_var);
1259
1260
1261 if (zstr(number) && sip->sip_to) {
1262 number = sip->sip_to->a_url->url_user;
1263 }
1264
1265 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Display-Number"))) {
1266 number = val;
1267 fs++;
1268 }
1269
1270 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Display-Name"))) {
1271 name = (char *) val;
1272 check_decode(name, session);
1273 fs++;
1274 }
1275
1276 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Lazy-Attended-Transfer"))) {
1277 lazy = switch_true(val);
1278 fs++;
1279 }
1280
1281 if ((val = sofia_glue_get_unknown_header(sip, "X-FS-Attended-Transfer"))) {
1282 att = switch_true(val);
1283 fs++;
1284 }
1285
1286 if (!fs) {
1287 sip_remote_party_id_t *rpid;
1288 if ((passerted = sip_p_asserted_identity(sip))) {
1289 if (passerted->paid_url->url_user) {
1290 number = passerted->paid_url->url_user;
1291 }
1292 if (!zstr(passerted->paid_display)) {
1293 dup = strdup(passerted->paid_display);
1294 switch_assert(dup);
1295 if (*dup == '"') {
1296 name = dup + 1;
1297 } else {
1298 name = dup;
1299 }
1300 if (end_of(name) == '"') {
1301 end_of(name) = '\0';
1302 }
1303 }
1304 } else if ((rpid = sip_remote_party_id(sip))) {
1305 if (rpid->rpid_url->url_user) {
1306 number = rpid->rpid_url->url_user;
1307 }
1308 if (!zstr(rpid->rpid_display)) {
1309 dup = strdup(rpid->rpid_display);
1310 switch_assert(dup);
1311 if (*dup == '"') {
1312 name = dup + 1;
1313 } else {
1314 name = dup;
1315 }
1316 if (end_of(name) == '"') {
1317 end_of(name) = '\0';
1318 }
1319 }
1320 }
1321 }
1322
1323
1324 if (zstr(number)) {
1325 if ((tmp = switch_channel_get_variable(channel, num_var)) && !zstr(tmp)) {
1326 number = (char *) tmp;
1327 }
1328
1329 if (zstr(number)) {
1330 number = "unknown";
1331 }
1332 }
1333
1334 if (zstr(name)) {
1335 if ((tmp = switch_channel_get_variable(channel, name_var)) && !zstr(tmp)) {
1336 name = (char *) tmp;
1337 }
1338 }
1339
1340 if (zstr(name)) {
1341 name = (char *) number;
1342 }
1343
1344 if (zstr(name) || zstr(number)) {
1345 goto end;
1346 }
1347
1348 caller_profile = switch_channel_get_caller_profile(channel);
1349
1350 if (switch_channel_inbound_display(channel)) {
1351
1352 if (!strcmp(caller_profile->caller_id_name, name) && !strcmp(caller_profile->caller_id_number, number)) {
1353 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s Same Caller ID \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1354 send = 0;
1355 } else {
1356 caller_profile->caller_id_name = switch_sanitize_number(switch_core_strdup(caller_profile->pool, name));
1357 caller_profile->caller_id_number = switch_sanitize_number(switch_core_strdup(caller_profile->pool, number));
1358 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Update Caller ID to \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1359 }
1360
1361 } else {
1362
1363 if (!strcmp(caller_profile->callee_id_name, name) && !strcmp(caller_profile->callee_id_number, number)) {
1364 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s Same Callee ID \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1365 send = 0;
1366 } else {
1367 caller_profile->callee_id_name = switch_sanitize_number(switch_core_strdup(caller_profile->pool, name));
1368 caller_profile->callee_id_number = switch_sanitize_number(switch_core_strdup(caller_profile->pool, number));
1369 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Update Callee ID to \"%s\" <%s>\n", switch_channel_get_name(channel), name, number);
1370
1371 if (lazy || (att && !switch_channel_get_partner_uuid(channel))) {
1372 switch_channel_flip_cid(channel);
1373 }
1374 }
1375 }
1376
1377 if (send) {
1378
1379 if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) {
1380 const char *uuid = switch_channel_get_partner_uuid(channel);
1381 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "RECV");
1382 if (uuid) {
1383 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
1384 }
1385 switch_channel_event_set_data(channel, event);
1386 switch_event_fire(&event);
1387 }
1388
1389 sofia_send_callee_id(session, NULL, NULL);
1390 }
1391
1392 end:
1393 switch_safe_free(dup);
1394 }
1395
tech_send_ack(nua_handle_t * nh,private_object_t * tech_pvt,const char * r_sdp)1396 static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const char *r_sdp)
1397 {
1398 const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from");
1399 const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to");
1400 int soa = sofia_use_soa(tech_pvt);
1401 const char *session_id_header = sofia_glue_session_id_header(tech_pvt->session, tech_pvt->profile);
1402
1403 if (sofia_test_pflag(tech_pvt->profile, PFLAG_TRACK_CALLS)) {
1404 const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via");
1405 const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri");
1406
1407 nua_ack(nh,
1408 TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
1409 TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
1410 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
1411 TAG_IF((zstr(tech_pvt->user_via) && !zstr(invite_full_via)), SIPTAG_VIA_STR(invite_full_via)),
1412 TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)),
1413 TAG_IF(r_sdp && soa, SOATAG_USER_SDP_STR(r_sdp)),
1414 TAG_IF(r_sdp && soa, SOATAG_REUSE_REJECTED(1)),
1415 TAG_IF(r_sdp && soa, SOATAG_AUDIO_AUX("cn telephone-event")),
1416 TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
1417 TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp)),
1418 TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0)),
1419 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
1420 TAG_END());
1421 } else {
1422 nua_ack(nh,
1423 TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
1424 TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
1425 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
1426 TAG_IF(r_sdp && soa, SOATAG_USER_SDP_STR(r_sdp)),
1427 TAG_IF(r_sdp && soa, SOATAG_REUSE_REJECTED(1)),
1428 TAG_IF(r_sdp && soa, SOATAG_AUDIO_AUX("cn telephone-event")),
1429 TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
1430 TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp)),
1431 TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0)),
1432 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
1433 TAG_END());
1434 }
1435
1436 }
1437
notify_watched_header(switch_core_session_t * session,const char * msgline,const char * hdrname,const char * hdrval)1438 static void notify_watched_header(switch_core_session_t *session, const char *msgline, const char *hdrname, const char *hdrval)
1439 {
1440 switch_event_t *event = NULL;
1441 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Found known watched header in message '%s', %s: %s\n", msgline, hdrname, hdrval);
1442 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_NOTIFY_WATCHED_HEADER) == SWITCH_STATUS_SUCCESS) {
1443 switch_channel_t *channel = switch_core_session_get_channel(session);
1444 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Message", msgline);
1445 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Header-Name", hdrname);
1446 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Header-Value", hdrval);
1447 switch_channel_event_set_data(channel, event);
1448 switch_event_fire(&event);
1449 } else {
1450 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed creating event of type %s!\n", MY_EVENT_NOTIFY_WATCHED_HEADER);
1451 }
1452 }
1453
1454
sofia_handle_sip_r_refer(nua_t * nua,sofia_profile_t * profile,nua_handle_t * nh,switch_core_session_t * session,int status,const char * phrase,sip_t const * sip,sofia_dispatch_event_t * de,tagi_t tags[])1455 static void sofia_handle_sip_r_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, int status, const char *phrase, sip_t const *sip, sofia_dispatch_event_t *de, tagi_t tags[])
1456 {
1457 private_object_t *tech_pvt = switch_core_session_get_private(session);
1458 switch_core_session_t *other_session;
1459 switch_channel_t *channel = switch_core_session_get_channel(session);
1460
1461 switch_channel_set_variable_printf(channel, "sip_refer_status_code", "%d", status);
1462
1463 if (status < 200) {
1464 return;
1465 }
1466
1467 if (tech_pvt->proxy_refer_uuid && (other_session = switch_core_session_locate(tech_pvt->proxy_refer_uuid))) {
1468 switch_core_session_message_t *msg;
1469
1470 msg = switch_core_session_alloc(other_session, sizeof(*msg));
1471 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
1472 msg->from = __FILE__;
1473 msg->numeric_arg = status;
1474 msg->string_arg = switch_core_session_strdup(other_session, phrase);
1475 switch_core_session_queue_message(other_session, msg);
1476 switch_core_session_rwunlock(other_session);
1477 } else {
1478 tech_pvt->proxy_refer_uuid = NULL;
1479 }
1480 }
1481
1482
1483
1484
1485 //sofia_dispatch_event_t *de
our_sofia_event_callback(nua_event_t event,int status,char const * phrase,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[])1486 static void our_sofia_event_callback(nua_event_t event,
1487 int status,
1488 char const *phrase,
1489 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
1490 sofia_dispatch_event_t *de, tagi_t tags[])
1491 {
1492 struct private_object *tech_pvt = NULL;
1493 auth_res_t auth_res = AUTH_FORBIDDEN;
1494 switch_core_session_t *session = NULL;
1495 switch_channel_t *channel = NULL;
1496 sofia_gateway_t *gateway = NULL;
1497 int locked = 0;
1498 int check_destroy = 1;
1499
1500 profile->last_sip_event = switch_time_now();
1501
1502 /* sofia_private will be == &mod_sofia_globals.keep_private whenever a request is done with a new handle that has to be
1503 freed whenever the request is done */
1504 if (nh && sofia_private == &mod_sofia_globals.keep_private) {
1505 if (status >= 300) {
1506 nua_handle_bind(nh, NULL);
1507 nua_handle_destroy(nh);
1508 return;
1509 }
1510 }
1511
1512
1513 if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
1514 if (!zstr(sofia_private->gateway_name)) {
1515 if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) {
1516 return;
1517 }
1518 } else if (!zstr(sofia_private->uuid)) {
1519 if ((session = de->init_session)) {
1520 de->init_session = NULL;
1521 } else if ((session = de->session) || (session = switch_core_session_locate(sofia_private->uuid))) {
1522 tech_pvt = switch_core_session_get_private(session);
1523 channel = switch_core_session_get_channel(session);
1524 if (tech_pvt) {
1525 switch_mutex_lock(tech_pvt->sofia_mutex);
1526 locked = 1;
1527 } else {
1528 if (session != de->session) switch_core_session_rwunlock(session);
1529 return;
1530 }
1531
1532 if (status >= 180 && !*sofia_private->auth_gateway_name) {
1533 const char *gwname = switch_channel_get_variable(channel, "sip_use_gateway");
1534 if (!zstr(gwname)) {
1535 switch_set_string(sofia_private->auth_gateway_name, gwname);
1536 }
1537 }
1538 if (!tech_pvt->call_id && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
1539 tech_pvt->call_id = switch_core_session_strdup(session, sip->sip_call_id->i_id);
1540 switch_channel_set_variable(channel, "sip_call_id", tech_pvt->call_id);
1541 }
1542
1543 if (tech_pvt->gateway_name) {
1544 gateway = sofia_reg_find_gateway(tech_pvt->gateway_name);
1545 }
1546
1547 if (channel && switch_channel_down(channel)) {
1548 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is already hungup.\n");
1549 goto done;
1550 }
1551 } else {
1552 /* we can't find the session it must be hanging up or something else, its too late to do anything with it. */
1553 return;
1554 }
1555 }
1556 }
1557
1558 if (session && tech_pvt && tech_pvt->watch_headers && sip) {
1559 char msgline[512];
1560 int hi;
1561 msg_header_t *h = NULL;
1562 if (sip->sip_request) {
1563 h = (msg_header_t *)sip->sip_request;
1564 msg_header_field_e(msgline, sizeof(msgline), h, 0);
1565 } else if (sip->sip_status) {
1566 h = (msg_header_t *)sip->sip_status;
1567 msg_header_field_e(msgline, sizeof(msgline), h, 0);
1568 }
1569 if (h) {
1570 sip_unknown_t *un = NULL;
1571 char buf[512];
1572 char *c = NULL;
1573
1574 msgline[sizeof(msgline)-1] = '\0';
1575 c = strchr(msgline, '\r');
1576 if (c) {
1577 *c = '\0';
1578 }
1579
1580 /* Faster (ie hash-based) search here would be nice? ie, make watch_headers a hash? */
1581
1582 /* Search first in the valid headers */
1583 for (h = h->sh_succ; h; h = h->sh_succ) {
1584 sip_header_t *sh = (sip_header_t *)h;
1585 if (!sh->sh_class->hc_name) {
1586 continue;
1587 }
1588 for (hi = 0; tech_pvt->watch_headers[hi]; hi++) {
1589 if (!strcasecmp(tech_pvt->watch_headers[hi], sh->sh_class->hc_name)) {
1590 msg_header_field_e(buf, sizeof(buf), h, 0);
1591 buf[sizeof(buf)-1] = '\0';
1592 notify_watched_header(session, msgline, sh->sh_class->hc_name, buf);
1593 }
1594 }
1595 }
1596
1597 /* Search now in the unknown headers */
1598 for (un = sip->sip_unknown; un; un = un->un_next) {
1599 for (hi = 0; tech_pvt->watch_headers[hi]; hi++) {
1600 if (!strcasecmp(tech_pvt->watch_headers[hi], un->un_name)) {
1601 notify_watched_header(session, msgline, un->un_name, un->un_value);
1602 }
1603 }
1604 }
1605 }
1606 }
1607
1608 if (sofia_test_pflag(profile, PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip && (event < nua_r_set_params || event > nua_r_authenticate)) {
1609 sip_authorization_t const *authorization = NULL;
1610
1611 if (sip->sip_authorization) {
1612 authorization = sip->sip_authorization;
1613 } else if (sip->sip_proxy_authorization) {
1614 authorization = sip->sip_proxy_authorization;
1615 }
1616
1617 if (authorization) {
1618 char network_ip[80];
1619 int network_port;
1620 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
1621 auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
1622 (char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, network_port, NULL, 0,
1623 REG_INVITE, NULL, NULL, NULL, NULL);
1624 }
1625
1626 if ((auth_res != AUTH_OK && auth_res != AUTH_RENEWED)) {
1627 //switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
1628 nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_END());
1629 goto done;
1630 }
1631
1632 if (channel) {
1633 switch_channel_set_variable(channel, "sip_authorized", "true");
1634 }
1635 }
1636
1637 if (sip && (status == 401 || status == 407)) {
1638 sofia_reg_handle_sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, session, gateway, sip, de, tags);
1639 goto done;
1640 }
1641
1642 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
1643 if (sip->sip_payload->pl_len != strlen(sip->sip_payload->pl_data)) {
1644 sip->sip_payload->pl_data = su_strndup(nh->nh_home, sip->sip_payload->pl_data, sip->sip_payload->pl_len);
1645 }
1646 }
1647
1648 switch (event) {
1649 case nua_r_get_params:
1650 case nua_i_fork:
1651 case nua_r_info:
1652 break;
1653 case nua_r_unregister:
1654 case nua_r_unsubscribe:
1655 case nua_i_terminated:
1656 case nua_r_publish:
1657 case nua_i_error:
1658 case nua_i_active:
1659 case nua_r_set_params:
1660 case nua_i_prack:
1661 case nua_r_prack:
1662 break;
1663
1664 case nua_i_cancel:
1665
1666 if (sip && channel) {
1667 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_cancel");
1668 switch_channel_set_variable(channel, "sip_invite_failure_status", "487");
1669 switch_channel_set_variable(channel, "sip_invite_failure_phrase", "CANCEL");
1670
1671 if (sip->sip_reason) {
1672 char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason);
1673
1674 if (!zstr(reason_header)) {
1675 switch_channel_set_variable(channel, "sip_reason", reason_header);
1676 switch_channel_set_variable_partner(channel, "sip_reason", reason_header);
1677 }
1678 }
1679 }
1680
1681 break;
1682 case nua_r_cancel:
1683 {
1684 if (status > 299 && nh) {
1685 nua_handle_destroy(nh);
1686 }
1687 }
1688 break;
1689 case nua_i_ack:
1690 {
1691 if (channel && sip) {
1692 const char *r_sdp = NULL;
1693 sofia_glue_store_session_id(session, profile, sip, 0);
1694
1695 if (sip->sip_payload && sip->sip_payload->pl_data) {
1696 if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) {
1697 r_sdp = sip->sip_payload->pl_data;
1698
1699 if (tech_pvt->mparams.last_sdp_str) {
1700 tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
1701 }
1702 tech_pvt->mparams.last_sdp_str = NULL;
1703
1704
1705 if (!zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) {
1706 switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data);
1707 tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
1708 } else {
1709 tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str;
1710 }
1711 } else {
1712 switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data);
1713 tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
1714 }
1715 }
1716
1717 if (sip->sip_to && sip->sip_to->a_tag) {
1718 switch_channel_set_variable(channel, "sip_to_tag", sip->sip_to->a_tag);
1719 }
1720
1721 if (sip->sip_from && sip->sip_from->a_tag) {
1722 switch_channel_set_variable(channel, "sip_from_tag", sip->sip_from->a_tag);
1723 }
1724
1725 if (sip->sip_cseq && sip->sip_cseq->cs_seq) {
1726 char sip_cseq[40] = "";
1727 switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq);
1728 switch_channel_set_variable(channel, "sip_cseq", sip_cseq);
1729 }
1730
1731 if (sip->sip_call_id && sip->sip_call_id->i_id) {
1732 switch_channel_set_variable(channel, "sip_call_id", sip->sip_call_id->i_id);
1733 }
1734
1735 extract_header_vars(profile, sip, session, nh);
1736 switch_core_recovery_track(session);
1737 sofia_set_flag(tech_pvt, TFLAG_GOT_ACK);
1738
1739 if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) && r_sdp) {
1740 if (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY)) {
1741 switch_channel_set_variable_partner(tech_pvt->channel, SWITCH_B_SDP_VARIABLE, r_sdp);
1742
1743 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
1744 sofia_media_activate_rtp(tech_pvt);
1745 switch_core_media_proxy_remote_addr(tech_pvt->session, r_sdp);
1746 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK);
1747 sofia_clear_flag(tech_pvt, TFLAG_PASS_ACK);
1748
1749 }
1750
1751 }
1752
1753
1754 if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) {
1755 switch_core_session_t *other_session;
1756
1757 sofia_clear_flag(tech_pvt, TFLAG_PASS_ACK);
1758
1759 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
1760 if (switch_core_session_compare(session, other_session)) {
1761 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
1762 tech_send_ack(other_tech_pvt->nh, other_tech_pvt, r_sdp);
1763 }
1764 switch_core_session_rwunlock(other_session);
1765 }
1766
1767 }
1768
1769
1770 }
1771 }
1772 case nua_r_ack:
1773 if (channel)
1774 switch_channel_set_flag(channel, CF_MEDIA_ACK);
1775 break;
1776 case nua_r_shutdown:
1777 if (status >= 200) {
1778 sofia_set_pflag(profile, PFLAG_SHUTDOWN);
1779 su_root_break(profile->s_root);
1780 }
1781 break;
1782 case nua_r_message:
1783 sofia_handle_sip_r_message(status, profile, nh, sip);
1784 break;
1785 case nua_r_invite:
1786 sofia_handle_sip_r_invite(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1787 break;
1788 case nua_r_options:
1789 sofia_handle_sip_r_options(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1790 break;
1791 case nua_i_bye:
1792 sofia_handle_sip_i_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1793 break;
1794 case nua_r_bye:
1795 sofia_handle_sip_r_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1796 break;
1797 case nua_r_notify:
1798 if (session) {
1799 sofia_handle_sip_r_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1800 }
1801 break;
1802 case nua_i_notify:
1803 sofia_handle_sip_i_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1804 break;
1805 case nua_r_register:
1806 sofia_reg_handle_sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1807 break;
1808 case nua_i_options:
1809 sofia_handle_sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1810 break;
1811 case nua_i_invite:
1812 if (session && sofia_private) {
1813 if (sofia_private->is_call > 1) {
1814 sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, de, tags);
1815 } else {
1816 sofia_private->is_call++;
1817 sofia_handle_sip_i_invite(session, nua, profile, nh, sofia_private, sip, de, tags);
1818 }
1819 }
1820 break;
1821 case nua_i_publish:
1822 sofia_presence_handle_sip_i_publish(nua, profile, nh, sofia_private, sip, de, tags);
1823 break;
1824 case nua_i_register:
1825 //nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
1826 //nua_handle_destroy(nh);
1827 sofia_reg_handle_sip_i_register(nua, profile, nh, &sofia_private, sip, de, tags);
1828 break;
1829 case nua_i_state:
1830 sofia_handle_sip_i_state(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
1831 break;
1832 case nua_i_message:
1833 {
1834 int handle_message = 1;
1835 int proxy_message = sofia_test_pflag(profile, PFLAG_PROXY_MESSAGE);
1836
1837 if (!proxy_message && session) {
1838 switch_channel_t *channel = switch_core_session_get_channel(session);
1839 proxy_message = switch_channel_var_true(channel, "sip_proxy_message");
1840 }
1841
1842 if (proxy_message) {
1843 if (sofia_proxy_sip_i_message(nua, profile, nh, session, sip, de, tags) == SWITCH_STATUS_SUCCESS) {
1844 handle_message = 0;
1845 }
1846 }
1847
1848 if (handle_message) {
1849 sofia_presence_handle_sip_i_message(status, phrase, nua, profile, nh, session, sofia_private, sip, de, tags);
1850 }
1851 }
1852 break;
1853 case nua_i_info:
1854 {
1855 int handle_info = 1;
1856 int proxy_info = sofia_test_pflag(profile, PFLAG_PROXY_INFO);
1857
1858 if (!proxy_info && session) {
1859 switch_channel_t *channel = switch_core_session_get_channel(session);
1860 proxy_info = switch_channel_var_true(channel, "sip_proxy_info");
1861 }
1862
1863 if (proxy_info) {
1864 if (sofia_proxy_sip_i_info(nua, profile, nh, session, sip, de, tags) == SWITCH_STATUS_SUCCESS) {
1865 handle_info = 0;
1866 }
1867 }
1868
1869 if (handle_info) {
1870 sofia_handle_sip_i_info(nua, profile, nh, session, sip, de, tags);
1871 }
1872
1873 }
1874 break;
1875 case nua_i_update:
1876 if (session) {
1877 sofia_update_callee_id(session, profile, sip, SWITCH_TRUE);
1878 }
1879 break;
1880 case nua_r_update:
1881 if (session && tech_pvt && locked) {
1882 sofia_clear_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
1883 }
1884 break;
1885 case nua_r_refer:
1886 if (session) {
1887 sofia_handle_sip_r_refer(nua, profile, nh, session, status, phrase, sip, de, tags);
1888 }
1889 break;
1890 case nua_i_refer:
1891 if (session) {
1892 sofia_handle_sip_i_refer(nua, profile, nh, session, sip, de, tags);
1893 } else if (sip) {
1894 const char *req_user = NULL, *req_host = NULL, *action = NULL, *ref_by_user = NULL, *ref_to_user = NULL, *ref_to_host = NULL;
1895 char *refer_to = NULL, *referred_by = NULL, *method = NULL, *full_url = NULL;
1896 char *params = NULL, *iparams = NULL;
1897 switch_event_t *event;
1898 char *tmp;
1899
1900 if (sip->sip_refer_to) {
1901 ref_to_user = sip->sip_refer_to->r_url->url_user;
1902 ref_to_host = sip->sip_refer_to->r_url->url_host;
1903
1904 if (sip->sip_refer_to->r_url->url_params && switch_stristr("method=", sip->sip_refer_to->r_url->url_params)) {
1905 params = su_strdup(nua_handle_home(nh), sip->sip_refer_to->r_url->url_params);
1906 }
1907
1908
1909 if ((refer_to = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_refer_to))) {
1910 if ((iparams = strchr(refer_to, ';'))) {
1911 *iparams++ = '\0';
1912
1913 if (!params || !switch_stristr("method=", params)) {
1914 params = iparams;
1915 }
1916 }
1917
1918 if ((tmp = sofia_glue_get_url_from_contact(refer_to, 0))) {
1919 refer_to = tmp;
1920 }
1921 }
1922
1923 if (params) {
1924 method = switch_find_parameter(params, "method", NULL);
1925 full_url = switch_find_parameter(params, "full_url", NULL);
1926 }
1927
1928
1929 }
1930
1931 if (!method) {
1932 method = strdup("INVITE");
1933 switch_assert(method);
1934 }
1935
1936 if (!strcasecmp(method, "INVITE")) {
1937 action = "call";
1938 } else if (!strcasecmp(method, "BYE")) {
1939 action = "end";
1940 } else {
1941 action = method;
1942 }
1943
1944 if (sip->sip_referred_by) {
1945 referred_by = sofia_glue_get_url_from_contact(sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_referred_by), 0);
1946 ref_by_user = sip->sip_referred_by->b_url->url_user;
1947 } else if(sip->sip_to){
1948 referred_by = sofia_glue_get_url_from_contact(sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_to), 0);
1949 ref_by_user = sip->sip_to->a_url->url_user;
1950 }
1951
1952 if (sip->sip_to) {
1953 req_user = sip->sip_to->a_url->url_user;
1954 req_host = sip->sip_to->a_url->url_host;
1955 }
1956
1957 if (switch_event_create(&event, SWITCH_EVENT_CALL_SETUP_REQ) == SWITCH_STATUS_SUCCESS) {
1958 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Requesting-Component", "mod_sofia");
1959 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Component", req_user);
1960 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Domain", req_host);
1961 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Action", action);
1962 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Target", "sofia/%s/%s", profile->name, refer_to);
1963 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Target-URI", "%s", refer_to);
1964 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Target-Extension", ref_to_user);
1965 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Target-Domain", ref_to_host);
1966 if (switch_true(full_url)) {
1967 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "full_url", "true");
1968 }
1969
1970 if (sip->sip_call_id && sip->sip_call_id->i_id) {
1971 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Call-ID", sip->sip_call_id->i_id);
1972 }
1973
1974 if (!zstr(referred_by)) {
1975 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Sender", "sofia/%s/%s", profile->name, referred_by);
1976 }
1977
1978 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_number", ref_by_user);
1979 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_name", ref_by_user);
1980 switch_event_fire(&event);
1981 }
1982
1983
1984
1985 {
1986 char *sql;
1987 sofia_nat_parse_t np = { { 0 } };
1988 char *contact_str;
1989 char *proto = "sip", *orig_proto = "sip";
1990 const char *call_id, *full_from, *full_to, *full_via, *from_user = NULL, *from_host = NULL, *to_user, *to_host, *full_agent;
1991 char to_tag[13] = "";
1992 char *event_str = "refer";
1993 sip_accept_t *ap = sip->sip_accept;
1994 char accept_header[256] = "";
1995
1996 np.fs_path = 1;
1997 contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, &np);
1998
1999 call_id = sip->sip_call_id ? sip->sip_call_id->i_id : "";
2000 full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from);
2001 full_to = sip_header_as_string(nh->nh_home, (void *) sip->sip_to);
2002 full_via = sip_header_as_string(nh->nh_home, (void *) sip->sip_via);
2003
2004 full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent);
2005
2006 switch_stun_random_string(to_tag, 12, NULL);
2007
2008 if (sip->sip_from) {
2009 from_user = sip->sip_from->a_url->url_user;
2010 from_host = sip->sip_from->a_url->url_host;
2011 } else {
2012 from_user = "n/a";
2013 from_host = "n/a";
2014 }
2015
2016 if (sip->sip_to) {
2017 to_user = sip->sip_to->a_url->url_user;
2018 to_host = sip->sip_to->a_url->url_host;
2019 } else {
2020 to_user = "n/a";
2021 to_host = "n/a";
2022 }
2023
2024 while (ap) {
2025 switch_snprintf(accept_header + strlen(accept_header), sizeof(accept_header) - strlen(accept_header),
2026 "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
2027 ap = ap->ac_next;
2028 }
2029
2030 sql = switch_mprintf("insert into sip_subscriptions "
2031 "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
2032 "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip,version,orig_proto, full_to) "
2033 "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q',-1,'%q','%q;tag=%q')",
2034 proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : "",
2035 event_str, contact_str, call_id, full_from, full_via,
2036 (long) switch_epoch_time_now(NULL) + 60,
2037 full_agent, accept_header, profile->name, mod_sofia_globals.hostname,
2038 np.network_port, np.network_ip, orig_proto, full_to, to_tag);
2039
2040 switch_assert(sql != NULL);
2041
2042
2043 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
2044 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s REFER SUBSCRIBE %s@%s %s@%s\n%s\n",
2045 profile->name, from_user, from_host, to_user, to_host, sql);
2046 }
2047
2048
2049 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
2050
2051 sip_to_tag(nh->nh_home, sip->sip_to, to_tag);
2052 }
2053
2054 nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_TO(sip->sip_to), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
2055 switch_safe_free(method);
2056 switch_safe_free(full_url);
2057
2058 }
2059 break;
2060 case nua_r_subscribe:
2061 sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
2062 break;
2063 case nua_i_subscribe:
2064 sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
2065 break;
2066 case nua_i_media_error:
2067 {
2068
2069 if (sofia_private && sofia_private->call_id && sofia_private->network_ip && sofia_private->network_port) {
2070 char *sql;
2071 switch_event_t *event = NULL;
2072
2073 sql = switch_mprintf("delete from sip_registrations where call_id='%q' and network_ip='%q' and network_port='%q'",
2074 sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
2075 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "SOCKET DISCONNECT: %s %s:%s\n",
2076 sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
2077 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2078
2079 switch_core_del_registration(sofia_private->user, sofia_private->realm, sofia_private->call_id);
2080
2081
2082
2083 if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
2084 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
2085 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
2086 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
2087 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent",
2088 (sip && sip->sip_user_agent) ? sip->sip_user_agent->g_string : "unknown");
2089 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", sofia_private->user, sofia_private->realm);
2090 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Unregistered");
2091 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-source", "register");
2092 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
2093 switch_event_fire(&event);
2094 }
2095
2096
2097 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) {
2098 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
2099 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from-user", sofia_private->user);
2100 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from-host", sofia_private->realm);
2101 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-id", sofia_private->call_id);
2102 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
2103 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "reason", "socket-disconnection");
2104 switch_event_fire(&event);
2105 }
2106
2107
2108 sofia_reg_check_socket(profile, sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port);
2109 nua_handle_destroy(nh);
2110 }
2111 }
2112 break;
2113 case nua_r_authenticate:
2114
2115 if (status >= 500) {
2116 if (sofia_private && !zstr(sofia_private->gateway_name)) {
2117 sofia_gateway_t *gateway = NULL;
2118
2119 if ((gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) {
2120 gateway->state = REG_STATE_FAILED;
2121 gateway->failure_status = status;
2122 sofia_reg_release_gateway(gateway);
2123 }
2124 } else {
2125 nua_handle_destroy(nh);
2126 }
2127 }
2128
2129 break;
2130 default:
2131 if (status > 100) {
2132 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s: unknown event %d: %03d %s\n", nua_event_name(event), event,
2133 status, phrase);
2134 } else {
2135 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s: unknown event %d\n", nua_event_name(event), event);
2136 }
2137 break;
2138 }
2139
2140 done:
2141
2142 if (tech_pvt && tech_pvt->want_event && event == tech_pvt->want_event) {
2143 tech_pvt->want_event = 0;
2144 }
2145
2146 if (sofia_private && sofia_private->call_id) {
2147 check_destroy = 0;
2148 }
2149
2150 switch (event) {
2151 case nua_i_subscribe:
2152 case nua_r_notify:
2153 check_destroy = 0;
2154 break;
2155
2156 case nua_i_notify:
2157
2158 if (sip && sip->sip_event && !strcmp(sip->sip_event->o_type, "dialog") && sip->sip_event->o_params && !strcmp(sip->sip_event->o_params[0], "sla")) {
2159 check_destroy = 0;
2160 }
2161
2162 break;
2163 default:
2164 break;
2165 }
2166
2167 if ((sofia_private && sofia_private == &mod_sofia_globals.destroy_private)) {
2168 nua_handle_bind(nh, NULL);
2169 nua_handle_destroy(nh);
2170 nh = NULL;
2171 }
2172
2173 if (check_destroy) {
2174 if (nh && ((sofia_private && sofia_private->destroy_nh) || !nua_handle_magic(nh))) {
2175 if (sofia_private) {
2176 nua_handle_bind(nh, NULL);
2177 }
2178
2179 if (tech_pvt && (tech_pvt->nh == nh)) {
2180 tech_pvt->nh = NULL;
2181 }
2182
2183 nua_handle_destroy(nh);
2184 nh = NULL;
2185 }
2186 }
2187
2188 if (sofia_private && sofia_private->destroy_me) {
2189 if (tech_pvt) {
2190 tech_pvt->sofia_private = NULL;
2191 }
2192
2193 if (nh) {
2194 nua_handle_bind(nh, NULL);
2195 }
2196 sofia_private->destroy_me = 12;
2197 sofia_private_free(sofia_private);
2198
2199 }
2200
2201 if (gateway) {
2202 sofia_reg_release_gateway(gateway);
2203 }
2204
2205 if (locked && tech_pvt) {
2206 switch_mutex_unlock(tech_pvt->sofia_mutex);
2207 }
2208
2209 if (session && session != de->session) {
2210 switch_core_session_rwunlock(session);
2211 }
2212 }
2213
2214 static uint32_t DE_THREAD_CNT = 0;
2215
sofia_msg_thread_run_once(switch_thread_t * thread,void * obj)2216 void *SWITCH_THREAD_FUNC sofia_msg_thread_run_once(switch_thread_t *thread, void *obj)
2217 {
2218 sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) obj;
2219 switch_memory_pool_t *pool = NULL;
2220
2221 switch_mutex_lock(mod_sofia_globals.mutex);
2222 DE_THREAD_CNT++;
2223 switch_mutex_unlock(mod_sofia_globals.mutex);
2224
2225 if (de) {
2226 pool = de->pool;
2227 de->pool = NULL;
2228 sofia_process_dispatch_event(&de);
2229 }
2230
2231 if (pool) {
2232 switch_core_destroy_memory_pool(&pool);
2233 }
2234
2235 switch_mutex_lock(mod_sofia_globals.mutex);
2236 DE_THREAD_CNT--;
2237 switch_mutex_unlock(mod_sofia_globals.mutex);
2238
2239 return NULL;
2240 }
2241
sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t ** dep)2242 void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep)
2243 {
2244 sofia_dispatch_event_t *de = *dep;
2245 switch_memory_pool_t *pool;
2246 //sofia_profile_t *profile = (*dep)->profile;
2247 switch_thread_data_t *td;
2248
2249 switch_core_new_memory_pool(&pool);
2250
2251 *dep = NULL;
2252 de->pool = pool;
2253
2254 td = switch_core_alloc(pool, sizeof(*td));
2255 td->func = sofia_msg_thread_run_once;
2256 td->obj = de;
2257
2258 switch_thread_pool_launch_thread(&td);
2259 }
2260
sofia_process_dispatch_event(sofia_dispatch_event_t ** dep)2261 void sofia_process_dispatch_event(sofia_dispatch_event_t **dep)
2262 {
2263 sofia_dispatch_event_t *de = *dep;
2264 nua_handle_t *nh = de->nh;
2265 nua_t *nua = de->nua;
2266 sofia_profile_t *profile = de->profile;
2267 sofia_private_t *sofia_private = nua_handle_magic(de->nh);
2268 *dep = NULL;
2269
2270 our_sofia_event_callback(de->data->e_event, de->data->e_status, de->data->e_phrase, de->nua, de->profile,
2271 de->nh, sofia_private, de->sip, de, (tagi_t *) de->data->e_tags);
2272
2273 nua_destroy_event(de->event);
2274 su_free(nh->nh_home, de);
2275
2276 switch_mutex_lock(profile->flag_mutex);
2277 profile->queued_events--;
2278 switch_mutex_unlock(profile->flag_mutex);
2279
2280 nua_handle_unref(nh);
2281 nua_stack_unref(nua);
2282 }
2283
2284
2285
2286 static int msg_queue_threads = 0;
2287 //static int count = 0;
2288
sofia_msg_thread_run(switch_thread_t * thread,void * obj)2289 void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj)
2290 {
2291 void *pop;
2292 switch_queue_t *q = (switch_queue_t *) obj;
2293 int my_id;
2294
2295
2296 for (my_id = 0; my_id < mod_sofia_globals.msg_queue_len; my_id++) {
2297 if (mod_sofia_globals.msg_queue_thread[my_id] == thread) {
2298 break;
2299 }
2300 }
2301
2302 switch_mutex_lock(mod_sofia_globals.mutex);
2303 msg_queue_threads++;
2304 switch_mutex_unlock(mod_sofia_globals.mutex);
2305
2306 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MSG Thread %d Started\n", my_id);
2307
2308
2309 for(;;) {
2310
2311 if (switch_queue_pop(q, &pop) != SWITCH_STATUS_SUCCESS) {
2312 switch_cond_next();
2313 continue;
2314 }
2315
2316 if (pop) {
2317 sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop;
2318 sofia_process_dispatch_event(&de);
2319 } else {
2320 break;
2321 }
2322 }
2323
2324 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MSG Thread Ended\n");
2325
2326 switch_mutex_lock(mod_sofia_globals.mutex);
2327 msg_queue_threads--;
2328 switch_mutex_unlock(mod_sofia_globals.mutex);
2329
2330 return NULL;
2331 }
2332
sofia_msg_thread_start(int idx)2333 void sofia_msg_thread_start(int idx)
2334 {
2335
2336 if (idx >= mod_sofia_globals.max_msg_queues ||
2337 idx >= SOFIA_MAX_MSG_QUEUE || (idx < mod_sofia_globals.msg_queue_len && mod_sofia_globals.msg_queue_thread[idx])) {
2338 return;
2339 }
2340
2341 switch_mutex_lock(mod_sofia_globals.mutex);
2342
2343 if (idx >= mod_sofia_globals.msg_queue_len) {
2344 int i;
2345 mod_sofia_globals.msg_queue_len = idx + 1;
2346
2347 for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) {
2348 if (!mod_sofia_globals.msg_queue_thread[i]) {
2349 switch_threadattr_t *thd_attr = NULL;
2350
2351 switch_threadattr_create(&thd_attr, mod_sofia_globals.pool);
2352 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
2353 //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
2354 switch_thread_create(&mod_sofia_globals.msg_queue_thread[i],
2355 thd_attr,
2356 sofia_msg_thread_run,
2357 mod_sofia_globals.msg_queue,
2358 mod_sofia_globals.pool);
2359 }
2360 }
2361 }
2362
2363 switch_mutex_unlock(mod_sofia_globals.mutex);
2364 }
2365
2366 //static int foo = 0;
sofia_queue_message(sofia_dispatch_event_t * de)2367 void sofia_queue_message(sofia_dispatch_event_t *de)
2368 {
2369 int launch = 0;
2370
2371 if (mod_sofia_globals.running == 0 || !mod_sofia_globals.msg_queue) {
2372 sofia_process_dispatch_event(&de);
2373 return;
2374 }
2375
2376
2377 if (de->profile && sofia_test_pflag(de->profile, PFLAG_THREAD_PER_REG) &&
2378 de->data->e_event == nua_i_register && DE_THREAD_CNT < mod_sofia_globals.max_reg_threads) {
2379 sofia_process_dispatch_event_in_thread(&de);
2380 return;
2381 }
2382
2383
2384 if ((switch_queue_size(mod_sofia_globals.msg_queue) > (SOFIA_MSG_QUEUE_SIZE * (unsigned int)msg_queue_threads))) {
2385 launch++;
2386 }
2387
2388
2389 if (launch) {
2390 if (mod_sofia_globals.msg_queue_len < mod_sofia_globals.max_msg_queues) {
2391 sofia_msg_thread_start(mod_sofia_globals.msg_queue_len + 1);
2392 }
2393 }
2394
2395 switch_queue_push(mod_sofia_globals.msg_queue, de);
2396 }
2397
set_call_id(private_object_t * tech_pvt,sip_t const * sip)2398 static void set_call_id(private_object_t *tech_pvt, sip_t const *sip)
2399 {
2400 if (!tech_pvt->call_id && tech_pvt->session && tech_pvt->channel && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
2401 tech_pvt->call_id = switch_core_session_strdup(tech_pvt->session, sip->sip_call_id->i_id);
2402 switch_channel_set_variable(tech_pvt->channel, "sip_call_id", tech_pvt->call_id);
2403 }
2404 }
2405
2406
sofia_event_callback(nua_event_t event,int status,char const * phrase,nua_t * nua,sofia_profile_t * profile,nua_handle_t * nh,sofia_private_t * sofia_private,sip_t const * sip,tagi_t tags[])2407 void sofia_event_callback(nua_event_t event,
2408 int status,
2409 char const *phrase,
2410 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
2411 tagi_t tags[])
2412 {
2413 sofia_dispatch_event_t *de;
2414 int critical = (((SOFIA_MSG_QUEUE_SIZE * mod_sofia_globals.max_msg_queues) * 900) / 1000);
2415 uint32_t sess_count = switch_core_session_count();
2416 uint32_t sess_max = switch_core_session_limit(0);
2417
2418 switch(event) {
2419 case nua_i_terminated:
2420 if ((status == 401 || status == 407 || status == 403) && sofia_private) {
2421 switch_core_session_t *session;
2422
2423 if ((session = switch_core_session_locate(sofia_private->uuid))) {
2424 switch_channel_t *channel = switch_core_session_get_channel(session);
2425 int end = 0;
2426
2427 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_ANSWERED)) {
2428 private_object_t *tech_pvt = switch_core_session_get_private(session);
2429
2430 if (status == 403) {
2431 switch_channel_set_flag(channel, CF_NO_CDR);
2432 switch_channel_hangup(channel, SWITCH_CAUSE_CALL_REJECTED);
2433 } else {
2434 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid);
2435
2436 if (!zstr(tech_pvt->call_id)) {
2437 tech_pvt->sofia_private = NULL;
2438 tech_pvt->nh = NULL;
2439 sofia_set_flag(tech_pvt, TFLAG_BYE);
2440 switch_mutex_lock(profile->flag_mutex);
2441 switch_core_hash_insert_auto_free(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session)));
2442 switch_mutex_unlock(profile->flag_mutex);
2443 nua_handle_destroy(nh);
2444 } else {
2445 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
2446 }
2447 }
2448 end++;
2449 }
2450
2451 switch_core_session_rwunlock(session);
2452
2453 if (end) {
2454 goto end;
2455 }
2456 }
2457 }
2458 break;
2459 case nua_i_invite:
2460 case nua_i_register:
2461 case nua_i_options:
2462 case nua_i_notify:
2463 case nua_i_info:
2464
2465
2466 if (event == nua_i_invite) {
2467 if (sip->sip_session_expires && profile->minimum_session_expires) {
2468 if (sip->sip_session_expires->x_delta < profile->minimum_session_expires) {
2469 char buf[64] = "";
2470 switch_snprintf(buf, sizeof(buf), "Min-SE: %d", profile->minimum_session_expires);
2471 nua_respond(nh, SIP_422_SESSION_TIMER_TOO_SMALL, SIPTAG_HEADER_STR(buf),TAG_END());
2472 goto end;
2473 }
2474 }
2475 }
2476
2477 if (!sofia_private) {
2478 if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready_inbound()) {
2479 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), NUTAG_WITH_THIS(nua), TAG_END());
2480 goto end;
2481 }
2482
2483
2484 if (switch_queue_size(mod_sofia_globals.msg_queue) > (unsigned int)critical) {
2485 nua_respond(nh, 503, "System Busy", SIPTAG_RETRY_AFTER_STR("300"), NUTAG_WITH_THIS(nua), TAG_END());
2486 goto end;
2487 }
2488
2489 if (sofia_test_pflag(profile, PFLAG_STANDBY)) {
2490 nua_respond(nh, 503, "System Paused", NUTAG_WITH_THIS(nua), TAG_END());
2491 goto end;
2492 }
2493 }
2494
2495 break;
2496
2497 default:
2498 break;
2499
2500 }
2501
2502 switch_mutex_lock(profile->flag_mutex);
2503 profile->queued_events++;
2504 switch_mutex_unlock(profile->flag_mutex);
2505
2506 de = su_alloc(nh->nh_home, sizeof(*de));
2507 memset(de, 0, sizeof(*de));
2508 nua_save_event(nua, de->event);
2509 de->nh = nua_handle_ref(nh);
2510 de->data = nua_event_data(de->event);
2511 de->sip = sip_object(de->data->e_msg);
2512 de->profile = profile;
2513 de->nua = nua_stack_ref(nua);
2514
2515 if (event == nua_i_invite && !sofia_private) {
2516 switch_core_session_t *session;
2517 private_object_t *tech_pvt = NULL;
2518
2519 if (!(sofia_private = su_alloc(nh->nh_home, sizeof(*sofia_private)))) {
2520 abort();
2521 }
2522
2523 memset(sofia_private, 0, sizeof(*sofia_private));
2524 sofia_private->is_call++;
2525 sofia_private->is_static++;
2526 nua_handle_bind(nh, sofia_private);
2527
2528
2529 if (sip->sip_call_id && sip->sip_call_id->i_id) {
2530 char *uuid = NULL, *tmp;
2531
2532 switch_mutex_lock(profile->flag_mutex);
2533 if ((tmp = (char *) switch_core_hash_find(profile->chat_hash, sip->sip_call_id->i_id))) {
2534 uuid = strdup(tmp);
2535 switch_core_hash_delete(profile->chat_hash, sip->sip_call_id->i_id);
2536 }
2537 switch_mutex_unlock(profile->flag_mutex);
2538
2539 if (uuid) {
2540 if ((session = switch_core_session_locate(uuid))) {
2541 tech_pvt = switch_core_session_get_private(session);
2542 switch_copy_string(sofia_private->uuid_str, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid_str));
2543 sofia_private->uuid = sofia_private->uuid_str;
2544 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Re-attaching to session %s\n", sofia_private->uuid);
2545 de->init_session = session;
2546 sofia_clear_flag(tech_pvt, TFLAG_BYE);
2547 tech_pvt->sofia_private = NULL;
2548 tech_pvt->nh = NULL;
2549 switch_core_session_queue_signal_data(session, de);
2550 switch_core_session_rwunlock(session);
2551 session = NULL;
2552 free(uuid);
2553 uuid = NULL;
2554 goto end;
2555 } else {
2556 free(uuid);
2557 uuid = NULL;
2558 sip = NULL;
2559 }
2560 }
2561 }
2562
2563 if (!sip || !sip->sip_call_id || zstr(sip->sip_call_id->i_id)) {
2564 nua_respond(nh, 503, "INVALID INVITE", TAG_END());
2565 nua_destroy_event(de->event);
2566 su_free(nh->nh_home, de);
2567
2568 switch_mutex_lock(profile->flag_mutex);
2569 profile->queued_events--;
2570 switch_mutex_unlock(profile->flag_mutex);
2571
2572 nua_handle_unref(nh);
2573 nua_stack_unref(nua);
2574
2575 goto end;
2576 }
2577
2578 if (sofia_test_pflag(profile, PFLAG_CALLID_AS_UUID)) {
2579 session = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL, sip->sip_call_id->i_id);
2580 } else {
2581 session = switch_core_session_request(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL);
2582 }
2583
2584 if (session) {
2585 const char *channel_name = NULL;
2586 tech_pvt = sofia_glue_new_pvt(session);
2587
2588 if (sip->sip_from) {
2589 channel_name = url_set_chanvars(session, sip->sip_from->a_url, sip_from);
2590 }
2591 if (!channel_name && sip->sip_contact) {
2592 channel_name = url_set_chanvars(session, sip->sip_contact->m_url, sip_contact);
2593 }
2594 if (sip->sip_referred_by) {
2595 channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by);
2596 }
2597
2598 sofia_glue_attach_private(session, profile, tech_pvt, channel_name);
2599
2600 set_call_id(tech_pvt, sip);
2601 } else {
2602 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
2603 nua_destroy_event(de->event);
2604 su_free(nh->nh_home, de);
2605
2606 switch_mutex_lock(profile->flag_mutex);
2607 profile->queued_events--;
2608 switch_mutex_unlock(profile->flag_mutex);
2609
2610 nua_handle_unref(nh);
2611 nua_stack_unref(nua);
2612
2613 goto end;
2614 }
2615
2616
2617 if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
2618 char *uuid;
2619
2620 if (!switch_core_session_running(session) && !switch_core_session_started(session)) {
2621 nua_handle_bind(nh, NULL);
2622 sofia_private_free(sofia_private);
2623 switch_core_session_destroy(&session);
2624 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
2625 }
2626 switch_mutex_lock(profile->flag_mutex);
2627 if ((uuid = switch_core_hash_find(profile->chat_hash, tech_pvt->call_id))) {
2628 free(uuid);
2629 uuid = NULL;
2630 switch_core_hash_delete(profile->chat_hash, tech_pvt->call_id);
2631 }
2632 switch_mutex_unlock(profile->flag_mutex);
2633
2634 goto end;
2635 }
2636
2637 switch_copy_string(sofia_private->uuid_str, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid_str));
2638 sofia_private->uuid = sofia_private->uuid_str;
2639
2640 de->init_session = session;
2641 switch_core_session_queue_signal_data(session, de);
2642 goto end;
2643 }
2644
2645 if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
2646 switch_core_session_t *session;
2647
2648 if ((session = switch_core_session_locate(sofia_private->uuid))) {
2649 switch_core_session_queue_signal_data(session, de);
2650 switch_core_session_rwunlock(session);
2651 goto end;
2652 }
2653 }
2654
2655 sofia_queue_message(de);
2656
2657 end:
2658 //switch_cond_next();
2659
2660 return;
2661 }
2662
2663
event_handler(switch_event_t * event)2664 void event_handler(switch_event_t *event)
2665 {
2666 char *subclass, *sql;
2667 char *class;
2668 switch_event_t *pevent;
2669
2670 /* Get Original Event Name */
2671 class = switch_event_get_header_nil(event, "orig-event-name");
2672 if (!strcasecmp(class, "PRESENCE_IN")) {
2673 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nGot Presence IN event via MultiCast\n");
2674 if (switch_event_create(&pevent, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
2675 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "alt_event_type", switch_event_get_header_nil(event, "orig-alt_event_type"));
2676 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "answer-state", switch_event_get_header_nil(event, "orig-answer-state"));
2677 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "astate", switch_event_get_header_nil(event, "orig-astate"));
2678 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "call-direction", switch_event_get_header_nil(event, "orig-call-direction"));
2679 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Callee-ID-Number", switch_event_get_header_nil(event, "Orig-Caller-Callee-ID-Number"));
2680 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Caller-ID-Name", switch_event_get_header_nil(event, "Orig-Caller-Caller-ID-Name"));
2681 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Caller-ID-Number", switch_event_get_header_nil(event, "Orig-Caller-Caller-ID-Number"));
2682 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Destination-Number", switch_event_get_header_nil(event, "Orig-Caller-Destination-Number"));
2683 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Direction", switch_event_get_header_nil(event, "Orig-Caller-Direction"));
2684 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Caller-Username", switch_event_get_header_nil(event, "Orig-Caller-Username"));
2685 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "channel-state", switch_event_get_header_nil(event, "orig-channel-state"));
2686 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "force-status", switch_event_get_header_nil(event, "orig-force-status"));
2687 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "from", switch_event_get_header_nil(event, "orig-from"));
2688 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "login", switch_event_get_header_nil(event, "orig-login"));
2689 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"));
2690 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"));
2691 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "presence-call-direction", switch_event_get_header_nil(event, "orig-presence-call-direction"));
2692 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "presence-call-info-state", switch_event_get_header_nil(event, "orig-presence-call-info-state"));
2693 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Presence-Privacy", switch_event_get_header_nil(event, "Orig-Presence-Privacy"));
2694 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "proto", switch_event_get_header_nil(event, "orig-proto"));
2695 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "register-source", switch_event_get_header_nil(event, "orig-register-source"));
2696 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "resub", switch_event_get_header_nil(event, "orig-resub"));
2697 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "rpid", switch_event_get_header_nil(event, "orig-rpid"));
2698 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "status", switch_event_get_header_nil(event, "orig-status"));
2699 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "Unique-ID", switch_event_get_header_nil(event, "Orig-Unique-ID"));
2700 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "variable_sip_from_user", switch_event_get_header_nil(event, "Orig-variable_sip_from_user"));
2701 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "variable_sip_to_user", switch_event_get_header_nil(event, "Orig-variable_sip_to_user"));
2702
2703 /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
2704 sofia_presence_event_handler(pevent);
2705 return;
2706 } else {
2707 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nCannot inject PRESENCE_IN event\n");
2708 return;
2709 }
2710 } else if (!strcasecmp(class, "MESSAGE_WAITING")) {
2711 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nGot MWI event via MultiCast\n");
2712 if (switch_event_create(&pevent, SWITCH_EVENT_MESSAGE_WAITING) == SWITCH_STATUS_SUCCESS) {
2713 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", switch_event_get_header_nil(event, "orig-MWI-Messages-Waiting"));
2714 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "MWI-Message-Account", switch_event_get_header_nil(event, "orig-MWI-Message-Account"));
2715 switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", switch_event_get_header_nil(event, "orig-MWI-Voice-Message"));
2716 /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
2717 sofia_presence_event_handler(pevent);
2718 return;
2719 } else {
2720 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nCannot inject MWI event\n");
2721 return;
2722 }
2723 } else if ((subclass = switch_event_get_header_nil(event, "orig-event-subclass")) && !strcasecmp(subclass, MY_EVENT_UNREGISTER)) {
2724 char *profile_name = switch_event_get_header_nil(event, "orig-profile-name");
2725 char *from_user = switch_event_get_header_nil(event, "orig-from-user");
2726 char *from_host = switch_event_get_header_nil(event, "orig-from-host");
2727 char *call_id = switch_event_get_header_nil(event, "orig-call-id");
2728 char *contact_str = switch_event_get_header_nil(event, "orig-contact");
2729
2730 sofia_profile_t *profile = NULL;
2731
2732 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) {
2733 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
2734 return;
2735 }
2736
2737 if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
2738 sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
2739 } else {
2740 sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", from_user, from_host);
2741 }
2742
2743 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2744 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Expired propagated registration for %s@%s->%s\n", from_user, from_host, contact_str);
2745
2746 sofia_glue_release_profile(profile);
2747 } else if ((subclass = switch_event_get_header_nil(event, "orig-event-subclass")) && !strcasecmp(subclass, MY_EVENT_REGISTER)) {
2748 char *from_user = switch_event_get_header_nil(event, "orig-from-user");
2749 char *from_host = switch_event_get_header_nil(event, "orig-from-host");
2750 char *to_host = switch_event_get_header_nil(event, "orig-to-host");
2751 char *contact_str = switch_event_get_header_nil(event, "orig-contact");
2752 char *exp_str = switch_event_get_header_nil(event, "orig-expires");
2753 char *rpid = switch_event_get_header_nil(event, "orig-rpid");
2754 char *call_id = switch_event_get_header_nil(event, "orig-call-id");
2755 char *user_agent = switch_event_get_header_nil(event, "orig-user-agent");
2756 long expires = (long) switch_epoch_time_now(NULL);
2757 char *profile_name = switch_event_get_header_nil(event, "orig-profile-name");
2758 char *to_user = switch_event_get_header_nil(event, "orig-to-user");
2759 char *presence_hosts = switch_event_get_header_nil(event, "orig-presence-hosts");
2760 char *network_ip = switch_event_get_header_nil(event, "orig-network-ip");
2761 char *network_port = switch_event_get_header_nil(event, "orig-network-port");
2762 char *username = switch_event_get_header_nil(event, "orig-username");
2763 char *realm = switch_event_get_header_nil(event, "orig-realm");
2764 char *orig_server_host = switch_event_get_header_nil(event, "orig-FreeSWITCH-IPv4");
2765 char *orig_hostname = switch_event_get_header_nil(event, "orig-FreeSWITCH-Hostname");
2766 char *fixed_contact_str = NULL;
2767
2768 sofia_profile_t *profile = NULL;
2769 char guess_ip4[256];
2770
2771 char *mwi_account = NULL;
2772 char *dup_mwi_account = NULL;
2773 char *mwi_user = NULL;
2774 char *mwi_host = NULL;
2775
2776 if ((mwi_account = switch_event_get_header_nil(event, "orig-mwi-account"))) {
2777 dup_mwi_account = strdup(mwi_account);
2778 switch_assert(dup_mwi_account != NULL);
2779 switch_split_user_domain(dup_mwi_account, &mwi_user, &mwi_host);
2780 }
2781
2782 if (!mwi_user) {
2783 mwi_user = (char *) from_user;
2784 }
2785 if (!mwi_host) {
2786 mwi_host = (char *) from_host;
2787 }
2788
2789 if (exp_str) {
2790 expires += atol(exp_str);
2791 }
2792
2793 if (!rpid) {
2794 rpid = "unknown";
2795 }
2796
2797 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) {
2798 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
2799 goto end;
2800 }
2801 if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
2802 sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id);
2803 } else {
2804 sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", from_user, from_host);
2805 }
2806
2807 if (mod_sofia_globals.rewrite_multicasted_fs_path && contact_str) {
2808 const char *needle = ";fs_path=";
2809 char *sptr, *eptr = NULL;
2810 /* allocate enough room for worst-case scenario, depends on rewrite_multicased_fs_path setting */
2811 size_t len;
2812 switch (mod_sofia_globals.rewrite_multicasted_fs_path) {
2813 case 1:
2814 len = strlen(contact_str) + strlen(to_host) + 14;
2815 break;
2816 case 2:
2817 len = strlen(contact_str) + strlen(orig_server_host) + 14;
2818 break;
2819 case 3:
2820 len = strlen(contact_str) + strlen(orig_hostname) + 14;
2821 break;
2822 default:
2823 len = strlen(contact_str) + strlen(to_host) + 14;
2824 break;
2825 }
2826
2827 fixed_contact_str = malloc(len);
2828 switch_assert(fixed_contact_str);
2829 switch_copy_string(fixed_contact_str, contact_str, len);
2830
2831 if ((sptr = strstr(fixed_contact_str, needle))) {
2832 char *origsptr = strstr(contact_str, needle);
2833 eptr = strchr(++origsptr, ';');
2834 } else {
2835 sptr = strchr(fixed_contact_str, '\0') - 1;
2836 }
2837
2838 switch (mod_sofia_globals.rewrite_multicasted_fs_path) {
2839 case 1:
2840 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", to_host, eptr ? eptr : ">");
2841 break;
2842 case 2:
2843 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", orig_server_host, eptr ? eptr : ">");
2844 break;
2845 case 3:
2846 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", orig_hostname, eptr ? eptr : ">");
2847 break;
2848 default:
2849 switch_snprintf(sptr, len - (sptr - fixed_contact_str), ";fs_path=sip:%s%s", to_host, eptr ? eptr : ">");
2850 break;
2851 }
2852
2853 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Rewrote contact string from '%s' to '%s'\n", contact_str, fixed_contact_str);
2854 contact_str = fixed_contact_str;
2855 }
2856
2857
2858 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2859
2860 switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET);
2861 sql = switch_mprintf("insert into sip_registrations "
2862 "(call_id, sip_user, sip_host, presence_hosts, contact, status, rpid, expires,"
2863 "user_agent, server_user, server_host, profile_name, hostname, network_ip, network_port, sip_username, sip_realm,"
2864 "mwi_user, mwi_host, orig_server_host, orig_hostname, ping_status, ping_count) "
2865 "values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)",
2866 call_id, from_user, from_host, presence_hosts, contact_str, rpid, expires, user_agent, to_user, guess_ip4,
2867 profile_name, mod_sofia_globals.hostname, network_ip, network_port, username, realm, mwi_user, mwi_host,
2868 orig_server_host, orig_hostname, "Reachable", 0);
2869
2870 if (sql) {
2871 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2872 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str);
2873 }
2874
2875
2876 sofia_glue_release_profile(profile);
2877 end:
2878 switch_safe_free(fixed_contact_str);
2879 switch_safe_free(dup_mwi_account);
2880 } else if ((subclass = switch_event_get_header_nil(event, "orig-event-subclass")) && !strcasecmp(subclass, MY_EVENT_SIP_USER_STATE)) {
2881 char *profile_name = switch_event_get_header_nil(event, "orig-profile-name");
2882 char *from_user = switch_event_get_header_nil(event, "orig-from-user");
2883 char *from_host = switch_event_get_header_nil(event, "orig-from-host");
2884 const char *call_id = switch_event_get_header_nil(event, "orig-call-id");
2885 char *ping_status = switch_event_get_header_nil(event, "orig-Ping-Status");
2886 sofia_profile_t *profile = NULL;
2887
2888 if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) {
2889 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
2890 } else {
2891 if (!strcmp(ping_status, "REACHABLE")) {
2892 sql = switch_mprintf("update sip_registrations set ping_status='%q' where sip_user='%q' and sip_host='%q' and call_id='%q'",
2893 "Reachable", from_user, from_host, call_id);
2894 } else {
2895 sql = switch_mprintf("update sip_registrations set ping_status='%q' where sip_user='%q' and sip_host='%q' and call_id='%q'",
2896 "Unreachable", from_user, from_host, call_id);
2897 }
2898 if (sql) {
2899 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
2900 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating sip_user_state for %s@%s. Ping-Status: %s\n", from_user, from_host, ping_status);
2901 }
2902
2903 sofia_glue_release_profile(profile);
2904 }
2905 }
2906 }
2907
sofia_perform_profile_start_failure(sofia_profile_t * profile,char * profile_name,char * file,int line)2908 static void sofia_perform_profile_start_failure(sofia_profile_t *profile, char *profile_name, char *file, int line)
2909 {
2910 int arg = 0;
2911 switch_event_t *s_event;
2912
2913 if (profile) {
2914 if (!strcasecmp(profile->shutdown_type, "true")) {
2915 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s could not load! Shutting down!\n", profile->name);
2916 switch_core_session_ctl(SCSC_SHUTDOWN, &arg);
2917 } else if (!strcasecmp(profile->shutdown_type, "elegant")) {
2918 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s could not load! Waiting for calls to finish, then shutting down!\n",
2919 profile->name);
2920 switch_core_session_ctl(SCSC_SHUTDOWN_ELEGANT, &arg);
2921 } else if (!strcasecmp(profile->shutdown_type, "asap")) {
2922 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s could not load! Shutting down ASAP!\n", profile->name);
2923 switch_core_session_ctl(SCSC_SHUTDOWN_ASAP, &arg);
2924 } else if (!strcasecmp(profile->shutdown_type, "reincarnate-now")) {
2925 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s could not load! Asking for reincarnation now!\n", profile->name);
2926 switch_core_session_ctl(SCSC_REINCARNATE_NOW, &arg);
2927 }
2928 }
2929
2930 if ((switch_event_create(&s_event, SWITCH_EVENT_FAILURE) == SWITCH_STATUS_SUCCESS)) {
2931 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
2932 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile_name);
2933 if (profile) {
2934 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
2935 }
2936 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "failure_message", "Profile failed to start.");
2937 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "file", file);
2938 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "line", "%d", line);
2939
2940 switch_event_fire(&s_event);
2941 }
2942 }
2943
2944 /* not a static function so that it's still visible on stacktraces */
watchdog_triggered_abort(void)2945 void watchdog_triggered_abort(void) {
2946 abort();
2947 }
2948
2949 #define sofia_profile_start_failure(p, xp) sofia_perform_profile_start_failure(p, xp, __FILE__, __LINE__)
2950
2951
2952 #define SQLLEN 1024 * 1024
sofia_profile_worker_thread_run(switch_thread_t * thread,void * obj)2953 void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread, void *obj)
2954 {
2955 sofia_profile_t *profile = (sofia_profile_t *) obj;
2956 uint32_t ireg_loops = profile->ireg_seconds; /* Number of loop iterations done when we haven't checked for registrations */
2957 uint32_t iping_loops = profile->iping_freq; /* Number of loop iterations done when we haven't checked for ping expires */
2958 uint32_t gateway_loops = GATEWAY_SECONDS; /* Number of loop iterations done when we haven't checked for gateways */
2959 void *pop;
2960 int tick = 0, x = 0;
2961
2962 sofia_set_pflag_locked(profile, PFLAG_WORKER_RUNNING);
2963
2964 while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING))) {
2965
2966 if (tick) {
2967 if (profile->watchdog_enabled) {
2968 uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0;
2969
2970 if (profile->step_timeout) {
2971 step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000);
2972
2973 if (step_diff > profile->step_timeout) {
2974 step_fail = 1;
2975 }
2976 }
2977
2978 if (profile->event_timeout) {
2979 event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000);
2980
2981 if (event_diff > profile->event_timeout) {
2982 event_fail = 1;
2983 }
2984 }
2985
2986 if (step_fail && profile->event_timeout && !event_fail) {
2987 step_fail = 0;
2988 }
2989
2990 if (event_fail || step_fail) {
2991 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED BY WATCHDOG!\n"
2992 "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name);
2993 switch_yield(2000000);
2994 watchdog_triggered_abort();
2995 }
2996 }
2997
2998
2999 if (!sofia_test_pflag(profile, PFLAG_STANDBY)) {
3000 if (++ireg_loops >= (uint32_t)profile->ireg_seconds) {
3001 time_t now = switch_epoch_time_now(NULL);
3002 sofia_reg_check_expire(profile, now, 0);
3003 ireg_loops = 0;
3004 }
3005
3006 if(++iping_loops >= (uint32_t)profile->iping_freq) {
3007 time_t now = switch_epoch_time_now(NULL);
3008 sofia_reg_check_ping_expire(profile, now, profile->iping_seconds);
3009 iping_loops = 0;
3010 }
3011
3012 if (++gateway_loops >= GATEWAY_SECONDS) {
3013 sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL));
3014 sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL));
3015 gateway_loops = 0;
3016 }
3017 }
3018
3019 tick = 0;
3020 }
3021
3022 if (switch_queue_pop_timeout(mod_sofia_globals.general_event_queue, &pop, 100000) == SWITCH_STATUS_SUCCESS) {
3023
3024 do {
3025 switch_event_t *event = (switch_event_t *) pop;
3026 general_event_handler(event);
3027 switch_event_destroy(&event);
3028
3029 pop = NULL;
3030 switch_queue_trypop(mod_sofia_globals.general_event_queue, &pop);
3031 } while (pop);
3032
3033 }
3034
3035 sofia_glue_fire_events(profile);
3036
3037 if (++x == 10) {
3038 tick = 1;
3039 x = 0;
3040 }
3041
3042 }
3043
3044 sofia_clear_pflag_locked(profile, PFLAG_WORKER_RUNNING);
3045
3046 return NULL;
3047 }
3048
launch_sofia_worker_thread(sofia_profile_t * profile)3049 switch_thread_t *launch_sofia_worker_thread(sofia_profile_t *profile)
3050 {
3051 switch_thread_t *thread = NULL;
3052 switch_threadattr_t *thd_attr = NULL;
3053 int x = 0;
3054 switch_xml_t cfg = NULL, xml = NULL, xprofile = NULL, xprofiles = NULL, gateways_tag = NULL, domains_tag = NULL, domain_tag = NULL;
3055 switch_event_t *params = NULL;
3056 char *cf = "sofia.conf";
3057
3058 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Launching worker thread for %s\n", profile->name);
3059
3060 /* Parse gateways */
3061 switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS);
3062 switch_assert(params);
3063 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile->name);
3064
3065 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
3066 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
3067 goto end;
3068 }
3069
3070 if ((xprofiles = switch_xml_child(cfg, "profiles"))) {
3071 if ((xprofile = switch_xml_find_child(xprofiles, "profile", "name", profile->name))) {
3072
3073 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
3074 parse_gateways(profile, gateways_tag, NULL);
3075 }
3076
3077 if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
3078 switch_event_t *xml_params;
3079 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS);
3080 switch_assert(xml_params);
3081 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways");
3082 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
3083
3084 for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
3085 switch_xml_t droot, x_domain_tag;
3086 const char *dname = switch_xml_attr_soft(domain_tag, "name");
3087 const char *parse = switch_xml_attr_soft(domain_tag, "parse");
3088 const char *alias = switch_xml_attr_soft(domain_tag, "alias");
3089
3090 if (!zstr(dname)) {
3091 if (!strcasecmp(dname, "all")) {
3092 switch_xml_t xml_root, x_domains;
3093 if (switch_xml_locate("directory", NULL, NULL, NULL, &xml_root, &x_domains, xml_params, SWITCH_FALSE) ==
3094 SWITCH_STATUS_SUCCESS) {
3095 for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
3096 dname = switch_xml_attr_soft(x_domain_tag, "name");
3097 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
3098 }
3099 switch_xml_free(xml_root);
3100 }
3101 } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) {
3102 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
3103 switch_xml_free(droot);
3104 }
3105 }
3106 }
3107
3108 switch_event_destroy(&xml_params);
3109 }
3110
3111 }
3112 }
3113
3114 switch_threadattr_create(&thd_attr, profile->pool);
3115 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
3116 //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
3117 switch_thread_create(&thread, thd_attr, sofia_profile_worker_thread_run, profile, profile->pool);
3118
3119 while (!sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)) {
3120 switch_yield(100000);
3121 if (++x >= 100) {
3122 break;
3123 }
3124 }
3125
3126 end:
3127 switch_event_destroy(¶ms);
3128
3129 if (xml) {
3130 switch_xml_free(xml);
3131 }
3132
3133 return thread;
3134 }
3135
sofia_profile_thread_run(switch_thread_t * thread,void * obj)3136 void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj)
3137 {
3138 sofia_profile_t *profile = (sofia_profile_t *) obj;
3139 //switch_memory_pool_t *pool;
3140 sip_alias_node_t *node;
3141 switch_event_t *s_event;
3142 int use_100rel = !sofia_test_pflag(profile, PFLAG_DISABLE_100REL);
3143 int use_timer = !sofia_test_pflag(profile, PFLAG_DISABLE_TIMER);
3144 int use_rfc_5626 = sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626);
3145 const char *supported = NULL;
3146 int sanity, attempts = 0;
3147 switch_thread_t *worker_thread;
3148 switch_status_t st;
3149 char qname [128] = "";
3150
3151 switch_mutex_lock(mod_sofia_globals.mutex);
3152 mod_sofia_globals.threads++;
3153 switch_mutex_unlock(mod_sofia_globals.mutex);
3154
3155 profile->s_root = su_root_create(NULL);
3156 //profile->home = su_home_new(sizeof(*profile->home));
3157
3158 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating agent for %s\n", profile->name);
3159
3160 if (!sofia_glue_init_sql(profile)) {
3161 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name);
3162 sofia_profile_start_failure(profile, profile->name);
3163 sofia_glue_del_profile(profile);
3164 goto end;
3165 }
3166
3167 supported = switch_core_sprintf(profile->pool, "%s%s%spath, replaces", use_100rel ? "precondition, 100rel, " : "", use_timer ? "timer, " : "", use_rfc_5626 ? "outbound, " : "");
3168
3169 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_nat_get_type()) {
3170 if ( (! sofia_test_pflag(profile, PFLAG_TLS) || ! profile->tls_only) && switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_UDP, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
3171 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3172 }
3173 if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_TCP, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
3174 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3175 }
3176 if (sofia_test_pflag(profile, PFLAG_TLS)
3177 && switch_nat_add_mapping(profile->tls_sip_port, SWITCH_NAT_TCP, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
3178 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
3179 }
3180 }
3181
3182 /* 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 */
3183 if ( (profile->tls_verify_policy & TPTLS_VERIFY_SUBJECTS_IN) && profile->tls_verify_in_subjects_str && ! profile->tls_verify_in_subjects) {
3184 profile->tls_verify_in_subjects = su_strlst_dup_split((su_home_t *)profile->nua, profile->tls_verify_in_subjects_str, "|");
3185 }
3186
3187 do {
3188 profile->nua = nua_create(profile->s_root, /* Event loop */
3189 sofia_event_callback, /* Callback for processing events */
3190 profile, /* Additional data to pass to callback */
3191 TAG_IF( ! sofia_test_pflag(profile, PFLAG_TLS) || ! profile->tls_only, NUTAG_URL(profile->bindurl)),
3192 NTATAG_USER_VIA(1),
3193 TPTAG_PONG2PING(1),
3194 NTATAG_TCP_RPORT(0),
3195 NTATAG_TLS_RPORT(0),
3196 NUTAG_RETRY_AFTER_ENABLE(0),
3197 NUTAG_AUTO_INVITE_100(0),
3198 TAG_IF(!strchr(profile->sipip, ':'),
3199 SOATAG_AF(SOA_AF_IP4_ONLY)),
3200 TAG_IF(strchr(profile->sipip, ':'),
3201 SOATAG_AF(SOA_AF_IP6_ONLY)),
3202 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
3203 NUTAG_SIPS_URL(profile->tls_bindurl)),
3204 TAG_IF(profile->ws_bindurl,
3205 NUTAG_WS_URL(profile->ws_bindurl)),
3206 TAG_IF(profile->wss_bindurl,
3207 NUTAG_WSS_URL(profile->wss_bindurl)),
3208 TAG_IF(profile->tls_cert_dir,
3209 NUTAG_CERTIFICATE_DIR(profile->tls_cert_dir)),
3210 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_passphrase,
3211 TPTAG_TLS_PASSPHRASE(profile->tls_passphrase)),
3212 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
3213 TPTAG_TLS_VERIFY_POLICY(profile->tls_verify_policy)),
3214 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
3215 TPTAG_TLS_VERIFY_DEPTH(profile->tls_verify_depth)),
3216 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
3217 TPTAG_TLS_VERIFY_DATE(profile->tls_verify_date)),
3218 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_verify_in_subjects,
3219 TPTAG_TLS_VERIFY_SUBJECTS(profile->tls_verify_in_subjects)),
3220 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
3221 TPTAG_TLS_CIPHERS(profile->tls_ciphers)),
3222 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
3223 TPTAG_TLS_VERSION(profile->tls_version)),
3224 TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_timeout,
3225 TPTAG_TLS_TIMEOUT(profile->tls_timeout)),
3226 TAG_IF(!strchr(profile->sipip, ':'),
3227 NTATAG_UDP_MTU(65535)),
3228 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV),
3229 NTATAG_USE_SRV(0)),
3230 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_NAPTR),
3231 NTATAG_USE_NAPTR(0)),
3232 TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_PINGPONG),
3233 TPTAG_PINGPONG(profile->tcp_pingpong)),
3234 TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_PING2PONG),
3235 TPTAG_PINGPONG(profile->tcp_ping2pong)),
3236 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV503),
3237 NTATAG_SRV_503(0)),
3238 TAG_IF(sofia_test_pflag(profile, PFLAG_SOCKET_TCP_KEEPALIVE),
3239 TPTAG_SOCKET_KEEPALIVE(profile->socket_tcp_keepalive)),
3240 TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_KEEPALIVE),
3241 TPTAG_KEEPALIVE(profile->tcp_keepalive)),
3242 NTATAG_DEFAULT_PROXY(profile->outbound_proxy),
3243 NTATAG_SERVER_RPORT(profile->server_rport_level),
3244 NTATAG_CLIENT_RPORT(profile->client_rport_level),
3245 TPTAG_LOG(sofia_test_flag(profile, TFLAG_TPORT_LOG)),
3246 TPTAG_CAPT(sofia_test_flag(profile, TFLAG_CAPTURE) ? mod_sofia_globals.capture_server : NULL),
3247 TAG_IF(sofia_test_pflag(profile, PFLAG_SIPCOMPACT),
3248 NTATAG_SIPFLAGS(MSG_DO_COMPACT)),
3249 TAG_IF(profile->timer_t1, NTATAG_SIP_T1(profile->timer_t1)),
3250 TAG_IF(profile->timer_t1x64, NTATAG_SIP_T1X64(profile->timer_t1x64)),
3251 TAG_IF(profile->timer_t2, NTATAG_SIP_T2(profile->timer_t2)),
3252 TAG_IF(profile->timer_t4, NTATAG_SIP_T4(profile->timer_t4)),
3253 SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed"),
3254 TAG_IF(sofia_test_pflag(profile, PFLAG_NO_CONNECTION_REUSE),
3255 TPTAG_REUSE(0)),
3256 TAG_END()); /* Last tag should always finish the sequence */
3257
3258 if (!profile->nua) {
3259 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s) ATTEMPT %d (RETRY IN %d SEC)\n",
3260 profile->name, profile->bindurl, attempts + 1, profile->bind_attempt_interval);
3261 if (attempts < profile->bind_attempts) {
3262 switch_yield(1000000 * profile->bind_attempt_interval);
3263 }
3264 }
3265
3266 } while (!profile->nua && attempts++ < profile->bind_attempts);
3267
3268 if (!profile->nua) {
3269 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s)\n"
3270 "The likely causes for this are:\n" "1) Another application is already listening on the specified address.\n"
3271 "2) The IP the profile is attempting to bind to is not local to this system.\n", profile->name, profile->bindurl);
3272 sofia_profile_start_failure(profile, profile->name);
3273 sofia_glue_del_profile(profile);
3274 goto end;
3275 }
3276
3277 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created agent for %s\n", profile->name);
3278
3279 nua_set_params(profile->nua,
3280 SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO"),
3281 SIPTAG_USER_AGENT(SIP_NONE),
3282 NUTAG_AUTOANSWER(0),
3283 NUTAG_AUTOACK(0),
3284 NUTAG_AUTOALERT(0),
3285 NUTAG_ENABLEMESSENGER(1),
3286 NTATAG_EXTRA_100(0),
3287 TAG_IF(sofia_test_pflag(profile, PFLAG_ALLOW_UPDATE), NUTAG_ALLOW("UPDATE")),
3288 TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER")),
3289 TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER")),
3290 TAG_IF(!sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_ALLOW("PRACK")),
3291 NUTAG_ALLOW("INFO"),
3292 NUTAG_ALLOW("NOTIFY"),
3293 NUTAG_ALLOW_EVENTS("talk"),
3294 NUTAG_ALLOW_EVENTS("hold"),
3295 NUTAG_ALLOW_EVENTS("conference"),
3296 NUTAG_APPL_METHOD("OPTIONS"),
3297 NUTAG_APPL_METHOD("INVITE"),
3298 NUTAG_APPL_METHOD("REFER"),
3299 NUTAG_APPL_METHOD("REGISTER"),
3300 NUTAG_APPL_METHOD("NOTIFY"), NUTAG_APPL_METHOD("INFO"), NUTAG_APPL_METHOD("ACK"), NUTAG_APPL_METHOD("SUBSCRIBE"),
3301 #ifdef MANUAL_BYE
3302 NUTAG_APPL_METHOD("BYE"),
3303 #endif
3304 NUTAG_APPL_METHOD("MESSAGE"),
3305
3306 TAG_IF(profile->session_timeout && profile->minimum_session_expires, NUTAG_MIN_SE(profile->minimum_session_expires)),
3307 NUTAG_SESSION_TIMER(profile->session_timeout),
3308 NTATAG_MAX_PROCEEDING(profile->max_proceeding),
3309 TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH")),
3310 TAG_IF(profile->pres_type, NUTAG_ALLOW("SUBSCRIBE")),
3311 TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1)),
3312 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence")),
3313 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("as-feature-event")),
3314 TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("dialog")),
3315 TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("line-seize")),
3316 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("call-info")),
3317 TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("sla")),
3318 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("include-session-description")),
3319 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence.winfo")),
3320 TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("message-summary")),
3321 TAG_IF(profile->pres_type == PRES_TYPE_PNP, NUTAG_ALLOW_EVENTS("ua-profile")),
3322 NUTAG_ALLOW_EVENTS("refer"), SIPTAG_SUPPORTED_STR(supported),
3323 TAG_IF(strcasecmp(profile->user_agent, "_undef_"), SIPTAG_USER_AGENT_STR(profile->user_agent)),
3324 TAG_END());
3325
3326 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set params for %s\n", profile->name);
3327
3328 if (sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT) || sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)) {
3329 sip_via_t *vias = nta_agent_via(profile->nua->nua_nta);
3330 sip_via_t *via = NULL;
3331
3332 for (via = vias; via; via = via->v_next) {
3333 if (sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT) && !strcmp(via->v_protocol, "SIP/2.0/UDP")) {
3334 profile->sip_port = (switch_port_t)atoi(via->v_port);
3335 if (!profile->extsipport) profile->extsipport = profile->sip_port;
3336 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found auto sip port %d for %s\n", profile->sip_port, profile->name);
3337 }
3338
3339 if (sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT) && !strcmp(via->v_protocol, "SIP/2.0/TLS")) {
3340 profile->tls_sip_port = (switch_port_t)atoi(via->v_port);
3341 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found auto sip port %d for %s (TLS)\n", profile->tls_sip_port, profile->name);
3342 }
3343
3344 }
3345
3346 config_sofia_profile_urls(profile);
3347 }
3348
3349 for (node = profile->aliases; node; node = node->next) {
3350 node->nua = nua_create(profile->s_root, /* Event loop */
3351 sofia_event_callback, /* Callback for processing events */
3352 profile, /* Additional data to pass to callback */
3353 NTATAG_SERVER_RPORT(profile->server_rport_level), NUTAG_URL(node->url), TAG_END()); /* Last tag should always finish the sequence */
3354
3355 nua_set_params(node->nua,
3356 SIPTAG_USER_AGENT(SIP_NONE),
3357 NUTAG_APPL_METHOD("OPTIONS"),
3358 NUTAG_APPL_METHOD("REFER"),
3359 NUTAG_APPL_METHOD("SUBSCRIBE"),
3360 NUTAG_AUTOANSWER(0),
3361 NUTAG_AUTOACK(0),
3362 NUTAG_AUTOALERT(0),
3363 TAG_IF((profile->mflags & MFLAG_REGISTER), NUTAG_ALLOW("REGISTER")),
3364 TAG_IF((profile->mflags & MFLAG_REFER), NUTAG_ALLOW("REFER")),
3365 NUTAG_ALLOW("INFO"),
3366 TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH")),
3367 TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1)),
3368 SIPTAG_SUPPORTED_STR(supported),
3369 TAG_IF(strcasecmp(profile->user_agent, "_undef_"), SIPTAG_USER_AGENT_STR(profile->user_agent)),
3370 TAG_END());
3371 }
3372
3373 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Activated db for %s\n", profile->name);
3374
3375 switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
3376 switch_mutex_init(&profile->dbh_mutex, SWITCH_MUTEX_NESTED, profile->pool);
3377 switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED, profile->pool);
3378 switch_queue_create(&profile->event_queue, SOFIA_QUEUE_SIZE, profile->pool);
3379
3380
3381 switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name);
3382 switch_sql_queue_manager_init_name(qname,
3383 &profile->qm,
3384 2,
3385 profile->odbc_dsn ? profile->odbc_dsn : profile->dbname,
3386 SWITCH_MAX_TRANS,
3387 profile->pre_trans_execute,
3388 profile->post_trans_execute,
3389 profile->inner_pre_trans_execute,
3390 profile->inner_post_trans_execute);
3391 switch_sql_queue_manager_start(profile->qm);
3392
3393 if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) {
3394 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s",
3395 (sofia_test_pflag(profile, PFLAG_TLS)) ? ",_sips._tcp" : "");
3396
3397 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
3398 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
3399 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
3400 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
3401
3402 if (sofia_test_pflag(profile, PFLAG_TLS)) {
3403 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "tls_port", "%d", profile->tls_sip_port);
3404 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_tls_uri", profile->tls_url);
3405 }
3406 switch_event_fire(&s_event);
3407 }
3408
3409 sofia_glue_add_profile(profile->name, profile);
3410
3411 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Starting thread for %s\n", profile->name);
3412
3413 profile->started = switch_epoch_time_now(NULL);
3414
3415 sofia_set_pflag_locked(profile, PFLAG_RUNNING);
3416 worker_thread = launch_sofia_worker_thread(profile);
3417
3418 switch_yield(1000000);
3419
3420
3421 while (mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING) && sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)) {
3422 su_root_step(profile->s_root, 1000);
3423 profile->last_root_step = switch_time_now();
3424 }
3425
3426 sofia_clear_pflag_locked(profile, PFLAG_RUNNING);
3427 sofia_reg_close_handles(profile);
3428
3429 switch_core_session_hupall_matching_var("sofia_profile_name", profile->name, SWITCH_CAUSE_MANAGER_REQUEST);
3430 sanity = 10;
3431 while (profile->inuse) {
3432 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Waiting for %d session(s)\n", profile->inuse);
3433 su_root_step(profile->s_root, 1000);
3434 if (!--sanity) {
3435 break;
3436 } else if (sanity == 5) {
3437 switch_core_session_hupall_matching_var("sofia_profile_name", profile->name, SWITCH_CAUSE_MANAGER_REQUEST);
3438 }
3439 }
3440
3441
3442 sofia_reg_unregister(profile);
3443 nua_shutdown(profile->nua);
3444
3445 sanity = 100;
3446 while (!sofia_test_pflag(profile, PFLAG_SHUTDOWN) || profile->queued_events > 0) {
3447 su_root_step(profile->s_root, 1000);
3448 if (!--sanity) {
3449 break;
3450 }
3451 }
3452
3453 sofia_clear_pflag_locked(profile, PFLAG_RUNNING);
3454 sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN);
3455 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
3456
3457 if ( worker_thread ) {
3458 switch_thread_join(&st, worker_thread);
3459 } else {
3460 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n");
3461 }
3462
3463 sanity = 4;
3464 while (profile->inuse) {
3465 switch_core_session_hupall_matching_var("sofia_profile_name", profile->name, SWITCH_CAUSE_MANAGER_REQUEST);
3466 switch_yield(5000000);
3467 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Waiting for %d session(s)\n", profile->inuse);
3468 if (!--sanity) {
3469 break;
3470 }
3471 }
3472 nua_destroy(profile->nua);
3473
3474 switch_mutex_lock(profile->ireg_mutex);
3475 switch_mutex_unlock(profile->ireg_mutex);
3476
3477 switch_mutex_lock(profile->flag_mutex);
3478 switch_mutex_unlock(profile->flag_mutex);
3479
3480 switch_sql_queue_manager_destroy(&profile->qm);
3481
3482 if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH) == SWITCH_STATUS_SUCCESS) {
3483 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s",
3484 (sofia_test_pflag(profile, PFLAG_TLS)) ? ",_sips._tcp" : "");
3485
3486 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
3487 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
3488 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
3489 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
3490
3491 if (sofia_test_pflag(profile, PFLAG_TLS)) {
3492 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "tls_port", "%d", profile->tls_sip_port);
3493 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_tls_uri", profile->tls_url);
3494 }
3495 switch_event_fire(&s_event);
3496 }
3497
3498 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_nat_get_type()) {
3499 if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_UDP) == SWITCH_STATUS_SUCCESS) {
3500 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleted UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3501 }
3502 if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_TCP) == SWITCH_STATUS_SUCCESS) {
3503 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleted TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
3504 }
3505 if (sofia_test_pflag(profile, PFLAG_TLS) && switch_nat_del_mapping(profile->tls_sip_port, SWITCH_NAT_TCP) == SWITCH_STATUS_SUCCESS) {
3506 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleted TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
3507 }
3508 }
3509
3510 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name);
3511 switch_thread_rwlock_wrlock(profile->rwlock);
3512
3513 //su_home_unref(profile->home);
3514 su_root_destroy(profile->s_root);
3515 //pool = profile->pool;
3516
3517 sofia_glue_del_profile(profile);
3518 switch_core_hash_destroy(&profile->chat_hash);
3519 switch_core_hash_destroy(&profile->reg_nh_hash);
3520 switch_core_hash_destroy(&profile->mwi_debounce_hash);
3521
3522 switch_thread_rwlock_unlock(profile->rwlock);
3523 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name);
3524
3525 if (sofia_test_pflag(profile, PFLAG_RESPAWN)) {
3526 config_sofia(SOFIA_CONFIG_RESPAWN, profile->name);
3527 }
3528
3529 sofia_profile_destroy(profile);
3530
3531 end:
3532 switch_mutex_lock(mod_sofia_globals.mutex);
3533 mod_sofia_globals.threads--;
3534 switch_mutex_unlock(mod_sofia_globals.mutex);
3535
3536 return NULL;
3537 }
3538
sofia_profile_destroy(sofia_profile_t * profile)3539 void sofia_profile_destroy(sofia_profile_t *profile)
3540 {
3541 if (!profile->inuse) {
3542 switch_memory_pool_t *pool = profile->pool;
3543 switch_core_destroy_memory_pool(&pool);
3544 } else {
3545 sofia_set_pflag(profile, PFLAG_DESTROY);
3546 }
3547 }
3548
launch_sofia_profile_thread(sofia_profile_t * profile)3549 void launch_sofia_profile_thread(sofia_profile_t *profile)
3550 {
3551 //switch_thread_t *thread;
3552 switch_threadattr_t *thd_attr = NULL;
3553
3554 switch_threadattr_create(&thd_attr, profile->pool);
3555 switch_threadattr_detach_set(thd_attr, 1);
3556 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
3557 switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
3558 switch_thread_create(&profile->thread, thd_attr, sofia_profile_thread_run, profile, profile->pool);
3559 }
3560
logger(void * logarg,char const * fmt,va_list ap)3561 static void logger(void *logarg, char const *fmt, va_list ap)
3562 {
3563 if (!fmt) return;
3564
3565 switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap);
3566 }
3567
sofia_get_logger(const char * name)3568 static su_log_t *sofia_get_logger(const char *name)
3569 {
3570 if (!strcasecmp(name, "tport")) {
3571 return tport_log;
3572 } else if (!strcasecmp(name, "iptsec")) {
3573 return iptsec_log;
3574 } else if (!strcasecmp(name, "nea")) {
3575 return nea_log;
3576 } else if (!strcasecmp(name, "nta")) {
3577 return nta_log;
3578 } else if (!strcasecmp(name, "nth_client")) {
3579 return nth_client_log;
3580 } else if (!strcasecmp(name, "nth_server")) {
3581 return nth_server_log;
3582 } else if (!strcasecmp(name, "nua")) {
3583 return nua_log;
3584 } else if (!strcasecmp(name, "soa")) {
3585 return soa_log;
3586 } else if (!strcasecmp(name, "sresolv")) {
3587 return sresolv_log;
3588 #ifdef HAVE_SOFIA_STUN
3589 } else if (!strcasecmp(name, "stun")) {
3590 return stun_log;
3591 #endif
3592 } else if (!strcasecmp(name, "default")) {
3593 return su_log_default;
3594 } else {
3595 return NULL;
3596 }
3597 }
3598
sofia_set_loglevel(const char * name,int level)3599 switch_status_t sofia_set_loglevel(const char *name, int level)
3600 {
3601 su_log_t *log = NULL;
3602
3603 if (level < 0 || level > 9) {
3604 return SWITCH_STATUS_FALSE;
3605 }
3606
3607 if (!strcasecmp(name, "all")) {
3608 su_log_set_level(su_log_default, level);
3609 su_log_set_level(tport_log, level);
3610 su_log_set_level(iptsec_log, level);
3611 su_log_set_level(nea_log, level);
3612 su_log_set_level(nta_log, level);
3613 su_log_set_level(nth_client_log, level);
3614 su_log_set_level(nth_server_log, level);
3615 su_log_set_level(nua_log, level);
3616 su_log_set_level(soa_log, level);
3617 su_log_set_level(sresolv_log, level);
3618 #ifdef HAVE_SOFIA_STUN
3619 su_log_set_level(stun_log, level);
3620 #endif
3621 return SWITCH_STATUS_SUCCESS;
3622 }
3623
3624 if (!(log = sofia_get_logger(name))) {
3625 return SWITCH_STATUS_FALSE;
3626 }
3627
3628 su_log_set_level(log, level);
3629
3630 return SWITCH_STATUS_SUCCESS;
3631 }
3632
sofia_get_loglevel(const char * name)3633 int sofia_get_loglevel(const char *name)
3634 {
3635 su_log_t *log = NULL;
3636
3637 if ((log = sofia_get_logger(name))) {
3638 return log->log_level;
3639 } else {
3640 return -1;
3641 }
3642 }
3643
parse_gateway_subscriptions(sofia_profile_t * profile,sofia_gateway_t * gateway,switch_xml_t gw_subs_tag)3644 static void parse_gateway_subscriptions(sofia_profile_t *profile, sofia_gateway_t *gateway, switch_xml_t gw_subs_tag)
3645 {
3646 switch_xml_t subscription_tag, param;
3647
3648 for (subscription_tag = switch_xml_child(gw_subs_tag, "subscription"); subscription_tag; subscription_tag = subscription_tag->next) {
3649 sofia_gateway_subscription_t *gw_sub;
3650
3651 if ((gw_sub = switch_core_alloc(profile->pool, sizeof(*gw_sub)))) {
3652 char *expire_seconds = "3600", *retry_seconds = "30", *content_type = "NO_CONTENT_TYPE";
3653 uint32_t username_in_request = 0;
3654 char *event = (char *) switch_xml_attr_soft(subscription_tag, "event");
3655 gw_sub->event = switch_core_strdup(gateway->pool, event);
3656 gw_sub->gateway = gateway;
3657 gw_sub->next = NULL;
3658
3659 for (param = switch_xml_child(subscription_tag, "param"); param; param = param->next) {
3660 char *var = (char *) switch_xml_attr_soft(param, "name");
3661 char *val = (char *) switch_xml_attr_soft(param, "value");
3662 if (!strcmp(var, "expire-seconds")) {
3663 expire_seconds = val;
3664 } else if (!strcmp(var, "retry-seconds")) {
3665 retry_seconds = val;
3666 } else if (!strcmp(var, "content-type")) {
3667 content_type = val;
3668 } else if (!strcmp(var, "username-in-request")) {
3669 username_in_request = switch_true(val);
3670 }
3671 }
3672
3673 gw_sub->retry_seconds = atoi(retry_seconds);
3674 if (gw_sub->retry_seconds < 10) {
3675 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "INVALID: retry_seconds correcting the value to 30\n");
3676 gw_sub->retry_seconds = 30;
3677 }
3678
3679 gw_sub->expires_str = switch_core_strdup(gateway->pool, expire_seconds);
3680
3681 if ((gw_sub->freq = atoi(gw_sub->expires_str)) < 5) {
3682 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Freq: %d. Setting Register-Frequency to 3600\n", gw_sub->freq);
3683 gw_sub->freq = 3600;
3684 }
3685
3686 if(username_in_request) {
3687 gw_sub->request_uri = gateway->register_to;
3688 } else {
3689 gw_sub->request_uri = gateway->register_url;
3690 }
3691
3692 gw_sub->freq -= 2;
3693 gw_sub->content_type = switch_core_strdup(gateway->pool, content_type);
3694 gw_sub->next = gateway->subscriptions;
3695 }
3696 gateway->subscriptions = gw_sub;
3697 }
3698 }
3699
parse_gateways(sofia_profile_t * profile,switch_xml_t gateways_tag,const char * gwname)3700 static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag, const char *gwname)
3701 {
3702 switch_xml_t gateway_tag, param = NULL, x_params, gw_subs_tag;
3703 sofia_gateway_t *gp;
3704
3705 for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
3706 char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
3707 sofia_gateway_t *gateway;
3708 char *pkey = switch_mprintf("%s::%s", profile->name, name);
3709
3710 if (zstr(name) || switch_regex_match(name, "^[\\w\\.\\-\\_]+$") != SWITCH_STATUS_SUCCESS) {
3711 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring invalid name '%s'\n", name ? name : "NULL");
3712 free(pkey);
3713 goto skip;
3714 }
3715
3716 if (gwname && strcmp(gwname, name)) {
3717 free(pkey);
3718 goto skip;
3719 }
3720
3721 switch_mutex_lock(mod_sofia_globals.hash_mutex);
3722 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) {
3723 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", name);
3724 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
3725 free(pkey);
3726 goto skip;
3727 }
3728 free(pkey);
3729 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
3730
3731 if ((gateway = switch_core_alloc(profile->pool, sizeof(*gateway)))) {
3732 const char *sipip, *format;
3733 switch_uuid_t uuid;
3734 uint32_t ping_freq = 0, extension_in_contact = 0, contact_in_ping = 0, ping_monitoring = 0, distinct_to = 0, rfc_5626 = 0;
3735 int ping_max = 1, ping_min = 1;
3736 char *register_str = "true", *scheme = "Digest",
3737 *realm = NULL,
3738 *username = NULL,
3739 *auth_username = NULL,
3740 *password = NULL,
3741 *caller_id_in_from = "false",
3742 *extension = NULL,
3743 *proxy = NULL,
3744 *options_user_agent = NULL,
3745 *context = profile->context,
3746 *expire_seconds = "3600",
3747 *retry_seconds = "30",
3748 *fail_908_retry_seconds = NULL,
3749 *timeout_seconds = "60",
3750 *from_user = "", *from_domain = NULL, *outbound_proxy = NULL, *register_proxy = NULL, *contact_host = NULL,
3751 *contact_params = "", *params = NULL, *register_transport = NULL,
3752 *reg_id = NULL, *str_rfc_5626 = "";
3753
3754 if (!context) {
3755 context = "default";
3756 }
3757
3758 switch_uuid_get(&uuid);
3759 switch_uuid_format(gateway->uuid_str, &uuid);
3760
3761 gateway->register_transport = SOFIA_TRANSPORT_UDP;
3762 gateway->pool = profile->pool;
3763 gateway->profile = profile;
3764 gateway->name = switch_core_strdup(gateway->pool, name);
3765 gateway->freq = 0;
3766 gateway->next = NULL;
3767 gateway->ping = 0;
3768 gateway->ping_freq = 0;
3769 gateway->ping_max = 0;
3770 gateway->ping_min = 0;
3771 gateway->ping_sent = 0;
3772 gateway->ping_time = 0;
3773 gateway->ping_count = 0;
3774 gateway->ping_monitoring = SWITCH_FALSE;
3775 gateway->ib_calls = 0;
3776 gateway->ob_calls = 0;
3777 gateway->ib_failed_calls = 0;
3778 gateway->ob_failed_calls = 0;
3779 gateway->destination_prefix = "";
3780
3781 if ((x_params = switch_xml_child(gateway_tag, "variables"))) {
3782 param = switch_xml_child(x_params, "variable");
3783 } else {
3784 param = switch_xml_child(gateway_tag, "variable");
3785 }
3786
3787
3788 for (; param; param = param->next) {
3789 const char *var = switch_xml_attr(param, "name");
3790 const char *val = switch_xml_attr(param, "value");
3791 const char *direction = switch_xml_attr(param, "direction");
3792 int in = 0, out = 0;
3793
3794 if (var && val) {
3795 if (direction) {
3796 if (!strcasecmp(direction, "inbound")) {
3797 in = 1;
3798 } else if (!strcasecmp(direction, "outbound")) {
3799 out = 1;
3800 }
3801 } else {
3802 in = out = 1;
3803 }
3804
3805 if (in) {
3806 if (!gateway->ib_vars) {
3807 switch_event_create_plain(&gateway->ib_vars, SWITCH_EVENT_GENERAL);
3808 }
3809 switch_event_add_header_string(gateway->ib_vars, SWITCH_STACK_BOTTOM, var, val);
3810 }
3811
3812 if (out) {
3813 if (!gateway->ob_vars) {
3814 switch_event_create_plain(&gateway->ob_vars, SWITCH_EVENT_GENERAL);
3815 }
3816 switch_event_add_header_string(gateway->ob_vars, SWITCH_STACK_BOTTOM, var, val);
3817 }
3818 }
3819 }
3820
3821 if ((x_params = switch_xml_child(gateway_tag, "params"))) {
3822 param = switch_xml_child(x_params, "param");
3823 } else {
3824 param = switch_xml_child(gateway_tag, "param");
3825 }
3826
3827 for (; param; param = param->next) {
3828 char *var = (char *) switch_xml_attr_soft(param, "name");
3829 char *val = (char *) switch_xml_attr_soft(param, "value");
3830
3831 if (!strcmp(var, "register")) {
3832 register_str = val;
3833 } else if (!strcmp(var, "scheme")) {
3834 scheme = val;
3835 } else if (!strcmp(var, "realm")) {
3836 realm = val;
3837 } else if (!strcmp(var, "username")) {
3838 username = val;
3839 } else if (!strcmp(var, "extension-in-contact")) {
3840 extension_in_contact = switch_true(val);
3841 } else if (!strcmp(var, "auth-username")) {
3842 auth_username = val;
3843 } else if (!strcmp(var, "password")) {
3844 password = val;
3845 } else if (!strcmp(var, "caller-id-in-from")) {
3846 caller_id_in_from = val;
3847 } else if (!strcmp(var, "extension")) {
3848 extension = val;
3849 } else if (!strcmp(var, "contact-in-ping")) {
3850 contact_in_ping = switch_true(val);
3851 } else if (!strcmp(var, "ping")) {
3852 ping_freq = atoi(val);
3853 } else if (!strcmp(var, "ping-max")) {
3854 ping_max = atoi(val);
3855 } else if (!strcmp(var, "ping-min")) {
3856 ping_min = atoi(val);
3857 } else if (!strcmp(var, "ping-user-agent")) {
3858 options_user_agent = val;
3859 } else if (!strcmp(var, "ping-monitoring")) { // if true then every gw ping result will fire a gateway status event
3860 ping_monitoring = switch_true(val);
3861 } else if (!strcmp(var, "proxy")) {
3862 proxy = val;
3863 } else if (!strcmp(var, "context")) {
3864 context = val;
3865 } else if (!strcmp(var, "expire-seconds")) {
3866 expire_seconds = val;
3867 } else if (!strcmp(var, "908-retry-seconds")) {
3868 fail_908_retry_seconds = val;
3869 } else if (!strcmp(var, "retry-seconds")) {
3870 retry_seconds = val;
3871 } else if (!strcmp(var, "timeout-seconds")) {
3872 timeout_seconds = val;
3873 } else if (!strcmp(var, "retry_seconds")) { // support typo for back compat
3874 retry_seconds = val;
3875 } else if (!strcmp(var, "from-user")) {
3876 from_user = val;
3877 } else if (!strcmp(var, "from-domain")) {
3878 from_domain = val;
3879 } else if (!strcmp(var, "contact-host")) {
3880 contact_host = val;
3881 } else if (!strcmp(var, "register-proxy")) {
3882 register_proxy = val;
3883 } else if (!strcmp(var, "outbound-proxy")) {
3884 outbound_proxy = val;
3885 } else if (!strcmp(var, "distinct-to")) {
3886 distinct_to = switch_true(val);
3887 } else if (!strcmp(var, "destination-prefix")) {
3888 if (!zstr(val)) {
3889 gateway->destination_prefix = switch_core_strdup(gateway->pool, val);
3890 }
3891 } else if (!strcmp(var, "rfc-5626")) {
3892 rfc_5626 = switch_true(val);
3893 } else if (!strcmp(var, "reg-id")) {
3894 reg_id = val;
3895 } else if (!strcmp(var, "contact-params")) {
3896 contact_params = val;
3897 } else if (!strcmp(var, "register-transport")) {
3898 sofia_transport_t transport = sofia_glue_str2transport(val);
3899
3900 if (transport == SOFIA_TRANSPORT_UNKNOWN || (!sofia_test_pflag(profile, PFLAG_TLS) && sofia_glue_transport_has_tls(transport))) {
3901 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: unsupported transport\n");
3902 goto skip;
3903 }
3904
3905 gateway->register_transport = transport;
3906 }
3907 }
3908
3909 /* RFC 5626 enable in the GW profile and the UA profile */
3910 if (rfc_5626 && sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626)) {
3911 char str_guid[su_guid_strlen + 1];
3912 su_guid_t guid[1];
3913 su_guid_generate(guid);
3914 su_guid_sprintf(str_guid, su_guid_strlen + 1, guid);
3915 str_rfc_5626 = switch_core_sprintf(gateway->pool, ";reg-id=%s;+sip.instance=\"<urn:uuid:%s>\"",reg_id,str_guid);
3916 }
3917
3918 if (zstr(realm)) {
3919 if (zstr(proxy)) {
3920 realm = name;
3921 } else {
3922 realm = proxy;
3923 }
3924 }
3925
3926 if (switch_true(register_str)) {
3927 if (zstr(username)) {
3928 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: username param is REQUIRED!\n");
3929 goto skip;
3930 }
3931
3932 if (zstr(password)) {
3933 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: password param is REQUIRED!\n");
3934 goto skip;
3935 }
3936 } else {
3937 if (zstr(username)) {
3938 username = "FreeSWITCH";
3939 }
3940
3941 if (zstr(password)) {
3942 password = "";
3943 }
3944 }
3945
3946 if (zstr(from_user)) {
3947 from_user = username;
3948 }
3949
3950 if (zstr(proxy)) {
3951 proxy = realm;
3952 }
3953
3954 if (!switch_true(register_str)) {
3955 gateway->state = REG_STATE_NOREG;
3956 gateway->status = SOFIA_GATEWAY_UP;
3957 gateway->uptime = switch_time_now();
3958 }
3959
3960 if (zstr(auth_username)) {
3961 auth_username = username;
3962 }
3963
3964 if (!zstr(register_proxy)) {
3965 if (strncasecmp(register_proxy, "sip:", 4) && strncasecmp(register_proxy, "sips:", 5)) {
3966 gateway->register_sticky_proxy = switch_core_sprintf(gateway->pool, "sip:%s", register_proxy);
3967 } else {
3968 gateway->register_sticky_proxy = switch_core_strdup(gateway->pool, register_proxy);
3969 }
3970 }
3971
3972 if (!zstr(outbound_proxy)) {
3973 if (strncasecmp(outbound_proxy, "sip:", 4) && strncasecmp(outbound_proxy, "sips:", 5)) {
3974 gateway->outbound_sticky_proxy = switch_core_sprintf(gateway->pool, "sip:%s", outbound_proxy);
3975 } else {
3976 gateway->outbound_sticky_proxy = switch_core_strdup(gateway->pool, outbound_proxy);
3977 }
3978 }
3979
3980 gateway->retry_seconds = atoi(retry_seconds);
3981
3982 if (fail_908_retry_seconds) {
3983 gateway->fail_908_retry_seconds = atoi(fail_908_retry_seconds);
3984 }
3985
3986 if (gateway->retry_seconds < 5) {
3987 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid retry-seconds of %d on gateway %s, using the value of 30 instead.\n",
3988 gateway->retry_seconds, name);
3989 gateway->retry_seconds = 30;
3990 }
3991
3992 gateway->reg_timeout_seconds = atoi(timeout_seconds);
3993
3994 if (gateway->reg_timeout_seconds < 5) {
3995 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid timeout-seconds of %d on gateway %s, using the value of 60 instead.\n",
3996 gateway->reg_timeout_seconds, name);
3997 gateway->reg_timeout_seconds = 60;
3998 }
3999
4000
4001 gateway->register_scheme = switch_core_strdup(gateway->pool, scheme);
4002 gateway->register_context = switch_core_strdup(gateway->pool, context);
4003 gateway->register_realm = switch_core_strdup(gateway->pool, realm);
4004 gateway->register_username = switch_core_strdup(gateway->pool, username);
4005 gateway->auth_username = switch_core_strdup(gateway->pool, auth_username);
4006 gateway->register_password = switch_core_strdup(gateway->pool, password);
4007 gateway->distinct_to = distinct_to;
4008 gateway->options_user_agent = options_user_agent;
4009
4010 if (switch_true(caller_id_in_from)) {
4011 sofia_set_flag(gateway, REG_FLAG_CALLERID);
4012 }
4013
4014 register_transport = (char *) sofia_glue_transport2str(gateway->register_transport);
4015
4016 if (! zstr(contact_params)) {
4017 if (*contact_params == ';') {
4018 params = switch_core_sprintf(gateway->pool, "%s;transport=%s;gw=%s", contact_params, register_transport, gateway->name);
4019 } else {
4020 params = switch_core_sprintf(gateway->pool, ";%s;transport=%s;gw=%s", contact_params, register_transport, gateway->name);
4021 }
4022 } else {
4023 params = switch_core_sprintf(gateway->pool, ";transport=%s;gw=%s", register_transport, gateway->name);
4024 }
4025
4026 if (!zstr(from_domain)) {
4027 gateway->from_domain = switch_core_strdup(gateway->pool, from_domain);
4028 }
4029
4030 if (!zstr(register_transport) && !switch_stristr("transport=", proxy)) {
4031 gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", proxy, register_transport);
4032 } else {
4033 gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
4034 }
4035
4036 gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s>",
4037 from_user, !zstr(from_domain) ? from_domain : proxy);
4038
4039 if (ping_freq) {
4040 if (ping_freq >= 5) {
4041 gateway->ping_freq = ping_freq;
4042 gateway->ping_max = ping_max;
4043 gateway->ping_min = ping_min;
4044 gateway->ping_monitoring = ping_monitoring;
4045 gateway->ping = switch_epoch_time_now(NULL) + ping_freq;
4046 gateway->options_to_uri = switch_core_sprintf(gateway->pool, "<sip:%s>",
4047 !zstr(from_domain) ? from_domain : proxy);
4048 gateway->options_from_uri = gateway->options_to_uri;
4049 if (contact_in_ping) {
4050 gateway->contact_in_ping = contact_in_ping;
4051 }
4052 } else {
4053 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: invalid ping!\n");
4054 }
4055 }
4056
4057 if (contact_host) {
4058 if (!strcmp(contact_host, "sip-ip")) {
4059 sipip = profile->sipip;
4060 } else {
4061 sipip = contact_host;
4062 }
4063 } else if (profile->extsipip) {
4064 sipip = profile->extsipip;
4065 } else {
4066 sipip = profile->sipip;
4067 }
4068
4069 if (zstr(extension)) {
4070 extension = username;
4071 } else {
4072 gateway->real_extension = switch_core_strdup(gateway->pool, extension);
4073 }
4074
4075 gateway->extension = switch_core_strdup(gateway->pool, extension);
4076
4077 if (!strncasecmp(proxy, "sip:", 4)) {
4078 gateway->register_proxy = switch_core_strdup(gateway->pool, proxy);
4079 gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy + 4);
4080 } else {
4081 gateway->register_proxy = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
4082 gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy);
4083 }
4084
4085 /* This checks to make sure we provide the right contact on register for targets behind nat with us. */
4086 if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
4087 char *register_host = NULL;
4088
4089 register_host = sofia_glue_get_register_host(gateway->register_proxy);
4090
4091 if (register_host && switch_is_lan_addr(register_host)) {
4092 sipip = profile->sipip;
4093 }
4094
4095 switch_safe_free(register_host);
4096 }
4097
4098 if (extension_in_contact) {
4099 if (rfc_5626) {
4100 format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d>%s" : "<sip:%s@%s:%d%s>%s";
4101 gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
4102 sipip,
4103 sofia_glue_transport_has_tls(gateway->register_transport) ?
4104 profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
4105
4106 } else {
4107 format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d%s>" : "<sip:%s@%s:%d%s>";
4108 gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
4109 sipip,
4110 sofia_glue_transport_has_tls(gateway->register_transport) ?
4111 profile->tls_sip_port : profile->extsipport, params);
4112 }
4113 } else {
4114 if (rfc_5626) {
4115 format = strchr(sipip, ':') ? "<sip:gw+%s@[%s]:%d%s>%s" : "<sip:gw+%s@%s:%d%s>%s";
4116 gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
4117 sipip,
4118 sofia_glue_transport_has_tls(gateway->register_transport) ?
4119 profile->tls_sip_port : profile->extsipport, params, str_rfc_5626);
4120
4121 } else {
4122 format = strchr(sipip, ':') ? "<sip:gw+%s@[%s]:%d%s>" : "<sip:gw+%s@%s:%d%s>";
4123 gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name,
4124 sipip,
4125 sofia_glue_transport_has_tls(gateway->register_transport) ?
4126 profile->tls_sip_port : profile->extsipport, params);
4127
4128 }
4129 }
4130
4131 gateway->expires_str = switch_core_strdup(gateway->pool, expire_seconds);
4132
4133 if ((gateway->freq = atoi(gateway->expires_str)) < 5) {
4134 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
4135 "Invalid register-frequency of %d on gateway %s, using the value of 3600 instead\n", gateway->freq, name);
4136 gateway->freq = 3600;
4137 }
4138
4139 if ((gw_subs_tag = switch_xml_child(gateway_tag, "subscriptions"))) {
4140 parse_gateway_subscriptions(profile, gateway, gw_subs_tag);
4141 }
4142
4143 sofia_reg_add_gateway(profile, gateway->name, gateway);
4144
4145 }
4146
4147 skip:
4148 switch_assert(gateway_tag);
4149 }
4150 }
4151
parse_domain_tag(sofia_profile_t * profile,switch_xml_t x_domain_tag,const char * dname,const char * parse,const char * alias)4152 static void parse_domain_tag(sofia_profile_t *profile, switch_xml_t x_domain_tag, const char *dname, const char *parse, const char *alias)
4153 {
4154 if (switch_true(alias)) {
4155 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, dname), profile) == SWITCH_STATUS_SUCCESS) {
4156 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", dname, profile->name);
4157 } else {
4158 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Alias [%s] for profile [%s] (already exists)\n", dname, profile->name);
4159 }
4160 }
4161
4162 if (switch_true(parse)) {
4163 switch_xml_t gts, gt, uts, ut, gateways_tag;
4164 /* Backwards Compatibility */
4165 for (ut = switch_xml_child(x_domain_tag, "user"); ut; ut = ut->next) {
4166 if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
4167 parse_gateways(profile, gateways_tag, NULL);
4168 }
4169 }
4170 /* New Method with <groups> tags and users are now inside a <users> tag */
4171 for (gts = switch_xml_child(x_domain_tag, "groups"); gts; gts = gts->next) {
4172 for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) {
4173 for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) {
4174 for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) {
4175 if (((gateways_tag = switch_xml_child(ut, "gateways")))) {
4176 parse_gateways(profile, gateways_tag, NULL);
4177 }
4178 }
4179 }
4180 }
4181 }
4182 }
4183 }
4184
config_sofia_profile_urls(sofia_profile_t * profile)4185 static void config_sofia_profile_urls(sofia_profile_t * profile)
4186 {
4187
4188 if (profile->extsipip) {
4189 char *ipv6 = strchr(profile->extsipip, ':');
4190 profile->public_url = switch_core_sprintf(profile->pool,
4191 "sip:%s@%s%s%s:%d",
4192 profile->contact_user,
4193 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
4194 }
4195
4196 if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
4197 char *ipv6 = strchr(profile->extsipip, ':');
4198 profile->url = switch_core_sprintf(profile->pool,
4199 "sip:%s@%s%s%s:%d",
4200 profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->extsipport);
4201 profile->bindurl = switch_core_sprintf(profile->pool, "%s;maddr=%s", profile->url, profile->sipip);
4202 } else {
4203 char *ipv6 = strchr(profile->sipip, ':');
4204 profile->url = switch_core_sprintf(profile->pool,
4205 "sip:%s@%s%s%s:%d",
4206 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->sip_port);
4207 profile->bindurl = profile->url;
4208 }
4209
4210 profile->tcp_contact = switch_core_sprintf(profile->pool, "<%s;transport=tcp>", profile->url);
4211
4212 if (profile->public_url) {
4213 profile->tcp_public_contact = switch_core_sprintf(profile->pool, "<%s;transport=tcp>", profile->public_url);
4214 }
4215
4216 if (profile->bind_params) {
4217 char *bindurl;
4218 if (!switch_stristr("transport=", profile->bind_params)) {
4219 profile->bind_params = switch_core_sprintf(profile->pool, "%s;transport=udp,tcp", profile->bind_params);
4220 }
4221 bindurl = switch_core_sprintf(profile->pool, "%s;%s", profile->bindurl, profile->bind_params);
4222 profile->bindurl = bindurl;
4223 } else {
4224 char *bindurl = switch_core_sprintf(profile->pool, "%s;transport=udp,tcp", profile->bindurl);
4225 profile->bindurl = bindurl;
4226 }
4227
4228
4229 if ( profile->ws_port ) {
4230 char *ip = !zstr(profile->ws_ip) ? profile->ws_ip : profile->sipip;
4231 switch_port_t port = profile->ws_port;
4232 char *ipv6 = strchr(ip, ':');
4233 profile->ws_bindurl =
4234 switch_core_sprintf(profile->pool,
4235 "sip:%s@%s%s%s:%d;transport=ws",
4236 profile->contact_user, ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
4237 }
4238
4239 if ( profile->wss_port ) {
4240 char *ip = !zstr(profile->wss_ip) ? profile->wss_ip : profile->sipip;
4241 switch_port_t port = profile->wss_port;
4242 char *ipv6 = strchr(ip, ':');
4243 profile->wss_bindurl =
4244 switch_core_sprintf(profile->pool,
4245 "sips:%s@%s%s%s:%d;transport=wss",
4246 profile->contact_user, ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
4247 }
4248
4249 /*
4250 * handle TLS params #2
4251 */
4252 if (sofia_test_pflag(profile, PFLAG_TLS)) {
4253 if (!profile->tls_sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT)) {
4254 profile->tls_sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_TLS_PORT);
4255 }
4256
4257 if (profile->extsipip) {
4258 char *ipv6 = strchr(profile->extsipip, ':');
4259 profile->tls_public_url = switch_core_sprintf(profile->pool,
4260 "sip:%s@%s%s%s:%d",
4261 profile->contact_user,
4262 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port);
4263 }
4264
4265 if (profile->extsipip && !sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
4266 char *ipv6 = strchr(profile->extsipip, ':');
4267 profile->tls_url =
4268 switch_core_sprintf(profile->pool,
4269 "sip:%s@%s%s%s:%d",
4270 profile->contact_user, ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port);
4271 profile->tls_bindurl =
4272 switch_core_sprintf(profile->pool,
4273 "sips:%s@%s%s%s:%d;maddr=%s",
4274 profile->contact_user,
4275 ipv6 ? "[" : "", profile->extsipip, ipv6 ? "]" : "", profile->tls_sip_port, profile->sipip);
4276 } else {
4277 char *ipv6 = strchr(profile->sipip, ':');
4278 profile->tls_url =
4279 switch_core_sprintf(profile->pool,
4280 "sip:%s@%s%s%s:%d",
4281 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->tls_sip_port);
4282 profile->tls_bindurl =
4283 switch_core_sprintf(profile->pool,
4284 "sips:%s@%s%s%s:%d",
4285 profile->contact_user, ipv6 ? "[" : "", profile->sipip, ipv6 ? "]" : "", profile->tls_sip_port);
4286 }
4287
4288 if (profile->tls_bind_params) {
4289 char *tls_bindurl = profile->tls_bindurl;
4290 profile->tls_bindurl = switch_core_sprintf(profile->pool, "%s;%s", tls_bindurl, profile->tls_bind_params);
4291 }
4292
4293 profile->tls_contact = switch_core_sprintf(profile->pool, "<%s;transport=tls>", profile->tls_url);
4294 if (profile->tls_public_url) {
4295 profile->tls_public_contact = switch_core_sprintf(profile->pool, "<%s;transport=tls>", profile->tls_public_url);
4296 }
4297
4298
4299 }
4300 }
4301
4302 #ifdef SOFIA_CUSTOM_TIME
4303 /* appears to not be granular enough */
sofia_time(su_time_t * tv)4304 static void sofia_time(su_time_t *tv)
4305 {
4306 switch_time_t now;
4307
4308 if (tv) {
4309 now = switch_micro_time_now();
4310 tv->tv_sec = ((uint32_t) (now / 1000000)) + 2208988800UL;
4311 tv->tv_usec = (uint32_t) (now % 1000000);
4312 }
4313
4314 }
4315 #endif
4316
sofia_init(void)4317 switch_status_t sofia_init(void)
4318 {
4319 su_init();
4320 if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) {
4321 su_deinit();
4322 sip_cloned_parser_destroy();
4323 return SWITCH_STATUS_GENERR;
4324 }
4325
4326 #ifdef SOFIA_TIME
4327 su_set_time_func(sofia_time);
4328 #endif
4329
4330 /* Redirect loggers in sofia */
4331 su_log_redirect(su_log_default, logger, NULL);
4332 su_log_redirect(tport_log, logger, NULL);
4333 su_log_redirect(iptsec_log, logger, NULL);
4334 su_log_redirect(nea_log, logger, NULL);
4335 su_log_redirect(nta_log, logger, NULL);
4336 su_log_redirect(nth_client_log, logger, NULL);
4337 su_log_redirect(nth_server_log, logger, NULL);
4338 su_log_redirect(nua_log, logger, NULL);
4339 su_log_redirect(soa_log, logger, NULL);
4340 su_log_redirect(sresolv_log, logger, NULL);
4341 #ifdef HAVE_SOFIA_STUN
4342 su_log_redirect(stun_log, logger, NULL);
4343 #endif
4344
4345 return SWITCH_STATUS_SUCCESS;
4346 }
4347
config_gateway(const char * profile_name,const char * gateway_name)4348 switch_status_t config_gateway(const char *profile_name, const char *gateway_name)
4349 {
4350 switch_xml_t cfg, xml = NULL, xprofiles, xprofile, gateways_tag;
4351 switch_status_t status = SWITCH_STATUS_SUCCESS;
4352 sofia_profile_t *profile = NULL;
4353 switch_event_t *params = NULL;
4354 const char *cf = "sofia.conf";
4355
4356 if (zstr(profile_name) || !(profile = sofia_glue_find_profile(profile_name))) {
4357 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile [%s] does not exist.\n", profile_name);
4358 status = SWITCH_STATUS_FALSE;
4359 return status;
4360 }
4361
4362 switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS);
4363 switch_assert(params);
4364 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile_name);
4365 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true");
4366 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "gateway", gateway_name);
4367
4368 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4369 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", gateway_name);
4370 status = SWITCH_STATUS_FALSE;
4371 goto done;
4372 }
4373
4374 if ((xprofiles = switch_xml_child(cfg, "profiles"))) {
4375 if ((xprofile = switch_xml_find_child(xprofiles, "profile", "name", profile->name))) {
4376 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
4377 parse_gateways(profile, gateways_tag, strcmp(gateway_name, "_all_") ? gateway_name : NULL);
4378 }
4379 }
4380 }
4381
4382 status = SWITCH_STATUS_SUCCESS;
4383
4384 done:
4385
4386 sofia_glue_release_profile(profile);
4387 if (xml) switch_xml_free(xml);
4388
4389 switch_event_destroy(¶ms);
4390
4391 return status;
4392 }
4393
config_sofia(sofia_config_t reload,char * profile_name)4394 switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
4395 {
4396 char *cf = "sofia.conf";
4397 switch_xml_t cfg, xml = NULL, xprofile, param, settings, profiles;
4398 switch_status_t status = SWITCH_STATUS_SUCCESS;
4399 sofia_profile_t *profile = NULL;
4400 char url[512] = "";
4401 int profile_found = 0;
4402 switch_event_t *params = NULL;
4403 sofia_profile_t *profile_already_started = NULL;
4404
4405 if (!zstr(profile_name) && (profile = sofia_glue_find_profile(profile_name))) {
4406 if (reload == SOFIA_CONFIG_RESCAN) {
4407 profile_already_started = profile;
4408 } else {
4409 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile [%s] Already exists.\n", switch_str_nil(profile_name));
4410 status = SWITCH_STATUS_FALSE;
4411 sofia_glue_release_profile(profile);
4412 return status;
4413 }
4414 }
4415
4416 switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS);
4417 switch_assert(params);
4418 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile_name);
4419 if (reload == SOFIA_CONFIG_RESCAN) {
4420 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true");
4421 }
4422
4423 if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4424 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
4425 status = SWITCH_STATUS_FALSE;
4426 goto done;
4427 }
4428
4429 mod_sofia_globals.auto_restart = SWITCH_TRUE;
4430 mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = SWITCH_FALSE; /* handle backwards compatilibity - by default use new behavior */
4431 mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
4432
4433 if ((settings = switch_xml_child(cfg, "global_settings"))) {
4434 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
4435 char *var = (char *) switch_xml_attr_soft(param, "name");
4436 char *val = (char *) switch_xml_attr_soft(param, "value");
4437 if (!strcasecmp(var, "log-level")) {
4438 su_log_set_level(NULL, atoi(val));
4439 } else if (!strcasecmp(var, "abort-on-empty-external-ip")) {
4440 mod_sofia_globals.abort_on_empty_external_ip = switch_true(val);
4441 } else if (!strcasecmp(var, "tracelevel")) {
4442 mod_sofia_globals.tracelevel = switch_log_str2level(val);
4443 } else if (!strcasecmp(var, "debug-presence")) {
4444 mod_sofia_globals.debug_presence = atoi(val);
4445 } else if (!strcasecmp(var, "debug-sla")) {
4446 mod_sofia_globals.debug_sla = atoi(val);
4447 } else if (!strcasecmp(var, "max-reg-threads") && val) {
4448 int x = atoi(val);
4449
4450 if (x > 0) {
4451 mod_sofia_globals.max_reg_threads = x;
4452 }
4453
4454 } else if (!strcasecmp(var, "auto-restart")) {
4455 mod_sofia_globals.auto_restart = switch_true(val);
4456 } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */
4457 mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
4458 if (switch_true(val)) {
4459 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
4460 "deprecated and will be removed - let FS devs know if you think it should stay\n");
4461 }
4462 } else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
4463 if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) {
4464 /* old behaviour */
4465 mod_sofia_globals.rewrite_multicasted_fs_path = 1;
4466 } else if (!strcasecmp(val, "original_server_host")) {
4467 mod_sofia_globals.rewrite_multicasted_fs_path = 2;
4468 } else if (!strcasecmp(val, "original_hostname")) {
4469 mod_sofia_globals.rewrite_multicasted_fs_path = 3;
4470 } else {
4471 mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
4472 }
4473 } else if (!strcasecmp(var, "capture-server")) {
4474 mod_sofia_globals.capture_server = switch_core_strdup(mod_sofia_globals.pool, val);
4475 }
4476 }
4477 }
4478
4479 if ((profiles = switch_xml_child(cfg, "profiles"))) {
4480 for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
4481 char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name");
4482 char *xprofiledomain = (char *) switch_xml_attr(xprofile, "domain");
4483 if (!(settings = switch_xml_child(xprofile, "settings"))) {
4484 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Settings, check the new config!\n");
4485 sofia_profile_start_failure(NULL, xprofilename);
4486 } else {
4487 switch_memory_pool_t *pool = NULL;
4488
4489 if (!xprofilename) {
4490 xprofilename = "unnamed";
4491 }
4492
4493 if (profile_name) {
4494 if (strcasecmp(profile_name, xprofilename)) {
4495 continue;
4496 } else {
4497 profile_found = 1;
4498 }
4499 }
4500
4501 if (!profile_already_started) {
4502
4503 /* Setup the pool */
4504 if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
4505 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
4506 sofia_profile_start_failure(NULL, xprofilename);
4507 goto done;
4508 }
4509
4510 if (!(profile = (sofia_profile_t *) switch_core_alloc(pool, sizeof(*profile)))) {
4511 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
4512 sofia_profile_start_failure(NULL, xprofilename);
4513 goto done;
4514 }
4515
4516 profile->tls_verify_policy = TPTLS_VERIFY_NONE;
4517 sofia_set_pflag(profile, PFLAG_AUTO_INVITE_100);
4518 /* lib default */
4519 profile->tls_verify_depth = 2;
4520
4521
4522 switch_mutex_init(&profile->gw_mutex, SWITCH_MUTEX_NESTED, pool);
4523
4524 profile->trans_timeout = 100;
4525
4526 profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
4527
4528 profile->pool = pool;
4529
4530 profile->user_agent = switch_core_sprintf(profile->pool, "FreeSWITCH-mod_sofia/%s", switch_version_full());
4531
4532 profile->sip_user_ping_max = 3;
4533 profile->sip_user_ping_min = 1;
4534
4535 profile->name = switch_core_strdup(profile->pool, xprofilename);
4536 switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename);
4537
4538 if (xprofiledomain) {
4539 profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain);
4540 }
4541
4542 profile->dbname = switch_core_strdup(profile->pool, url);
4543 switch_core_hash_init(&profile->chat_hash);
4544 switch_core_hash_init(&profile->reg_nh_hash);
4545 switch_core_hash_init(&profile->mwi_debounce_hash);
4546 switch_thread_rwlock_create(&profile->rwlock, profile->pool);
4547 switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED, profile->pool);
4548 profile->dtmf_duration = 100;
4549 profile->rtp_digit_delay = 40;
4550 profile->sip_force_expires = 0;
4551 profile->sip_force_expires_min = 0;
4552 profile->sip_force_expires_max = 0;
4553 profile->sip_expires_max_deviation = 0;
4554 profile->sip_expires_late_margin = 60;
4555 profile->sip_subscription_max_deviation = 0;
4556 profile->tls_ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
4557 profile->tls_version = SOFIA_TLS_VERSION_TLSv1;
4558 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_1;
4559 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
4560 profile->tls_timeout = 300;
4561 profile->mflags = MFLAG_REFER | MFLAG_REGISTER;
4562 profile->server_rport_level = 1;
4563 profile->client_rport_level = 1;
4564 profile->tls_cert_dir = SWITCH_GLOBAL_dirs.certs_dir;
4565 sofia_set_pflag(profile, PFLAG_DISABLE_100REL);
4566 sofia_set_pflag(profile, PFLAG_ENABLE_CHAT);
4567 profile->auto_restart = 1;
4568 sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING);
4569 sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE);
4570 profile->contact_user = SOFIA_DEFAULT_CONTACT_USER;
4571 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
4572 sofia_set_pflag(profile, PFLAG_ALLOW_UPDATE);
4573 sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE);
4574 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
4575 //sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
4576
4577 sofia_clear_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER);
4578 sofia_clear_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE);
4579 sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
4580 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
4581 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403);
4582 sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER);
4583 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY);
4584 sofia_clear_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK);
4585 profile->shutdown_type = "false";
4586 profile->local_network = "localnet.auto";
4587 sofia_set_flag(profile, TFLAG_ENABLE_SOA);
4588 sofia_set_pflag(profile, PFLAG_CID_IN_1XX);
4589 profile->mndlb |= SM_NDLB_ALLOW_NONDUP_SDP;
4590 profile->te = 101;
4591 profile->ireg_seconds = IREG_SECONDS;
4592 profile->iping_seconds = IPING_SECONDS;
4593 profile->iping_freq = IPING_FREQUENCY;
4594 profile->paid_type = PAID_DEFAULT;
4595 profile->bind_attempts = 2;
4596 profile->bind_attempt_interval = 5;
4597 profile->dtmf_type = DTMF_2833;
4598 profile->tls_verify_policy = TPTLS_VERIFY_NONE;
4599 /* lib default */
4600 profile->tls_verify_depth = 2;
4601 profile->tls_verify_date = SWITCH_TRUE;
4602 } else {
4603
4604 /* you could change profile->foo here if it was a minor change like context or dialplan ... */
4605 profile->acl_count = 0;
4606 profile->nat_acl_count = 0;
4607 profile->reg_acl_count = 0;
4608 profile->proxy_acl_count = 0;
4609 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
4610 profile->ib_calls = 0;
4611 profile->ob_calls = 0;
4612 profile->ib_failed_calls = 0;
4613 profile->ob_failed_calls = 0;
4614 profile->shutdown_type = "false";
4615 profile->rtpip_index = 0;
4616 profile->rtpip_index6 = 0;
4617
4618 if (xprofiledomain) {
4619 profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain);
4620 }
4621 }
4622
4623 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
4624 char *var = (char *) switch_xml_attr_soft(param, "name");
4625 char *val = (char *) switch_xml_attr_soft(param, "value");
4626 int found = 1; // Used to break up long if/elseif chain (MSVC2015 fails (parser stack overflow) otherwise)
4627
4628 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s [%s]\n", var, val);
4629
4630 if (!strcasecmp(var, "debug") && val) {
4631 profile->debug = atoi(val);
4632 } else if (!strcasecmp(var, "parse-invite-tel-params")) {
4633 profile->parse_invite_tel_params = switch_true(val);
4634 } else if (!strcasecmp(var, "keepalive-method") && !zstr(val)) {
4635 if (!strcasecmp(val, "info")) {
4636 profile->keepalive = KA_INFO;
4637 } else {
4638 profile->keepalive = KA_MESSAGE;
4639 }
4640 } else if (!strcasecmp(var, "bind-attempts") && val) {
4641 int ba = atoi(val) - 1;
4642
4643 if (ba >= 0) {
4644 profile->bind_attempts = ba;
4645 }
4646 } else if (!strcasecmp(var, "bind-attempt-interval") && val) {
4647 int bai = atoi(val);
4648
4649 if (bai >= 0) {
4650 profile->bind_attempt_interval = bai;
4651 }
4652 } else if (!strcasecmp(var, "shutdown-on-fail")) {
4653 profile->shutdown_type = switch_core_strdup(profile->pool, val);
4654 } else if (!strcasecmp(var, "sip-trace")) {
4655 if (switch_true(val)) {
4656 sofia_set_flag(profile, TFLAG_TPORT_LOG);
4657 } else {
4658 sofia_clear_flag(profile, TFLAG_TPORT_LOG);
4659 }
4660 } else if (!strcasecmp(var, "sip-capture")) {
4661 if (switch_true(val)) {
4662 sofia_set_flag(profile, TFLAG_CAPTURE);
4663 nua_set_params(profile->nua, TPTAG_CAPT(mod_sofia_globals.capture_server), TAG_END());
4664 } else {
4665 sofia_clear_flag(profile, TFLAG_CAPTURE);
4666 }
4667 } else if (!strcasecmp(var, "socket-tcp-keepalive") && !zstr(val)) {
4668 profile->socket_tcp_keepalive = atoi(val);
4669 sofia_set_pflag(profile, PFLAG_SOCKET_TCP_KEEPALIVE);
4670 } else if (!strcasecmp(var, "tcp-keepalive") && !zstr(val)) {
4671 profile->tcp_keepalive = atoi(val);
4672 sofia_set_pflag(profile, PFLAG_TCP_KEEPALIVE);
4673 } else if (!strcasecmp(var, "tcp-pingpong") && !zstr(val)) {
4674 profile->tcp_pingpong = atoi(val);
4675 sofia_set_pflag(profile, PFLAG_TCP_PINGPONG);
4676 } else if (!strcasecmp(var, "tcp-ping2pong") && !zstr(val)) {
4677 profile->tcp_ping2pong = atoi(val);
4678 sofia_set_pflag(profile, PFLAG_TCP_PING2PONG);
4679 } else if ((!strcasecmp(var, "proxy-refer-replaces") || !strcasecmp(var, "proxy-refer")) && !zstr(val)) {
4680 if (switch_true(val)) {
4681 sofia_set_pflag(profile, PFLAG_PROXY_REFER);
4682 } else {
4683 sofia_clear_pflag(profile, PFLAG_PROXY_REFER);
4684 }
4685 } else if (!strcasecmp(var, "sip-messages-respond-200-ok") && !zstr(val)) {
4686 if (switch_true(val)) {
4687 sofia_set_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK);
4688 } else {
4689 sofia_clear_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK);
4690 }
4691 } else if (!strcasecmp(var, "sip-subscribe-respond-200-ok") && !zstr(val)) {
4692 if (switch_true(val)) {
4693 sofia_set_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK);
4694 } else {
4695 sofia_clear_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK);
4696 }
4697 } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) {
4698 profile->odbc_dsn = switch_core_strdup(profile->pool, val);
4699 } else if (!strcasecmp(var, "db-pre-trans-execute") && !zstr(val)) {
4700 profile->pre_trans_execute = switch_core_strdup(profile->pool, val);
4701 } else if (!strcasecmp(var, "db-post-trans-execute") && !zstr(val)) {
4702 profile->post_trans_execute = switch_core_strdup(profile->pool, val);
4703 } else if (!strcasecmp(var, "db-inner-pre-trans-execute") && !zstr(val)) {
4704 profile->inner_pre_trans_execute = switch_core_strdup(profile->pool, val);
4705 } else if (!strcasecmp(var, "db-inner-post-trans-execute") && !zstr(val)) {
4706 profile->inner_post_trans_execute = switch_core_strdup(profile->pool, val);
4707 } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) {
4708 if (switch_true(val)) {
4709 sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
4710 } else {
4711 sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY);
4712 }
4713 } else if (!strcasecmp(var, "NDLB-proxy-never-patch-reinvites")) {
4714 if (switch_true(val)) {
4715 profile->mndlb |= SM_NDLB_NEVER_PATCH_REINVITE;
4716 } else {
4717 profile->mndlb &= ~SM_NDLB_NEVER_PATCH_REINVITE;
4718 }
4719 } else if (!strcasecmp(var, "registration-thread-frequency") && !zstr(val)) {
4720 profile->ireg_seconds = atoi(val);
4721 if (profile->ireg_seconds < 0) {
4722 profile->ireg_seconds = IREG_SECONDS;
4723 }
4724 } else if (!strcasecmp(var, "ping-mean-interval") && !zstr(val)) {
4725 profile->iping_seconds = atoi(val);
4726 if (profile->iping_seconds < 0) {
4727 profile->iping_seconds = IPING_SECONDS;
4728 }
4729 } else if (!strcasecmp(var, "ping-thread-frequency") && !zstr(val)) {
4730 profile->iping_freq = atoi(val);
4731 if (profile->iping_freq < 0) {
4732 profile->iping_freq = IPING_FREQUENCY;
4733 }
4734 } else if (!strcasecmp(var, "user-agent-string")) {
4735 profile->user_agent = switch_core_strdup(profile->pool, val);
4736 } else if (!strcasecmp(var, "auto-restart")) {
4737 profile->auto_restart = switch_true(val);
4738 } else if (!strcasecmp(var, "log-auth-failures")) {
4739 if (switch_true(val)) {
4740 sofia_set_pflag(profile, PFLAG_LOG_AUTH_FAIL);
4741 } else {
4742 sofia_clear_pflag(profile, PFLAG_LOG_AUTH_FAIL);
4743 }
4744 } else if (!strcasecmp(var, "confirm-blind-transfer")) {
4745 if (switch_true(val)) {
4746 sofia_set_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER);
4747 } else {
4748 sofia_clear_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER);
4749 }
4750 } else if (!strcasecmp(var, "allow-update")) {
4751 if (switch_true(val)) {
4752 sofia_set_pflag(profile, PFLAG_ALLOW_UPDATE);
4753 } else {
4754 sofia_clear_pflag(profile, PFLAG_ALLOW_UPDATE);
4755 }
4756 } else if (!strcasecmp(var, "send-display-update")) {
4757 if (switch_true(val)) {
4758 sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE);
4759 } else {
4760 sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE);
4761 }
4762 } else if (!strcasecmp(var, "mwi-use-reg-callid")) {
4763 if (switch_true(val)) {
4764 sofia_set_pflag(profile, PFLAG_MWI_USE_REG_CALLID);
4765 } else {
4766 sofia_clear_pflag(profile, PFLAG_MWI_USE_REG_CALLID);
4767 }
4768 } else if (!strcasecmp(var, "tcp-unreg-on-socket-close")) {
4769 if (switch_true(val)) {
4770 sofia_set_pflag(profile, PFLAG_TCP_UNREG_ON_SOCKET_CLOSE);
4771 } else {
4772 sofia_clear_pflag(profile, PFLAG_TCP_UNREG_ON_SOCKET_CLOSE);
4773 }
4774 } else if (!strcasecmp(var, "tcp-always-nat")) {
4775 if (switch_true(val)) {
4776 sofia_set_pflag(profile, PFLAG_TCP_ALWAYS_NAT);
4777 } else {
4778 sofia_clear_pflag(profile, PFLAG_TCP_ALWAYS_NAT);
4779 }
4780 } else if (!strcasecmp(var, "tls-always-nat")) {
4781 if (switch_true(val)) {
4782 sofia_set_pflag(profile, PFLAG_TLS_ALWAYS_NAT);
4783 } else {
4784 sofia_clear_pflag(profile, PFLAG_TLS_ALWAYS_NAT);
4785 }
4786 } else if (!strcasecmp(var, "presence-proto-lookup")) {
4787 if (switch_true(val)) {
4788 sofia_set_pflag(profile, PFLAG_PRESENCE_MAP);
4789 } else {
4790 sofia_clear_pflag(profile, PFLAG_PRESENCE_MAP);
4791 }
4792 } else if (!strcasecmp(var, "profile-standby")) {
4793 if (switch_true(val)) {
4794 sofia_set_pflag(profile, PFLAG_STANDBY);
4795 } else {
4796 sofia_clear_pflag(profile, PFLAG_STANDBY);
4797 }
4798 } else if (!strcasecmp(var, "liberal-dtmf")) {
4799 if (switch_true(val)) {
4800 sofia_set_pflag(profile, PFLAG_LIBERAL_DTMF);
4801 } else {
4802 sofia_clear_pflag(profile, PFLAG_LIBERAL_DTMF);
4803 }
4804 } else if (!strcasecmp(var, "rtp-digit-delay") && !zstr(val)) {
4805 int delay = atoi(val);
4806 if (delay < 0) {
4807 delay = 0;
4808 }
4809 profile->rtp_digit_delay = (uint32_t) delay;
4810 } else if (!strcasecmp(var, "watchdog-enabled")) {
4811 profile->watchdog_enabled = switch_true(val);
4812 } else if (!strcasecmp(var, "watchdog-step-timeout") && !zstr(val)) {
4813 profile->step_timeout = atoi(val);
4814 } else if (!strcasecmp(var, "watchdog-event-timeout") && !zstr(val)) {
4815 profile->event_timeout = atoi(val);
4816 } else if (!strcasecmp(var, "in-dialog-chat")) {
4817 if (switch_true(val)) {
4818 sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT);
4819 } else {
4820 sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT);
4821 }
4822 } else if (!strcasecmp(var, "enable-chat")) {
4823 if (switch_true(val)) {
4824 sofia_set_pflag(profile, PFLAG_ENABLE_CHAT);
4825 } else {
4826 sofia_clear_pflag(profile, PFLAG_ENABLE_CHAT);
4827 }
4828 } else if (!strcasecmp(var, "fire-bye-response-events")) {
4829 if (switch_true(val)) {
4830 sofia_set_pflag(profile, PFLAG_FIRE_BYE_RESPONSE_EVENTS);
4831 } else {
4832 sofia_clear_pflag(profile, PFLAG_FIRE_BYE_RESPONSE_EVENTS);
4833 }
4834 } else if (!strcasecmp(var, "fire-message-events")) {
4835 if (switch_true(val)) {
4836 sofia_set_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS);
4837 } else {
4838 sofia_clear_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS);
4839 }
4840 } else if (!strcasecmp(var, "t38-passthru")) {
4841 if (switch_true(val)) {
4842 sofia_set_pflag(profile, PFLAG_T38_PASSTHRU);
4843 } else {
4844 sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU);
4845 }
4846 } else if (!strcasecmp(var, "presence-disable-early")) {
4847 if (switch_true(val)) {
4848 sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
4849 } else {
4850 sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY);
4851 }
4852 } else if (!strcasecmp(var, "ignore-183nosdp")) {
4853 if (switch_true(val)) {
4854 sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP);
4855 } else {
4856 sofia_clear_pflag(profile, PFLAG_IGNORE_183NOSDP);
4857 }
4858 } else if (!strcasecmp(var, "presence-probe-on-register")) {
4859 if (switch_true(val)) {
4860 sofia_set_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER);
4861 } else {
4862 sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER);
4863 }
4864 } else if (!strcasecmp(var, "send-presence-on-register")) {
4865 if (val && (switch_true(val) || !strcasecmp(val, "all"))) {
4866 sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER);
4867 } else if (val && !strcasecmp(val, "first-only")) {
4868 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER);
4869 sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
4870 } else {
4871 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER);
4872 sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
4873 }
4874 } else if (!strcasecmp(var, "cid-in-1xx")) {
4875 if (switch_true(val)) {
4876 sofia_set_pflag(profile, PFLAG_CID_IN_1XX);
4877 } else {
4878 sofia_clear_pflag(profile, PFLAG_CID_IN_1XX);
4879 }
4880 } else if (!strcasecmp(var, "disable-hold")) {
4881 if (switch_true(val)) {
4882 sofia_set_media_flag(profile, SCMF_DISABLE_HOLD);
4883 } else {
4884 sofia_clear_media_flag(profile, SCMF_DISABLE_HOLD);
4885 }
4886 } else if (!strcasecmp(var, "auto-jitterbuffer-msec") && !zstr(val)) {
4887 int msec = atoi(val);
4888 if (msec > 19) {
4889 profile->jb_msec = switch_core_strdup(profile->pool, val);
4890 }
4891 } else if (!strcasecmp(var, "dtmf-type")) {
4892 if (val && !strcasecmp(val, "rfc2833")) {
4893 profile->dtmf_type = DTMF_2833;
4894 } else if (val && !strcasecmp(val, "info")) {
4895 profile->dtmf_type = DTMF_INFO;
4896 } else {
4897 profile->dtmf_type = DTMF_NONE;
4898 }
4899 } else if (!strcasecmp(var, "NDLB-force-rport")) {
4900 if (val && !strcasecmp(val, "safe")) {
4901 profile->server_rport_level = 3;
4902 profile->client_rport_level = 1;
4903 } else if (val && !strcasecmp(val, "disabled")) {
4904 profile->server_rport_level = 0;
4905 profile->client_rport_level = 0;
4906 } else if (val && !strcasecmp(val, "client-only")) {
4907 profile->client_rport_level = 1;
4908 } else if (val && !strcasecmp(val, "server-only")) {
4909 profile->client_rport_level = 0;
4910 profile->server_rport_level = 1;
4911 } else if (switch_true(val)) {
4912 profile->server_rport_level = 2;
4913 profile->client_rport_level = 1;
4914 }
4915 } else if (!strcasecmp(var, "auto-rtp-bugs")) {
4916 switch_core_media_parse_rtp_bugs(&profile->auto_rtp_bugs, val);
4917 } else if (!strcasecmp(var, "manual-rtp-bugs")) {
4918 switch_core_media_parse_rtp_bugs(&profile->manual_rtp_bugs, val);
4919 } else if (!strcasecmp(var, "manual-video-rtp-bugs")) {
4920 switch_core_media_parse_rtp_bugs(&profile->manual_video_rtp_bugs, val);
4921 } else if (!strcasecmp(var, "dbname")) {
4922 profile->dbname = switch_core_strdup(profile->pool, val);
4923 } else if (!strcasecmp(var, "presence-hosts")) {
4924 profile->presence_hosts = switch_core_strdup(profile->pool, val);
4925 } else if (!strcasecmp(var, "caller-id-type")) {
4926 profile->cid_type = sofia_cid_name2type(val);
4927 } else if (!strcasecmp(var, "record-template")) {
4928 profile->record_template = switch_core_strdup(profile->pool, val);
4929 } else if (!strcasecmp(var, "record-path")) {
4930 profile->record_path = switch_core_strdup(profile->pool, val);
4931 } else if (!strcasecmp(var, "inbound-no-media") || !strcasecmp(var, "inbound-bypass-media")) {
4932 if (switch_true(val)) {
4933 sofia_set_flag(profile, TFLAG_INB_NOMEDIA);
4934 } else {
4935 sofia_clear_flag(profile, TFLAG_INB_NOMEDIA);
4936 }
4937 } else if (!strcasecmp(var, "inbound-late-negotiation")) {
4938 if (switch_true(val)) {
4939 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
4940 } else {
4941 sofia_clear_flag(profile, TFLAG_LATE_NEGOTIATION);
4942 }
4943 } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) {
4944 if (switch_true(val)) {
4945 sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE);
4946 } else {
4947 sofia_clear_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE);
4948 }
4949 } else if (!strcasecmp(var, "manual-redirect")) {
4950 if (switch_true(val)) {
4951 sofia_set_pflag(profile, PFLAG_MANUAL_REDIRECT);
4952 } else {
4953 sofia_clear_pflag(profile, PFLAG_MANUAL_REDIRECT);
4954 }
4955 } else if (!strcasecmp(var, "inbound-proxy-media")) {
4956 if (switch_true(val)) {
4957 sofia_set_flag(profile, TFLAG_PROXY_MEDIA);
4958 } else {
4959 sofia_clear_flag(profile, TFLAG_PROXY_MEDIA);
4960 }
4961 } else if (!strcasecmp(var, "inbound-zrtp-passthru")) {
4962 if (switch_true(val)) {
4963 sofia_set_flag(profile, TFLAG_ZRTP_PASSTHRU);
4964 } else {
4965 sofia_clear_flag(profile, TFLAG_ZRTP_PASSTHRU);
4966 }
4967 } else if (!strcasecmp(var, "force-subscription-expires") && !zstr(val)) {
4968 int tmp = atoi(val);
4969 if (tmp > 0) {
4970 profile->force_subscription_expires = tmp;
4971 }
4972 } else if (!strcasecmp(var, "force-publish-expires") && !zstr(val)) {
4973 int tmp = atoi(val);
4974 if (tmp > 0) {
4975 profile->force_publish_expires = tmp;
4976 }
4977 } else if (!strcasecmp(var, "send-message-query-on-register")) {
4978 if (switch_true(val)) {
4979 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
4980 } else if (val && !strcasecmp(val, "first-only")) {
4981 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
4982 sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
4983 } else {
4984 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
4985 sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
4986 }
4987 } else if (!strcasecmp(var, "inbound-reg-in-new-thread") && val) {
4988 if (switch_true(val)) {
4989 sofia_set_pflag(profile, PFLAG_THREAD_PER_REG);
4990 } else {
4991 sofia_clear_pflag(profile, PFLAG_THREAD_PER_REG);
4992 }
4993 } else if (!strcasecmp(var, "inbound-use-callid-as-uuid")) {
4994 if (switch_true(val)) {
4995 sofia_set_pflag(profile, PFLAG_CALLID_AS_UUID);
4996 } else {
4997 sofia_clear_pflag(profile, PFLAG_CALLID_AS_UUID);
4998 }
4999 } else if (!strcasecmp(var, "outbound-use-uuid-as-callid")) {
5000 if (switch_true(val)) {
5001 sofia_set_pflag(profile, PFLAG_UUID_AS_CALLID);
5002 } else {
5003 sofia_clear_pflag(profile, PFLAG_UUID_AS_CALLID);
5004 }
5005 } else if (!strcasecmp(var, "track-calls")) {
5006 if (switch_true(val)) {
5007 sofia_set_pflag(profile, PFLAG_TRACK_CALLS);
5008 }
5009 } else if (!strcasecmp(var, "NDLB-received-in-nat-reg-contact")) {
5010 if (switch_true(val)) {
5011 sofia_set_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT);
5012 } else {
5013 sofia_clear_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT);
5014 }
5015 } else if (!strcasecmp(var, "aggressive-nat-detection")) {
5016 if (switch_true(val)) {
5017 sofia_set_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION);
5018 } else {
5019 sofia_clear_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION);
5020 }
5021 } else if (!strcasecmp(var, "disable-rtp-auto-adjust")) {
5022 if (switch_true(val)) {
5023 sofia_set_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ);
5024 } else {
5025 sofia_clear_media_flag(profile, SCMF_DISABLE_RTP_AUTOADJ);
5026 }
5027 } else if (!strcasecmp(var, "NDLB-support-asterisk-missing-srtp-auth")) {
5028 if (switch_true(val)) {
5029 profile->mndlb |= SM_NDLB_DISABLE_SRTP_AUTH;
5030 } else {
5031 profile->mndlb &= ~SM_NDLB_DISABLE_SRTP_AUTH;
5032 }
5033 } else if (!strcasecmp(var, "user-agent-filter")) {
5034 profile->user_agent_filter = switch_core_strdup(profile->pool, val);
5035 } else if (!strcasecmp(var, "max-registrations-per-extension") && !zstr(val)) {
5036 profile->max_registrations_perext = atoi(val);
5037 } else if (!strcasecmp(var, "rfc2833-pt") && !zstr(val)) {
5038 profile->te = (switch_payload_t) atoi(val);
5039 } else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG) && !zstr(val)) {
5040 profile->cng_pt = (switch_payload_t) atoi(val);
5041 } else if (!strcasecmp(var, "sip-port") && !zstr(val)) {
5042 if (!strcasecmp(val, "auto")) {
5043 sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_PORT);
5044 } else {
5045 profile->sip_port = (switch_port_t) atoi(val);
5046 if (!profile->extsipport) profile->extsipport = profile->sip_port;
5047 }
5048 } else if (!strcasecmp(var, "vad") && !zstr(val)) {
5049 if (!strcasecmp(val, "in")) {
5050 profile->vflags |= VAD_IN;
5051 } else if (!strcasecmp(val, "out")) {
5052 profile->vflags |= VAD_OUT;
5053 } else if (!strcasecmp(val, "both")) {
5054 profile->vflags |= VAD_OUT | VAD_IN;
5055 } else if (strcasecmp(val, "none")) {
5056 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid option %s for VAD\n", val);
5057 }
5058 } else if (!strcasecmp(var, "ext-rtp-ip")) {
5059 if (!zstr(val)) {
5060 char *ip = mod_sofia_globals.guess_ip;
5061
5062 if (!strcmp(val, "0.0.0.0")) {
5063 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n",
5064 mod_sofia_globals.guess_ip);
5065 } else if (!strcasecmp(val, "auto-nat")) {
5066 ip = NULL;
5067 } else {
5068 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5069 sofia_clear_pflag(profile, PFLAG_AUTO_NAT);
5070 }
5071 if (ip) {
5072 if (!strncasecmp(ip, "autonat:", 8)) {
5073 profile->extrtpip = switch_core_strdup(profile->pool, ip + 8);
5074 if (zstr(profile->extsipip)) {
5075 profile->extsipip = switch_core_strdup(profile->pool, profile->extrtpip);
5076 }
5077 sofia_set_pflag(profile, PFLAG_AUTO_NAT);
5078 } else {
5079 profile->extrtpip = switch_core_strdup(profile->pool, ip);
5080 }
5081 }
5082 } else {
5083 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ext-rtp-ip\n");
5084 if (mod_sofia_globals.abort_on_empty_external_ip) {
5085 switch_goto_status(SWITCH_STATUS_GENERR, done);
5086 }
5087 }
5088 } else if (!strcasecmp(var, "rtp-ip")) {
5089 char *ip = mod_sofia_globals.guess_ip;
5090 char buf[64];
5091
5092 if (zstr(val)) {
5093 ip = mod_sofia_globals.guess_ip;
5094 } else if (!strcmp(val, "0.0.0.0")) {
5095 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
5096 } else if (!strncasecmp(val, "interface:", 10)) {
5097 char *ifname = val+10;
5098 int family = AF_UNSPEC;
5099 if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC; }
5100 if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET; }
5101 if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET6; }
5102 if (switch_find_interface_ip(buf, sizeof(buf), NULL, ifname, family) == SWITCH_STATUS_SUCCESS) {
5103 ip = buf;
5104 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for rtp-ip\n", ip, val+10);
5105 } else {
5106 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown IP for interface %s for rtp-ip\n", val+10);
5107 }
5108 } else {
5109 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5110 }
5111
5112 if (strchr(ip, ':')) {
5113 if (profile->rtpip_index6 < MAX_RTPIP) {
5114 profile->rtpip6[profile->rtpip_index6++] = switch_core_strdup(profile->pool, ip);
5115 } else {
5116 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
5117 }
5118 } else {
5119 if (profile->rtpip_index < MAX_RTPIP) {
5120 profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, ip);
5121 } else {
5122 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
5123 }
5124 }
5125 } else if (!strcasecmp(var, "sip-ip") && val) {
5126 char *ip = mod_sofia_globals.guess_ip;
5127 char buf[64];
5128
5129 if (!strcmp(val, "0.0.0.0")) {
5130 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n", mod_sofia_globals.guess_ip);
5131 } else if (!strncasecmp(val, "interface:", 10)) {
5132 char *ifname = val+10;
5133 int family = AF_UNSPEC;
5134 if (!strncasecmp(ifname, "auto/", 5)) { ifname += 5; family = AF_UNSPEC; }
5135 if (!strncasecmp(ifname, "ipv4/", 5)) { ifname += 5; family = AF_INET; }
5136 if (!strncasecmp(ifname, "ipv6/", 5)) { ifname += 5; family = AF_INET6; }
5137 if (switch_find_interface_ip(buf, sizeof(buf), NULL, ifname, family) == SWITCH_STATUS_SUCCESS) {
5138 ip = buf;
5139 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Using %s IP for interface %s for sip-ip\n", ip, val+10);
5140 } else {
5141 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown IP for interface %s for sip-ip\n", val+10);
5142 }
5143 } else {
5144 ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
5145 }
5146 profile->sipip = switch_core_strdup(profile->pool, ip);
5147 } else if (!strcasecmp(var, "ext-sip-port") && val) {
5148 int tmp = atoi(val);
5149 if (tmp > 0) profile->extsipport = (switch_port_t)tmp;
5150 } else if (!strcasecmp(var, "ext-sip-ip")) {
5151 if (!zstr(val)) {
5152 char *ip = mod_sofia_globals.guess_ip;
5153 char stun_ip[50] = "";
5154 char *myip = stun_ip;
5155
5156 switch_copy_string(stun_ip, ip, sizeof(stun_ip));
5157
5158 if (!strcasecmp(val, "0.0.0.0")) {
5159 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid IP 0.0.0.0 replaced with %s\n",
5160 mod_sofia_globals.guess_ip);
5161 } else if (!strcasecmp(val, "auto-nat")) {
5162 ip = NULL;
5163 } else if (strcasecmp(val, "auto")) {
5164 if (sofia_glue_ext_address_lookup(profile, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) {
5165 ip = myip;
5166 sofia_clear_pflag(profile, PFLAG_AUTO_NAT);
5167 } else {
5168 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get external ip.\n");
5169 }
5170 }
5171 if (ip) {
5172 if (!strncasecmp(ip, "autonat:", 8)) {
5173 profile->extsipip = switch_core_strdup(profile->pool, ip + 8);
5174 sofia_set_pflag(profile, PFLAG_AUTO_NAT);
5175 } else {
5176 profile->extsipip = switch_core_strdup(profile->pool, ip);
5177 }
5178 }
5179 } else {
5180 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ext-sip-ip\n");
5181 switch_goto_status(SWITCH_STATUS_GENERR, done);
5182 }
5183 } else if (!strcasecmp(var, "local-network-acl")) {
5184 if (val && !strcasecmp(val, "none")) {
5185 profile->local_network = NULL;
5186 } else {
5187 profile->local_network = switch_core_strdup(profile->pool, val);
5188 }
5189 } else if (!strcasecmp(var, "force-register-domain")) {
5190 profile->reg_domain = switch_core_strdup(profile->pool, val);
5191 } else if (!strcasecmp(var, "force-register-db-domain")) {
5192 profile->reg_db_domain = switch_core_strdup(profile->pool, val);
5193 } else if (!strcasecmp(var, "force-subscription-domain")) {
5194 profile->sub_domain = switch_core_strdup(profile->pool, val);
5195 } else if (!strcasecmp(var, "bind-params")) {
5196 profile->bind_params = switch_core_strdup(profile->pool, val);
5197 } else if (!strcasecmp(var, "sip-domain")) {
5198 profile->sipdomain = switch_core_strdup(profile->pool, val);
5199 } else if (!strcasecmp(var, "rtp-timer-name")) {
5200 profile->timer_name = switch_core_strdup(profile->pool, val);
5201 } else if (!strcasecmp(var, "hold-music")) {
5202 profile->hold_music = switch_core_strdup(profile->pool, val);
5203 } else if (!strcasecmp(var, "outbound-proxy") && val) {
5204 if (strncasecmp(val, "sip:", 4) && strncasecmp(val, "sips:", 5)) {
5205 profile->outbound_proxy = switch_core_sprintf(profile->pool, "sip:%s", val);
5206 } else {
5207 profile->outbound_proxy = switch_core_strdup(profile->pool, val);
5208 }
5209 } else if (!strcasecmp(var, "rtcp-audio-interval-msec")) {
5210 profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val);
5211 } else if (!strcasecmp(var, "rtcp-video-interval-msec")) {
5212 profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val);
5213 } else if (!strcasecmp(var, "session-timeout") && !zstr(val)) {
5214 int v_session_timeout = atoi(val);
5215 if (v_session_timeout >= 0) {
5216 profile->session_timeout = v_session_timeout;
5217 }
5218 } else if (!strcasecmp(var, "max-proceeding") && !zstr(val)) {
5219 int v_max_proceeding = atoi(val);
5220 if (v_max_proceeding >= 0) {
5221 profile->max_proceeding = v_max_proceeding;
5222 }
5223 } else if (!strcasecmp(var, "rtp-timeout-sec") && !zstr(val)) {
5224 int v = atoi(val);
5225 if (v >= 0) {
5226 profile->rtp_timeout_sec = v;
5227 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
5228 "rtp-timeout-sec deprecated use media_timeout variable.\n");
5229 }
5230 } else if (!strcasecmp(var, "rtp-hold-timeout-sec") && !zstr(val)) {
5231 int v = atoi(val);
5232 if (v >= 0) {
5233 profile->rtp_hold_timeout_sec = v;
5234 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
5235 "rtp-hold-timeout-sec deprecated use media_hold_timeout variable.\n");
5236 }
5237 } else if (!strcasecmp(var, "disable-transfer")) {
5238 if (switch_true(val)) {
5239 profile->mflags &= ~MFLAG_REFER;
5240 } else {
5241 profile->mflags |= MFLAG_REFER;
5242 }
5243 } else if (!strcasecmp(var, "disable-register")) {
5244 if (switch_true(val)) {
5245 profile->mflags &= ~MFLAG_REGISTER;
5246 } else {
5247 profile->mflags |= MFLAG_REGISTER;
5248 }
5249 } else if (!strcasecmp(var, "media-option") && !zstr(val)) {
5250 if (!strcasecmp(val, "resume-media-on-hold")) {
5251 profile->media_options |= MEDIA_OPT_MEDIA_ON_HOLD;
5252 } else if (!strcasecmp(val, "bypass-media-after-att-xfer")) {
5253 profile->media_options |= MEDIA_OPT_BYPASS_AFTER_ATT_XFER;
5254 } else if (!strcasecmp(val, "bypass-media-after-hold")) {
5255 if (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
5256 profile->media_options |= MEDIA_OPT_BYPASS_AFTER_HOLD;
5257 } else {
5258 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
5259 "bypass-media-after-hold can be set only with resume-media-on-hold media-option\n");
5260 }
5261 } else if (!strcasecmp(val, "none")) {
5262 profile->media_options = 0;
5263 }
5264 } else if (!strcasecmp(var, "pnp-provision-url")) {
5265 profile->pnp_prov_url = switch_core_strdup(profile->pool, val);
5266 } else if (!strcasecmp(var, "manage-presence")) {
5267 if (val && !strcasecmp(val, "passive")) {
5268 profile->pres_type = PRES_TYPE_PASSIVE;
5269
5270 } else if (val && !strcasecmp(val, "pnp")) {
5271 profile->pres_type = PRES_TYPE_PNP;
5272 } else if (switch_true(val)) {
5273 profile->pres_type = PRES_TYPE_FULL;
5274 } else {
5275 profile->pres_type = 0;
5276 }
5277 } else if (!strcasecmp(var, "presence-hold-state")) {
5278 if (val && !strcasecmp(val, "confirmed")) {
5279 profile->pres_held_type = PRES_HELD_CONFIRMED;
5280 } else if (val && !strcasecmp(val, "terminated")) {
5281 profile->pres_held_type = PRES_HELD_TERMINATED;
5282 } else {
5283 profile->pres_held_type = 0;
5284 }
5285 } else if (!strcasecmp(var, "presence-privacy")) {
5286 if (switch_true(val)) {
5287 sofia_set_pflag(profile, PFLAG_PRESENCE_PRIVACY);
5288 } else {
5289 sofia_clear_pflag(profile, PFLAG_PRESENCE_PRIVACY);
5290 }
5291 } else if (!strcasecmp(var, "update-refresher")) {
5292 if (switch_true(val)) {
5293 sofia_set_pflag(profile, PFLAG_UPDATE_REFRESHER);
5294 } else {
5295 sofia_clear_pflag(profile, PFLAG_UPDATE_REFRESHER);
5296 }
5297 } else if (!strcasecmp(var, "rfc-7989")) {
5298 if (switch_true(val)) {
5299 sofia_set_pflag(profile, PFLAG_RFC7989_SESSION_ID);
5300 } else {
5301 sofia_clear_pflag(profile, PFLAG_RFC7989_SESSION_ID);
5302 }
5303 } else if (!strcasecmp(var, "rfc-7989-filter")) {
5304 profile->rfc7989_filter = switch_core_strdup(profile->pool, val);
5305 } else if (!strcasecmp(var, "rfc-7989-force-old")) {
5306 if (switch_true(val)) {
5307 sofia_set_pflag(profile, PFLAG_RFC7989_FORCE_OLD);
5308 } else {
5309 sofia_clear_pflag(profile, PFLAG_RFC7989_FORCE_OLD);
5310 }
5311 } else if (!strcasecmp(var, "manage-shared-appearance")) {
5312 if (switch_true(val)) {
5313 sofia_set_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE);
5314 profile->pres_type = PRES_TYPE_FULL;
5315 sofia_set_pflag(profile, PFLAG_MULTIREG);
5316
5317 } else if (val && !strcasecmp(val, "sylantro")) {
5318 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
5319 "Sylantro support has been removed.\n"
5320 "It was incomplete anyway, and we fully support the broadsoft SCA shared line spec.");
5321 sofia_clear_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE);
5322 } else {
5323 sofia_clear_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE);
5324 }
5325 } else if (!strcasecmp(var, "disable-srv")) {
5326 if (switch_true(val)) {
5327 sofia_set_pflag(profile, PFLAG_DISABLE_SRV);
5328 } else {
5329 sofia_clear_pflag(profile, PFLAG_DISABLE_SRV);
5330 }
5331 } else if (!strcasecmp(var, "disable-naptr")) {
5332 if (switch_true(val)) {
5333 sofia_set_pflag(profile, PFLAG_DISABLE_NAPTR);
5334 } else {
5335 sofia_clear_pflag(profile, PFLAG_DISABLE_NAPTR);
5336 }
5337 } else if (!strcasecmp(var, "disable-srv503")) {
5338 if (switch_true(val)) {
5339 sofia_set_pflag(profile, PFLAG_DISABLE_SRV503);
5340 } else {
5341 sofia_clear_pflag(profile, PFLAG_DISABLE_SRV503);
5342 }
5343 } else if (!strcasecmp(var, "unregister-on-options-fail")) {
5344 if (switch_true(val)) {
5345 sofia_set_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL);
5346 } else {
5347 sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL);
5348 }
5349 } else if (!strcasecmp(var, "sip-user-ping-max") && !zstr(val)) {
5350 profile->sip_user_ping_max = atoi(val);
5351 } else if (!strcasecmp(var, "sip-user-ping-min") && !zstr(val)) {
5352 profile->sip_user_ping_min = atoi(val);
5353 } else if (!strcasecmp(var, "require-secure-rtp")) {
5354 if (switch_true(val)) {
5355 sofia_set_pflag(profile, PFLAG_SECURE);
5356 } else {
5357 sofia_clear_pflag(profile, PFLAG_SECURE);
5358 }
5359 } else if (!strcasecmp(var, "auto-invite-100")) {
5360 if (switch_true(val)) {
5361 sofia_set_pflag(profile, PFLAG_AUTO_INVITE_100);
5362 } else {
5363 sofia_clear_pflag(profile, PFLAG_AUTO_INVITE_100);
5364 }
5365 } else {
5366 found = 0;
5367 }
5368 if (found) continue;
5369
5370 if (!strcasecmp(var, "multiple-registrations")) {
5371 if (val && !strcasecmp(val, "call-id")) {
5372 sofia_set_pflag(profile, PFLAG_MULTIREG);
5373 } else if (val && (!strcasecmp(val, "contact") || switch_true(val))) {
5374 sofia_set_pflag(profile, PFLAG_MULTIREG);
5375 sofia_set_pflag(profile, PFLAG_MULTIREG_CONTACT);
5376 } else if (!switch_true(val)) {
5377 sofia_clear_pflag(profile, PFLAG_MULTIREG);
5378 sofia_clear_pflag(profile, PFLAG_MULTIREG_CONTACT);
5379 }
5380 } else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) {
5381 if (switch_true(val)) {
5382 sofia_set_media_flag(profile, SCMF_SUPPRESS_CNG);
5383 profile->cng_pt = 0;
5384 } else {
5385 sofia_clear_media_flag(profile, SCMF_SUPPRESS_CNG);
5386 }
5387 } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) {
5388 if (switch_true(val)) {
5389 profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH;
5390 } else {
5391 profile->ndlb &= ~PFLAG_NDLB_BROKEN_AUTH_HASH;
5392 }
5393 } else if (!strcasecmp(var, "NDLB-sendrecv-in-session")) {
5394 if (switch_true(val)) {
5395 profile->mndlb |= SM_NDLB_SENDRECV_IN_SESSION;
5396 } else {
5397 profile->mndlb &= ~SM_NDLB_SENDRECV_IN_SESSION;
5398 }
5399 } else if (!strcasecmp(var, "NDLB-allow-bad-iananame")) {
5400 if (switch_true(val)) {
5401 profile->ndlb |= SM_NDLB_ALLOW_BAD_IANANAME;
5402 } else {
5403 profile->ndlb &= ~SM_NDLB_ALLOW_BAD_IANANAME;
5404 }
5405 } else if (!strcasecmp(var, "NDLB-expires-in-register-response")) {
5406 if (switch_true(val)) {
5407 profile->ndlb |= PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE;
5408 } else {
5409 profile->ndlb &= ~PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE;
5410 }
5411 } else if (!strcasecmp(var, "NDLB-allow-crypto-in-avp")) {
5412 if (switch_true(val)) {
5413 profile->mndlb |= SM_NDLB_ALLOW_CRYPTO_IN_AVP;
5414 } else {
5415 profile->mndlb &= ~SM_NDLB_ALLOW_CRYPTO_IN_AVP;
5416 }
5417 } else if (!strcasecmp(var, "NDLB-allow-nondup-sdp")) {
5418 if (switch_true(val)) {
5419 profile->mndlb |= SM_NDLB_ALLOW_NONDUP_SDP;
5420 } else {
5421 profile->mndlb &= ~SM_NDLB_ALLOW_NONDUP_SDP;
5422 }
5423 } else if (!strcasecmp(var, "pass-rfc2833")) {
5424 if (switch_true(val)) {
5425 sofia_set_pflag(profile, PFLAG_PASS_RFC2833);
5426 } else {
5427 sofia_clear_pflag(profile, PFLAG_PASS_RFC2833);
5428 }
5429 } else if (!strcasecmp(var, "rtp-autofix-timing")) {
5430 if (switch_true(val)) {
5431 sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING);
5432 } else {
5433 sofia_clear_media_flag(profile, SCMF_AUTOFIX_TIMING);
5434 }
5435 } else if (!strcasecmp(var, "contact-user")) {
5436 profile->contact_user = switch_core_strdup(profile->pool, val);
5437 } else if (!strcasecmp(var, "nat-options-ping")) {
5438 if (val && !strcasecmp(val, "udp-only")) {
5439 sofia_set_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING);
5440 } else if (switch_true(val)) {
5441 sofia_set_pflag(profile, PFLAG_NAT_OPTIONS_PING);
5442 } else {
5443 sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING);
5444 sofia_clear_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING);
5445 }
5446 } else if (!strcasecmp(var, "all-reg-options-ping")) {
5447 if (switch_true(val)) {
5448 sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING);
5449 } else {
5450 sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING);
5451 }
5452 } else if (!strcasecmp(var, "inbound-codec-negotiation")) {
5453 if (val && !strcasecmp(val, "greedy")) {
5454 sofia_set_media_flag(profile, SCMF_CODEC_GREEDY);
5455 } else if (val && !strcasecmp(val, "scrooge")) {
5456 sofia_set_media_flag(profile, SCMF_CODEC_GREEDY);
5457 sofia_set_media_flag(profile, SCMF_CODEC_SCROOGE);
5458 } else {
5459 sofia_clear_media_flag(profile, SCMF_CODEC_SCROOGE);
5460 sofia_clear_media_flag(profile, SCMF_CODEC_GREEDY);
5461 }
5462 } else if (!strcasecmp(var, "disable-transcoding")) {
5463 if (switch_true(val)) {
5464 sofia_set_media_flag(profile, SCMF_DISABLE_TRANSCODING);
5465 } else {
5466 sofia_clear_media_flag(profile, SCMF_DISABLE_TRANSCODING);
5467 }
5468 } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) {
5469 if (switch_true(val)) {
5470 sofia_set_media_flag(profile, SCMF_REWRITE_TIMESTAMPS);
5471 } else {
5472 sofia_clear_media_flag(profile, SCMF_REWRITE_TIMESTAMPS);
5473 }
5474 } else if (!strcasecmp(var, "auth-calls")) {
5475 if (switch_true(val)) {
5476 sofia_set_pflag(profile, PFLAG_AUTH_CALLS);
5477 } else {
5478 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS);
5479 }
5480 } else if (!strcasecmp(var, "auth-messages")) {
5481 if (switch_true(val)) {
5482 sofia_set_pflag(profile, PFLAG_AUTH_MESSAGES);
5483 } else {
5484 sofia_clear_pflag(profile, PFLAG_AUTH_MESSAGES);
5485 }
5486 } else if (!strcasecmp(var, "auth-subscriptions")) {
5487 if (switch_true(val)) {
5488 sofia_set_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS);
5489 } else {
5490 sofia_clear_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS);
5491 }
5492 } else if (!strcasecmp(var, "extended-info-parsing")) {
5493 if (switch_true(val)) {
5494 sofia_set_pflag(profile, PFLAG_EXTENDED_INFO_PARSING);
5495 } else {
5496 sofia_clear_pflag(profile, PFLAG_EXTENDED_INFO_PARSING);
5497 }
5498 } else if (!strcasecmp(var, "nonce-ttl") && !zstr(val)) {
5499 profile->nonce_ttl = atoi(val);
5500 } else if (!strcasecmp(var, "max-auth-validity") && !zstr(val)) {
5501 profile->max_auth_validity = atoi(val);
5502 } else if (!strcasecmp(var, "auth-require-user")) {
5503 if (switch_true(val)) {
5504 sofia_set_pflag(profile, PFLAG_AUTH_REQUIRE_USER);
5505 } else {
5506 sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER);
5507 }
5508 } else if (!strcasecmp(var, "accept-blind-reg")) {
5509 if (switch_true(val)) {
5510 sofia_set_pflag(profile, PFLAG_BLIND_REG);
5511 } else {
5512 sofia_clear_pflag(profile, PFLAG_BLIND_REG);
5513 }
5514 } else if (!strcasecmp(var, "3pcc-reinvite-bridged-on-ack")) {
5515 if (switch_true(val)) {
5516 sofia_set_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK);
5517 } else {
5518 sofia_clear_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK);
5519 }
5520 } else if (!strcasecmp(var, "enable-3pcc")) {
5521 if (switch_true(val)) {
5522 sofia_set_pflag(profile, PFLAG_3PCC);
5523 } else if (!strcasecmp(val, "proxy")) {
5524 sofia_set_pflag(profile, PFLAG_3PCC_PROXY);
5525 }
5526 } else if (!strcasecmp(var, "accept-blind-auth")) {
5527 if (switch_true(val)) {
5528 sofia_set_pflag(profile, PFLAG_BLIND_AUTH);
5529 } else {
5530 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH);
5531 }
5532 } else if (!strcasecmp(var, "auth-all-packets")) {
5533 if (switch_true(val)) {
5534 sofia_set_pflag(profile, PFLAG_AUTH_ALL);
5535 } else {
5536 sofia_clear_pflag(profile, PFLAG_AUTH_ALL);
5537 }
5538 } else if (!strcasecmp(var, "full-id-in-dialplan")) {
5539 if (switch_true(val)) {
5540 sofia_set_pflag(profile, PFLAG_FULL_ID);
5541 } else {
5542 sofia_clear_pflag(profile, PFLAG_FULL_ID);
5543 }
5544 } else if (!strcasecmp(var, "inbound-reg-force-matching-username")) {
5545 if (switch_true(val)) {
5546 sofia_set_pflag(profile, PFLAG_CHECKUSER);
5547 } else {
5548 sofia_clear_pflag(profile, PFLAG_CHECKUSER);
5549 }
5550 } else if (!strcasecmp(var, "enable-timer")) {
5551 if (!switch_true(val)) {
5552 sofia_set_pflag(profile, PFLAG_DISABLE_TIMER);
5553 } else {
5554 sofia_clear_pflag(profile, PFLAG_DISABLE_TIMER);
5555 }
5556 } else if (!strcasecmp(var, "enable-rfc-5626")) {
5557 if (switch_true(val)) {
5558 sofia_set_pflag(profile, PFLAG_ENABLE_RFC5626);
5559 } else {
5560 sofia_clear_pflag(profile, PFLAG_ENABLE_RFC5626);
5561 }
5562 } else if (!strcasecmp(var, "minimum-session-expires") && !zstr(val)) {
5563 profile->minimum_session_expires = atoi(val);
5564 /* per RFC 4028: minimum_session_expires must be > 90 */
5565 if (profile->minimum_session_expires < 90) {
5566 profile->minimum_session_expires = 90;
5567 }
5568 } else if (!strcasecmp(var, "enable-100rel")) {
5569 if (switch_true(val)) {
5570 sofia_clear_pflag(profile, PFLAG_DISABLE_100REL);
5571 } else {
5572 sofia_set_pflag(profile, PFLAG_DISABLE_100REL);
5573 }
5574 } else if (!strcasecmp(var, "enable-compact-headers")) {
5575 if (switch_true(val)) {
5576 sofia_set_pflag(profile, PFLAG_SIPCOMPACT);
5577 } else {
5578 sofia_clear_pflag(profile, PFLAG_SIPCOMPACT);
5579 }
5580 } else if (!strcasecmp(var, "pass-callee-id")) {
5581 if (switch_true(val)) {
5582 sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
5583 } else {
5584 sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID);
5585 }
5586 } else if (!strcasecmp(var, "enable-soa")) {
5587 if (switch_true(val)) {
5588 sofia_set_flag(profile, TFLAG_ENABLE_SOA);
5589 } else {
5590 sofia_clear_flag(profile, TFLAG_ENABLE_SOA);
5591 }
5592 } else if (!strcasecmp(var, "parse-all-invite-headers")) {
5593 if (switch_true(val)) {
5594 sofia_set_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS);
5595 } else {
5596 sofia_clear_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS);
5597 }
5598 } else if (!strcasecmp(var, "bitpacking")) {
5599 if (val && !strcasecmp(val, "aal2")) {
5600 profile->codec_flags = SWITCH_CODEC_FLAG_AAL2;
5601 } else {
5602 profile->codec_flags = 0;
5603 }
5604 } else if (!strcasecmp(var, "username")) {
5605 profile->sdp_username = switch_core_strdup(profile->pool, val);
5606 } else if (!strcasecmp(var, "context")) {
5607 profile->context = switch_core_strdup(profile->pool, val);
5608 } else if (!strcasecmp(var, "apply-nat-acl") && !zstr(val)) {
5609 if (!strcasecmp(val,"none")) {
5610 profile->nat_acl_count = 0;
5611 } else if (profile->nat_acl_count < SOFIA_MAX_ACL) {
5612 if (!profile->extsipip && profile->sipip && switch_check_network_list_ip(profile->sipip, val)) {
5613 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val);
5614 } else {
5615 profile->nat_acl[profile->nat_acl_count++] = switch_core_strdup(profile->pool, val);
5616 }
5617 } else {
5618 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
5619 }
5620 } else if (!strcasecmp(var, "apply-inbound-acl") && !zstr(val)) {
5621 if (!strcasecmp(val,"none")) {
5622 profile->acl_count = 0;
5623 } else if (profile->acl_count < SOFIA_MAX_ACL) {
5624 char *list, *pass = NULL, *fail = NULL;
5625
5626 list = switch_core_strdup(profile->pool, val);
5627
5628 if ((pass = strchr(list, ':'))) {
5629 *pass++ = '\0';
5630 if ((fail = strchr(pass, ':'))) {
5631 *fail++ = '\0';
5632 }
5633
5634 if (zstr(pass)) pass = NULL;
5635 if (zstr(fail)) fail = NULL;
5636
5637 profile->acl_pass_context[profile->acl_count] = pass;
5638 profile->acl_fail_context[profile->acl_count] = fail;
5639 }
5640
5641 profile->acl[profile->acl_count++] = list;
5642
5643 } else {
5644 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
5645 }
5646 } else if (!strcasecmp(var, "apply-proxy-acl") && !zstr(val)) {
5647 if (!strcasecmp(val,"none")) {
5648 profile->proxy_acl_count = 0;
5649 } else if (profile->proxy_acl_count < SOFIA_MAX_ACL) {
5650 profile->proxy_acl[profile->proxy_acl_count++] = switch_core_strdup(profile->pool, val);
5651 } else {
5652 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
5653 }
5654 } else if (!strcasecmp(var, "apply-register-acl") && !zstr(val)) {
5655 if (!strcasecmp(val,"none")) {
5656 profile->reg_acl_count = 0;
5657 } else if (profile->reg_acl_count < SOFIA_MAX_ACL) {
5658 profile->reg_acl[profile->reg_acl_count++] = switch_core_strdup(profile->pool, val);
5659 } else {
5660 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
5661 }
5662
5663 } else if (!strcasecmp(var, "apply-candidate-acl") && !zstr(val)) {
5664 if (!strcasecmp(val,"none")) {
5665 profile->cand_acl_count = 0;
5666 } else if (profile->cand_acl_count < SWITCH_MAX_CAND_ACL) {
5667 profile->cand_acl[profile->cand_acl_count++] = switch_core_strdup(profile->pool, val);
5668 } else {
5669 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SWITCH_MAX_CAND_ACL);
5670 }
5671 } else if (!strcasecmp(var, "alias")) {
5672 sip_alias_node_t *node;
5673 if (zstr(val)) {
5674 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Alias Param has no data...\n");
5675 } else {
5676 if ((node = switch_core_alloc(profile->pool, sizeof(*node)))) {
5677 if ((node->url = switch_core_strdup(profile->pool, val))) {
5678 node->next = profile->aliases;
5679 profile->aliases = node;
5680 }
5681 }
5682 }
5683 } else if (!strcasecmp(var, "dialplan")) {
5684 profile->dialplan = switch_core_strdup(profile->pool, val);
5685 } else if (!strcasecmp(var, "max-calls") && !zstr(val)) {
5686 profile->max_calls = atoi(val);
5687 } else if (!strcasecmp(var, "codec-prefs")) {
5688 profile->inbound_codec_string = switch_core_strdup(profile->pool, val);
5689 profile->outbound_codec_string = switch_core_strdup(profile->pool, val);
5690 } else if (!strcasecmp(var, "inbound-codec-prefs")) {
5691 profile->inbound_codec_string = switch_core_strdup(profile->pool, val);
5692 } else if (!strcasecmp(var, "outbound-codec-prefs")) {
5693 profile->outbound_codec_string = switch_core_strdup(profile->pool, val);
5694 } else if (!strcasecmp(var, "challenge-realm")) {
5695 profile->challenge_realm = switch_core_strdup(profile->pool, val);
5696 } else if (!strcasecmp(var, "dtmf-duration") && !zstr(val)) {
5697 uint32_t dur = atoi(val);
5698 if (dur >= switch_core_min_dtmf_duration(0) && dur <= switch_core_max_dtmf_duration(0)) {
5699 profile->dtmf_duration = dur;
5700 } else {
5701 profile->dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION;
5702 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Duration out of bounds, using default of %d!\n",
5703 SWITCH_DEFAULT_DTMF_DURATION);
5704 }
5705
5706 } else if (!strcasecmp(var, "ws-binding") && !zstr(val)) {
5707 int tmp;
5708 char *p;
5709
5710 profile->ws_ip = switch_core_strdup(profile->pool, val);
5711 if ((p = strrchr(profile->ws_ip, ':'))) {
5712 *p++ = '\0';
5713
5714 if ((tmp = atol(p)) && tmp > 0) {
5715 profile->ws_port = (switch_port_t) tmp;
5716 }
5717 }
5718
5719 } else if (!strcasecmp(var, "wss-binding") && !zstr(val)) {
5720 int tmp;
5721 char *p;
5722
5723 profile->wss_ip = switch_core_strdup(profile->pool, val);
5724 if ((p = strrchr(profile->wss_ip, ':'))) {
5725 *p++ = '\0';
5726
5727 if ((tmp = atol(p)) && tmp > 0) {
5728 profile->wss_port = (switch_port_t) tmp;
5729 }
5730 }
5731
5732 /*
5733 * handle TLS params #1
5734 */
5735 } else if (!strcasecmp(var, "tls")) {
5736 if (switch_true(val)) {
5737 sofia_set_pflag(profile, PFLAG_TLS);
5738 if (profile->tls_bind_params) {
5739 if (!switch_stristr("transport=tls", profile->tls_bind_params)) {
5740 profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", profile->tls_bind_params);
5741 }
5742 } else {
5743 profile->tls_bind_params = switch_core_strdup(profile->pool, "transport=tls");
5744 }
5745 } else {
5746 sofia_clear_pflag(profile, PFLAG_TLS);
5747 }
5748 } else if (!strcasecmp(var, "tls-bind-params")) {
5749 if (val && switch_stristr("transport=tls", val)) {
5750 profile->tls_bind_params = switch_core_strdup(profile->pool, val);
5751 } else {
5752 profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", val);
5753 }
5754 } else if (!strcasecmp(var, "tls-only")) {
5755 profile->tls_only = switch_true(val);
5756 } else if (!strcasecmp(var, "tls-verify-date")) {
5757 profile->tls_verify_date = switch_true(val);
5758 } else if (!strcasecmp(var, "tls-verify-depth") && !zstr(val)) {
5759 profile->tls_verify_depth = atoi(val);
5760 } else if (!strcasecmp(var, "tls-verify-policy")) {
5761 profile->tls_verify_policy = sofia_glue_str2tls_verify_policy(val);
5762 } else if (!strcasecmp(var, "tls-sip-port") && !zstr(val)) {
5763 if (!strcasecmp(val, "auto")) {
5764 sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT);
5765 } else {
5766 sofia_clear_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT);
5767 profile->tls_sip_port = (switch_port_t) atoi(val);
5768 }
5769 } else if (!strcasecmp(var, "tls-cert-dir") && !zstr(val)) {
5770 profile->tls_cert_dir = switch_core_strdup(profile->pool, val);
5771 } else if (!strcasecmp(var, "tls-passphrase") && !zstr(val)) {
5772 profile->tls_passphrase = switch_core_strdup(profile->pool, val);
5773 } else if (!strcasecmp(var, "tls-verify-in-subjects") && !zstr(val)) {
5774 profile->tls_verify_in_subjects_str = switch_core_strdup(profile->pool, val);
5775 } else if (!strcasecmp(var, "tls-ciphers") && !zstr(val)) {
5776 profile->tls_ciphers = switch_core_strdup(profile->pool, val);
5777 } else if (!strcasecmp(var, "tls-version") && !zstr(val)) {
5778 char *ps = val, *pe = val;
5779 profile->tls_version = 0;
5780 while (ps && *pe) {
5781 int n;
5782 pe = strchr(ps,',');
5783 if (!pe && !(pe = memchr(ps,0,1024))) break;
5784 n = (int)(pe-ps);
5785 if (n==5 && !strncasecmp(ps, "sslv2", n))
5786 profile->tls_version |= SOFIA_TLS_VERSION_SSLv2;
5787 if (n==5 && !strncasecmp(ps, "sslv3", n))
5788 profile->tls_version |= SOFIA_TLS_VERSION_SSLv3;
5789 if (n==6 && !strncasecmp(ps, "sslv23", n))
5790 profile->tls_version |= SOFIA_TLS_VERSION_SSLv2 | SOFIA_TLS_VERSION_SSLv3;
5791 if (n==5 && !strncasecmp(ps, "tlsv1", n))
5792 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1;
5793 if (n==7 && !strncasecmp(ps, "tlsv1.1", n))
5794 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_1;
5795 if (n==7 && !strncasecmp(ps, "tlsv1.2", n))
5796 profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
5797 ps=pe+1;
5798 }
5799 } else if (!strcasecmp(var, "tls-timeout") && !zstr(val)) {
5800 int v = atoi(val);
5801 profile->tls_timeout = v > 0 ? (unsigned int)v : 300;
5802 } else if (!strcasecmp(var, "timer-T1") && !zstr(val)) {
5803 int v = atoi(val);
5804 if (v > 0) {
5805 profile->timer_t1 = v;
5806 } else {
5807 profile->timer_t1 = 500;
5808 }
5809 } else if (!strcasecmp(var, "timer-T1X64") && !zstr(val)) {
5810 int v = atoi(val);
5811 if (v > 0) {
5812 profile->timer_t1x64 = v;
5813 } else {
5814 profile->timer_t1x64 = 32000;
5815 }
5816 } else if (!strcasecmp(var, "timer-T2") && !zstr(val)) {
5817 int v = atoi(val);
5818 if (v > 0) {
5819 profile->timer_t2 = v;
5820 } else {
5821 profile->timer_t2 = 4000;
5822 }
5823 } else if (!strcasecmp(var, "timer-T4") && !zstr(val)) {
5824 int v = atoi(val);
5825 if (v > 0) {
5826 profile->timer_t4 = v;
5827 } else {
5828 profile->timer_t4 = 4000;
5829 }
5830 } else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) {
5831 if (switch_true(val)) {
5832 sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
5833 } else {
5834 sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
5835 }
5836 } else if (!strcasecmp(var, "sip-expires-late-margin") && !zstr(val)) {
5837 int32_t sip_expires_late_margin = atoi(val);
5838 if (sip_expires_late_margin >= 0) {
5839 profile->sip_expires_late_margin = sip_expires_late_margin;
5840 } else {
5841 profile->sip_expires_late_margin = 60;
5842 }
5843 } else if (!strcasecmp(var, "sip-force-expires-min") && !zstr(val)) {
5844 int32_t sip_force_expires_min = atoi(val);
5845 if (sip_force_expires_min >= 0) {
5846 profile->sip_force_expires_min = sip_force_expires_min;
5847 } else {
5848 profile->sip_force_expires_min = 0;
5849 }
5850 } else if (!strcasecmp(var, "sip-force-expires-max") && !zstr(val)) {
5851 int32_t sip_force_expires_max = atoi(val);
5852 if (sip_force_expires_max >= 0) {
5853 profile->sip_force_expires_max = sip_force_expires_max;
5854 } else {
5855 profile->sip_force_expires_max = 0;
5856 }
5857 } else if (!strcasecmp(var, "sip-force-expires") && !zstr(val)) {
5858 int32_t sip_force_expires = atoi(val);
5859 if (sip_force_expires >= 0) {
5860 profile->sip_force_expires = sip_force_expires;
5861 } else {
5862 profile->sip_force_expires = 0;
5863 }
5864 } else if (!strcasecmp(var, "sip-expires-max-deviation") && !zstr(val)) {
5865 int32_t sip_expires_max_deviation = atoi(val);
5866 if (sip_expires_max_deviation >= 0) {
5867 profile->sip_expires_max_deviation = sip_expires_max_deviation;
5868 } else {
5869 profile->sip_expires_max_deviation = 0;
5870 }
5871 } else if (!strcasecmp(var, "sip-subscription-max-deviation") && !zstr(val)) {
5872 int32_t sip_subscription_max_deviation = atoi(val);
5873 if (sip_subscription_max_deviation >= 0) {
5874 profile->sip_subscription_max_deviation = sip_subscription_max_deviation;
5875 } else {
5876 profile->sip_subscription_max_deviation = 0;
5877 }
5878 } else if (!strcasecmp(var, "reuse-connections")) {
5879 switch_bool_t value = switch_true(val);
5880 if (!value) {
5881 sofia_set_pflag(profile, PFLAG_NO_CONNECTION_REUSE);
5882 } else {
5883 sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE);
5884 }
5885 } else if (!strcasecmp(var, "p-asserted-id-parse")) {
5886 if (!val) {
5887 profile->paid_type = PAID_DEFAULT;
5888 } else if (!strncasecmp(val, "default", 7)) {
5889 profile->paid_type = PAID_DEFAULT;
5890 } else if (!strncasecmp(val, "user-only", 9)) {
5891 profile->paid_type = PAID_USER;
5892 } else if (!strncasecmp(val, "user-domain", 11)) {
5893 profile->paid_type = PAID_USER_DOMAIN;
5894 } else if (!strncasecmp(val, "verbatim", 8)) {
5895 profile->paid_type = PAID_VERBATIM;
5896 } else {
5897 profile->paid_type = PAID_DEFAULT;
5898 }
5899 } else if (!strcasecmp(var, "channel-xml-fetch-on-nightmare-transfer")) {
5900 if(switch_true(val)) {
5901 sofia_set_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER);
5902 } else {
5903 sofia_clear_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER);
5904 }
5905 } else if (!strcasecmp(var, "make-every-transfer-a-nightmare")) {
5906 if(switch_true(val)) {
5907 sofia_set_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE);
5908 } else {
5909 sofia_clear_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE);
5910 }
5911 } else if (!strcasecmp(var, "fire-transfer-events")) {
5912 if(switch_true(val)) {
5913 sofia_set_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
5914 } else {
5915 sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
5916 }
5917 } else if (!strcasecmp(var, "enforce-blind-auth-result")) {
5918 if(switch_true(val)) {
5919 sofia_set_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
5920 } else {
5921 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
5922 }
5923 } else if (!strcasecmp(var, "blind-auth-reply-403")) {
5924 if(switch_true(val)) {
5925 sofia_set_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403);
5926 } else {
5927 sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403);
5928 }
5929 } else if (!strcasecmp(var, "auth-calls-acl-only")) {
5930 if(switch_true(val)) {
5931 sofia_set_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY);
5932 } else {
5933 sofia_clear_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY);
5934 }
5935 } else if (!strcasecmp(var, "use-port-for-acl-check")) {
5936 if(switch_true(val)) {
5937 sofia_set_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK);
5938 } else {
5939 sofia_clear_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK);
5940 }
5941 } else if (!strcasecmp(var, "apply-inbound-acl-x-token")) {
5942 profile->acl_inbound_x_token_header = switch_core_strdup(profile->pool, val);
5943 } else if (!strcasecmp(var, "apply-proxy-acl-x-token")) {
5944 profile->acl_proxy_x_token_header = switch_core_strdup(profile->pool, val);
5945 } else if (!strcasecmp(var, "proxy-hold")) {
5946 if(switch_true(val)) {
5947 sofia_set_pflag(profile, PFLAG_PROXY_HOLD);
5948 } else {
5949 sofia_clear_pflag(profile, PFLAG_PROXY_HOLD);
5950 }
5951 } else if (!strcasecmp(var, "proxy-info")) {
5952 if(switch_true(val)) {
5953 sofia_set_pflag(profile, PFLAG_PROXY_INFO);
5954 } else {
5955 sofia_clear_pflag(profile, PFLAG_PROXY_INFO);
5956 }
5957 } else if (!strcasecmp(var, "proxy-message")) {
5958 if(switch_true(val)) {
5959 sofia_set_pflag(profile, PFLAG_PROXY_MESSAGE);
5960 } else {
5961 sofia_clear_pflag(profile, PFLAG_PROXY_MESSAGE);
5962 }
5963 } else if (!strcasecmp(var, "proxy-notify-events")) {
5964 profile->proxy_notify_events = switch_core_strdup(profile->pool, val);
5965 } else if (!strcasecmp(var, "proxy-info-content-types")) {
5966 profile->proxy_info_content_types = switch_core_strdup(profile->pool, val);
5967 }
5968 }
5969
5970 if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU) && !sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION)) {
5971 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ZRTP passthrough implictly enables inbound-late-negotiation\n");
5972 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
5973 }
5974
5975 if (sofia_test_flag(profile, TFLAG_INB_NOMEDIA) && !sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION)) {
5976 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "inbound-bypass-media implictly enables inbound-late-negotiation\n");
5977 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
5978 }
5979
5980 if (sofia_test_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE) && !sofia_test_pflag(profile, PFLAG_ALLOW_UPDATE)) {
5981 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "send-display-update=true is set, but we can't comply because allow-update=false\n");
5982 sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE);
5983 }
5984 if (sofia_test_pflag(profile, PFLAG_PROXY_HOLD)) {
5985 if (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) {
5986 profile->media_options &= ~MEDIA_OPT_MEDIA_ON_HOLD;
5987 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "proxy-hold=true is set, incompatible with media-option=resume-media-on-hold\n");
5988 }
5989 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_HOLD) {
5990 profile->media_options &= ~MEDIA_OPT_BYPASS_AFTER_HOLD;
5991 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "proxy-hold=true is set, incompatible with media-option=bypass-media-after-hold\n");
5992 }
5993 }
5994
5995 if ((!profile->cng_pt) && (!sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG))) {
5996 profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD;
5997 }
5998
5999 if (!profile->sipip) {
6000 profile->sipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
6001 }
6002
6003 if (!profile->rtpip[0] && !profile->rtpip6[0]) {
6004 profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
6005 }
6006
6007 if (switch_nat_get_type()) {
6008 char *ip = switch_core_get_variable_dup("nat_public_addr");
6009 if (ip && !strchr(profile->sipip, ':')) {
6010 if (!profile->extrtpip) {
6011 profile->extrtpip = switch_core_strdup(profile->pool, ip);
6012 }
6013 if (!profile->extsipip) {
6014 profile->extsipip = switch_core_strdup(profile->pool, ip);
6015 }
6016 sofia_set_pflag(profile, PFLAG_AUTO_NAT);
6017 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "NAT detected setting external ip to %s\n", ip);
6018 }
6019 switch_safe_free(ip);
6020 }
6021
6022 if (profile->nonce_ttl < 60) {
6023 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting nonce TTL to 60 seconds\n");
6024 profile->nonce_ttl = 60;
6025 }
6026
6027 if (!profile->max_auth_validity) {
6028 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting MAX Auth Validity to 0 Attempts\n");
6029 profile->max_auth_validity = 0;
6030 }
6031
6032 if (!profile->sdp_username) {
6033 profile->sdp_username = switch_core_strdup(profile->pool, "FreeSWITCH");
6034 }
6035
6036 if (!profile->rtpip[0] && !profile->rtpip6[0]) {
6037 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Setting ip to '127.0.0.1'\n");
6038 profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, "127.0.0.1");
6039 }
6040
6041 if (!profile->sip_port && !sofia_test_pflag(profile, PFLAG_AUTO_ASSIGN_PORT)) {
6042 profile->sip_port = (switch_port_t) atoi(SOFIA_DEFAULT_PORT);
6043 if (!profile->extsipport) profile->extsipport = profile->sip_port;
6044 }
6045
6046 if (!profile->dialplan) {
6047 profile->dialplan = switch_core_strdup(profile->pool, "XML");
6048 }
6049
6050 if (!profile->context) {
6051 profile->context = switch_core_strdup(profile->pool, "default");
6052 }
6053
6054 if (!profile->sipdomain) {
6055 profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip);
6056 }
6057
6058 if (profile->pres_type == PRES_TYPE_PNP) {
6059 if (!profile->pnp_prov_url) {
6060 profile->pnp_prov_url = switch_core_sprintf(profile->pool, "http://%s/provision/", mod_sofia_globals.guess_ip);
6061 }
6062
6063 if (!profile->pnp_notify_profile) {
6064 profile->pnp_notify_profile = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
6065 }
6066
6067 if (!profile->extsipip) {
6068 profile->extsipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
6069 }
6070
6071 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "we're configured to provision to [%s] on profile [%s]\n",
6072 profile->pnp_prov_url, profile->pnp_notify_profile);
6073 }
6074
6075 config_sofia_profile_urls(profile);
6076
6077 if (profile->tls_cert_dir) {
6078 if (profile->wss_ip) {
6079 char *key, *cert;
6080 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.key");
6081 if (switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS) key = NULL;
6082 cert = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.crt");
6083 if (switch_file_exists(cert, profile->pool) != SWITCH_STATUS_SUCCESS) cert = NULL;
6084 if ( !key || !cert) {
6085 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "wss.pem");
6086 if ( switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS ) {
6087 switch_core_gen_certs(key);
6088 }
6089 }
6090 }
6091 if (sofia_test_pflag(profile, PFLAG_TLS)) {
6092 char *key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "agent.pem");
6093 char *ca = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "cafile.pem");;
6094 if (switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS) key = NULL;
6095 if (switch_file_exists(ca, profile->pool) != SWITCH_STATUS_SUCCESS) ca = NULL;
6096 if ( !key || !ca ) {
6097 key = switch_core_sprintf(profile->pool, "%s/%s", profile->tls_cert_dir, "tls.pem");
6098 if ( switch_file_exists(key, profile->pool) != SWITCH_STATUS_SUCCESS ) {
6099 switch_core_gen_certs(key);
6100 }
6101 }
6102 }
6103 }
6104 }
6105
6106 if (profile) {
6107 if (profile_already_started) {
6108 switch_xml_t gateways_tag, domain_tag, domains_tag, aliases_tag, alias_tag;
6109
6110 if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)) {
6111 sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
6112 }
6113
6114 if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
6115 parse_gateways(profile, gateways_tag, NULL);
6116 }
6117
6118 status = SWITCH_STATUS_SUCCESS;
6119
6120 if ((domains_tag = switch_xml_child(xprofile, "domains"))) {
6121 switch_event_t *xml_params;
6122 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS);
6123 switch_assert(xml_params);
6124 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways");
6125 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
6126
6127 for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) {
6128 switch_xml_t droot, x_domain_tag;
6129 const char *dname = switch_xml_attr_soft(domain_tag, "name");
6130 const char *parse = switch_xml_attr_soft(domain_tag, "parse");
6131 const char *alias = switch_xml_attr_soft(domain_tag, "alias");
6132
6133 if (!zstr(dname)) {
6134 if (!strcasecmp(dname, "all")) {
6135 switch_xml_t xml_root, x_domains;
6136 if (switch_xml_locate("directory", NULL, NULL, NULL, &xml_root, &x_domains, xml_params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
6137 for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
6138 dname = switch_xml_attr_soft(x_domain_tag, "name");
6139 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
6140 }
6141 switch_xml_free(xml_root);
6142 }
6143 } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) {
6144 parse_domain_tag(profile, x_domain_tag, dname, parse, alias);
6145 switch_xml_free(droot);
6146 }
6147 }
6148 }
6149
6150 switch_event_destroy(&xml_params);
6151 }
6152
6153 if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
6154 for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
6155 char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
6156 if (!zstr(aname)) {
6157
6158 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname), profile) == SWITCH_STATUS_SUCCESS) {
6159 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
6160 } else {
6161 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Alias [%s] for profile [%s] (already exists)\n",
6162 aname, profile->name);
6163 }
6164 }
6165 }
6166 }
6167
6168 } else {
6169 switch_xml_t aliases_tag, alias_tag;
6170
6171 if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) {
6172 for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) {
6173 char *aname = (char *) switch_xml_attr_soft(alias_tag, "name");
6174 if (!zstr(aname)) {
6175
6176 if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname), profile) == SWITCH_STATUS_SUCCESS) {
6177 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name);
6178 } else {
6179 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Adding Alias [%s] for profile [%s] (name in use)\n",
6180 aname, profile->name);
6181 }
6182 }
6183 }
6184 }
6185
6186 if (profile->sipip) {
6187 switch_event_t *s_event;
6188 if (!profile->extsipport) profile->extsipport = profile->sip_port;
6189
6190 launch_sofia_profile_thread(profile);
6191 if (profile->odbc_dsn) {
6192 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Connecting ODBC Profile %s [%s]\n", profile->name, url);
6193 switch_yield(1000000);
6194 } else {
6195 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url);
6196 }
6197 if ((switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_PROFILE_START) == SWITCH_STATUS_SUCCESS)) {
6198 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia");
6199 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
6200 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", profile->url);
6201 switch_event_fire(&s_event);
6202 }
6203 } else {
6204 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Unable to start Profile %s due to no configured sip-ip\n", profile->name);
6205 sofia_profile_start_failure(profile, profile->name);
6206 }
6207 profile = NULL;
6208 }
6209 if (profile_found) {
6210 break;
6211 }
6212 }
6213 }
6214 }
6215 done:
6216
6217 if (profile_already_started) {
6218 sofia_glue_release_profile(profile_already_started);
6219 }
6220
6221 switch_event_destroy(¶ms);
6222
6223 if (xml) {
6224 switch_xml_free(xml);
6225 }
6226
6227 if (profile_name && !profile_found) {
6228 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No Such Profile '%s'\n", profile_name);
6229 status = SWITCH_STATUS_FALSE;
6230 }
6231
6232 return status;
6233 }
6234
sofia_gateway_status_name(sofia_gateway_status_t status)6235 const char *sofia_gateway_status_name(sofia_gateway_status_t status)
6236 {
6237 static const char *status_names[] = { "DOWN", "UP", NULL };
6238
6239 if (status < SOFIA_GATEWAY_INVALID) {
6240 return status_names[status];
6241 } else {
6242 return "INVALID";
6243 }
6244 }
6245
sofia_sip_user_status_name(sofia_sip_user_status_t status)6246 const char *sofia_sip_user_status_name(sofia_sip_user_status_t status)
6247 {
6248 static const char *status_names[] = { "UNREACHABLE", "REACHABLE", NULL };
6249
6250 if (status < SOFIA_REG_INVALID) {
6251 return status_names[status];
6252 } else {
6253 return "INVALID";
6254 }
6255 }
6256
6257 struct cb_helper_sip_user_status {
6258 char *status;
6259 size_t status_len;
6260
6261 char *contact;
6262 size_t contact_len;
6263
6264 int count;
6265 };
6266
sofia_sip_user_status_callback(void * pArg,int argc,char ** argv,char ** columnNames)6267 int sofia_sip_user_status_callback(void *pArg, int argc, char **argv, char **columnNames)
6268 {
6269 struct cb_helper_sip_user_status *cbt = (struct cb_helper_sip_user_status *) pArg;
6270
6271 if (argc != 3) {
6272 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "expected 3 arguments from query, instead got %d\n", argc);
6273 return 0;
6274 }
6275
6276 switch_copy_string(cbt->status, argv[0], cbt->status_len);
6277 cbt->count = (argv[1] && switch_is_number(argv[1])) ? atoi(argv[1]) : 0;
6278
6279 switch_copy_string(cbt->contact, argv[2], cbt->contact_len);
6280
6281 return 1;
6282 }
6283
sofia_handle_sip_r_options(switch_core_session_t * session,int status,char const * phrase,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[])6284 static void sofia_handle_sip_r_options(switch_core_session_t *session, int status,
6285 char const *phrase,
6286 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
6287 sofia_dispatch_event_t *de,
6288 tagi_t tags[])
6289 {
6290 sofia_gateway_t *gateway = NULL;
6291 switch_bool_t do_fire_gateway_state_event = SWITCH_FALSE;
6292
6293 if (sofia_private && !zstr(sofia_private->gateway_name)) {
6294 gateway = sofia_reg_find_gateway(sofia_private->gateway_name);
6295 sofia_private->destroy_me = 1;
6296 }
6297
6298 if (gateway) {
6299 if (status >= 200 && status < 600 && status != 408 && status != 503) {
6300 if (gateway->state == REG_STATE_FAILED) {
6301 gateway->state = REG_STATE_UNREGED;
6302 }
6303
6304 if (gateway->ping_count < 0) {
6305 gateway->ping_count = 0;
6306 }
6307
6308 if (gateway->ping_count < gateway->ping_max) {
6309 gateway->ping_count++;
6310
6311 if (gateway->ping_count >= gateway->ping_min && gateway->status != SOFIA_GATEWAY_UP) {
6312 gateway->status = SOFIA_GATEWAY_UP;
6313 gateway->uptime = switch_time_now();
6314 do_fire_gateway_state_event = SWITCH_TRUE;
6315 }
6316
6317 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
6318 "Ping succeeded %s with code %d - count %d/%d/%d, state %s\n",
6319 gateway->name, status, gateway->ping_min, gateway->ping_count, gateway->ping_max, sofia_gateway_status_name(gateway->status));
6320 }
6321 if (gateway->ping_sent) {
6322 gateway->ping_time = (float)(switch_time_now() - gateway->ping_sent) / 1000;
6323 gateway->ping_sent = 0;
6324 }
6325 } else {
6326 if (gateway->state == REG_STATE_REGED) {
6327 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Unregister %s\n", gateway->name);
6328 gateway->state = REG_STATE_FAILED;
6329 gateway->ping_time = 0;
6330 }
6331
6332 if (gateway->ping_count > 0) {
6333 gateway->ping_count--;
6334 }
6335
6336 if (gateway->ping_count < gateway->ping_min && gateway->status != SOFIA_GATEWAY_DOWN) {
6337 gateway->status = SOFIA_GATEWAY_DOWN;
6338 do_fire_gateway_state_event = SWITCH_TRUE;
6339 gateway->ping_time = 0;
6340 }
6341
6342 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
6343 "Ping failed %s with code %d - count %d/%d/%d, state %s\n",
6344 gateway->name, status, gateway->ping_min, gateway->ping_count, gateway->ping_max, sofia_gateway_status_name(gateway->status));
6345 }
6346 if (gateway->ping_monitoring || do_fire_gateway_state_event) {
6347 sofia_reg_fire_custom_gateway_state_event(gateway, status, phrase);
6348 }
6349
6350 gateway->ping = switch_epoch_time_now(NULL) + gateway->ping_freq;
6351 sofia_reg_release_gateway(gateway);
6352 gateway->pinging = 0;
6353 } else if (sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')) {
6354 const char *call_id = strchr(sip->sip_call_id->i_id, '_') + 1;
6355 char *sql;
6356 struct cb_helper_sip_user_status sip_user_status;
6357 char ping_status[255] = "";
6358 char sip_contact[1024] = "";
6359 int sip_user_ping_min = profile->sip_user_ping_min;
6360 int sip_user_ping_max = profile->sip_user_ping_max;
6361
6362 char *sip_user = switch_mprintf("%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6363 int ping_time = 0;
6364
6365 if (sofia_private && sofia_private->ping_sent) {
6366 ping_time = (int)(switch_time_now() - sofia_private->ping_sent);
6367 }
6368
6369 sip_user_status.status = ping_status;
6370 sip_user_status.status_len = sizeof(ping_status);
6371 sip_user_status.contact = sip_contact;
6372 sip_user_status.contact_len = sizeof(sip_contact);
6373 sql = switch_mprintf("select ping_status, ping_count, contact from sip_registrations where sip_user='%q' and sip_host='%q' and call_id='%q'",
6374 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6375 sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sip_user_status_callback, &sip_user_status);
6376 switch_safe_free(sql);
6377
6378 if (status != 200 && status != 486) {
6379 sip_user_status.count--;
6380 if (sip_user_status.count >= 0) {
6381 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' failed with code %d - count %d, state %s\n",
6382 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
6383 sql = switch_mprintf("update sip_registrations set ping_count=%d, ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6384 sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6385 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6386 switch_safe_free(sql);
6387 }
6388 if (sip_user_status.count < sip_user_ping_min) {
6389 if (strcmp(sip_user_status.status, "Unreachable")) {
6390 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Unreachable\n",
6391 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6392 sql = switch_mprintf("update sip_registrations set ping_status='Unreachable', ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6393 ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6394 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6395 switch_safe_free(sql);
6396 sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
6397 sip->sip_to->a_url->url_host, call_id, SOFIA_REG_REACHABLE, status, phrase);
6398
6399 if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)) {
6400 time_t now = switch_epoch_time_now(NULL);
6401 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire sip user '%s@%s' due to options failure\n",
6402 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6403
6404 sql = switch_mprintf("update sip_registrations set expires=%ld, ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6405 (long) now, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6406 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6407 switch_safe_free(sql);
6408 }
6409 }
6410 }
6411 } else {
6412 sip_user_status.count++;
6413 if (sip_user_status.count <= sip_user_ping_max) {
6414 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' succeeded with code %d - count %d, state %s\n",
6415 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
6416 sql = switch_mprintf("update sip_registrations set ping_count=%d, ping_time=%d where sip_user='%q' and sip_host='%q' and call_id='%q'",
6417 sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6418 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6419 switch_safe_free(sql);
6420 }
6421 if (sip_user_status.count >= sip_user_ping_min) {
6422 if (strcmp(sip_user_status.status, "Reachable")) {
6423 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Reachable\n",
6424 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
6425 sql = switch_mprintf("update sip_registrations set ping_status='Reachable' where sip_user='%q' and sip_host='%q' and call_id='%q'",
6426 sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
6427 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
6428 switch_safe_free(sql);
6429 sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
6430 sip->sip_to->a_url->url_host, call_id, SOFIA_REG_UNREACHABLE, status, phrase);
6431 }
6432 }
6433 }
6434
6435 switch_safe_free(sip_user);
6436
6437 }
6438 }
6439
sofia_handle_sip_r_invite(switch_core_session_t * session,int status,char const * phrase,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[])6440 static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status,
6441 char const *phrase,
6442 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
6443 sofia_dispatch_event_t *de,
6444 tagi_t tags[])
6445 {
6446 char *call_info = NULL;
6447 if (sip && session) {
6448 switch_channel_t *channel = switch_core_session_get_channel(session);
6449 const char *uuid;
6450 switch_core_session_t *other_session;
6451 private_object_t *tech_pvt = switch_core_session_get_private(session);
6452 char network_ip[80];
6453 int network_port = 0;
6454 switch_caller_profile_t *caller_profile = NULL;
6455 int has_t38 = 0;
6456
6457 switch_channel_clear_flag(channel, CF_REQ_MEDIA);
6458
6459 if (status < 200) {
6460 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
6461 if(switch_core_session_compare(session, other_session)) {
6462 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
6463 if (sofia_test_flag(other_tech_pvt, TFLAG_3PCC)) {
6464 sofia_set_flag_locked(tech_pvt, TFLAG_SKIP_EARLY);
6465 }
6466 }
6467 switch_core_session_rwunlock(other_session);
6468 }
6469
6470 if (sofia_test_flag(tech_pvt, TFLAG_SKIP_EARLY)) {
6471 return;
6472 }
6473 }
6474
6475 if (status >= 900) {
6476 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s status %d received.\n",
6477 switch_channel_get_name(channel), status);
6478 return;
6479 }
6480
6481 if (status > 299) {
6482 switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_refuse");
6483 }
6484
6485 if (status >= 400) {
6486 char status_str[5];
6487 switch_snprintf(status_str, sizeof(status_str), "%d", status);
6488 switch_channel_set_variable(channel, "sip_invite_failure_status", status_str);
6489 switch_channel_set_variable(channel, "sip_invite_failure_phrase", phrase);
6490 switch_channel_set_variable_partner(channel, "sip_invite_failure_status", status_str);
6491 switch_channel_set_variable_partner(channel, "sip_invite_failure_phrase", phrase);
6492 } else {
6493 switch_channel_set_variable_partner(channel, "sip_invite_failure_status", NULL);
6494 switch_channel_set_variable_partner(channel, "sip_invite_failure_phrase", NULL);
6495 }
6496
6497 if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
6498 || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
6499 || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
6500 tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
6501 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote Reason: %d\n", tech_pvt->q850_cause);
6502 }
6503
6504 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
6505
6506 switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
6507 switch_channel_set_variable(channel, "sip_reply_host", network_ip);
6508 switch_channel_set_variable_printf(channel, "sip_reply_port", "%d", network_port);
6509
6510 switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip);
6511 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
6512
6513 if ((caller_profile = switch_channel_get_caller_profile(channel)) && !zstr(network_ip) &&
6514 (zstr(caller_profile->network_addr) || strcmp(caller_profile->network_addr, network_ip))) {
6515 caller_profile->network_addr = switch_core_strdup(caller_profile->pool, network_ip);
6516 }
6517
6518 if (tech_pvt->mparams.last_sdp_response) {
6519 tech_pvt->mparams.prev_sdp_response = tech_pvt->mparams.last_sdp_response;
6520 }
6521 tech_pvt->mparams.last_sdp_response = NULL;
6522
6523 if (sip->sip_payload && sip->sip_payload->pl_data) {
6524 switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE);
6525
6526 if (!zstr(tech_pvt->mparams.prev_sdp_response) && !strcmp(tech_pvt->mparams.prev_sdp_response, sip->sip_payload->pl_data)) {
6527 tech_pvt->mparams.last_sdp_response = tech_pvt->mparams.prev_sdp_response;
6528 } else {
6529 tech_pvt->mparams.last_sdp_response = switch_core_session_strdup(session, sip->sip_payload->pl_data);
6530 }
6531 }
6532
6533 if (status > 299 && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ)) {
6534 switch_channel_set_private(channel, "t38_options", NULL);
6535 switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
6536 switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ);
6537 switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_FAIL);
6538 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 invite failed\n", switch_channel_get_name(tech_pvt->channel));
6539 }
6540
6541
6542 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
6543 if (channel && sip->sip_call_info) {
6544 char *p;
6545 call_info = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_call_info);
6546
6547 if (switch_stristr("appearance", call_info)) {
6548 switch_channel_set_variable(channel, "presence_call_info_full", call_info);
6549 if ((p = strchr(call_info, ';'))) {
6550 switch_channel_set_variable(channel, "presence_call_info", p + 1);
6551 }
6552 }
6553 } else if ((status == 180 || status == 183 || status == 200)) {
6554 char buf[128] = "";
6555 char *sql;
6556 char *state = "active";
6557
6558 if (status != 200) {
6559 state = "progressing";
6560 }
6561
6562 if (sip->sip_from && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
6563 sip->sip_to && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
6564 sql =
6565 switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
6566 "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
6567 sip->sip_from->a_url->url_host);
6568 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
6569
6570 if (mod_sofia_globals.debug_sla > 1) {
6571 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
6572 }
6573 free(sql);
6574
6575 if (!zstr(buf)) {
6576 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
6577 "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
6578
6579 if (mod_sofia_globals.debug_sla > 1) {
6580 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
6581 }
6582
6583 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
6584
6585 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
6586 sip->sip_from->a_url->url_host, buf);
6587 switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
6588 switch_channel_set_variable(channel, "presence_call_info", buf);
6589 }
6590 }
6591 }
6592 }
6593
6594 if ((status == 180 || status == 183 || status > 199)) {
6595 const char *vval;
6596
6597 sofia_set_accept_language_channel_variable(channel, sip);
6598
6599 if (status > 199) {
6600 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
6601 } else {
6602 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
6603 }
6604
6605
6606 if (!(vval = switch_channel_get_variable(channel, "sip_copy_custom_headers")) || switch_true(vval)) {
6607 switch_core_session_t *other_session;
6608
6609 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
6610 if (status > 199) {
6611 switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_RESPONSE_HEADER_PREFIX_T);
6612 } else {
6613 switch_ivr_transfer_variable(session, other_session, SOFIA_SIP_PROGRESS_HEADER_PREFIX_T);
6614 }
6615 switch_core_session_rwunlock(other_session);
6616 }
6617 }
6618 }
6619
6620 if ((status == 180 || status == 183 || status == 200)) {
6621 const char *x_freeswitch_support;
6622
6623 switch_channel_set_flag(channel, CF_MEDIA_ACK);
6624
6625 sofia_glue_store_session_id(session, profile, sip, 1);
6626
6627 if ((x_freeswitch_support = sofia_glue_get_unknown_header(sip, "X-FS-Support"))) {
6628 tech_pvt->x_freeswitch_support_remote = switch_core_session_strdup(session, x_freeswitch_support);
6629 }
6630
6631 if (sip->sip_user_agent && sip->sip_user_agent->g_string) {
6632 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_user_agent->g_string);
6633 } else if (sip->sip_server && sip->sip_server->g_string) {
6634 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_server->g_string);
6635 }
6636
6637 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_allow");
6638
6639 sofia_update_callee_id(session, profile, sip, SWITCH_FALSE);
6640
6641 if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)) {
6642 switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
6643 }
6644
6645 }
6646
6647 if (channel && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
6648 sip_contact_t *p_contact = sip->sip_contact;
6649 int i = 0;
6650 char var_name[80];
6651 const char *diversion_header;
6652 char *full_contact = NULL;
6653 char *invite_contact;
6654 const char *br;
6655 const char *v;
6656
6657 if ((v = switch_channel_get_variable(channel, "outbound_redirect_fatal")) && switch_true(v)) {
6658 su_home_t *home = su_home_new(sizeof(*home));
6659 switch_assert(home != NULL);
6660
6661 for (p_contact = sip->sip_contact; p_contact; p_contact = p_contact->m_next) {
6662 full_contact = sip_header_as_string(home, (void *) p_contact);
6663 invite_contact = sofia_glue_strip_uri(full_contact);
6664
6665 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_%d", i);
6666 switch_channel_set_variable(channel, var_name, full_contact);
6667
6668 if (i == 0) {
6669 switch_channel_set_variable(channel, "sip_redirected_to", full_contact);
6670 }
6671
6672 if (p_contact->m_url->url_user) {
6673 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_user_%d", i);
6674 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_user);
6675 }
6676 if (p_contact->m_url->url_host) {
6677 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_host_%d", i);
6678 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_host);
6679 }
6680 if (p_contact->m_url->url_params) {
6681 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_params_%d", i);
6682 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_params);
6683 }
6684
6685 free(invite_contact);
6686 i++;
6687 }
6688 su_home_unref(home);
6689 home = NULL;
6690 switch_snprintf(var_name, sizeof(var_name), "sip:%d", status);
6691 switch_channel_set_variable(channel, SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE, var_name);
6692 switch_channel_hangup(channel, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL);
6693 goto end;
6694 }
6695
6696 if (!p_contact) {
6697 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Missing contact header in redirect request\n");
6698 goto end;
6699 }
6700
6701 if ((br = switch_channel_get_partner_uuid(channel))) {
6702 switch_xml_t root = NULL, domain = NULL;
6703 switch_core_session_t *a_session;
6704 switch_channel_t *a_channel;
6705
6706 const char *sip_redirect_profile, *sip_redirect_context, *sip_redirect_dialplan, *sip_redirect_fork;
6707
6708 if ((a_session = switch_core_session_locate(br)) && (a_channel = switch_core_session_get_channel(a_session))) {
6709 switch_stream_handle_t stream = { 0 };
6710 char separator[2] = "|";
6711 char *redirect_dialstring;
6712 su_home_t *home = su_home_new(sizeof(*home));
6713 switch_assert(home != NULL);
6714
6715 SWITCH_STANDARD_STREAM(stream);
6716
6717 if (!(sip_redirect_profile = switch_channel_get_variable(channel, "sip_redirect_profile"))) {
6718 sip_redirect_profile = profile->name;
6719 }
6720 if (!(sip_redirect_context = switch_channel_get_variable(channel, "sip_redirect_context"))) {
6721 sip_redirect_context = "redirected";
6722 }
6723 if (!(sip_redirect_dialplan = switch_channel_get_variable(channel, "sip_redirect_dialplan"))) {
6724 sip_redirect_dialplan = "XML";
6725 }
6726
6727 sip_redirect_fork = switch_channel_get_variable(channel, "sip_redirect_fork");
6728
6729 if (switch_true(sip_redirect_fork)) {
6730 *separator = ',';
6731 }
6732
6733 for (p_contact = sip->sip_contact; p_contact; p_contact = p_contact->m_next) {
6734 full_contact = sip_header_as_string(home, (void *) p_contact);
6735 invite_contact = sofia_glue_strip_uri(full_contact);
6736
6737 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_%d", i);
6738 switch_channel_set_variable(a_channel, var_name, full_contact);
6739
6740 if (i == 0) {
6741 switch_channel_set_variable(channel, "sip_redirected_to", full_contact);
6742 switch_channel_set_variable(a_channel, "sip_redirected_to", full_contact);
6743 }
6744
6745 if (p_contact->m_url->url_user) {
6746 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_user_%d", i);
6747 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_user);
6748 switch_channel_set_variable(a_channel, var_name, p_contact->m_url->url_user);
6749 }
6750 if (p_contact->m_url->url_host) {
6751 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_host_%d", i);
6752 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_host);
6753 switch_channel_set_variable(a_channel, var_name, p_contact->m_url->url_host);
6754 }
6755 if (p_contact->m_url->url_params) {
6756 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_contact_params_%d", i);
6757 switch_channel_set_variable(channel, var_name, p_contact->m_url->url_params);
6758 switch_channel_set_variable(a_channel, var_name, p_contact->m_url->url_params);
6759 }
6760
6761 switch_snprintf(var_name, sizeof(var_name), "sip_redirect_dialstring_%d", i);
6762 switch_channel_set_variable_printf(channel, var_name, "sofia/%s/%s", sip_redirect_profile, invite_contact);
6763 switch_channel_set_variable_printf(a_channel, var_name, "sofia/%s/%s", sip_redirect_profile, invite_contact);
6764 stream.write_function(&stream, "%ssofia/%s/%s", i ? separator : "", sip_redirect_profile, invite_contact);
6765 free(invite_contact);
6766 i++;
6767 }
6768
6769 redirect_dialstring = stream.data;
6770
6771 switch_channel_set_variable_printf(channel, "sip_redirect_count", "%d", i);
6772 switch_channel_set_variable(channel, "sip_redirect_dialstring", redirect_dialstring);
6773 switch_channel_set_variable(a_channel, "sip_redirect_dialstring", redirect_dialstring);
6774
6775 p_contact = sip->sip_contact;
6776 full_contact = sip_header_as_string(home, (void *) sip->sip_contact);
6777
6778 if ((diversion_header = sofia_glue_get_unknown_header(sip, "diversion"))) {
6779 switch_channel_set_variable(channel, "sip_redirected_by", diversion_header);
6780 switch_channel_set_variable(a_channel, "sip_redirected_by", diversion_header);
6781 }
6782
6783 if (sofia_test_pflag(profile, PFLAG_MANUAL_REDIRECT)) {
6784 if (!(v = switch_channel_get_variable(channel, "outbound_redirect_info"))) {
6785 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Redirect: Transfering to %s %s %s\n",
6786 p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
6787
6788 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer"))) {
6789 switch_ivr_transfer_recordings(session, a_session);
6790 }
6791
6792 switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
6793 }
6794 switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION);
6795 } else if( !p_contact->m_url->url_host ) {
6796 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Received redirect with invalid URI\n");
6797 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "REDIRECT_ERROR");
6798 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
6799 } else if ((!strcmp(profile->sipip, p_contact->m_url->url_host))
6800 || (profile->extsipip && !strcmp(profile->extsipip, p_contact->m_url->url_host))
6801 || (switch_xml_locate_domain(p_contact->m_url->url_host, NULL, &root, &domain) == SWITCH_STATUS_SUCCESS)) {
6802 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Redirect: Transfering to %s\n",
6803 p_contact->m_url->url_user);
6804
6805 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer"))) {
6806 switch_ivr_transfer_recordings(session, a_session);
6807 }
6808
6809 switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, NULL, NULL);
6810 switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION);
6811 switch_xml_free(root);
6812 } else {
6813 invite_contact = sofia_glue_strip_uri(full_contact);
6814 tech_pvt->redirected = switch_core_session_strdup(session, invite_contact);
6815 free(invite_contact);
6816 }
6817
6818 su_home_unref(home);
6819 home = NULL;
6820
6821 free(stream.data);
6822
6823 switch_core_session_rwunlock(a_session);
6824 }
6825 } else {
6826 su_home_t *home = su_home_new(sizeof(*home));
6827 switch_assert(home != NULL);
6828 full_contact = sip_header_as_string(home, (void *) sip->sip_contact);
6829 invite_contact = sofia_glue_strip_uri(full_contact);
6830
6831 switch_channel_set_variable(channel, "sip_redirected_to", invite_contact);
6832 tech_pvt->redirected = switch_core_session_strdup(session, invite_contact);
6833
6834 free(invite_contact);
6835 su_home_unref(home);
6836 home = NULL;
6837 }
6838 }
6839
6840
6841 if (sip->sip_payload && sip->sip_payload->pl_data && switch_stristr("m=image", sip->sip_payload->pl_data)) {
6842 has_t38 = 1;
6843 }
6844
6845 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
6846 switch_channel_clear_flag(channel, CF_T38_PASSTHRU);
6847 has_t38 = 0;
6848 }
6849
6850 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && has_t38) {
6851 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
6852 switch_core_media_udptl_mode(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
6853
6854 if ((uuid = switch_channel_get_partner_uuid(channel)) && (other_session = switch_core_session_locate(uuid))) {
6855 if (switch_core_session_compare(session, other_session)) {
6856 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
6857 if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
6858 switch_core_media_udptl_mode(other_tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
6859 }
6860 }
6861 switch_core_session_rwunlock(other_session);
6862 }
6863 }
6864
6865 has_t38 = 0;
6866 }
6867
6868 if (status > 199 && (switch_channel_test_flag(channel, CF_PROXY_MODE) ||
6869 switch_channel_test_flag(channel, CF_PROXY_MEDIA) ||
6870 (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && (has_t38 || status > 299)))) {
6871
6872 if (sofia_test_flag(tech_pvt, TFLAG_SENT_UPDATE)) {
6873 sofia_clear_flag_locked(tech_pvt, TFLAG_SENT_UPDATE);
6874
6875 if ((uuid = switch_channel_get_partner_uuid(channel)) && (other_session = switch_core_session_locate(uuid))) {
6876 const char *r_sdp = NULL;
6877 switch_core_session_message_t *msg;
6878 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
6879 //switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
6880
6881 if (sip->sip_payload && sip->sip_payload->pl_data &&
6882 sip->sip_content_type && sip->sip_content_type->c_subtype && switch_stristr("sdp", sip->sip_content_type->c_subtype)) {
6883 tech_pvt->mparams.remote_sdp_str = switch_core_session_strdup(tech_pvt->session, sip->sip_payload->pl_data);
6884 r_sdp = tech_pvt->mparams.remote_sdp_str;
6885 switch_core_media_proxy_remote_addr(session, NULL);
6886 }
6887
6888 if (status == 415) {
6889 int new_status = 488;
6890 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overriding %d %s with %d\n", status, phrase, new_status);
6891 status = new_status;
6892 }
6893
6894 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n%s\n", status, phrase, switch_str_nil(r_sdp));
6895
6896 if (switch_core_session_compare(session, other_session)) {
6897 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
6898 sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK);
6899 }
6900
6901
6902 if (status == 491 && (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) ||
6903 switch_channel_test_flag(channel, CF_PROXY_MODE))) {
6904 nua_respond(other_tech_pvt->nh, SIP_491_REQUEST_PENDING, TAG_END());
6905 switch_core_session_rwunlock(other_session);
6906 goto end;
6907 } else if (status > 299) {
6908 switch_core_media_reset_t38(session);
6909 switch_core_media_reset_t38(other_session);
6910 } else if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) &&
6911 has_t38 && sip->sip_payload && sip->sip_payload->pl_data) {
6912 switch_t38_options_t *t38_options = switch_core_media_extract_t38_options(session, sip->sip_payload->pl_data);
6913
6914 if (!t38_options) {
6915 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Could not parse T.38 options from sdp.\n");
6916 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "T.38 NEGOTIATION ERROR");
6917 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
6918 switch_core_session_rwunlock(other_session);
6919 goto end;
6920 } else {
6921 switch_core_media_process_t38_passthru(session, other_session, t38_options);
6922 }
6923 }
6924
6925
6926 msg = switch_core_session_alloc(other_session, sizeof(*msg));
6927 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
6928 msg->from = __FILE__;
6929 msg->numeric_arg = status;
6930 msg->string_arg = switch_core_session_strdup(other_session, phrase);
6931
6932 if (status == 200 && switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && has_t38) {
6933 msg->pointer_arg = switch_core_session_strdup(other_session, "t38");
6934 } else if (r_sdp) {
6935 msg->pointer_arg = switch_core_session_strdup(other_session, r_sdp);
6936 msg->pointer_arg_size = strlen(r_sdp);
6937 }
6938
6939 if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) && has_t38) {
6940 if (switch_core_media_ready(session, SWITCH_MEDIA_TYPE_AUDIO) &&
6941 switch_core_media_ready(other_session, SWITCH_MEDIA_TYPE_AUDIO)) {
6942 switch_channel_clear_flag(channel, CF_NOTIMER_DURING_BRIDGE);
6943 switch_core_media_udptl_mode(session, SWITCH_MEDIA_TYPE_AUDIO);
6944 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n");
6945 }
6946 }
6947
6948 switch_core_session_queue_message(other_session, msg);
6949
6950 switch_core_session_rwunlock(other_session);
6951 }
6952 goto end;
6953 }
6954 }
6955
6956 if ((status == 180 || status == 183 || status == 200)) {
6957 const char *astate = "early";
6958 url_t *from = NULL, *to = NULL, *contact = NULL;
6959
6960 if (sip->sip_to) {
6961 to = sip->sip_to->a_url;
6962 }
6963 if (sip->sip_from) {
6964 from = sip->sip_from->a_url;
6965 }
6966 if (sip->sip_contact) {
6967 contact = sip->sip_contact->m_url;
6968 }
6969
6970 if (status == 200) {
6971 astate = "confirmed";
6972 }
6973
6974 if ((!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED) &&
6975 !switch_channel_test_flag(channel, CF_RING_READY)) || switch_channel_test_flag(channel, CF_RECOVERING)) {
6976 const char *from_user = "", *from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
6977 const char *user_agent = "", *call_id = "";
6978 const char *to_tag = "";
6979 const char *from_tag = "";
6980 char *sql = NULL;
6981
6982 if (sip->sip_user_agent) {
6983 user_agent = switch_str_nil(sip->sip_user_agent->g_string);
6984 }
6985
6986 if (sip->sip_call_id) {
6987 call_id = switch_str_nil(sip->sip_call_id->i_id);
6988 }
6989
6990 if (to) {
6991 from_user = switch_str_nil(to->url_user);
6992 from_tag = switch_str_nil(sip->sip_to->a_tag);
6993 }
6994
6995 if (from) {
6996 from_host = switch_str_nil(from->url_host);
6997 to_user = switch_str_nil(from->url_user);
6998 to_host = switch_str_nil(from->url_host);
6999 to_tag = switch_str_nil(sip->sip_from->a_tag);
7000 }
7001
7002 if (contact) {
7003 contact_user = switch_str_nil(contact->url_user);
7004 contact_host = switch_str_nil(contact->url_host);
7005 }
7006
7007 if (profile->pres_type) {
7008 const char *presence_data = switch_channel_get_variable(channel, "presence_data");
7009 const char *presence_id = switch_channel_get_variable(channel, "presence_id");
7010 char *full_contact = NULL;
7011 char *p = NULL;
7012 time_t now;
7013
7014 if (sip->sip_contact) {
7015 full_contact = sip_header_as_string(nua_handle_home(tech_pvt->nh), (void *) sip->sip_contact);
7016 }
7017
7018 if (call_info && (p = strchr(call_info, ';'))) {
7019 p++;
7020 }
7021
7022 now = switch_epoch_time_now(NULL);
7023
7024 sql = switch_mprintf("insert into sip_dialogs "
7025 "(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
7026 "contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
7027 "call_info,rcd,call_info_state) "
7028 "values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
7029 call_id,
7030 switch_core_session_get_uuid(session),
7031 to_user, to_host, to_tag, from_user, from_host, from_tag, contact_user,
7032 contact_host, astate, "outbound", user_agent,
7033 profile->name, mod_sofia_globals.hostname, switch_str_nil(full_contact),
7034 switch_str_nil(presence_id), switch_str_nil(presence_data), switch_str_nil(p), (long) now);
7035 switch_assert(sql);
7036
7037 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7038
7039 if ( full_contact ) {
7040 su_free(nua_handle_home(tech_pvt->nh), full_contact);
7041 }
7042 }
7043 } else if (status == 200 && (profile->pres_type)) {
7044 char *sql = NULL;
7045 const char *presence_data = switch_channel_get_variable(channel, "presence_data");
7046 const char *presence_id = switch_channel_get_variable(channel, "presence_id");
7047
7048 sql = switch_mprintf("update sip_dialogs set state='%q',presence_id='%q',presence_data='%q' "
7049 "where uuid='%q';\n", astate, switch_str_nil(presence_id), switch_str_nil(presence_data),
7050 switch_core_session_get_uuid(session));
7051 switch_assert(sql);
7052 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7053 }
7054
7055 extract_header_vars(profile, sip, session, nh);
7056 extract_vars(profile, sip, session);
7057 switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING);
7058 }
7059
7060 }
7061
7062 end:
7063
7064 if (call_info) {
7065 su_free(nua_handle_home(nh), call_info);
7066 }
7067
7068 if (!session && (status == 180 || status == 183 || status == 200)) {
7069 /* nevermind */
7070 nua_handle_bind(nh, NULL);
7071 nua_handle_destroy(nh);
7072 }
7073 }
7074
7075 /* Pure black magic, if you can't understand this code you are lucky.........*/
media_on_hold_thread_run(switch_thread_t * thread,void * obj)7076 void *SWITCH_THREAD_FUNC media_on_hold_thread_run(switch_thread_t *thread, void *obj)
7077 {
7078 switch_core_session_t *other_session = NULL, *session = (switch_core_session_t *) obj;
7079 const char *uuid;
7080
7081 if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
7082 switch_channel_t *channel = switch_core_session_get_channel(session);
7083 private_object_t *tech_pvt = switch_core_session_get_private(session);
7084
7085 if ((uuid = switch_channel_get_partner_uuid(channel)) && (other_session = switch_core_session_locate(uuid))) {
7086 if (switch_core_session_compare(session, other_session)) {
7087 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
7088 sofia_set_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
7089
7090 switch_yield(250000);
7091 switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
7092 switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
7093
7094 if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7095 switch_ivr_3p_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE|SMF_REPLYONLY_B);
7096 } else {
7097 switch_ivr_3p_media(switch_core_session_get_uuid(other_session), SMF_REBRIDGE);
7098 }
7099
7100
7101 switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
7102 switch_core_media_clear_rtp_flag(other_session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
7103
7104
7105 switch_core_media_toggle_hold(session, 1);
7106 }
7107 switch_core_session_rwunlock(other_session);
7108 }
7109
7110 switch_core_session_rwunlock(session);
7111 }
7112
7113 return NULL;
7114 }
7115
launch_media_on_hold(switch_core_session_t * session)7116 static void launch_media_on_hold(switch_core_session_t *session)
7117 {
7118 switch_thread_t *thread;
7119 switch_threadattr_t *thd_attr = NULL;
7120
7121 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
7122 switch_threadattr_detach_set(thd_attr, 1);
7123 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
7124 switch_thread_create(&thread, thd_attr, media_on_hold_thread_run, session, switch_core_session_get_pool(session));
7125 }
7126
7127
7128
mark_transfer_record(switch_core_session_t * session,const char * br_a,const char * br_b)7129 static void mark_transfer_record(switch_core_session_t *session, const char *br_a, const char *br_b)
7130 {
7131 switch_core_session_t *br_b_session, *br_a_session;
7132 switch_channel_t *channel;
7133 const char *uvar1, *dvar1, *uvar2, *dvar2;
7134
7135 channel = switch_core_session_get_channel(session);
7136
7137 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7138 uvar1 = "sip_from_user";
7139 dvar1 = "sip_from_host";
7140 } else {
7141 uvar1 = "sip_to_user";
7142 dvar1 = "sip_to_host";
7143 }
7144
7145
7146 if ((br_b_session = switch_core_session_locate(br_b)) ) {
7147 switch_channel_t *br_b_channel = switch_core_session_get_channel(br_b_session);
7148 switch_caller_profile_t *cp = switch_channel_get_caller_profile(br_b_channel);
7149
7150 if (switch_channel_direction(br_b_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7151 uvar2 = "sip_from_user";
7152 dvar2 = "sip_from_host";
7153 } else {
7154 uvar2 = "sip_to_user";
7155 dvar2 = "sip_to_host";
7156 }
7157
7158 cp->transfer_source = switch_core_sprintf(cp->pool,
7159 "%ld:%s:att_xfer:%s@%s/%s@%s",
7160 (long) switch_epoch_time_now(NULL),
7161 cp->uuid_str,
7162 switch_channel_get_variable(channel, uvar1),
7163 switch_channel_get_variable(channel, dvar1),
7164 switch_channel_get_variable(br_b_channel, uvar2),
7165 switch_channel_get_variable(br_b_channel, dvar2));
7166
7167 switch_channel_add_variable_var_check(br_b_channel, SWITCH_TRANSFER_HISTORY_VARIABLE, cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
7168 switch_channel_set_variable(br_b_channel, SWITCH_TRANSFER_SOURCE_VARIABLE, cp->transfer_source);
7169
7170 switch_core_session_rwunlock(br_b_session);
7171 }
7172
7173
7174
7175 if ((br_a_session = switch_core_session_locate(br_a)) ) {
7176 switch_channel_t *br_a_channel = switch_core_session_get_channel(br_a_session);
7177 switch_caller_profile_t *cp = switch_channel_get_caller_profile(br_a_channel);
7178
7179 if (switch_channel_direction(br_a_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7180 uvar2 = "sip_from_user";
7181 dvar2 = "sip_from_host";
7182 } else {
7183 uvar2 = "sip_to_user";
7184 dvar2 = "sip_to_host";
7185 }
7186
7187 cp->transfer_source = switch_core_sprintf(cp->pool,
7188 "%ld:%s:att_xfer:%s@%s/%s@%s",
7189 (long) switch_epoch_time_now(NULL),
7190 cp->uuid_str,
7191 switch_channel_get_variable(channel, uvar1),
7192 switch_channel_get_variable(channel, dvar1),
7193 switch_channel_get_variable(br_a_channel, uvar2),
7194 switch_channel_get_variable(br_a_channel, dvar2));
7195
7196 switch_channel_add_variable_var_check(br_a_channel, SWITCH_TRANSFER_HISTORY_VARIABLE, cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
7197 switch_channel_set_variable(br_a_channel, SWITCH_TRANSFER_SOURCE_VARIABLE, cp->transfer_source);
7198
7199 switch_core_session_rwunlock(br_a_session);
7200 }
7201
7202
7203 }
7204
7205
sofia_handle_sip_i_state(switch_core_session_t * session,int status,char const * phrase,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[])7206 static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
7207 char const *phrase,
7208 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
7209 sofia_dispatch_event_t *de,
7210 tagi_t tags[])
7211 {
7212 const char *l_sdp = NULL, *r_sdp = NULL;
7213 int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
7214 int ss_state = nua_callstate_init;
7215 switch_channel_t *channel = NULL;
7216 private_object_t *tech_pvt = NULL;
7217 const char *replaces_str = NULL;
7218 switch_core_session_t *other_session = NULL;
7219 switch_channel_t *other_channel = NULL;
7220 //private_object_t *other_tech_pvt = NULL;
7221 char st[80] = "";
7222 int is_dup_sdp = 0;
7223 switch_event_t *s_event = NULL;
7224 char *p;
7225 char *patched_sdp = NULL;
7226 const char *session_id_header = sofia_glue_session_id_header(session, profile);
7227
7228 tl_gets(tags,
7229 NUTAG_CALLSTATE_REF(ss_state),
7230 NUTAG_OFFER_RECV_REF(offer_recv),
7231 NUTAG_ANSWER_RECV_REF(answer_recv),
7232 NUTAG_OFFER_SENT_REF(offer_sent),
7233 NUTAG_ANSWER_SENT_REF(answer_sent),
7234 SIPTAG_REPLACES_STR_REF(replaces_str), SOATAG_LOCAL_SDP_STR_REF(l_sdp), SOATAG_REMOTE_SDP_STR_REF(r_sdp), TAG_END());
7235
7236 if (session) {
7237 channel = switch_core_session_get_channel(session);
7238 tech_pvt = switch_core_session_get_private(session);
7239
7240 if (!tech_pvt || !tech_pvt->nh) {
7241 goto done;
7242 }
7243
7244 if (!r_sdp && (status == 100 || status == 200)) {
7245 if (ss_state == nua_callstate_completing) {
7246 if (tech_pvt->mparams.last_sdp_response) {
7247 r_sdp = tech_pvt->mparams.last_sdp_response;
7248 }
7249 } else if (ss_state == nua_callstate_received || ss_state == nua_callstate_ready) {
7250 if (tech_pvt->mparams.last_sdp_str) {
7251 r_sdp = tech_pvt->mparams.last_sdp_str;
7252 }
7253 }
7254 }
7255
7256 if (tech_pvt->mparams.last_sdp_str) {
7257 tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
7258 }
7259
7260 if (tech_pvt->mparams.last_sdp_response) {
7261 tech_pvt->mparams.prev_sdp_response = tech_pvt->mparams.last_sdp_response;
7262 }
7263
7264 tech_pvt->mparams.last_sdp_str = NULL;
7265 tech_pvt->mparams.last_sdp_response = NULL;
7266
7267 if (r_sdp && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) {
7268 const char *var;
7269
7270 if ((var = switch_channel_get_variable(channel, "bypass_media_sdp_filter"))) {
7271 if ((patched_sdp = switch_core_media_process_sdp_filter(r_sdp, var, session))) {
7272 r_sdp = patched_sdp;
7273 }
7274 }
7275 }
7276
7277 if ((switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) ||
7278 (sofia_test_flag(profile, TFLAG_INB_NOMEDIA) || sofia_test_flag(profile, TFLAG_PROXY_MEDIA))) {
7279
7280 /* This marr in our code brought to you by people who can't read........ */
7281 if (profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME && r_sdp && (p = (char *) switch_stristr("g729a/8000", r_sdp))) {
7282 p += 4;
7283 *p++ = '/';
7284 *p++ = '8';
7285 *p++ = '0';
7286 *p++ = '0';
7287 *p++ = '0';
7288 *p++ = ' ';
7289 }
7290 }
7291 }
7292
7293
7294 if (ss_state == nua_callstate_terminated) {
7295
7296 if ((status == 300 || status == 301 || status == 302 || status == 305) && session) {
7297 channel = switch_core_session_get_channel(session);
7298 tech_pvt = switch_core_session_get_private(session);
7299
7300 if (!tech_pvt || !tech_pvt->nh) {
7301 goto done;
7302 }
7303
7304
7305 if (tech_pvt->redirected) {
7306 sofia_glue_do_invite(session);
7307 goto done;
7308 }
7309 }
7310
7311 if (sofia_private) {
7312 sofia_private->destroy_me = 1;
7313 }
7314 }
7315
7316 if (session) {
7317 if ((switch_channel_test_flag(channel, CF_ANSWERED) && (status == 180 || status == 183) && !r_sdp) || (ss_state == nua_callstate_ready && status >= 300)) {
7318 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel %s skipping state [%s][%d]\n",
7319 switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
7320 goto done;
7321 } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (status == 180 || status == 183) && r_sdp) {
7322 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
7323 }
7324
7325 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel %s entering state [%s][%d]\n",
7326 switch_channel_get_name(channel), nua_callstate_name(ss_state), status);
7327
7328 if (r_sdp) {
7329 switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
7330
7331 if (!(profile->mndlb & SM_NDLB_ALLOW_NONDUP_SDP) || (!zstr(tech_pvt->mparams.remote_sdp_str) && !strcmp(tech_pvt->mparams.remote_sdp_str, r_sdp))) {
7332 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Duplicate SDP\n%s\n", r_sdp);
7333 is_dup_sdp = 1;
7334 } else {
7335 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
7336 tech_pvt->mparams.remote_sdp_str = switch_core_session_strdup(session, r_sdp);
7337 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && status < 200) {
7338 switch_channel_mark_pre_answered(channel);
7339 }
7340 //if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
7341 // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE);
7342 //}
7343 switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
7344 sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
7345 sofia_set_flag(tech_pvt, TFLAG_NEW_SDP);
7346
7347 }
7348 }
7349 }
7350
7351 if (status == 988) {
7352 goto done;
7353 }
7354
7355 if (status == 183 && !r_sdp) {
7356 if ((channel && switch_true(switch_channel_get_variable(channel, "sip_ignore_183nosdp"))) || sofia_test_pflag(profile, PFLAG_IGNORE_183NOSDP)) {
7357 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Ignoring 183 w/o sdp\n", channel ? switch_channel_get_name(channel) : "None");
7358 goto done;
7359 }
7360 status = 180;
7361 }
7362
7363 if (status == 180 && r_sdp) {
7364 status = 183;
7365 }
7366
7367 if (channel && profile->pres_type && ss_state == nua_callstate_ready && status == 200) {
7368 const char* to_tag = "";
7369 char *sql = NULL;
7370 to_tag = switch_str_nil(switch_channel_get_variable(channel, "sip_to_tag"));
7371 sql = switch_mprintf("update sip_dialogs set sip_to_tag='%q' "
7372 "where uuid='%q' and sip_to_tag = ''", to_tag, switch_core_session_get_uuid(session));
7373
7374 if (mod_sofia_globals.debug_presence > 1) {
7375 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "QUERY SQL %s\n", sql);
7376 }
7377 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
7378 }
7379
7380 if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
7381 const char *full_to = NULL;
7382 const char *var;
7383 if ((var = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(var) &&
7384 !((var = switch_channel_get_variable(channel, "sip_auto_answer_suppress_notify")) && switch_true(var))) {
7385 full_to = switch_str_nil(switch_channel_get_variable(channel, "sip_full_to"));
7386
7387 nua_notify(nh,
7388 NUTAG_NEWSUB(1),
7389 NUTAG_WITH_THIS_MSG(de->data->e_msg),
7390 NUTAG_SUBSTATE(nua_substate_terminated),
7391 TAG_IF((full_to), SIPTAG_TO_STR(full_to)),
7392 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
7393 SIPTAG_EVENT_STR("talk"),
7394 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7395 TAG_END());
7396 }
7397 }
7398
7399
7400
7401 state_process:
7402
7403 switch ((enum nua_callstate) ss_state) {
7404 case nua_callstate_terminated:
7405 case nua_callstate_terminating:
7406 case nua_callstate_ready:
7407 case nua_callstate_completed:
7408 case nua_callstate_received:
7409 case nua_callstate_proceeding:
7410 case nua_callstate_completing:
7411 case nua_callstate_calling:
7412 if (!(session && channel && tech_pvt))
7413 goto done;
7414 default:
7415 break;
7416 }
7417
7418 switch ((enum nua_callstate) ss_state) {
7419 case nua_callstate_init:
7420 break;
7421 case nua_callstate_authenticating:
7422 break;
7423 case nua_callstate_calling:
7424 tech_pvt->sent_last_invite = 1;
7425 tech_pvt->sent_invites++;
7426 break;
7427 case nua_callstate_proceeding:
7428
7429 if (sofia_test_flag(tech_pvt, TFLAG_SKIP_EARLY)) {
7430 sofia_clear_flag_locked(tech_pvt, TFLAG_SKIP_EARLY);
7431 goto done;
7432 }
7433
7434 switch (status) {
7435 case 180:
7436 switch_channel_mark_ring_ready(channel);
7437 break;
7438 case 182:
7439 switch_channel_mark_ring_ready_value(channel, SWITCH_RING_READY_QUEUED);
7440 break;
7441 default:
7442 break;
7443 }
7444
7445 if (r_sdp) {
7446 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7447 char ibuf[35] = "", pbuf[35] = "";
7448 const char *ptr;
7449
7450 if ((ptr = switch_stristr("c=IN IP4", r_sdp))) {
7451 int i = 0;
7452
7453 ptr += 8;
7454
7455 while(*ptr == ' ') {
7456 ptr++;
7457 }
7458 while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
7459 ibuf[i++] = *ptr++;
7460 }
7461
7462 switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, ibuf);
7463 }
7464
7465 if ((ptr = switch_stristr("m=audio", r_sdp))) {
7466 int i = 0;
7467
7468 ptr += 7;
7469
7470 while(*ptr == ' ') {
7471 ptr++;
7472 }
7473 while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') {
7474 pbuf[i++] = *ptr++;
7475 }
7476
7477 switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, pbuf);
7478 }
7479
7480 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7481 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
7482 }
7483 sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
7484 switch_channel_mark_pre_answered(channel);
7485 sofia_set_flag(tech_pvt, TFLAG_SDP);
7486 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) || switch_channel_test_flag(channel, CF_REINVITE)) {
7487 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7488 goto done;
7489 }
7490 }
7491 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
7492 other_channel = switch_core_session_get_channel(other_session);
7493 switch_channel_pass_sdp(channel, other_channel, r_sdp);
7494
7495 //switch_channel_pre_answer(other_channel);
7496 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_PROGRESS);
7497 switch_core_session_rwunlock(other_session);
7498 }
7499 goto done;
7500 } else {
7501 if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
7502 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION");
7503 } else if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7504 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
7505 switch_core_media_patch_sdp(tech_pvt->session);
7506 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7507 nua_respond(nh, SIP_488_NOT_ACCEPTABLE,
7508 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
7509 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
7510 } else{
7511 switch_channel_mark_pre_answered(channel);
7512 }
7513
7514 } else {
7515 if (sofia_media_tech_media(tech_pvt, (char *) r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
7516 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
7517 nua_respond(nh, SIP_488_NOT_ACCEPTABLE,
7518 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
7519 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
7520 }
7521 }
7522 goto done;
7523 }
7524 }
7525 break;
7526 case nua_callstate_completing:
7527 {
7528 int send_ack = 1;
7529
7530 if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
7531 const char *wait_for_ack = switch_channel_get_variable(channel, "sip_wait_for_aleg_ack");
7532
7533 if (switch_true(wait_for_ack)) {
7534 switch_core_session_t *other_session;
7535
7536 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
7537 if (switch_core_session_compare(session, other_session)) {
7538 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
7539
7540 if (!sofia_test_flag(tech_pvt, TFLAG_3PCC) && !sofia_test_flag(other_tech_pvt, TFLAG_3PCC)) {
7541 sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK);
7542 send_ack = 0;
7543 }
7544 }
7545 switch_core_session_rwunlock(other_session);
7546 }
7547 }
7548 }
7549
7550 if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED)) {
7551 if (switch_channel_test_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG)) {
7552 switch_core_session_t *other_session;
7553
7554 switch_channel_clear_flag(channel, CF_3P_NOMEDIA_REQUESTED_BLEG);
7555
7556 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
7557 if (switch_core_session_compare(session, other_session)) {
7558 //switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
7559 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
7560
7561 sofia_glue_clear_soa(other_session, SWITCH_TRUE);
7562
7563 if (sofia_use_soa(other_tech_pvt)) {
7564 nua_ack(other_tech_pvt->nh,
7565 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
7566 SIPTAG_CONTACT_STR(other_tech_pvt->reply_contact),
7567 SOATAG_USER_SDP_STR(r_sdp),
7568 SOATAG_REUSE_REJECTED(1),
7569 SOATAG_RTP_SELECT(1),
7570 SOATAG_AUDIO_AUX("cn telephone-event"),
7571 TAG_IF(sofia_test_pflag(other_tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
7572 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7573 TAG_END());
7574 } else {
7575 nua_ack(other_tech_pvt->nh,
7576 NUTAG_MEDIA_ENABLE(0),
7577 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
7578 SIPTAG_CONTACT_STR(other_tech_pvt->reply_contact),
7579 TAG_IF(r_sdp, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
7580 TAG_IF(r_sdp, SIPTAG_PAYLOAD_STR(r_sdp)),
7581 SOATAG_AUDIO_AUX("cn telephone-event"),
7582 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7583 TAG_END());
7584 }
7585
7586 nua_ack(tech_pvt->nh,
7587 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
7588 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
7589 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7590 TAG_END());
7591
7592 }
7593 switch_core_session_rwunlock(other_session);
7594 }
7595 } else {
7596 switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
7597 }
7598
7599 switch_channel_clear_flag(channel, CF_3P_NOMEDIA_REQUESTED);
7600 goto done;
7601
7602 } else if (switch_channel_test_flag(channel, CF_3P_MEDIA_REQUESTED)) {
7603 uint8_t match = 0;
7604
7605 switch_channel_clear_flag(channel, CF_PROXY_MODE);
7606
7607 switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
7608 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
7609
7610 if (tech_pvt->mparams.num_codecs) {
7611 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
7612 }
7613
7614 if (!match) {
7615 if (switch_channel_get_state(channel) != CS_NEW) {
7616 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE,
7617 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),TAG_END());
7618 }
7619 } else {
7620 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
7621 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED");
7622 sofia_set_flag_locked(tech_pvt, TFLAG_READY);
7623
7624 sofia_set_flag(tech_pvt, TFLAG_SDP);
7625 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "RESTABLISH MEDIA SDP:\n%s\n", tech_pvt->mparams.local_sdp_str);
7626
7627 switch_channel_set_flag(channel, CF_REQ_MEDIA);
7628 switch_channel_set_flag(channel, CF_MEDIA_ACK);
7629 switch_channel_set_flag(channel, CF_MEDIA_SET);
7630
7631 switch_core_media_activate_rtp(session);
7632
7633
7634 if (sofia_use_soa(tech_pvt)) {
7635 nua_ack(tech_pvt->nh,
7636 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
7637 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
7638 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
7639 SOATAG_REUSE_REJECTED(1),
7640 SOATAG_RTP_SELECT(1),
7641 SOATAG_AUDIO_AUX("cn telephone-event"),
7642 TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
7643 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7644 TAG_END());
7645 } else {
7646 nua_ack(tech_pvt->nh,
7647 NUTAG_MEDIA_ENABLE(0),
7648 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
7649 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
7650 TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_CONTENT_TYPE_STR("application/sdp")),
7651 TAG_IF(tech_pvt->mparams.local_sdp_str, SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str)),
7652 SOATAG_AUDIO_AUX("cn telephone-event"),
7653 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7654 TAG_END());
7655 }
7656
7657 switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED);
7658 goto done;
7659 }
7660
7661 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS");
7662 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
7663
7664 switch_channel_clear_flag(channel, CF_3P_MEDIA_REQUESTED);
7665 goto done;
7666 //ss_state = nua_callstate_ready;
7667 //goto state_process;
7668 }
7669
7670 if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE) && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {
7671 sofia_set_flag(tech_pvt, TFLAG_SDP);
7672 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
7673 other_channel = switch_core_session_get_channel(other_session);
7674 //other_tech_pvt = switch_core_session_get_private(other_session);
7675
7676 switch_channel_pass_sdp(channel, other_channel, r_sdp);
7677 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
7678 switch_core_session_rwunlock(other_session);
7679 }
7680 goto done;
7681
7682 }
7683
7684 if (send_ack) {
7685 tech_send_ack(nh, tech_pvt, NULL);
7686 } else {
7687 ss_state = nua_callstate_ready;
7688 goto state_process;
7689 }
7690
7691 }
7692 goto done;
7693 case nua_callstate_received:
7694 tech_pvt->recv_invites++;
7695 tech_pvt->sent_last_invite = 0;
7696
7697 if (!sofia_test_flag(tech_pvt, TFLAG_SDP)) {
7698 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
7699 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
7700 int r = sofia_test_flag(other_tech_pvt, TFLAG_REINVITED);
7701 switch_core_session_rwunlock(other_session);
7702
7703 if (r) {
7704 /* Due to a race between simultaneous reinvites to both legs of a bridge,
7705 an earlier call to nua_invite silently failed.
7706 So we reject the incoming invite with a 491 and redo the failed outgoing invite. */
7707
7708 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
7709 "Other leg already handling a reinvite, so responding with 491\n");
7710
7711 nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING,
7712 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
7713 sofia_glue_do_invite(session);
7714 goto done;
7715 }
7716 }
7717
7718
7719 if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {
7720 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
7721 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOMEDIA");
7722 sofia_set_flag_locked(tech_pvt, TFLAG_READY);
7723 if (switch_channel_get_state(channel) == CS_NEW) {
7724 switch_channel_set_state(channel, CS_INIT);
7725 }
7726 sofia_set_flag(tech_pvt, TFLAG_SDP);
7727 goto done;
7728 } else if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
7729 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA");
7730 sofia_set_flag_locked(tech_pvt, TFLAG_READY);
7731 if (switch_channel_get_state(channel) == CS_NEW) {
7732 switch_channel_set_state(channel, CS_INIT);
7733 }
7734 } else if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION)) {
7735 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION");
7736 sofia_set_flag_locked(tech_pvt, TFLAG_READY);
7737 if (switch_channel_get_state(channel) == CS_NEW) {
7738 switch_channel_set_state(channel, CS_INIT);
7739 }
7740 } else {
7741 uint8_t match = 0;
7742
7743 if (tech_pvt->mparams.num_codecs) {
7744 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
7745 }
7746
7747 if (!match) {
7748 if (switch_channel_get_state(channel) != CS_NEW) {
7749 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
7750 }
7751 } else {
7752 nua_handle_t *bnh;
7753 sip_replaces_t *replaces;
7754 su_home_t *home = NULL;
7755 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED");
7756 sofia_set_flag_locked(tech_pvt, TFLAG_READY);
7757
7758 if (switch_channel_get_state(channel) == CS_NEW) {
7759 switch_channel_set_state(channel, CS_INIT);
7760 } else {
7761 nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
7762 }
7763 sofia_set_flag(tech_pvt, TFLAG_SDP);
7764 if (replaces_str) {
7765 home = su_home_new(sizeof(*home));
7766 switch_assert(home != NULL);
7767 if ((replaces = sip_replaces_make(home, replaces_str))
7768 && (bnh = nua_handle_by_replaces(nua, replaces))) {
7769 sofia_private_t *b_private;
7770
7771 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing Replaces Attended Transfer\n");
7772 while (switch_channel_get_state(channel) < CS_EXECUTE) {
7773 switch_yield(10000);
7774 }
7775
7776 if ((b_private = nua_handle_magic(bnh))) {
7777 const char *br_b = switch_channel_get_partner_uuid(channel);
7778 char *br_a = b_private->uuid;
7779
7780
7781 if (br_b) {
7782 switch_core_session_t *tmp;
7783
7784 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")) &&
7785 (tmp = switch_core_session_locate(br_a))) {
7786 switch_ivr_transfer_recordings(session, tmp);
7787 switch_core_session_rwunlock(tmp);
7788 }
7789
7790 switch_channel_set_variable_printf(channel, "transfer_to", "att:%s", br_b);
7791
7792 mark_transfer_record(session, br_a, br_b);
7793 switch_ivr_uuid_bridge(br_a, br_b);
7794 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
7795 sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
7796 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
7797 sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
7798 switch_channel_hangup(channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
7799 } else {
7800 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR");
7801 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
7802 }
7803 } else {
7804 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR");
7805 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
7806 }
7807 nua_handle_unref(bnh);
7808 }
7809 su_home_unref(home);
7810 home = NULL;
7811 }
7812
7813 goto done;
7814 }
7815
7816 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS");
7817 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
7818 }
7819 } else {
7820 if (sofia_test_pflag(profile, PFLAG_3PCC)) {
7821 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7822 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc=yes cannot work with bypass or proxy media, hanging up.\n");
7823 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
7824 switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
7825 } else {
7826 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
7827 switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
7828 switch_core_media_prepare_codecs(session, 1);
7829 switch_channel_set_state(channel, CS_HIBERNATE);
7830 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0);
7831 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
7832
7833 if (sofia_use_soa(tech_pvt)) {
7834 nua_respond(tech_pvt->nh, SIP_200_OK,
7835 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
7836 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
7837 SOATAG_REUSE_REJECTED(1),
7838 SOATAG_AUDIO_AUX("cn telephone-event"),
7839 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
7840 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7841 TAG_END());
7842 } else {
7843 nua_respond(tech_pvt->nh, SIP_200_OK,
7844 NUTAG_MEDIA_ENABLE(0),
7845 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
7846 SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
7847 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7848 TAG_END());
7849 }
7850 }
7851 } else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
7852 //3PCC proxy mode delays the 200 OK until the call is answered
7853 // 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...
7854 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
7855 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
7856 //switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
7857 //switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
7858 sofia_set_flag(tech_pvt, TFLAG_LATE_NEGOTIATION);
7859 //Moves into CS_INIT so call moves forward into the dialplan
7860 switch_channel_set_state(channel, CS_INIT);
7861 } else {
7862 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc not enabled, hanging up.\n");
7863 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
7864 switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
7865 }
7866 goto done;
7867 }
7868
7869 } else if (tech_pvt && sofia_test_flag(tech_pvt, TFLAG_SDP) && !r_sdp) {
7870 sofia_set_flag_locked(tech_pvt, TFLAG_NOSDP_REINVITE);
7871 if ((switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
7872 sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
7873 sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
7874
7875 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
7876 switch_core_session_message_t *msg;
7877 if (switch_core_session_compare(session, other_session)) {
7878 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
7879 sofia_clear_flag(other_tech_pvt, TFLAG_ENABLE_SOA);
7880 }
7881
7882 msg = switch_core_session_alloc(other_session, sizeof(*msg));
7883 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
7884 msg->from = __FILE__;
7885 msg->string_arg = NULL;
7886 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing NOSDP to other leg.\n");
7887 switch_core_session_queue_message(other_session, msg);
7888 switch_core_session_rwunlock(other_session);
7889 } else {
7890 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
7891 "NOSDP Re-INVITE to a proxy mode channel that is not in a bridge.\n");
7892 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
7893 }
7894 goto done;
7895 }
7896
7897 if (switch_channel_var_true(channel, "sip_unhold_nosdp")) {
7898 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, "sendrecv",
7899 zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
7900 } else {
7901 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL,
7902 zstr(tech_pvt->mparams.local_sdp_str) || !switch_channel_test_flag(channel, CF_PROXY_MODE));
7903 }
7904
7905 if (zstr(tech_pvt->mparams.local_sdp_str)) {
7906 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot find a SDP\n");
7907 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
7908 } else {
7909 if (sofia_use_soa(tech_pvt)) {
7910 nua_respond(tech_pvt->nh, SIP_200_OK,
7911 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
7912 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
7913 SOATAG_REUSE_REJECTED(1),
7914 SOATAG_AUDIO_AUX("cn telephone-event"),
7915 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
7916 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7917 TAG_END());
7918 } else {
7919 nua_respond(tech_pvt->nh, SIP_200_OK,
7920 NUTAG_MEDIA_ENABLE(0),
7921 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
7922 SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
7923 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
7924 TAG_END());
7925 }
7926 }
7927
7928 goto done;
7929
7930 } else {
7931 ss_state = nua_callstate_completed;
7932 goto state_process;
7933 }
7934
7935 break;
7936 case nua_callstate_early:
7937 if (answer_recv) {
7938 uint8_t match = 0;
7939 switch_assert(tech_pvt);
7940 sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
7941 switch_channel_mark_pre_answered(channel);
7942 sofia_set_flag(tech_pvt, TFLAG_SDP);
7943
7944
7945 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
7946 if (match) {
7947 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
7948 goto done;
7949 }
7950
7951 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
7952
7953 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
7954 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Early Media RTP Error!\n");
7955 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
7956 }
7957 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
7958 } else {
7959 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
7960 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Early Media Codec Error!\n");
7961 }
7962 }
7963 break;
7964 case nua_callstate_completed:
7965 if (r_sdp) {
7966 const char *var;
7967 uint8_t match = 0, is_ok = 1, is_t38 = 0;
7968
7969 tech_pvt->mparams.hold_laps = 0;
7970
7971 if ((var = switch_channel_get_variable(channel, "sip_ignore_reinvites")) && switch_true(var)) {
7972 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ignoring Re-invite\n");
7973 nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
7974 goto done;
7975 }
7976
7977 if (switch_stristr("m=image", r_sdp)) {
7978 is_t38 = 1;
7979 }
7980
7981
7982 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
7983 if ((sofia_test_media_flag(profile, SCMF_DISABLE_HOLD)
7984 || ((var = switch_channel_get_variable(channel, "rtp_disable_hold")) && switch_true(var)))
7985 && ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) || tech_pvt->mparams.hold_laps)) {
7986 nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
7987
7988 if (tech_pvt->mparams.hold_laps) {
7989 tech_pvt->mparams.hold_laps = 0;
7990 } else {
7991 tech_pvt->mparams.hold_laps = 1;
7992 }
7993
7994 goto done;
7995 }
7996
7997 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
7998 switch_core_session_message_t *msg;
7999 private_object_t *other_tech_pvt;
8000 int media_on_hold = switch_true(switch_channel_get_variable_dup(channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1));
8001
8002 switch_core_media_clear_rtp_flag(other_session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
8003
8004
8005 if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 &&
8006 ((profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) || media_on_hold)) {
8007 if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) {
8008 tech_pvt->mparams.hold_laps = 1;
8009 switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
8010 switch_channel_clear_flag(channel, CF_PROXY_MODE);
8011 switch_core_media_set_local_sdp(tech_pvt->session, NULL, SWITCH_FALSE);
8012 switch_core_media_clear_rtp_flag(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_RTP_FLAG_AUTOADJ);
8013
8014 if (!switch_channel_media_ready(channel)) {
8015 //if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
8016 //const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
8017
8018
8019 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
8020 if (sofia_media_tech_media(tech_pvt, r_sdp, SDP_TYPE_REQUEST) != SWITCH_STATUS_SUCCESS) {
8021 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
8022 switch_core_session_rwunlock(other_session);
8023 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
8024 goto done;
8025 }
8026 //}
8027 }
8028
8029
8030 if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
8031 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
8032 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8033 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
8034 switch_core_session_rwunlock(other_session);
8035 goto done;
8036 }
8037 }
8038
8039 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 1);
8040
8041 if (sofia_use_soa(tech_pvt)) {
8042 nua_respond(tech_pvt->nh, SIP_200_OK,
8043 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
8044 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
8045 SOATAG_REUSE_REJECTED(1),
8046 SOATAG_AUDIO_AUX("cn telephone-event"),
8047 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
8048 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8049 TAG_END());
8050 } else {
8051 nua_respond(tech_pvt->nh, SIP_200_OK,
8052 NUTAG_MEDIA_ENABLE(0),
8053 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
8054 SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
8055 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8056 TAG_END());
8057 }
8058
8059 switch_channel_set_flag(channel, CF_PROXY_MODE);
8060 switch_yield(250000);
8061 launch_media_on_hold(session);
8062
8063 switch_core_session_rwunlock(other_session);
8064 goto done;
8065 }
8066 }
8067
8068 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8069 sofia_media_activate_rtp(tech_pvt);
8070 switch_core_media_proxy_remote_addr(session, r_sdp);
8071
8072 if ((tech_pvt->profile->mndlb & SM_NDLB_NEVER_PATCH_REINVITE)) {
8073 nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
8074 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NOT proxying re-invite.\n");
8075 switch_core_session_rwunlock(other_session);
8076 goto done;
8077 }
8078 }
8079
8080 other_tech_pvt = switch_core_session_get_private(other_session);
8081
8082 if (sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)) {
8083 /* The other leg won the reinvite race */
8084 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Other leg already handling reinvite, so responding with 491\n");
8085 nua_respond(tech_pvt->nh, SIP_491_REQUEST_PENDING,
8086 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
8087 switch_core_session_rwunlock(other_session);
8088 goto done;
8089 }
8090 sofia_set_flag(tech_pvt, TFLAG_REINVITED);
8091
8092 msg = switch_core_session_alloc(other_session, sizeof(*msg));
8093 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
8094 msg->from = __FILE__;
8095 msg->string_arg = switch_core_session_strdup(other_session, r_sdp);
8096 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing SDP to other leg.\n%s\n", r_sdp);
8097
8098 if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
8099 if (!switch_stristr("sendonly", r_sdp) && !switch_stristr("inactive", r_sdp)) {
8100 sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
8101 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
8102 switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL);
8103 }
8104 } else if (switch_stristr("sendonly", r_sdp) && !switch_stristr("inactive", r_sdp)) {
8105 const char *msg = "hold";
8106
8107 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
8108 const char *info = switch_channel_get_variable(channel, "presence_call_info");
8109 if (info) {
8110 if (switch_stristr("private", info)) {
8111 msg = "hold-private";
8112 }
8113 }
8114 }
8115
8116 sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
8117 switch_channel_set_flag(channel, CF_LEG_HOLDING);
8118 switch_channel_presence(tech_pvt->channel, "unknown", msg, NULL);
8119 }
8120
8121 switch_core_session_queue_message(other_session, msg);
8122
8123 switch_core_session_rwunlock(other_session);
8124 } else {
8125 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
8126 "Re-INVITE to a no-media channel that is not in a bridge.\n");
8127 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
8128 }
8129 goto done;
8130 } else {
8131 int hold_related = 0;
8132
8133 if (sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
8134 hold_related = 2;
8135 } else if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp) || switch_stristr("inactive", r_sdp)) {
8136 hold_related = 1;
8137 }
8138
8139 if (!is_t38 && hold_related && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
8140 if (switch_core_session_compare(session, other_session)) {
8141 switch_core_session_message_t *msg;
8142 const char *hold_msg = "hold";
8143 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
8144
8145 if (sofia_test_pflag(profile, PFLAG_PROXY_HOLD)) {
8146 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
8147
8148 if (tech_pvt->mparams.num_codecs){
8149 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
8150 }
8151
8152 if (!match) {
8153 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
8154 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE,
8155 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8156 TAG_END());
8157 switch_core_session_rwunlock(other_session);
8158 goto done;
8159 }
8160
8161 msg = switch_core_session_alloc(other_session, sizeof(*msg));
8162
8163 if (switch_stristr("inactive", r_sdp)) {
8164 sofia_set_flag_locked(other_tech_pvt, TFLAG_SIP_HOLD_INACTIVE);
8165 //switch_channel_set_variable(channel, "sofia_hold_inactive", "true");
8166 } else {
8167 sofia_clear_flag_locked(other_tech_pvt, TFLAG_SIP_HOLD_INACTIVE);
8168 }
8169
8170 if (hold_related == 1) {
8171 msg->message_id = SWITCH_MESSAGE_INDICATE_HOLD;
8172 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
8173 const char *info = switch_channel_get_variable(channel, "presence_call_info");
8174
8175 if (info) {
8176 if (switch_stristr("private", info)) {
8177 hold_msg = "hold-private";
8178 }
8179 }
8180 }
8181 sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
8182 switch_channel_set_flag(channel, CF_LEG_HOLDING);
8183 switch_channel_presence(tech_pvt->channel, "unknown", hold_msg, NULL);
8184 } else {
8185 hold_msg = "unhold";
8186 msg->message_id = SWITCH_MESSAGE_INDICATE_UNHOLD;
8187 sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
8188 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
8189 switch_channel_presence(tech_pvt->channel, "unknown", hold_msg, NULL);
8190 }
8191 msg->from = __FILE__;
8192 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Indicating %s to other leg.\n%s\n", hold_msg, r_sdp);
8193
8194 switch_core_session_queue_message(other_session, msg);
8195
8196
8197
8198 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
8199 if (sofia_use_soa(tech_pvt)){
8200 nua_respond(tech_pvt->nh, SIP_200_OK,
8201 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
8202 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
8203 SOATAG_REUSE_REJECTED(1),
8204 SOATAG_AUDIO_AUX("cn telephone-event"),
8205 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
8206 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8207 TAG_END());
8208 } else {
8209 nua_respond(tech_pvt->nh, SIP_200_OK,
8210 NUTAG_MEDIA_ENABLE(0),
8211 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
8212 SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
8213 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8214 TAG_END());
8215 }
8216 switch_core_session_rwunlock(other_session);
8217 goto done;
8218 }
8219 }
8220
8221 switch_core_session_rwunlock(other_session);
8222 }
8223
8224 if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) {
8225 if (sofia_use_soa(tech_pvt)) {
8226 nua_respond(tech_pvt->nh, SIP_200_OK,
8227 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
8228 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
8229 SOATAG_REUSE_REJECTED(1),
8230 SOATAG_AUDIO_AUX("cn telephone-event"),
8231 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
8232 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8233 TAG_END());
8234 } else {
8235 nua_respond(tech_pvt->nh, SIP_200_OK,
8236 NUTAG_MEDIA_ENABLE(0),
8237 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
8238 SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
8239 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8240 TAG_END());
8241 }
8242 goto done;
8243 }
8244
8245 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
8246
8247 if (tech_pvt->mparams.num_codecs) {
8248 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
8249 }
8250
8251
8252 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
8253 nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
8254 goto done;
8255 }
8256
8257 if (match && sofia_test_flag(tech_pvt, TFLAG_NOREPLY)) {
8258 sofia_clear_flag(tech_pvt, TFLAG_NOREPLY);
8259 goto done;
8260 }
8261
8262 if (match) {
8263 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8264 goto done;
8265 }
8266
8267 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
8268
8269 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8270 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
8271 is_ok = 0;
8272 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
8273 }
8274 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
8275 } else {
8276 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8277 nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
8278 goto done;
8279 }
8280
8281 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8282 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Reinvite resulted in codec negotiation failure.\n");
8283 is_ok = 0;
8284 }
8285 }
8286
8287
8288 if (is_ok) {
8289
8290 if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
8291 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
8292 }
8293
8294 if (!switch_channel_test_flag(tech_pvt->channel, CF_AWAITING_STREAM_CHANGE)) {
8295 if (sofia_use_soa(tech_pvt)) {
8296 nua_respond(tech_pvt->nh, SIP_200_OK,
8297 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
8298 SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
8299 SOATAG_REUSE_REJECTED(1),
8300 SOATAG_AUDIO_AUX("cn telephone-event"),
8301 TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
8302 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8303 TAG_END());
8304 } else {
8305 nua_respond(tech_pvt->nh, SIP_200_OK,
8306 NUTAG_MEDIA_ENABLE(0),
8307 SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
8308 SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str),
8309 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8310 TAG_END());
8311 }
8312 }
8313
8314 if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REINVITE) == SWITCH_STATUS_SUCCESS) {
8315 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
8316 switch_event_fire(&s_event);
8317 }
8318 } else {
8319 nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE,
8320 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8321 TAG_END());
8322 }
8323 }
8324 break;
8325 case nua_callstate_ready:
8326 if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA) &&
8327 r_sdp && (!is_dup_sdp || sofia_test_flag(tech_pvt, TFLAG_NEW_SDP)) && switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) && !sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)) {
8328 /* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */
8329 uint8_t match = 0;
8330
8331 sofia_clear_flag(tech_pvt, TFLAG_NEW_SDP);
8332 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
8333
8334
8335 if (tech_pvt->mparams.num_codecs) {
8336 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8337 }
8338 if (match) {
8339 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
8340 goto done;
8341 }
8342 switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
8343
8344 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
8345 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
8346
8347 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8348 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error!\n");
8349 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
8350 goto done;
8351 }
8352 } else {
8353 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8354 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error! %s\n", r_sdp);
8355 goto done;
8356
8357 }
8358 }
8359
8360 if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)) {
8361 sofia_clear_flag_locked(tech_pvt, TFLAG_NOSDP_REINVITE);
8362 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8363 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8364 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8365 goto done;
8366 }
8367 }
8368
8369 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
8370 other_channel = switch_core_session_get_channel(other_session);
8371 switch_channel_pass_sdp(channel, other_channel, r_sdp);
8372
8373 if (sofia_test_flag(tech_pvt, TFLAG_3PCC) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
8374 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8375 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK);
8376 } else {
8377 switch_core_session_message_t *msg;
8378
8379 if (sofia_test_pflag(profile, PFLAG_3PCC_REINVITE_BRIDGED_ON_ACK)) {
8380 msg = switch_core_session_alloc(other_session, sizeof(*msg));
8381 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT;
8382 msg->from = __FILE__;
8383 msg->string_arg = switch_core_session_strdup(other_session, r_sdp);
8384 switch_core_session_queue_message(other_session, msg);
8385 }
8386
8387 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8388 }
8389
8390 switch_core_session_rwunlock(other_session);
8391 }
8392 } else {
8393 uint8_t match = 0;
8394 int is_ok = 1;
8395
8396 if (!tech_pvt) goto done;
8397
8398 if (tech_pvt->mparams.num_codecs) {
8399 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8400 }
8401
8402 if (match) {
8403 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
8404 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8405 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error!\n");
8406 switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RTP ERROR");
8407 is_ok = 0;
8408 }
8409 switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE);
8410 } else {
8411 switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR");
8412 is_ok = 0;
8413 }
8414
8415 if (!is_ok) {
8416 nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
8417 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
8418 }
8419 }
8420 goto done;
8421 }
8422
8423 if (channel) {
8424 switch_channel_clear_flag(channel, CF_REQ_MEDIA);
8425 }
8426 if (tech_pvt && nh == tech_pvt->nh2) {
8427 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Cheater Reinvite!\n");
8428 switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
8429 tech_pvt->nh = tech_pvt->nh2;
8430 tech_pvt->nh2 = NULL;
8431 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) == SWITCH_STATUS_SUCCESS) {
8432 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8433 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cheater Reinvite RTP Error!\n");
8434 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
8435 }
8436 }
8437 goto done;
8438 }
8439
8440 if (channel) {
8441 if (sofia_test_flag(tech_pvt, TFLAG_EARLY_MEDIA) && !sofia_test_flag(tech_pvt, TFLAG_ANS)) {
8442 sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
8443 sofia_set_flag(tech_pvt, TFLAG_SDP);
8444 switch_channel_mark_answered(channel);
8445
8446 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8447 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
8448 //other_channel = switch_core_session_get_channel(other_session);
8449 //switch_channel_answer(other_channel);
8450 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8451 switch_core_session_rwunlock(other_session);
8452 }
8453 }
8454 goto done;
8455 }
8456
8457 if (!r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {
8458 r_sdp = (const char *) switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE);
8459 }
8460
8461 if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {
8462 if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8463 sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
8464 sofia_set_flag_locked(tech_pvt, TFLAG_SDP);
8465 switch_channel_mark_answered(channel);
8466
8467 if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
8468 if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
8469 goto done;
8470 }
8471 }
8472
8473 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
8474 other_channel = switch_core_session_get_channel(other_session);
8475 switch_channel_pass_sdp(channel, other_channel, r_sdp);
8476
8477 //switch_channel_answer(other_channel);
8478 switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER);
8479
8480 switch_core_session_rwunlock(other_session);
8481 }
8482
8483 if (sofia_test_flag(tech_pvt, TFLAG_3PCC) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
8484 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8485 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK);
8486 }
8487
8488 goto done;
8489 } else {
8490 uint8_t match = 0;
8491
8492
8493 match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
8494
8495
8496 sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
8497
8498 if (match) {
8499 switch_channel_check_zrtp(channel);
8500
8501 if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) == SWITCH_STATUS_SUCCESS) {
8502 if (sofia_media_activate_rtp(tech_pvt) == SWITCH_STATUS_SUCCESS) {
8503 switch_channel_mark_answered(channel);
8504 } else {
8505 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error!\n");
8506 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
8507 }
8508
8509 if (sofia_test_flag(tech_pvt, TFLAG_3PCC)) {
8510 /* Check if we are in 3PCC proxy mode, if so then set the flag to indicate we received the ack */
8511 if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) {
8512 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
8513 sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK);
8514 } else if (switch_channel_get_state(channel) == CS_HIBERNATE) {
8515 sofia_set_flag_locked(tech_pvt, TFLAG_READY);
8516 switch_channel_set_state(channel, CS_INIT);
8517 sofia_set_flag(tech_pvt, TFLAG_SDP);
8518 }
8519 }
8520 goto done;
8521 }
8522 }
8523
8524 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS");
8525 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
8526 }
8527 }
8528 }
8529
8530 break;
8531 case nua_callstate_terminating:
8532 if (status == 488 || switch_channel_get_state(channel) == CS_HIBERNATE) {
8533 tech_pvt->q850_cause = SWITCH_CAUSE_MANDATORY_IE_MISSING;
8534 }
8535 case nua_callstate_terminated:
8536 sofia_set_flag_locked(tech_pvt, TFLAG_BYE);
8537 if (sofia_test_flag(tech_pvt, TFLAG_NOHUP)) {
8538 sofia_clear_flag_locked(tech_pvt, TFLAG_NOHUP);
8539 } else if (switch_channel_up(channel)) {
8540 int cause;
8541 if (tech_pvt->q850_cause) {
8542 cause = tech_pvt->q850_cause;
8543 } else {
8544 cause = sofia_glue_sip_cause_to_freeswitch(status);
8545 }
8546 if (status) {
8547 switch_snprintf(st, sizeof(st), "%d", status);
8548 switch_channel_set_variable(channel, "sip_term_status", st);
8549 switch_snprintf(st, sizeof(st), "sip:%d", status);
8550 switch_channel_set_variable(channel, SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE, st);
8551 if (phrase) {
8552 switch_channel_set_variable_partner(channel, "sip_hangup_phrase", phrase);
8553 }
8554 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_BYE_HEADER_PREFIX);
8555 }
8556 switch_snprintf(st, sizeof(st), "%d", cause);
8557 switch_channel_set_variable(channel, "sip_term_cause", st);
8558 switch_channel_hangup(channel, cause);
8559 ss_state = nua_callstate_terminated;
8560 }
8561
8562 if (ss_state == nua_callstate_terminated) {
8563 if (tech_pvt->sofia_private) {
8564 tech_pvt->sofia_private = NULL;
8565 }
8566
8567 tech_pvt->nh = NULL;
8568
8569 if (nh) {
8570 nua_handle_bind(nh, NULL);
8571 nua_handle_destroy(nh);
8572 }
8573 }
8574
8575 break;
8576 }
8577
8578 done:
8579
8580 switch_safe_free(patched_sdp);
8581
8582 if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) {
8583 sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY);
8584 }
8585
8586
8587 return;
8588 }
8589
8590 typedef struct {
8591 char *exten;
8592 char *exten_with_params;
8593 char *event;
8594 char *reply_uuid;
8595 char *bridge_to_uuid;
8596 switch_event_t *vars;
8597 switch_memory_pool_t *pool;
8598 sofia_profile_t *profile;
8599 } nightmare_xfer_helper_t;
8600
nightmare_xfer_thread_run(switch_thread_t * thread,void * obj)8601 void *SWITCH_THREAD_FUNC nightmare_xfer_thread_run(switch_thread_t *thread, void *obj)
8602 {
8603 nightmare_xfer_helper_t *nhelper = (nightmare_xfer_helper_t *) obj;
8604 switch_memory_pool_t *pool;
8605 switch_status_t status = SWITCH_STATUS_FALSE;
8606 switch_core_session_t *session, *a_session;
8607
8608 if ((a_session = switch_core_session_locate(nhelper->bridge_to_uuid))) {
8609 switch_core_session_t *tsession = NULL;
8610 switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
8611 uint32_t timeout = 60;
8612 char *tuuid_str;
8613
8614 if ((session = switch_core_session_locate(nhelper->reply_uuid))) {
8615 private_object_t *tech_pvt = switch_core_session_get_private(session);
8616 switch_channel_t *channel_a = switch_core_session_get_channel(session);
8617 const char *session_id_header = sofia_glue_session_id_header(session, nhelper->profile);
8618
8619 if ((status = switch_ivr_originate(NULL, &tsession, &cause, nhelper->exten_with_params, timeout, NULL, NULL, NULL,
8620 switch_channel_get_caller_profile(channel_a), nhelper->vars, SOF_NONE, NULL, NULL)) == SWITCH_STATUS_SUCCESS) {
8621 if (switch_channel_up(channel_a)) {
8622
8623 if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer"))) {
8624 switch_ivr_transfer_recordings(session, a_session);
8625 }
8626
8627
8628 tuuid_str = switch_core_session_get_uuid(tsession);
8629 switch_channel_set_variable_printf(channel_a, "transfer_to", "att:%s", tuuid_str);
8630 mark_transfer_record(session, nhelper->bridge_to_uuid, tuuid_str);
8631 switch_ivr_uuid_bridge(nhelper->bridge_to_uuid, tuuid_str);
8632 switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
8633 } else {
8634 switch_channel_hangup(switch_core_session_get_channel(tsession), SWITCH_CAUSE_ORIGINATOR_CANCEL);
8635 status = SWITCH_STATUS_FALSE;
8636 }
8637 switch_core_session_rwunlock(tsession);
8638 }
8639
8640 if (status == SWITCH_STATUS_SUCCESS) {
8641 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "The nightmare is over.....\n");
8642 } else {
8643 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "1 .. 2 .. Freddie's commin' for you...\n");
8644 }
8645
8646 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
8647 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
8648 SIPTAG_PAYLOAD_STR(status == SWITCH_STATUS_SUCCESS ? "SIP/2.0 200 OK\r\n" :
8649 "SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(nhelper->event),
8650 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8651 TAG_END());
8652
8653 switch_core_session_rwunlock(session);
8654 }
8655
8656 switch_core_session_rwunlock(a_session);
8657 }
8658
8659 switch_event_destroy(&nhelper->vars);
8660
8661 pool = nhelper->pool;
8662 switch_core_destroy_memory_pool(&pool);
8663
8664 return NULL;
8665 }
8666
launch_nightmare_xfer(nightmare_xfer_helper_t * nhelper)8667 static void launch_nightmare_xfer(nightmare_xfer_helper_t *nhelper)
8668 {
8669 switch_thread_t *thread;
8670 switch_threadattr_t *thd_attr = NULL;
8671
8672 switch_threadattr_create(&thd_attr, nhelper->pool);
8673 switch_threadattr_detach_set(thd_attr, 1);
8674 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
8675 switch_thread_create(&thread, thd_attr, nightmare_xfer_thread_run, nhelper, nhelper->pool);
8676 }
8677
8678 /*---------------------------------------*/
8679
xfer_hanguphook(switch_core_session_t * session)8680 static switch_status_t xfer_hanguphook(switch_core_session_t *session)
8681 {
8682 switch_channel_t *channel = switch_core_session_get_channel(session);
8683 switch_channel_state_t state = switch_channel_get_state(channel);
8684
8685 if (state == CS_HANGUP) {
8686 switch_core_session_t *ksession;
8687 const char *uuid = switch_channel_get_variable(channel, "att_xfer_kill_uuid");
8688
8689 if (uuid && (ksession = switch_core_session_force_locate(uuid))) {
8690 switch_channel_t *kchannel = switch_core_session_get_channel(ksession);
8691
8692 switch_channel_clear_flag(kchannel, CF_XFER_ZOMBIE);
8693 switch_channel_clear_flag(kchannel, CF_TRANSFER);
8694 if (switch_channel_up(kchannel)) {
8695 switch_channel_hangup(kchannel, SWITCH_CAUSE_NORMAL_CLEARING);
8696 }
8697
8698 switch_core_session_rwunlock(ksession);
8699 }
8700
8701 switch_core_event_hook_remove_state_change(session, xfer_hanguphook);
8702
8703 }
8704
8705 return SWITCH_STATUS_SUCCESS;
8706 }
8707
sofia_global_nua_handle_by_replaces(sip_replaces_t * replaces)8708 nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces)
8709 {
8710 nua_handle_t *nh = NULL;
8711 switch_hash_index_t *hi;
8712 const void *var;
8713 void *val;
8714 sofia_profile_t *profile;
8715
8716 switch_mutex_lock(mod_sofia_globals.hash_mutex);
8717 if (mod_sofia_globals.profile_hash) {
8718 for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash); hi; hi = switch_core_hash_next(&hi)) {
8719 switch_core_hash_this(hi, &var, NULL, &val);
8720 if ((profile = (sofia_profile_t *) val)) {
8721 if (!(nh = nua_handle_by_replaces(profile->nua, replaces))) {
8722 nh = nua_handle_by_call_id(profile->nua, replaces->rp_call_id);
8723 }
8724 if (nh)
8725 break;
8726 }
8727 }
8728 switch_safe_free(hi);
8729 }
8730 switch_mutex_unlock(mod_sofia_globals.hash_mutex);
8731
8732 return nh;
8733
8734 }
8735
sofia_process_proxy_refer(switch_core_session_t * session,const char * refer_to)8736 static switch_status_t sofia_process_proxy_refer(switch_core_session_t *session, const char *refer_to)
8737 {
8738 switch_core_session_t *other_session;
8739 private_object_t *tech_pvt = switch_core_session_get_private(session);
8740
8741 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
8742 switch_core_session_message_t *msg;
8743
8744 tech_pvt->proxy_refer_uuid = switch_core_session_strdup(session, switch_core_session_get_uuid(other_session));
8745 msg = switch_core_session_alloc(other_session, sizeof(*msg));
8746 MESSAGE_STAMP_FFL(msg);
8747 msg->message_id = SWITCH_MESSAGE_INDICATE_DEFLECT;
8748 msg->string_arg = switch_core_session_strdup(other_session, refer_to);
8749 msg->string_array_arg[0] = switch_core_session_strdup(other_session, switch_core_session_get_uuid(session));
8750 msg->from = __FILE__;
8751 switch_core_session_queue_message(other_session, msg);
8752 switch_core_session_rwunlock(other_session);
8753 return SWITCH_STATUS_SUCCESS;
8754 }
8755
8756 return SWITCH_STATUS_FALSE;
8757 }
8758
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,sofia_dispatch_event_t * de,tagi_t tags[])8759 void 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,
8760 sofia_dispatch_event_t *de, tagi_t tags[])
8761 {
8762 /* Incoming refer */
8763 sip_from_t const *from;
8764 //sip_to_t const *to;
8765 sip_refer_to_t const *refer_to;
8766 private_object_t *tech_pvt = switch_core_session_get_private(session);
8767 char *etmp = NULL, *exten = NULL;
8768 switch_channel_t *channel_a = switch_core_session_get_channel(session);
8769 switch_channel_t *channel_b = NULL;
8770 su_home_t *home = NULL;
8771 char *full_ref_by = NULL;
8772 char *full_ref_to = NULL;
8773 nightmare_xfer_helper_t *nightmare_xfer_helper;
8774 switch_memory_pool_t *npool;
8775 switch_event_t *event = NULL;
8776 const char *session_id_header = sofia_glue_session_id_header(session, profile);
8777
8778 if (!(profile->mflags & MFLAG_REFER)) {
8779 nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
8780 goto done;
8781 }
8782
8783 if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
8784 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
8785 goto done;
8786 }
8787
8788 home = su_home_new(sizeof(*home));
8789 switch_assert(home != NULL);
8790
8791 if ((refer_to = sip->sip_refer_to)) {
8792 full_ref_to = sip_header_as_string(home, (void *) sip->sip_refer_to);
8793 }
8794
8795 if (full_ref_to && sofia_test_pflag(profile, PFLAG_PROXY_REFER)) {
8796 if (sofia_process_proxy_refer(session, full_ref_to) == SWITCH_STATUS_SUCCESS) {
8797 if (tech_pvt->proxy_refer_msg) {
8798 msg_ref_destroy(tech_pvt->proxy_refer_msg);
8799 tech_pvt->proxy_refer_msg = NULL;
8800 }
8801 tech_pvt->proxy_refer_msg = msg_ref_create(de->data->e_msg);
8802 //nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), TAG_END());
8803 goto done;
8804 }
8805 }
8806
8807 from = sip->sip_from;
8808 //to = sip->sip_to;
8809
8810 nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"),
8811 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
8812
8813
8814 switch_channel_set_variable(tech_pvt->channel, SOFIA_REPLACES_HEADER, NULL);
8815
8816 if (sip->sip_referred_by) {
8817 full_ref_by = sip_header_as_string(home, (void *) sip->sip_referred_by);
8818 }
8819
8820 if (refer_to) {
8821 char *rep = NULL;
8822
8823 if (sofia_test_pflag(profile, PFLAG_FULL_ID)) {
8824 exten = switch_core_session_sprintf(session, "%s@%s", (char *) refer_to->r_url->url_user, (char *) refer_to->r_url->url_host);
8825 } else {
8826 exten = (char *) refer_to->r_url->url_user;
8827 }
8828
8829 if (refer_to->r_url->url_params) {
8830 switch_channel_set_variable(tech_pvt->channel, "sip_refer_to_params", refer_to->r_url->url_params);
8831 }
8832
8833 switch_core_session_queue_indication(session, SWITCH_MESSAGE_REFER_EVENT);
8834 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
8835
8836 switch_channel_set_variable(tech_pvt->channel, "transfer_disposition", "recv_replace");
8837
8838
8839 if (refer_to->r_url->url_headers) {
8840 rep = (char *) switch_stristr("Replaces=", refer_to->r_url->url_headers);
8841 }
8842
8843
8844 if (rep) {
8845 sip_replaces_t *replaces;
8846 nua_handle_t *bnh = NULL;
8847
8848 const char *br_a = NULL, *br_b = NULL;
8849 char *buf;
8850 char *p;
8851
8852 rep = switch_core_session_strdup(session, rep + 9);
8853
8854 if ((buf = switch_core_session_alloc(session, strlen(rep) + 1))) {
8855 rep = url_unescape(buf, (const char *) rep);
8856 if ((p = strchr(rep, ';'))) {
8857 *p = '\0';
8858 }
8859 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Replaces: [%s]\n", rep);
8860 } else {
8861 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
8862 goto done;
8863 }
8864
8865 if ((replaces = sip_replaces_make(home, rep))) {
8866 if (!(bnh = nua_handle_by_replaces(nua, replaces))) {
8867 if (!(bnh = nua_handle_by_call_id(nua, replaces->rp_call_id))) {
8868 bnh = sofia_global_nua_handle_by_replaces(replaces);
8869 }
8870 }
8871 }
8872
8873 if (bnh && !sofia_test_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE)) {
8874 sofia_private_t *b_private = NULL;
8875 private_object_t *b_tech_pvt = NULL;
8876 switch_core_session_t *b_session = NULL;
8877
8878
8879 switch_channel_set_variable(channel_a, SOFIA_REPLACES_HEADER, rep);
8880 if ((b_private = nua_handle_magic(bnh))) {
8881 int deny_refer_requests = 0;
8882
8883 if (!(b_session = switch_core_session_locate(b_private->uuid))) {
8884 goto done;
8885 }
8886 b_tech_pvt = (private_object_t *) switch_core_session_get_private(b_session);
8887 channel_b = switch_core_session_get_channel(b_session);
8888
8889 switch_channel_set_variable(channel_a, "refer_uuid", b_private->uuid);
8890 switch_channel_set_variable(channel_b, "transfer_disposition", "replaced");
8891
8892 br_a = switch_channel_get_partner_uuid(channel_a);
8893 br_b = switch_channel_get_partner_uuid(channel_b);
8894
8895 if (!switch_ivr_uuid_exists(br_a)) {
8896 br_a = NULL;
8897 }
8898
8899 if (!switch_ivr_uuid_exists(br_b)) {
8900 br_b = NULL;
8901 }
8902
8903 if (channel_a && switch_true(switch_channel_get_variable(channel_a, "deny_refer_requests"))) {
8904 deny_refer_requests = 1;
8905 }
8906
8907 if (!deny_refer_requests && channel_b && switch_true(switch_channel_get_variable(channel_b, "deny_refer_requests"))) {
8908 deny_refer_requests = 1;
8909 }
8910
8911 if (!deny_refer_requests && br_a) {
8912 switch_core_session_t *a_session;
8913 if ((a_session = switch_core_session_locate(br_a))) {
8914 switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
8915
8916 if (a_channel && switch_true(switch_channel_get_variable(a_channel, "deny_refer_requests"))) {
8917 deny_refer_requests = 1;
8918 }
8919 switch_core_session_rwunlock(a_session);
8920 }
8921 }
8922
8923 if (!deny_refer_requests && br_b) {
8924 switch_core_session_t *b_session;
8925 if ((b_session = switch_core_session_locate(br_b))) {
8926 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
8927
8928 if (b_channel && switch_true(switch_channel_get_variable(b_channel, "deny_refer_requests"))) {
8929 deny_refer_requests = 1;
8930 }
8931 switch_core_session_rwunlock(b_session);
8932 }
8933 }
8934
8935 if (deny_refer_requests) {
8936 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Denying Attended Transfer, variable [deny_refer_requests] was set to true\n");
8937
8938 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
8939 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
8940 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
8941 SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp), TAG_END());
8942
8943 } else if (switch_channel_test_flag(channel_b, CF_ORIGINATOR)) {
8944 switch_core_session_t *a_session;
8945
8946 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE,
8947 "Attended Transfer on originating session %s\n", switch_core_session_get_uuid(b_session));
8948
8949
8950
8951 switch_channel_set_variable_printf(channel_b, "transfer_to", "satt:%s", br_a);
8952
8953 switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
8954
8955
8956 sofia_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD);
8957 switch_channel_clear_flag(channel_b, CF_LEG_HOLDING);
8958 sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
8959
8960 switch_channel_set_variable(channel_b, SWITCH_HOLDING_UUID_VARIABLE, br_a);
8961 switch_channel_set_flag(channel_b, CF_XFER_ZOMBIE);
8962 switch_channel_set_flag(channel_b, CF_TRANSFER);
8963
8964
8965 if ((a_session = switch_core_session_locate(br_a))) {
8966 const char *moh = profile->hold_music;
8967 switch_core_session_t *tmpsess = NULL;
8968 switch_channel_t *a_channel = switch_core_session_get_channel(a_session);
8969 switch_caller_profile_t *prof = switch_channel_get_caller_profile(channel_b);
8970 const char *tmp;
8971
8972 switch_core_event_hook_add_state_change(a_session, xfer_hanguphook);
8973 switch_channel_set_variable(a_channel, "att_xfer_kill_uuid", switch_core_session_get_uuid(b_session));
8974 switch_channel_set_variable(a_channel, "att_xfer_destination_number", prof->destination_number);
8975 switch_channel_set_variable(a_channel, "att_xfer_callee_id_name", prof->callee_id_name);
8976 switch_channel_set_variable(a_channel, "att_xfer_callee_id_number", prof->callee_id_number);
8977
8978 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) {
8979 switch_channel_set_flag(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE);
8980 }
8981
8982
8983 if ((tmp = switch_channel_get_hold_music(a_channel))) {
8984 moh = tmp;
8985 }
8986
8987 if (!zstr(moh) && !strcasecmp(moh, "silence")) {
8988 moh = NULL;
8989 }
8990
8991 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
8992 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED) == SWITCH_STATUS_SUCCESS) {
8993 switch_channel_event_set_data(channel_b, event);
8994 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", br_a);
8995 switch_event_fire(&event);
8996 }
8997
8998 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
8999 switch_channel_event_set_data(channel_a, event);
9000 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9001 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9002 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_core_session_get_uuid(b_session));
9003 switch_event_fire(&event);
9004 }
9005
9006 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
9007 switch_channel_event_set_data(a_channel, event);
9008 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_call_id", switch_core_session_get_uuid(b_session));
9009 switch_event_fire(&event);
9010 }
9011 }
9012
9013 if (moh) {
9014 char *xdest;
9015 xdest = switch_core_session_sprintf(a_session, "m:\":endless_playback:%s\"park", moh);
9016 switch_ivr_session_transfer(a_session, xdest, "inline", NULL);
9017 } else {
9018 switch_ivr_session_transfer(a_session, "park", "inline", NULL);
9019 }
9020 if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer"))) {
9021 switch_ivr_transfer_recordings(session, a_session);
9022 }
9023 if (switch_true(switch_channel_get_variable(channel_b, "recording_follow_transfer")) && (tmpsess = switch_core_session_locate(br_a))) {
9024 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE,
9025 "Early transfer detected with no media, moving recording bug to other leg\n");
9026 switch_ivr_transfer_recordings(b_session, tmpsess);
9027 switch_core_session_rwunlock(tmpsess);
9028 }
9029
9030 switch_core_session_rwunlock(a_session);
9031
9032 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9033 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
9034 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9035 TAG_END());
9036
9037 if (b_tech_pvt && !sofia_test_flag(b_tech_pvt, TFLAG_BYE)) {
9038 char *q850 = NULL;
9039 const char *val = NULL;
9040
9041 sofia_set_flag_locked(b_tech_pvt, TFLAG_BYE);
9042 val = switch_channel_get_variable(tech_pvt->channel, "disable_q850_reason");
9043 if (!val || switch_true(val)) {
9044 q850 = switch_core_session_sprintf(a_session, "Q.850;cause=16;text=\"normal_clearing\"");
9045 }
9046 nua_bye(b_tech_pvt->nh,
9047 SIPTAG_CONTACT(SIP_NONE),
9048 TAG_IF(!zstr(q850), SIPTAG_REASON_STR(q850)),
9049 TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
9050 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9051 TAG_END());
9052
9053 }
9054 } else {
9055 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9056 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
9057 SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
9058 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9059 TAG_END());
9060 }
9061
9062 } else if (br_a && br_b) {
9063 switch_core_session_t *tmp = NULL;
9064 switch_event_t *event = NULL;
9065
9066 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n",
9067 switch_str_nil(br_a), switch_str_nil(br_b));
9068
9069 if ((tmp = switch_core_session_locate(br_b))) {
9070 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9071
9072 if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER)) {
9073 switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE);
9074 }
9075
9076 switch_channel_set_variable(tchannel, "transfer_disposition", "bridge");
9077
9078 switch_channel_set_flag(tchannel, CF_ATTENDED_TRANSFER);
9079 switch_core_session_rwunlock(tmp);
9080 }
9081
9082 if ((profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) && (tmp = switch_core_session_locate(br_a))) {
9083 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9084 switch_channel_set_flag(tchannel, CF_BYPASS_MEDIA_AFTER_BRIDGE);
9085 switch_core_session_rwunlock(tmp);
9086 }
9087
9088
9089 if (switch_true(switch_channel_get_variable(channel_a, "recording_follow_transfer")) &&
9090 (tmp = switch_core_session_locate(br_a))) {
9091 switch_channel_set_variable(switch_core_session_get_channel(tmp), "transfer_disposition", "bridge");
9092 switch_ivr_transfer_recordings(session, tmp);
9093 switch_core_session_rwunlock(tmp);
9094 }
9095
9096
9097 if (switch_true(switch_channel_get_variable(channel_b, "recording_follow_transfer")) &&
9098 (tmp = switch_core_session_locate(br_b))) {
9099 switch_ivr_transfer_recordings(b_session, tmp);
9100 switch_core_session_rwunlock(tmp);
9101 }
9102
9103 switch_channel_set_variable_printf(channel_a, "transfer_to", "att:%s", br_b);
9104
9105 mark_transfer_record(session, br_a, br_b);
9106
9107 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
9108 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED) == SWITCH_STATUS_SUCCESS) {
9109 switch_channel_event_set_data(channel_b, event);
9110 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", br_a);
9111 switch_event_fire(&event);
9112 }
9113
9114 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
9115 switch_channel_event_set_data(channel_a, event);
9116 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9117 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9118 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_core_session_get_uuid(b_session));
9119 switch_event_fire(&event);
9120 }
9121
9122 if ((tmp = switch_core_session_locate(br_a))) {
9123 switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
9124
9125 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
9126 switch_channel_event_set_data(tchannel, event);
9127 switch_event_fire(&event);
9128 }
9129
9130 switch_core_session_rwunlock(tmp);
9131 }
9132 }
9133
9134 switch_ivr_uuid_bridge(br_a, br_b);
9135 switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
9136 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9137 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
9138 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9139 TAG_END());
9140
9141 sofia_clear_flag_locked(b_tech_pvt, TFLAG_SIP_HOLD);
9142 switch_channel_clear_flag(channel_b, CF_LEG_HOLDING);
9143 sofia_clear_flag_locked(tech_pvt, TFLAG_HOLD_LOCK);
9144 switch_channel_set_variable(channel_b, "park_timeout", "2:attended_transfer");
9145 switch_channel_set_state(channel_b, CS_PARK);
9146 switch_channel_wait_for_state_timeout(channel_b, CS_PARK, 5000);
9147
9148 } else {
9149 if (!br_a && !br_b) {
9150 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
9151 "Cannot transfer channels that are not in a bridge.\n");
9152 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9153 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"),
9154 SIPTAG_EVENT_STR(etmp),
9155 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9156 TAG_END());
9157 } else {
9158 switch_core_session_t *t_session, *hup_session;
9159 switch_channel_t *hup_channel;
9160 switch_event_t *event = NULL;
9161 const char *ext;
9162
9163 if (br_a && !br_b) {
9164 t_session = switch_core_session_locate(br_a);
9165 hup_channel = channel_b;
9166 hup_session = b_session;
9167 } else {
9168 private_object_t *h_tech_pvt = (private_object_t *) switch_core_session_get_private(b_session);
9169 t_session = switch_core_session_locate(br_b);
9170 hup_channel = channel_a;
9171 hup_session = session;
9172 sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
9173 switch_channel_clear_flag(tech_pvt->channel, CF_LEG_HOLDING);
9174 sofia_clear_flag_locked(h_tech_pvt, TFLAG_SIP_HOLD);
9175 switch_channel_clear_flag(h_tech_pvt->channel, CF_LEG_HOLDING);
9176 switch_channel_hangup(channel_b, SWITCH_CAUSE_ATTENDED_TRANSFER);
9177 }
9178
9179 if (t_session) {
9180 switch_channel_t *t_channel = switch_core_session_get_channel(t_session);
9181 const char *idest = switch_channel_get_variable(hup_channel, "inline_destination");
9182 ext = switch_channel_get_variable(hup_channel, "destination_number");
9183
9184 if (!zstr(full_ref_by)) {
9185 switch_channel_set_variable(t_channel, SOFIA_SIP_HEADER_PREFIX "Referred-By", full_ref_by);
9186 }
9187
9188 if (!zstr(full_ref_to)) {
9189 switch_channel_set_variable(t_channel, SOFIA_REFER_TO_VARIABLE, full_ref_to);
9190 }
9191
9192
9193 if (switch_true(switch_channel_get_variable(hup_channel, "recording_follow_transfer"))) {
9194 switch_ivr_transfer_recordings(hup_session, t_session);
9195 }
9196
9197 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
9198 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
9199 switch_channel_event_set_data(channel_a, event);
9200 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", switch_core_session_get_uuid(hup_session));
9201 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", switch_core_session_get_uuid(t_session));
9202 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_peer_uuid", switch_channel_get_partner_uuid(t_channel));
9203 switch_event_fire(&event);
9204 }
9205
9206 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
9207 switch_channel_event_set_data(t_channel, event);
9208 switch_event_fire(&event);
9209 }
9210 }
9211
9212 if (idest) {
9213 switch_ivr_session_transfer(t_session, idest, "inline", NULL);
9214 } else {
9215 switch_ivr_session_transfer(t_session, ext, NULL, NULL);
9216 }
9217
9218 nua_notify(tech_pvt->nh,
9219 NUTAG_NEWSUB(1),
9220 SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9221 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
9222 SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
9223 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9224 TAG_END());
9225 switch_core_session_rwunlock(t_session);
9226 switch_channel_hangup(hup_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
9227 } else {
9228 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session to transfer to not found.\n");
9229 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9230 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
9231 SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
9232 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9233 TAG_END());
9234 }
9235 }
9236 }
9237 switch_core_session_rwunlock(b_session);
9238 }
9239 nua_handle_unref(bnh);
9240 } else { /* the other channel is on a different box, we have to go find them */
9241 if (exten && (br_a = switch_channel_get_partner_uuid(channel_a))) {
9242 switch_core_session_t *a_session;
9243 switch_channel_t *channel;
9244
9245 if ((a_session = switch_core_session_locate(br_a))) {
9246 const char *port = NULL;
9247 const char *rep_h = NULL;
9248
9249 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
9250 "REFER from %s replaces %s (%s@%s) with %s on another server\n",
9251 switch_core_session_get_uuid(session), rep, exten, (char *) refer_to->r_url->url_host, br_a);
9252
9253 if (refer_to->r_url->url_port) {
9254 port = refer_to->r_url->url_port;
9255 }
9256
9257 channel = switch_core_session_get_channel(a_session);
9258
9259 exten = NULL;
9260
9261 if (sofia_test_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER)) {
9262 switch_xml_t xml_root = NULL, xml_channel = NULL;
9263 switch_event_t *xml_params = NULL;
9264 const char *xml_url = NULL, *use_profile = profile->name, *dial_prefix = NULL, *absolute_dial_string = NULL;
9265 switch_xml_t params = NULL, param = NULL;
9266
9267 switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS);
9268 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "nightmare_xfer");
9269 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name);
9270 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-user", refer_to->r_url->url_user);
9271 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-host", refer_to->r_url->url_host);
9272 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-params", refer_to->r_url->url_params ? refer_to->r_url->url_params : "");
9273 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-to-headers", refer_to->r_url->url_headers ? refer_to->r_url->url_headers : "");
9274 if (replaces) {
9275 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "replaces-call-id", replaces->rp_call_id);
9276 }
9277 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-from-channel-id", switch_core_session_get_uuid(session));
9278 switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "refer-for-channel-id", br_a);
9279
9280 if (switch_xml_locate("channels", NULL, NULL, NULL,
9281 &xml_root, &xml_channel, xml_params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
9282 if ((params = switch_xml_child(xml_channel, "params"))) {
9283 for (param = switch_xml_child(params, "param"); param; param = param->next) {
9284 const char *name = switch_xml_attr(param, "name");
9285 const char *value = switch_xml_attr(param, "value");
9286
9287 if (!(name && value)) continue;
9288
9289 if (!strcasecmp(name, "sip-url")) {
9290 xml_url = value;
9291 } else if (!strcasecmp(name, "dial-prefix")) {
9292 dial_prefix = value;
9293 } else if (!strcasecmp(name, "absolute-dial-string")) {
9294 absolute_dial_string = value;
9295 } else if (!strcasecmp(name, "sip-profile")) {
9296 use_profile = value;
9297 }
9298 }
9299 }
9300
9301 if (absolute_dial_string) {
9302 exten = switch_core_session_sprintf(session, "%s%s", dial_prefix, absolute_dial_string);
9303 } else if (xml_url) {
9304 exten = switch_core_session_sprintf(session, "%ssofia/%s/%s", dial_prefix, use_profile, xml_url);
9305 }
9306
9307 switch_xml_free(xml_root);
9308 }
9309
9310 switch_event_destroy(&xml_params);
9311 }
9312
9313
9314 if (zstr(exten)) {
9315 exten = switch_core_session_sprintf(session, "sofia/%s/sip:%s@%s%s%s",
9316 profile->name, refer_to->r_url->url_user,
9317 refer_to->r_url->url_host, port ? ":" : "", port ? port : "");
9318 }
9319
9320 switch_core_new_memory_pool(&npool);
9321 nightmare_xfer_helper = switch_core_alloc(npool, sizeof(*nightmare_xfer_helper));
9322 nightmare_xfer_helper->exten = switch_core_strdup(npool, exten);
9323
9324 if (refer_to->r_url->url_params || refer_to->r_url->url_headers) {
9325 if (refer_to->r_url->url_headers) {
9326 nightmare_xfer_helper->exten_with_params = switch_core_sprintf(npool,
9327 "{sip_invite_params=%s?%s}%s",
9328 refer_to->r_url->url_params ? refer_to->r_url->
9329 url_params : "", refer_to->r_url->url_headers, exten);
9330 } else {
9331 nightmare_xfer_helper->exten_with_params = switch_core_sprintf(npool,
9332 "{sip_invite_params=%s}%s", refer_to->r_url->url_params,
9333 exten);
9334 }
9335 } else {
9336 nightmare_xfer_helper->exten_with_params = nightmare_xfer_helper->exten;
9337 }
9338
9339 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Nightmare transfer to '%s'\n", nightmare_xfer_helper->exten_with_params);
9340
9341 nightmare_xfer_helper->event = switch_core_strdup(npool, etmp);
9342 nightmare_xfer_helper->reply_uuid = switch_core_strdup(npool, switch_core_session_get_uuid(session));
9343 nightmare_xfer_helper->bridge_to_uuid = switch_core_strdup(npool, br_a);
9344 nightmare_xfer_helper->pool = npool;
9345
9346 if (refer_to->r_url->url_headers) {
9347 char *h, *v, *hp;
9348 p = switch_core_session_strdup(session, refer_to->r_url->url_headers);
9349 while (p && *p) {
9350 h = p;
9351 if ((p = strchr(p, '='))) {
9352 *p++ = '\0';
9353 v = p;
9354 if ((p = strchr(p, '&'))) {
9355 *p++ = '\0';
9356 }
9357
9358 url_unescape(h, (const char *) h);
9359 url_unescape(v, (const char *) v);
9360 if (strcasecmp("Replaces", h)) {
9361 hp = switch_core_session_sprintf(session, "%s%s", SOFIA_SIP_HEADER_PREFIX, h);
9362 switch_channel_set_variable(channel, hp, v);
9363 } else {
9364 // use this one instead of rep value from above to keep all parameters
9365 switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, v);
9366 }
9367 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Exporting replaces URL header [%s:%s]\n",
9368 h, v);
9369 }
9370 }
9371 }
9372
9373
9374 switch_event_create(&nightmare_xfer_helper->vars, SWITCH_EVENT_CHANNEL_DATA);
9375
9376 rep_h = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
9377 if (rep_h) {
9378 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REPLACES_HEADER, rep_h);
9379 } else {
9380 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REPLACES_HEADER, rep);
9381 }
9382
9383
9384 if (!zstr(full_ref_by)) {
9385 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "Referred-By", full_ref_by);
9386 }
9387
9388 if (!zstr(full_ref_to)) {
9389 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REFER_TO_VARIABLE, full_ref_to);
9390 }
9391
9392 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
9393 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
9394 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_original_call_id", br_a);
9395 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_destination_call_id", br_b);
9396 switch_channel_event_set_data(channel_a, event);
9397 switch_event_fire(&event);
9398 }
9399
9400 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
9401 switch_channel_event_set_data(channel, event);
9402 switch_event_fire(&event);
9403 }
9404 }
9405
9406 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Refer-From", switch_core_session_get_uuid(session));
9407 switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Refer-For", br_a);
9408
9409 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Good Luck, you'll need it......\n");
9410 nightmare_xfer_helper->profile = profile;
9411 launch_nightmare_xfer(nightmare_xfer_helper);
9412
9413 switch_core_session_rwunlock(a_session);
9414
9415 } else {
9416 goto error;
9417 }
9418
9419 } else {
9420 error:
9421 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Transfer! [%s]\n", br_a);
9422 switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR");
9423 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9424 NUTAG_SUBSTATE(nua_substate_terminated),SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
9425 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9426 TAG_END());
9427 }
9428 }
9429 goto done;
9430 }
9431
9432 } else {
9433 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Missing Refer-To\n");
9434 goto done;
9435 }
9436
9437 if (exten) {
9438 switch_channel_t *channel = switch_core_session_get_channel(session);
9439 const char *br = switch_channel_get_partner_uuid(channel);
9440 switch_core_session_t *b_session;
9441
9442 switch_channel_set_variable_printf(channel, "transfer_to", "blind:%s", br ? br : exten);
9443 switch_channel_set_variable_printf(channel, "transfer_destination", "blind:%s", exten);
9444
9445 if (!zstr(br) && (b_session = switch_core_session_locate(br))) {
9446 const char *var;
9447 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
9448 switch_event_t *event = NULL;
9449
9450 switch_channel_set_variable(channel, "transfer_fallback_extension", from->a_user);
9451 if (!zstr(full_ref_by)) {
9452 switch_channel_set_variable(b_channel, SOFIA_SIP_HEADER_PREFIX "Referred-By", full_ref_by);
9453 }
9454
9455 if (!zstr(full_ref_to)) {
9456 switch_channel_set_variable(b_channel, SOFIA_REFER_TO_VARIABLE, full_ref_to);
9457 }
9458
9459 if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer"))) {
9460 switch_ivr_transfer_recordings(session, b_session);
9461 }
9462
9463 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "BLIND_TRANSFER");
9464
9465 if (((var = switch_channel_get_variable(channel, "confirm_blind_transfer")) && switch_true(var)) ||
9466 sofia_test_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER)) {
9467
9468 switch_channel_set_state_flag(b_channel, CF_CONFIRM_BLIND_TRANSFER);
9469 switch_channel_set_variable(channel, "sip_blind_transfer_event", etmp);
9470 switch_channel_set_variable(b_channel, "blind_transfer_uuid", switch_core_session_get_uuid(session));
9471 switch_channel_set_variable(channel, "blind_transfer_uuid", switch_core_session_get_uuid(b_session));
9472
9473 switch_channel_set_variable(channel, "park_timeout", "600:blind_transfer");
9474 switch_channel_set_state(channel, CS_PARK);
9475 } else {
9476 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9477 NUTAG_SUBSTATE(nua_substate_terminated),
9478 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
9479 SIPTAG_PAYLOAD_STR("SIP/2.0 200 OK\r\n"), SIPTAG_EVENT_STR(etmp),
9480 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9481 TAG_END());
9482 }
9483
9484 if (refer_to->r_url->url_params) {
9485 switch_channel_set_variable(b_channel, "sip_h_X-FS-Refer-Params", refer_to->r_url->url_params);
9486 }
9487
9488 if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
9489 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
9490 switch_channel_event_set_data(channel_a, event);
9491 switch_event_fire(&event);
9492 }
9493
9494 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
9495 switch_channel_event_set_data(b_channel, event);
9496 switch_event_fire(&event);
9497 }
9498 }
9499
9500 switch_ivr_session_transfer(b_session, exten, NULL, NULL);
9501 switch_core_session_rwunlock(b_session);
9502 } else {
9503 switch_event_t *event;
9504
9505 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR) == SWITCH_STATUS_SUCCESS) {
9506 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Error-Type", "blind_transfer");
9507 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Transfer-Exten", exten);
9508 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Full-Refer-To", full_ref_to);
9509 switch_channel_event_set_data(channel, event);
9510 switch_event_fire(&event);
9511 }
9512
9513 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot Blind Transfer 1 Legged calls\n");
9514 switch_channel_set_variable(channel_a, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR");
9515 nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
9516 NUTAG_SUBSTATE(nua_substate_terminated),
9517 SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
9518 SIPTAG_PAYLOAD_STR("SIP/2.0 403 Forbidden\r\n"), SIPTAG_EVENT_STR(etmp),
9519 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9520 TAG_END());
9521 }
9522 }
9523
9524 done:
9525 if (home) {
9526 su_home_unref(home);
9527 home = NULL;
9528 }
9529
9530 switch_safe_free(etmp);
9531 }
9532
9533
create_info_event(sip_t const * sip,nua_handle_t * nh,switch_event_t ** revent)9534 static switch_status_t create_info_event(sip_t const *sip,
9535 nua_handle_t *nh, switch_event_t **revent)
9536 {
9537 sip_alert_info_t *alert_info = sip_alert_info(sip);
9538 switch_event_t *event;
9539
9540 if (!(sip && switch_event_create(&event, SWITCH_EVENT_RECV_INFO) == SWITCH_STATUS_SUCCESS)) {
9541 return SWITCH_STATUS_FALSE;
9542 }
9543
9544 if (sip->sip_content_type) {
9545 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Content-Type", sip->sip_content_type->c_type);
9546 }
9547
9548 if (sip->sip_from) {
9549 if (sip->sip_from->a_url->url_user) {
9550 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-From-User", sip->sip_from->a_url->url_user);
9551 }
9552
9553 if (sip->sip_from->a_url->url_host) {
9554 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-From-Host", sip->sip_from->a_url->url_host);
9555 }
9556 }
9557
9558 if (sip->sip_to) {
9559 if (sip->sip_to->a_url->url_user) {
9560 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-To-User", sip->sip_to->a_url->url_user);
9561 }
9562
9563 if (sip->sip_to->a_url->url_host) {
9564 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-To-Host", sip->sip_to->a_url->url_host);
9565 }
9566 }
9567
9568
9569 if (sip->sip_contact) {
9570 if (sip->sip_contact->m_url->url_user) {
9571 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Contact-User", sip->sip_contact->m_url->url_user);
9572 }
9573
9574 if (sip->sip_contact->m_url->url_host) {
9575 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Contact-Host", sip->sip_contact->m_url->url_host);
9576 }
9577 }
9578
9579
9580 if (sip->sip_call_info) {
9581 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Call-Info",
9582 sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_call_info));
9583 }
9584
9585 if (alert_info) {
9586 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Alert-Info", sip_header_as_string(nua_handle_home(nh), (void *) alert_info));
9587 }
9588
9589
9590 if (sip->sip_payload && sip->sip_payload->pl_data) {
9591 switch_event_add_body(event, "%s", sip->sip_payload->pl_data);
9592 }
9593
9594 *revent = event;
9595
9596 return SWITCH_STATUS_SUCCESS;
9597 }
9598
sofia_proxy_sip_i_message(nua_t * nua,sofia_profile_t * profile,nua_handle_t * nh,switch_core_session_t * session,sip_t const * sip,sofia_dispatch_event_t * de,tagi_t tags[])9599 switch_status_t sofia_proxy_sip_i_message(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
9600 sofia_dispatch_event_t *de, tagi_t tags[])
9601 {
9602 switch_core_session_t *other_session = NULL;
9603 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9604
9605 if (session && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
9606 if (switch_core_session_compare(session, other_session)) {
9607 private_object_t *other_tech_pvt = NULL;
9608 const char *ct = NULL;
9609 char *pl = NULL;
9610
9611
9612 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
9613 pl = sip->sip_payload->pl_data;
9614 }
9615
9616 other_tech_pvt = (private_object_t *) switch_core_session_get_private(other_session);
9617
9618 if (sip && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype) {
9619 ct = sip->sip_content_type->c_type;
9620 }
9621
9622 nua_message(other_tech_pvt->nh,
9623 TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(other_tech_pvt->nh->nh_home, ct))),
9624 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
9625 TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(other_tech_pvt->nh->nh_home, pl))),
9626 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9627 TAG_END());
9628 }
9629
9630 switch_core_session_rwunlock(other_session);
9631
9632 nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg),
9633 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9634 TAG_END());
9635
9636 return SWITCH_STATUS_SUCCESS;
9637 }
9638
9639 return SWITCH_STATUS_FALSE;
9640 }
9641
sofia_proxy_sip_i_info(nua_t * nua,sofia_profile_t * profile,nua_handle_t * nh,switch_core_session_t * session,sip_t const * sip,sofia_dispatch_event_t * de,tagi_t tags[])9642 switch_status_t sofia_proxy_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
9643 sofia_dispatch_event_t *de, tagi_t tags[])
9644 {
9645 switch_core_session_t *other_session = NULL;
9646 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9647
9648 if (session && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
9649 if (switch_core_session_compare(session, other_session)) {
9650 private_object_t *other_tech_pvt = NULL;
9651 const char *ct = NULL;
9652 char *pl = NULL;
9653 switch_channel_t *channel = switch_core_session_get_channel(session);
9654
9655 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
9656 pl = sip->sip_payload->pl_data;
9657 }
9658
9659 other_tech_pvt = (private_object_t *) switch_core_session_get_private(other_session);
9660
9661 if (sip && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype) {
9662 ct = sip->sip_content_type->c_type;
9663 }
9664
9665 if (sip && sip->sip_content_type->c_type && !strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) {
9666 if (switch_channel_test_flag(channel, CF_VIDEO)) {
9667 switch_core_media_gen_key_frame(session);
9668 switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ);
9669 }
9670 }
9671
9672 nua_info(other_tech_pvt->nh,
9673 TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(su_strdup(other_tech_pvt->nh->nh_home, ct))),
9674 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
9675 TAG_IF(pl, SIPTAG_PAYLOAD_STR(su_strdup(other_tech_pvt->nh->nh_home, pl))),
9676 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9677 TAG_END());
9678 }
9679
9680 switch_core_session_rwunlock(other_session);
9681
9682 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
9683
9684 return SWITCH_STATUS_SUCCESS;
9685 }
9686
9687 return SWITCH_STATUS_FALSE;
9688 }
9689
9690
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,sofia_dispatch_event_t * de,tagi_t tags[])9691 void 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,
9692 sofia_dispatch_event_t *de, tagi_t tags[])
9693 {
9694 /* placeholder for string searching */
9695 const char *signal_ptr;
9696 const char *rec_header;
9697 const char *clientcode_header;
9698 switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), 0, SWITCH_DTMF_ENDPOINT };
9699 switch_event_t *event;
9700 private_object_t *tech_pvt = NULL;
9701 switch_channel_t *channel = NULL;
9702 const char *session_id_header = sofia_glue_session_id_header(session, profile);
9703
9704 if (session) {
9705 tech_pvt = (private_object_t *) switch_core_session_get_private(session);
9706 channel = switch_core_session_get_channel(session);
9707 }
9708
9709 if (sofia_test_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)) {
9710 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
9711 sip->sip_payload && sip->sip_payload->pl_data) {
9712
9713 if (!strncasecmp(sip->sip_content_type->c_type, "freeswitch", 10)) {
9714
9715 if (!strcasecmp(sip->sip_content_type->c_subtype, "session-event")) {
9716 if (session) {
9717
9718 if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
9719 if (switch_core_session_queue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
9720 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "queued freeswitch event for INFO\n");
9721 nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
9722 SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
9723 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9724 TAG_END());
9725 } else {
9726 switch_event_destroy(&event);
9727 nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
9728 SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
9729 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9730 TAG_END());
9731 }
9732 }
9733
9734 } else {
9735 nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"),
9736 SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
9737 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9738 TAG_END());
9739
9740 }
9741
9742 return;
9743
9744 } else if (!strcasecmp(sip->sip_content_type->c_subtype, "api-request")) {
9745 char *cmd = strdup(sip->sip_payload->pl_data);
9746 char *arg;
9747 switch_stream_handle_t stream = { 0 };
9748 switch_status_t status;
9749
9750 switch_assert(cmd);
9751 SWITCH_STANDARD_STREAM(stream);
9752 switch_assert(stream.data);
9753
9754 if ((arg = strchr(cmd, ':'))) {
9755 *arg++ = '\0';
9756 }
9757
9758 if ((status = switch_api_execute(cmd, arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) {
9759 nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"),
9760 SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS_MSG(de->data->e_msg),
9761 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9762 TAG_END());
9763 } else {
9764
9765 nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"),
9766 SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS_MSG(de->data->e_msg),
9767 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9768 TAG_END());
9769 }
9770
9771 switch_safe_free(stream.data);
9772 switch_safe_free(cmd);
9773 return;
9774 }
9775
9776 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
9777 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9778 TAG_END());
9779
9780 return;
9781 }
9782 }
9783 }
9784
9785 if (session) {
9786 const char *vval;
9787
9788 /* Barf if we didn't get our private */
9789 assert(switch_core_session_get_private(session));
9790
9791 sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_INFO_HEADER_PREFIX);
9792 if (!zstr(profile->proxy_info_content_types) && sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
9793 (!strcasecmp(profile->proxy_info_content_types,"all") || strstr(profile->proxy_info_content_types,sip->sip_content_type->c_type))) {
9794 switch_core_session_t *other_session;
9795
9796 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
9797 char *pl = NULL;
9798 char *ct = NULL;
9799 char *extra_headers = NULL;
9800 char *unknown = NULL;
9801 private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
9802
9803 ct = switch_core_session_strdup(other_session, (char*)sip->sip_content_type->c_type);
9804 if (sip->sip_payload && sip->sip_payload->pl_data) {
9805 pl = switch_core_session_strdup(other_session,(char*)sip->sip_payload->pl_data);
9806 }
9807 unknown = sofia_glue_get_non_extra_unknown_headers(sip);
9808
9809 extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_INFO_HEADER_PREFIX);
9810
9811 nua_info(other_tech_pvt->nh,
9812 SIPTAG_CONTENT_TYPE_STR(ct),
9813 TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
9814 TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)),
9815 TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
9816 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9817 TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)),
9818 TAG_END());
9819 switch_safe_free(extra_headers);
9820 switch_safe_free(unknown);
9821 switch_core_session_rwunlock(other_session);
9822 }
9823 }
9824
9825 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && !strcasecmp(sip->sip_content_type->c_type, "freeswitch/data")) {
9826 char *data = NULL;
9827
9828 if (sip->sip_payload && sip->sip_payload->pl_data) {
9829 data = sip->sip_payload->pl_data;
9830 }
9831
9832 if ((vval = switch_channel_get_variable(channel, "sip_copy_custom_headers")) && switch_true(vval)) {
9833 switch_core_session_t *nsession = NULL;
9834
9835 switch_core_session_get_partner(session, &nsession);
9836
9837 if (nsession) {
9838 switch_core_session_message_t *msg;
9839
9840 switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_INFO_HEADER_PREFIX_T);
9841 msg = switch_core_session_alloc(nsession, sizeof(*msg));
9842 MESSAGE_STAMP_FFL(msg);
9843 msg->message_id = SWITCH_MESSAGE_INDICATE_INFO;
9844
9845 msg->string_array_arg[2] = switch_core_session_strdup(nsession, data);
9846
9847 msg->from = __FILE__;
9848 switch_core_session_queue_message(nsession, msg);
9849
9850 switch_core_session_rwunlock(nsession);
9851 }
9852 }
9853 }
9854
9855 if (sip && sip->sip_content_type && sip->sip_content_type->c_subtype && sip->sip_content_type->c_type &&
9856 !strncasecmp(sip->sip_content_type->c_type, "message", 7) &&
9857 !strcasecmp(sip->sip_content_type->c_subtype, "update_display")) {
9858 sofia_update_callee_id(session, profile, sip, SWITCH_TRUE);
9859 goto end;
9860 }
9861
9862 if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
9863 sip->sip_payload && sip->sip_payload->pl_data) {
9864 if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) {
9865
9866 if (switch_channel_test_flag(channel, CF_VIDEO)) {
9867 switch_core_media_gen_key_frame(session);
9868 switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ);
9869 }
9870
9871 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) &&
9872 !strcasecmp(sip->sip_content_type->c_subtype, "vnd.nortelnetworks.digits")) {
9873 int tmp;
9874 if ((signal_ptr = switch_stristr("d=", sip->sip_payload->pl_data))) {
9875 signal_ptr = signal_ptr + 2;
9876
9877 while (*signal_ptr && *signal_ptr == ' ') {
9878 signal_ptr++;
9879 }
9880
9881 if (*signal_ptr && (*signal_ptr == '*' || *signal_ptr == '#' || *signal_ptr == 'A' || *signal_ptr == 'B'
9882 || *signal_ptr == 'C' || *signal_ptr == 'D')) {
9883 dtmf.digit = *signal_ptr;
9884 } else {
9885 tmp = atoi(signal_ptr);
9886 dtmf.digit = switch_rfc2833_to_char(tmp);
9887 }
9888
9889 dtmf.duration = 100;
9890 } else {
9891 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bad signal\n");
9892 goto end;
9893 }
9894 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) {
9895 /* Try and find signal information in the payload */
9896 if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) {
9897 int tmp;
9898 /* move signal_ptr where we need it (right past Signal=) */
9899 signal_ptr = signal_ptr + 7;
9900
9901 /* handle broken devices with spaces after the = (cough) VegaStream (cough) */
9902 while (*signal_ptr && *signal_ptr == ' ')
9903 signal_ptr++;
9904
9905 if (*signal_ptr
9906 && (*signal_ptr == '*' || *signal_ptr == '#' || *signal_ptr == 'A' || *signal_ptr == 'B' || *signal_ptr == 'C'
9907 || *signal_ptr == 'D')) {
9908 dtmf.digit = *signal_ptr;
9909 } else {
9910 tmp = atoi(signal_ptr);
9911 dtmf.digit = switch_rfc2833_to_char(tmp);
9912 }
9913 } else {
9914 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bad signal\n");
9915 goto end;
9916 }
9917
9918 if ((signal_ptr = switch_stristr("Duration=", sip->sip_payload->pl_data))) {
9919 int tmp;
9920 signal_ptr += 9;
9921
9922 /* handle broken devices with spaces after the = (cough) VegaStream (cough) */
9923 while (*signal_ptr && *signal_ptr == ' ')
9924 signal_ptr++;
9925
9926 if ((tmp = atoi(signal_ptr)) <= 0) {
9927 tmp = switch_core_default_dtmf_duration(0);
9928 }
9929 dtmf.duration = tmp * 8;
9930 }
9931 } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf")) {
9932 int tmp = atoi(sip->sip_payload->pl_data);
9933 dtmf.digit = switch_rfc2833_to_char(tmp);
9934 }
9935
9936 if (dtmf.digit) {
9937 if (tech_pvt->mparams.dtmf_type == DTMF_INFO ||
9938 sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || switch_channel_test_flag(tech_pvt->channel, CF_LIBERAL_DTMF)) {
9939 /* queue it up */
9940 switch_channel_queue_dtmf(channel, &dtmf);
9941
9942 /* print debug info */
9943 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "INFO DTMF(%c)\n", dtmf.digit);
9944
9945 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
9946 const char *uuid;
9947 switch_core_session_t *session_b;
9948
9949 if ((uuid = switch_channel_get_partner_uuid(channel)) && (session_b = switch_core_session_locate(uuid))) {
9950 while (switch_channel_has_dtmf(channel)) {
9951 switch_dtmf_t idtmf = { 0, 0 };
9952 if (switch_channel_dequeue_dtmf(channel, &idtmf) == SWITCH_STATUS_SUCCESS) {
9953 switch_core_session_send_dtmf(session_b, &idtmf);
9954 }
9955 }
9956
9957 switch_core_session_rwunlock(session_b);
9958 }
9959 }
9960
9961 /* Send 200 OK response */
9962 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
9963 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9964 TAG_END());
9965 } else {
9966 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
9967 "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit);
9968 }
9969 goto end;
9970 }
9971 }
9972
9973 if ((clientcode_header = sofia_glue_get_unknown_header(sip, "x-clientcode"))) {
9974 if (!zstr(clientcode_header)) {
9975 switch_channel_set_variable(channel, "call_clientcode", clientcode_header);
9976 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Setting CMC to %s\n", clientcode_header);
9977 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
9978 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9979 TAG_END());
9980 }
9981 goto end;
9982 }
9983
9984 if ((rec_header = sofia_glue_get_unknown_header(sip, "record"))) {
9985 if (zstr(profile->record_template)) {
9986 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Record attempted but no template defined.\n");
9987 nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg),
9988 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
9989 TAG_END());
9990 } else {
9991 if (!strcasecmp(rec_header, "on")) {
9992 char *file = NULL, *tmp = NULL;
9993
9994 if (switch_true(switch_channel_get_variable(channel, "sip_disable_recording"))) {
9995 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Record attempted but is disabled by sip_disable_recording variable.\n");
9996 nua_respond(nh, 488, "Recording disabled for this channel", NUTAG_WITH_THIS_MSG(de->data->e_msg),
9997 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
9998 } else {
9999
10000 tmp = switch_mprintf("%s%s%s", profile->record_path ? profile->record_path : "${recordings_dir}",
10001 SWITCH_PATH_SEPARATOR, profile->record_template);
10002 file = switch_channel_expand_variables(channel, tmp);
10003 switch_ivr_record_session(session, file, 0, NULL);
10004 switch_channel_set_variable(channel, "sofia_record_file", file);
10005 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Recording %s to %s\n", switch_channel_get_name(channel),
10006 file);
10007 switch_safe_free(tmp);
10008 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
10009 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
10010 TAG_END());
10011 if (file != profile->record_template) {
10012 free(file);
10013 file = NULL;
10014 }
10015 }
10016 } else {
10017 const char *file;
10018
10019 if ((file = switch_channel_get_variable(channel, "sofia_record_file"))) {
10020 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Done recording %s to %s\n",
10021 switch_channel_get_name(channel), file);
10022 switch_ivr_stop_record_session(session, file);
10023 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
10024 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
10025 TAG_END());
10026 } else {
10027 nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg),
10028 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
10029 TAG_END());
10030 }
10031 }
10032 }
10033 }
10034 }
10035
10036 end:
10037
10038 if (create_info_event(sip, nh, &event) == SWITCH_STATUS_SUCCESS) {
10039 if (channel) {
10040 switch_channel_event_set_data(channel, event);
10041 }
10042 switch_event_fire(&event);
10043 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "dispatched freeswitch event for INFO\n");
10044 }
10045
10046 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
10047 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
10048 TAG_END());
10049
10050 return;
10051
10052 }
10053
sofia_handle_sip_i_reinvite(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[])10054 void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
10055 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
10056 sofia_dispatch_event_t *de,
10057 tagi_t tags[])
10058 {
10059 char *call_info = NULL;
10060 switch_channel_t *channel = NULL;
10061 private_object_t *tech_pvt = NULL;
10062
10063 nua_respond(nh, SIP_100_TRYING, TAG_END());
10064
10065 if (session) {
10066 channel = switch_core_session_get_channel(session);
10067 tech_pvt = switch_core_session_get_private(session);
10068
10069
10070 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10071 tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
10072 }
10073 }
10074
10075 if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) {
10076 switch_channel_t *channel = switch_core_session_get_channel(session);
10077 private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
10078 char network_ip[80];
10079 int network_port = 0;
10080 char via_space[2048];
10081 char branch[16] = "";
10082
10083 sofia_glue_store_session_id(session, profile, sip, 0);
10084
10085 sofia_clear_flag(tech_pvt, TFLAG_GOT_ACK);
10086
10087 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
10088 switch_stun_random_string(branch, sizeof(branch) - 1, "0123456789abcdef");
10089
10090 switch_snprintf(via_space, sizeof(via_space), "SIP/2.0/UDP %s;rport=%d;branch=%s", network_ip, network_port, branch);
10091 switch_channel_set_variable(channel, "sip_full_via", via_space);
10092 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
10093 switch_channel_set_variable_printf(channel, "sip_recieved_port", "%d", network_port);
10094 switch_channel_set_variable_printf(channel, "sip_via_rport", "%d", network_port);
10095
10096 switch_core_recovery_track(session);
10097 }
10098
10099 if (profile && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
10100 if (channel && sip && sip->sip_call_info) {
10101 char *p;
10102 if ((call_info = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_call_info))) {
10103 if (switch_stristr("appearance", call_info)) {
10104 switch_channel_set_variable(channel, "presence_call_info_full", call_info);
10105 if ((p = strchr(call_info, ';'))) {
10106 switch_channel_set_variable(channel, "presence_call_info", p + 1);
10107 }
10108 }
10109 su_free(nua_handle_home(nh), call_info);
10110 }
10111 }
10112 }
10113
10114 if (channel) {
10115 if (tech_pvt->mparams.last_sdp_str) {
10116 tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
10117 }
10118 tech_pvt->mparams.last_sdp_str = NULL;
10119
10120 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10121 if (!zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) {
10122 switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data);
10123 tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
10124 } else {
10125 tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str;
10126 }
10127 }
10128
10129 switch_channel_execute_on(channel, "execute_on_sip_reinvite");
10130 }
10131
10132 }
10133
sofia_locate_user(char * user,switch_core_session_t * session,sip_t const * sip,switch_xml_t * x_user)10134 switch_status_t sofia_locate_user(char* user, switch_core_session_t *session, sip_t const *sip, switch_xml_t* x_user)
10135 {
10136 char *username, *domain;
10137 switch_event_t *v_event = NULL;
10138 switch_status_t result = SWITCH_STATUS_FALSE;
10139
10140 if (!session) {
10141 return SWITCH_STATUS_FALSE;
10142 }
10143
10144 if (zstr(user)) {
10145 return SWITCH_STATUS_FALSE;
10146 }
10147
10148 if (!(username = switch_core_session_strdup(session, user))) {
10149 return SWITCH_STATUS_FALSE;
10150 }
10151
10152 if (!(domain = strchr(username, '@'))) {
10153 return SWITCH_STATUS_FALSE;
10154 }
10155
10156 *domain++ = '\0';
10157
10158 if (switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS) == SWITCH_STATUS_SUCCESS) {
10159 sip_unknown_t *un;
10160 for (un = sip->sip_unknown; un; un = un->un_next) {
10161 switch_event_add_header_string(v_event, SWITCH_STACK_BOTTOM, un->un_name, un->un_value);
10162 };
10163 switch_channel_event_set_data(switch_core_session_get_channel(session), v_event);
10164 }
10165
10166 result = switch_xml_locate_user_merged("id", username, domain, NULL, x_user, v_event);
10167
10168 if (v_event) {
10169 switch_event_destroy(&v_event);
10170 }
10171
10172 return result;
10173 }
10174
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[])10175 void 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[])
10176 {
10177 char key[128] = "";
10178 sip_unknown_t *un;
10179 sip_remote_party_id_t *rpid = NULL;
10180 sip_p_asserted_identity_t *passerted = NULL;
10181 sip_p_preferred_identity_t *ppreferred = NULL;
10182 sip_privacy_t *privacy = NULL;
10183 sip_alert_info_t *alert_info = NULL;
10184 sip_call_info_t *call_info = NULL;
10185 private_object_t *tech_pvt = NULL;
10186 switch_channel_t *channel = NULL;
10187 //const char *channel_name = NULL;
10188 const char *displayname = NULL;
10189 const char *destination_number = NULL;
10190 const char *from_user = NULL, *from_host = NULL;
10191 const char *referred_by_user = NULL;//, *referred_by_host = NULL;
10192 const char *context = NULL;
10193 const char *dialplan = NULL;
10194 char network_ip[80];
10195 char proxied_client_ip[80];
10196 switch_event_t *v_event = NULL;
10197 switch_xml_t x_user = NULL;
10198 uint32_t sess_count = switch_core_session_count();
10199 uint32_t sess_max = switch_core_session_limit(0);
10200 int is_auth = 0, calling_myself = 0;
10201 int network_port = 0;
10202 char *is_nat = NULL;
10203 char *aniii = NULL;
10204 char acl_token[512] = "";
10205 sofia_transport_t transport;
10206 const char *gw_name = NULL;
10207 const char *gw_param_name = NULL;
10208 char *call_info_str = NULL;
10209 nua_handle_t *bnh = NULL;
10210 char sip_acl_authed_by[512] = "";
10211 char sip_acl_token[512] = "";
10212 const char *dialog_from_user = "", *dialog_from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = "";
10213 const char *user_agent = "", *call_id = "";
10214 url_t *from = NULL, *to = NULL, *contact = NULL;
10215 const char *to_tag = "";
10216 const char *from_tag = "";
10217 char *sql = NULL;
10218 char *acl_context = NULL;
10219 const char *r_sdp = NULL;
10220 int is_tcp = 0, is_tls = 0;
10221 const char *uparams = NULL;
10222 char *name_params = NULL;
10223 const char *req_uri = NULL;
10224 char *req_user = NULL;
10225 switch_time_t sip_invite_time;
10226 const char *session_id_header;
10227
10228 sofia_glue_store_session_id(session, profile, sip, 0);
10229 session_id_header = sofia_glue_session_id_header(session, profile);
10230
10231 if (sip && sip->sip_contact && sip->sip_contact->m_url->url_params) {
10232 uparams = sip->sip_contact->m_url->url_params;
10233 } else {
10234 uparams = NULL;
10235 }
10236
10237
10238 if (uparams) {
10239 if (switch_stristr("transport=tcp", uparams)) {
10240 is_tcp = 1;
10241 } else if (switch_stristr("transport=tls", uparams)) {
10242 is_tls = 1;
10243 }
10244 }
10245
10246 profile->ib_calls++;
10247
10248 if (sip && sip->sip_payload && sip->sip_payload->pl_data) {
10249 r_sdp = sip->sip_payload->pl_data;
10250 }
10251
10252 if (!session || (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING))) {
10253 nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"),
10254 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
10255 goto fail;
10256 }
10257
10258 tech_pvt = switch_core_session_get_private(session);
10259
10260 sip_invite_time = switch_micro_time_now();
10261
10262 if (!sip || !sip->sip_request || !sip->sip_request->rq_method_name) {
10263 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received an invalid packet!\n");
10264 nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE,
10265 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
10266 goto fail;
10267 }
10268
10269 if (!(sip->sip_contact)) {
10270 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT!\n");
10271 nua_respond(nh, 400, "Missing Contact Header",
10272 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
10273 goto fail;
10274 }
10275
10276
10277 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
10278
10279 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s receiving invite from %s:%d version: %s\n",
10280 switch_channel_get_name(tech_pvt->channel), network_ip, network_port, switch_version_full_human());
10281
10282
10283 if (sip->sip_via && sip->sip_via->v_protocol && switch_stristr("sip/2.0/ws", sip->sip_via->v_protocol)) {
10284 is_nat = "websockets";
10285 }
10286
10287
10288 if (r_sdp) {
10289 switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST);
10290 }
10291
10292
10293 if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION) ||
10294 (sofia_test_pflag(profile, PFLAG_TLS_ALWAYS_NAT) && (is_tcp || is_tls)) ||
10295 (!is_tcp && !is_tls && (zstr(network_ip) || !switch_check_network_list_ip(network_ip, profile->local_network)) &&
10296 profile->server_rport_level >= 2 && sip->sip_user_agent &&
10297 sip->sip_user_agent->g_string &&
10298 (!strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7) || !strncasecmp(sip->sip_user_agent->g_string, "KIRK Wireless Server", 20)))
10299 ) {
10300 if (sip->sip_via) {
10301 const char *port = sip->sip_via->v_port;
10302 const char *host = sip->sip_via->v_host;
10303
10304 if (host && sip->sip_via->v_received) {
10305 is_nat = "via received";
10306 } else if (host && strcmp(network_ip, host)) {
10307 is_nat = "via host";
10308 } else if (port && atoi(port) != network_port) {
10309 is_nat = "via port";
10310 }
10311 }
10312 }
10313
10314 if (!is_nat && profile->nat_acl_count) {
10315 uint32_t x = 0;
10316 int contact_private_ip = 1;
10317 int network_private_ip = 0;
10318 char *last_acl = NULL;
10319 const char *contact_host = NULL;
10320
10321 if (sip->sip_via && sip->sip_via->v_host) {
10322 contact_host = sip->sip_via->v_host;
10323 } else if (sip->sip_contact) {
10324 contact_host = sip->sip_contact->m_url->url_host;
10325 }
10326
10327 if (!zstr(contact_host)) {
10328 /* NAT mode double check logic and examples.
10329
10330 Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point
10331 is most likely behind nat with us so we need to veto that decision to turn on nat processing.
10332
10333 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
10334 the remote endpoint is likely behind a remote nat traversing the public internet.
10335
10336 This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net
10337 in cases where we don't really need to be doing this.
10338
10339 Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind
10340 remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process.
10341
10342 */
10343
10344 for (x = 0; x < profile->nat_acl_count; x++) {
10345 last_acl = profile->nat_acl[x];
10346 if ((contact_private_ip = switch_check_network_list_ip(contact_host, last_acl))) {
10347 break;
10348 }
10349 }
10350 if (contact_private_ip) {
10351 for (x = 0; x < profile->nat_acl_count; x++) {
10352 if ((network_private_ip = switch_check_network_list_ip(network_ip, profile->nat_acl[x]))) {
10353 break;
10354 }
10355 }
10356 }
10357
10358 if (contact_private_ip && !network_private_ip) {
10359 is_nat = last_acl;
10360 }
10361 }
10362 }
10363
10364 if (profile->acl_count) {
10365 uint32_t x = 0;
10366 int ok = 1;
10367 char *last_acl = NULL;
10368 const char *token = NULL;
10369 int acl_port = sofia_test_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK) ? network_port : 0;
10370
10371 for (x = 0; x < profile->acl_count; x++) {
10372 last_acl = profile->acl[x];
10373 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "verifying acl \"%s\" for ip/port %s:%i.\n",
10374 switch_str_nil(last_acl), network_ip, acl_port);
10375 if ((ok = switch_check_network_list_ip_port_token(network_ip, acl_port, last_acl, &token))) {
10376
10377 if (profile->acl_pass_context[x]) {
10378 acl_context = profile->acl_pass_context[x];
10379 }
10380 if(!token && profile->acl_inbound_x_token_header) {
10381 const char * x_auth_token = sofia_glue_get_unknown_header(sip, profile->acl_inbound_x_token_header);
10382 if (!zstr(x_auth_token)) {
10383 token = x_auth_token;
10384 }
10385 }
10386
10387 break;
10388 }
10389
10390 if (profile->acl_fail_context[x]) {
10391 acl_context = profile->acl_fail_context[x];
10392 } else {
10393 acl_context = NULL;
10394 }
10395 }
10396
10397 if (ok) {
10398 if (token) {
10399 switch_set_string(acl_token, token);
10400 }
10401 if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
10402 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
10403 network_ip, switch_str_nil(last_acl), acl_token);
10404 switch_set_string(sip_acl_authed_by, last_acl);
10405 switch_set_string(sip_acl_token, acl_token);
10406 is_auth = 1;
10407 }
10408 } else {
10409 int network_ip_is_proxy = 0;
10410 const char* x_auth_ip = network_ip;
10411 /* Check if network_ip is a proxy allowed to send us calls */
10412 if (profile->proxy_acl_count) {
10413 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%d acls to check for proxy\n", profile->proxy_acl_count);
10414 for (x = 0; x < profile->proxy_acl_count; x++) {
10415 last_acl = profile->proxy_acl[x];
10416 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "checking %s against acl %s\n", network_ip, last_acl);
10417 if (switch_check_network_list_ip_port_token(network_ip, network_port, last_acl, &token)) {
10418 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s is a proxy according to the %s acl\n", network_ip, last_acl);
10419 network_ip_is_proxy = 1;
10420 break;
10421 }
10422 }
10423 }
10424
10425 /*
10426 * if network_ip is a proxy allowed to send calls, check for auth
10427 * ip header and see if it matches against the inbound acl
10428 */
10429 if (network_ip_is_proxy) {
10430 const char * x_auth_port = sofia_glue_get_unknown_header(sip, "X-AUTH-PORT");
10431 int x_auth_port_i = sofia_test_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK) ? zstr(x_auth_port) ? 0 : atoi(x_auth_port) : 0;
10432
10433 /*
10434 * if network_ip is a proxy allowed to send calls,
10435 * authorize call if proxy provided matched token header
10436 */
10437 if (profile->acl_proxy_x_token_header) {
10438 const char * x_auth_token = sofia_glue_get_unknown_header(sip, profile->acl_proxy_x_token_header);
10439 if (!zstr(x_auth_token)) {
10440 token = x_auth_token;
10441 switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
10442 ok = 1;
10443 }
10444 }
10445
10446 if (!ok && (x_auth_ip = sofia_glue_get_unknown_header(sip, "X-AUTH-IP")) && !zstr(x_auth_ip)) {
10447 for (x = 0; x < profile->acl_count; x++) {
10448 last_acl = profile->acl[x];
10449 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "verifying acl \"%s\" from proxy for ip/port %s:%i.\n",
10450 switch_str_nil(last_acl), x_auth_ip, x_auth_port_i);
10451 if ((ok = switch_check_network_list_ip_port_token(x_auth_ip, x_auth_port_i, last_acl, &token))) {
10452
10453 switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
10454
10455 if (profile->acl_pass_context[x]) {
10456 acl_context = profile->acl_pass_context[x];
10457 }
10458
10459 break;
10460 }
10461
10462 if (profile->acl_fail_context[x]) {
10463 acl_context = profile->acl_fail_context[x];
10464 } else {
10465 acl_context = NULL;
10466 }
10467 }
10468 } else {
10469 x_auth_ip = network_ip;
10470 }
10471 }
10472
10473 if (ok) {
10474 if (token) {
10475 switch_set_string(acl_token, token);
10476 }
10477 if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
10478 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
10479 x_auth_ip, switch_str_nil(last_acl), acl_token);
10480 switch_set_string(sip_acl_authed_by, last_acl);
10481 switch_set_string(sip_acl_token, acl_token);
10482 is_auth = 1;
10483 }
10484 } else {
10485 if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
10486 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", x_auth_ip, switch_str_nil(last_acl));
10487 if (!acl_context) {
10488 nua_respond(nh, SIP_403_FORBIDDEN,
10489 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
10490 goto fail;
10491 } else {
10492 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
10493 x_auth_ip, switch_str_nil(last_acl));
10494 }
10495 }
10496 }
10497 }
10498 }
10499
10500
10501 if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS) && sofia_test_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)) {
10502 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP/Port %s %i Rejected by acls and auth-calls-acl-only flag is set, rejecting call\n",
10503 network_ip, network_port);
10504 nua_respond(nh, SIP_403_FORBIDDEN,
10505 TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)), TAG_END());
10506 goto fail;
10507 }
10508
10509 if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS) && sofia_test_pflag(profile, PFLAG_BLIND_AUTH)) {
10510 char *user = NULL;
10511 switch_status_t blind_result = SWITCH_STATUS_FALSE;
10512
10513 if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
10514 calling_myself++;
10515 }
10516
10517 if (sip->sip_from) {
10518 user = switch_core_session_sprintf(session, "%s@%s", sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host);
10519 blind_result = sofia_locate_user(user, session, sip, &x_user);
10520 }
10521 if (!sofia_test_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT) || blind_result == SWITCH_STATUS_SUCCESS) {
10522 is_auth++;
10523 } else if (sofia_test_pflag(profile, PFLAG_BLIND_AUTH_REPLY_403)) {
10524 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "blind auth enforce 403 enabled and couldn't find user %s, rejecting call\n", user);
10525 nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
10526 goto fail;
10527 }
10528 }
10529
10530
10531 tech_pvt->from_user = switch_core_session_strdup(session, sip->sip_from->a_url->url_user);
10532 tech_pvt->mparams.remote_ip = switch_core_session_strdup(session, network_ip);
10533 tech_pvt->mparams.remote_port = network_port;
10534
10535 if (!is_auth &&
10536 (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)
10537 || (!sofia_test_pflag(profile, PFLAG_BLIND_AUTH) && (sip->sip_proxy_authorization || sip->sip_authorization)))) {
10538 if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
10539 calling_myself++;
10540 } else {
10541 switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS);
10542
10543 if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, sizeof(key), &v_event, NULL, NULL, &x_user)) {
10544 if (v_event) {
10545 switch_event_destroy(&v_event);
10546 }
10547 if (x_user) {
10548 switch_xml_free(x_user);
10549 }
10550
10551 if (sip->sip_authorization || sip->sip_proxy_authorization) {
10552 goto fail;
10553 }
10554
10555 return;
10556 }
10557 }
10558 is_auth++;
10559 }
10560
10561 channel = tech_pvt->channel = switch_core_session_get_channel(session);
10562
10563 switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip);
10564 switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip);
10565 switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port);
10566 switch_channel_set_variable_printf(channel, "sip_invite_stamp", "%" SWITCH_TIME_T_FMT, sip_invite_time);
10567
10568 if (*acl_token) {
10569 if (x_user) {
10570 switch_xml_free(x_user);
10571 x_user = NULL;
10572 }
10573 switch_channel_set_variable(channel, "acl_token", acl_token);
10574 if (sofia_locate_user(acl_token, session, sip, &x_user) == SWITCH_STATUS_SUCCESS) {
10575 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Authenticating user %s\n", acl_token);
10576 } else {
10577 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Error Authenticating user %s\n", acl_token);
10578 if (sofia_test_pflag(profile, PFLAG_AUTH_REQUIRE_USER)) {
10579 nua_respond(nh, SIP_480_TEMPORARILY_UNAVAILABLE, TAG_END());
10580 if (v_event) {
10581 switch_event_destroy(&v_event);
10582 }
10583 goto fail;
10584 }
10585 }
10586 }
10587
10588 if (sip->sip_via) {
10589 char tmp[35] = "";
10590 const char *ipv6 = strchr(tech_pvt->mparams.remote_ip, ':');
10591
10592 transport = sofia_glue_via2transport(sip->sip_via);
10593
10594
10595 tech_pvt->record_route =
10596 switch_core_session_sprintf(session,
10597 "sip:%s%s%s:%d;transport=%s",
10598 ipv6 ? "[" : "", tech_pvt->mparams.remote_ip, ipv6 ? "]" : "",
10599 tech_pvt->mparams.remote_port, sofia_glue_transport2str(transport));
10600
10601 switch_channel_set_variable(channel, "sip_received_ip", tech_pvt->mparams.remote_ip);
10602 snprintf(tmp, sizeof(tmp), "%d", tech_pvt->mparams.remote_port);
10603 switch_channel_set_variable(channel, "sip_received_port", tmp);
10604 switch_channel_set_variable(channel, "sip_via_protocol", sofia_glue_transport2str(sofia_glue_via2transport(sip->sip_via)));
10605 }
10606
10607 if (*key != '\0') {
10608 tech_pvt->key = switch_core_session_strdup(session, key);
10609 }
10610
10611
10612 if (is_auth) {
10613 switch_channel_set_variable(channel, "sip_authorized", "true");
10614
10615 if (!zstr(sip_acl_authed_by)) {
10616 switch_channel_set_variable(channel, "sip_acl_authed_by", sip_acl_authed_by);
10617 }
10618
10619 if (!zstr(sip_acl_token)) {
10620 switch_channel_set_variable(channel, "sip_acl_token", sip_acl_token);
10621 }
10622
10623 }
10624
10625 if (calling_myself) {
10626 switch_channel_set_variable(channel, "sip_looped_call", "true");
10627 }
10628
10629 tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
10630 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, MODNAME, NULL, NULL);
10631 switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
10632
10633 if (x_user) {
10634 const char *ruser = NULL, *rdomain = NULL, *user = switch_xml_attr(x_user, "id"), *domain = switch_xml_attr(x_user, "domain-name");
10635
10636 if (v_event) {
10637 switch_event_header_t *hp;
10638
10639 for (hp = v_event->headers; hp; hp = hp->next) {
10640 switch_channel_set_variable(channel, hp->name, hp->value);
10641 }
10642
10643 ruser = switch_event_get_header(v_event, "user_name");
10644 rdomain = switch_event_get_header(v_event, "domain_name");
10645
10646 switch_channel_set_variable(channel, "requested_user_name", ruser);
10647 switch_channel_set_variable(channel, "requested_domain_name", rdomain);
10648 }
10649
10650 if (!user) user = ruser;
10651 if (!domain) domain = rdomain;
10652
10653 switch_ivr_set_user_xml(session, NULL, user, domain, x_user);
10654 switch_xml_free(x_user);
10655 x_user = NULL;
10656 }
10657
10658 if (v_event) {
10659 switch_event_destroy(&v_event);
10660 }
10661
10662 if (sip->sip_from) {
10663 from_user = sip->sip_from->a_url->url_user;
10664 from_host = sip->sip_from->a_url->url_host;
10665 //channel_name = url_set_chanvars(session, sip->sip_from->a_url, sip_from);
10666
10667 if (sip->sip_from->a_url->url_params) {
10668 aniii = switch_find_parameter(sip->sip_from->a_url->url_params, "isup-oli", switch_core_session_get_pool(session));
10669 }
10670
10671 if (!zstr(from_user)) {
10672 if (*from_user == '+') {
10673 switch_channel_set_variable(channel, "sip_from_user_stripped", (const char *) (from_user + 1));
10674 } else {
10675 switch_channel_set_variable(channel, "sip_from_user_stripped", from_user);
10676 }
10677 }
10678
10679 switch_channel_set_variable(channel, "sip_from_comment", sip->sip_from->a_comment);
10680
10681 if (sip->sip_from->a_params) {
10682 set_variable_sip_param(channel, "from", sip->sip_from->a_params);
10683 }
10684
10685 switch_channel_set_variable(channel, "sofia_profile_name", profile->name);
10686 switch_channel_set_variable(channel, "sofia_profile_url", profile->url);
10687 switch_channel_set_variable(channel, "recovery_profile_name", profile->name);
10688 switch_channel_set_variable(channel, "sofia_profile_domain_name", profile->domain_name);
10689
10690 if (!zstr(sip->sip_from->a_display)) {
10691 displayname = sip->sip_from->a_display;
10692 } else {
10693 displayname = zstr(from_user) ? "unknown" : from_user;
10694 }
10695 }
10696
10697 if ((rpid = sip_remote_party_id(sip))) {
10698 if (rpid->rpid_url->url_user) {
10699 char *full_rpid_header = sip_header_as_string(nh->nh_home, (void *) rpid);
10700 from_user = rpid->rpid_url->url_user;
10701 if (!zstr(full_rpid_header)) {
10702 switch_channel_set_variable(channel, "sip_Remote-Party-ID", full_rpid_header);
10703 }
10704
10705 }
10706 if (!zstr(rpid->rpid_display)) {
10707 displayname = rpid->rpid_display;
10708 }
10709 switch_channel_set_variable(channel, "sip_cid_type", "rpid");
10710 tech_pvt->cid_type = CID_TYPE_RPID;
10711 }
10712
10713 if ((passerted = sip_p_asserted_identity(sip))) {
10714 if (passerted->paid_url->url_user) {
10715 char *full_paid_header = sip_header_as_string(nh->nh_home, (void *) passerted);
10716 //char *full_paid_header = (char *)(passerted->paid_common->h_data);
10717 from_user = passerted->paid_url->url_user;
10718 if (!zstr(full_paid_header)) {
10719 if (profile->paid_type == PAID_DEFAULT || profile->paid_type == PAID_USER) {
10720 switch_channel_set_variable(channel, "sip_P-Asserted-Identity", from_user);
10721 } else if (profile->paid_type == PAID_USER_DOMAIN) {
10722 switch_channel_set_variable(channel, "sip_P-Asserted-Identity",
10723 switch_core_session_sprintf(session, "%s@%s", passerted->paid_url->url_user, passerted->paid_url->url_host));
10724 } else if (profile->paid_type == PAID_VERBATIM) {
10725 switch_channel_set_variable(channel, "sip_P-Asserted-Identity", full_paid_header);
10726 }
10727 }
10728 }
10729 if (!zstr(passerted->paid_display)) {
10730 displayname = passerted->paid_display;
10731 }
10732 switch_channel_set_variable(channel, "sip_cid_type", "pid");
10733 tech_pvt->cid_type = CID_TYPE_PID;
10734 }
10735
10736 if ((ppreferred = sip_p_preferred_identity(sip))) {
10737 if (ppreferred->ppid_url->url_user) {
10738 char *full_ppid_header = sip_header_as_string(nh->nh_home, (void *) ppreferred);
10739 from_user = ppreferred->ppid_url->url_user;
10740 if (!zstr(full_ppid_header)) {
10741 switch_channel_set_variable(channel, "sip_P-Preferred-Identity", full_ppid_header);
10742 }
10743
10744 }
10745 if (!zstr(ppreferred->ppid_display)) {
10746 displayname = ppreferred->ppid_display;
10747 }
10748 switch_channel_set_variable(channel, "sip_cid_type", "pid");
10749 tech_pvt->cid_type = CID_TYPE_PID;
10750 }
10751
10752 if (from_user) {
10753 check_decode(from_user, session);
10754
10755 if ((name_params = strchr(from_user, ';'))) {
10756 *name_params++ = '\0';
10757 switch_channel_set_variable(channel, "sip_name_params", name_params);
10758 }
10759 }
10760
10761 extract_header_vars(profile, sip, session, nh);
10762 sofia_add_invite_header_to_chanvars(channel, nh, sip->sip_allow, "sip_allow");
10763
10764 req_uri = url_set_chanvars(session, sip->sip_request->rq_url, sip_req);
10765 if (sip->sip_request->rq_url->url_user) {
10766
10767 req_user = switch_core_session_strdup(session, sip->sip_request->rq_url->url_user);
10768 if (profile->parse_invite_tel_params) {
10769 if (strchr(req_user, ';')) {
10770 int argc1, x1 = 0;
10771 char *argv1[32] = { 0 };
10772
10773 if ((argc1 = switch_separate_string(req_user, ';', argv1, (sizeof(argv1) / sizeof(argv1[0]))))) {
10774 for (x1 = 0; x1 < argc1; x1++) {
10775 if (x1 == 0) {
10776 switch_channel_set_variable(channel, "sip_req_user", argv1[0]);
10777 } else {
10778 int argc2 = 0;
10779 char *argv2[2] = { 0 };
10780 if ((argc2 = switch_separate_string(argv1[x1], '=', argv2, (sizeof(argv2) / sizeof(argv2[0])))) == 2) {
10781 char *var_name = NULL;
10782 var_name = switch_mprintf("sip_invite_%s", argv2[0]);
10783 switch_channel_set_variable(channel, var_name, argv2[1]);
10784 switch_safe_free( var_name );
10785 } else {
10786 char *var_name = NULL;
10787 var_name = switch_mprintf("sip_invite_%s", argv1[x1]);
10788 switch_channel_set_variable(channel, var_name, "true");
10789 switch_safe_free( var_name );
10790 }
10791 }
10792 }
10793 }
10794 }
10795 }
10796 }
10797
10798 if (sofia_test_pflag(profile, PFLAG_FULL_ID)) {
10799 destination_number = req_uri;
10800 } else {
10801 destination_number = req_user;
10802 }
10803 if (sip->sip_request->rq_url->url_params && (sofia_glue_find_parameter(sip->sip_request->rq_url->url_params, "intercom=true"))) {
10804 switch_channel_set_variable(channel, "sip_auto_answer_detected", "true");
10805 }
10806
10807 if (!destination_number && sip->sip_to) {
10808 destination_number = sip->sip_to->a_url->url_user;
10809 }
10810
10811 /* The human network, OH THE HUMANITY!!! lets send invites with no number! */
10812 if (!destination_number && sip->sip_from) {
10813 destination_number = sip->sip_from->a_url->url_user;
10814 }
10815
10816 if (destination_number) {
10817 check_decode(destination_number, session);
10818 } else {
10819 destination_number = "service";
10820 }
10821
10822 if (sip->sip_to) {
10823 const char *host, *user;
10824 int port, check_nat = 0;
10825 url_t *transport_url;
10826
10827 if (sip->sip_record_route) {
10828 transport_url = sip->sip_record_route->r_url;
10829 } else {
10830 transport_url = sip->sip_contact->m_url;
10831 }
10832
10833 transport = sofia_glue_url2transport(transport_url);
10834 tech_pvt->transport = transport;
10835
10836 url_set_chanvars(session, sip->sip_to->a_url, sip_to);
10837 if (switch_channel_get_variable(channel, "sip_to_uri")) {
10838 const char *ipv6;
10839 const char *tmp, *at, *url = NULL;
10840
10841 host = switch_channel_get_variable(channel, "sip_to_host");
10842 user = switch_channel_get_variable(channel, "sip_to_user");
10843
10844 switch_channel_set_variable(channel, "sip_to_comment", sip->sip_to->a_comment);
10845
10846 if (sip->sip_to->a_params) {
10847 set_variable_sip_param(channel, "to", sip->sip_to->a_params);
10848 }
10849
10850 if (sip->sip_contact->m_url->url_port) {
10851 port = atoi(sip->sip_contact->m_url->url_port);
10852 } else {
10853 port = sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->extsipport;
10854 }
10855
10856 ipv6 = strchr(host, ':');
10857 tech_pvt->to_uri =
10858 switch_core_session_sprintf(session,
10859 "sip:%s@%s%s%s:%d;transport=%s",
10860 user, ipv6 ? "[" : "", host, ipv6 ? "]" : "", port, sofia_glue_transport2str(transport));
10861
10862 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
10863 check_nat = 1;
10864 }
10865 url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport);
10866
10867 if (!url) {
10868 if (check_nat) {
10869 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Nat detected but no external address configured.\n");
10870 }
10871 url = profile->url;
10872 }
10873
10874 if (!url) {
10875 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
10876 }
10877
10878 tmp = sofia_overcome_sip_uri_weakness(session, url, transport, SWITCH_TRUE, NULL, NULL);
10879
10880 if ((at = strchr(tmp, '@'))) {
10881 url = switch_core_session_sprintf(session, "sip:%s%s", user, at);
10882 }
10883
10884 if (url) {
10885 const char *brackets = NULL;
10886 const char *proto = NULL;
10887
10888 brackets = strchr(url, '>');
10889 proto = switch_stristr("transport=", url);
10890 tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s%s%s%s%s",
10891 brackets ? "" : "<", url,
10892 proto ? "" : ";transport=",
10893 proto ? "" : sofia_glue_transport2str(transport), brackets ? "" : ">");
10894 } else {
10895 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
10896 }
10897
10898 } else {
10899 const char *url = NULL;
10900 url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport);
10901
10902 if (url) {
10903 const char *brackets = NULL;
10904 const char *proto = NULL;
10905
10906 brackets = strchr(url, '>');
10907 proto = switch_stristr("transport=", url);
10908 tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s%s%s%s%s",
10909 brackets ? "" : "<", url,
10910 proto ? "" : ";transport=",
10911 proto ? "" : sofia_glue_transport2str(transport), brackets ? "" : ">");
10912 } else {
10913 switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
10914 }
10915 }
10916 }
10917
10918 if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
10919 tech_pvt->user_via = sofia_glue_create_external_via(session, profile, tech_pvt->transport);
10920 nua_set_hparams(nh, SIPTAG_VIA_STR(tech_pvt->user_via), TAG_END());
10921 }
10922
10923 url_set_chanvars(session, sip->sip_contact->m_url, sip_contact);
10924
10925 if (sip->sip_referred_by) {
10926 referred_by_user = sip->sip_referred_by->b_url->url_user;
10927 //referred_by_host = sip->sip_referred_by->b_url->url_host;
10928 //channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by);
10929
10930 check_decode(referred_by_user, session);
10931
10932 if (!zstr(referred_by_user)) {
10933 if (*referred_by_user == '+') {
10934 switch_channel_set_variable(channel, "sip_referred_by_user_stripped", (const char *) (referred_by_user + 1));
10935 } else {
10936 switch_channel_set_variable(channel, "sip_referred_by_user_stripped", referred_by_user);
10937 }
10938 }
10939
10940 switch_channel_set_variable(channel, "sip_referred_by_cid", sip->sip_referred_by->b_cid);
10941
10942 if (sip->sip_referred_by->b_params) {
10943 set_variable_sip_param(channel, "referred_by", sip->sip_referred_by->b_params);
10944 }
10945 }
10946
10947 //sofia_glue_set_name(tech_pvt, channel_name);
10948 switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
10949
10950 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "INBOUND CALL");
10951
10952 if (sofia_test_flag(tech_pvt, TFLAG_INB_NOMEDIA)) {
10953 switch_channel_set_flag(channel, CF_PROXY_MODE);
10954 }
10955
10956 if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_HOLD) {
10957 switch_channel_set_flag(channel, CF_BYPASS_MEDIA_AFTER_HOLD);
10958 }
10959
10960 if (sofia_test_flag(tech_pvt, TFLAG_PROXY_MEDIA)) {
10961 switch_channel_set_flag(channel, CF_PROXY_MEDIA);
10962 }
10963
10964 if (sofia_test_flag(tech_pvt, TFLAG_ZRTP_PASSTHRU)) {
10965 switch_channel_set_flag(channel, CF_ZRTP_PASSTHRU_REQ);
10966 }
10967
10968 if (sip->sip_subject && sip->sip_subject->g_string) {
10969 switch_channel_set_variable(channel, "sip_subject", sip->sip_subject->g_string);
10970 }
10971
10972 if (sip->sip_user_agent && !zstr(sip->sip_user_agent->g_string)) {
10973 switch_channel_set_variable(channel, "sip_user_agent", sip->sip_user_agent->g_string);
10974 }
10975
10976 sofia_set_accept_language_channel_variable(channel, sip);
10977
10978 if (sip->sip_via) {
10979 if (sip->sip_via->v_host) {
10980 switch_channel_set_variable(channel, "sip_via_host", sip->sip_via->v_host);
10981 }
10982 if (sip->sip_via->v_port) {
10983 switch_channel_set_variable(channel, "sip_via_port", sip->sip_via->v_port);
10984 }
10985 if (sip->sip_via->v_rport) {
10986 switch_channel_set_variable(channel, "sip_via_rport", sip->sip_via->v_rport);
10987 }
10988 }
10989
10990
10991 if (sip->sip_multipart) {
10992 msg_multipart_t *mp;
10993
10994 for (mp = sip->sip_multipart; mp; mp = mp->mp_next) {
10995 if (mp->mp_payload && mp->mp_payload->pl_data && mp->mp_content_type && mp->mp_content_type->c_type) {
10996 char *val = switch_core_session_sprintf(session, "%s:%s", mp->mp_content_type->c_type, mp->mp_payload->pl_data);
10997 switch_channel_add_variable_var_check(channel, "sip_multipart", val, SWITCH_FALSE, SWITCH_STACK_PUSH);
10998 }
10999 }
11000 }
11001
11002 if (sip->sip_max_forwards) {
11003 char max_forwards[32];
11004 switch_snprintf(max_forwards, sizeof(max_forwards), "%lu", sip->sip_max_forwards->mf_count);
11005 switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards);
11006 }
11007
11008 if (acl_context) context = acl_context;
11009
11010 if (!context) {
11011 context = switch_channel_get_variable(channel, "user_context");
11012 }
11013
11014 if (!context) {
11015 if (profile->context && !strcasecmp(profile->context, "_domain_")) {
11016 context = from_host;
11017 } else {
11018 context = profile->context;
11019 }
11020 }
11021
11022 if (!(dialplan = switch_channel_get_variable(channel, "inbound_dialplan"))) {
11023 dialplan = profile->dialplan;
11024 }
11025
11026 if ((alert_info = sip_alert_info(sip))) {
11027 char *tmp = sip_header_as_string(nh->nh_home, (void *) alert_info);
11028 switch_channel_set_variable(channel, "alert_info", tmp);
11029 su_free(nh->nh_home, tmp);
11030 }
11031
11032 if ((call_info = sip_call_info(sip))) {
11033 call_info_str = sip_header_as_string(nh->nh_home, (void *) call_info);
11034
11035 if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE) && switch_stristr("appearance", call_info_str)) {
11036 char *p;
11037
11038 switch_channel_set_variable(channel, "presence_call_info_full", call_info_str);
11039 if ((p = strchr(call_info_str, ';'))) {
11040 p++;
11041 switch_channel_set_variable(channel, "presence_call_info", p);
11042 }
11043 }
11044
11045 if (call_info->ci_params && (msg_params_find(call_info->ci_params, "answer-after=0"))) {
11046 switch_channel_set_variable(channel, "sip_auto_answer_detected", "true");
11047 }
11048
11049 switch_channel_set_variable(channel, "sip_call_info", call_info_str);
11050
11051 call_info = call_info->ci_next;
11052
11053 while (call_info) {
11054 call_info_str = sip_header_as_string(nh->nh_home, (void *) call_info);
11055 switch_channel_add_variable_var_check(channel, "sip_call_info", call_info_str, SWITCH_FALSE, SWITCH_STACK_PUSH);
11056 call_info = call_info->ci_next;
11057 }
11058
11059 call_info = sip_call_info(sip);
11060
11061 } else if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
11062 char buf[128] = "";
11063 char *sql;
11064 char *state = "progressing";
11065
11066 if (sip->sip_from && sip->sip_from->a_url->url_user && sip->sip_from->a_url->url_host &&
11067 sip->sip_to && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host) {
11068 sql =
11069 switch_mprintf("select 'appearance-index=1' from sip_subscriptions where expires > -1 and hostname='%q' and event='call-info' and "
11070 "sub_to_user='%q' and sub_to_host='%q'", mod_sofia_globals.hostname, sip->sip_to->a_url->url_user,
11071 sip->sip_from->a_url->url_host);
11072 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
11073
11074 if (mod_sofia_globals.debug_sla > 1) {
11075 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s [%s]\n", sql, buf);
11076 }
11077 free(sql);
11078
11079 if (!zstr(buf)) {
11080 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' "
11081 "where uuid='%q'", buf, state, switch_core_session_get_uuid(session));
11082
11083 if (mod_sofia_globals.debug_sla > 1) {
11084 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
11085 }
11086
11087 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11088
11089
11090 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Auto-Fixing Broken SLA [<sip:%s>;%s]\n",
11091 sip->sip_from->a_url->url_host, buf);
11092
11093 switch_channel_set_variable_printf(channel, "presence_call_info_full", "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
11094 switch_channel_set_variable(channel, "presence_call_info", buf);
11095 call_info_str = switch_core_session_sprintf(session, "<sip:%s>;%s", sip->sip_from->a_url->url_host, buf);
11096 }
11097 }
11098 }
11099
11100
11101 if (profile->pres_type) {
11102 const char *presence_id = switch_channel_get_variable(channel, "presence_id");
11103 if (zstr(presence_id)) {
11104 const char *user = switch_str_nil(sip->sip_from->a_url->url_user);
11105 const char *host = switch_str_nil(sip->sip_from->a_url->url_host);
11106 char *tmp = switch_mprintf("%s@%s", user, host);
11107 switch_assert(tmp);
11108 switch_channel_set_variable(channel, "presence_id", tmp);
11109 free(tmp);
11110 }
11111 }
11112
11113
11114 if (sip->sip_request->rq_url->url_params) {
11115 gw_param_name = switch_find_parameter(sip->sip_request->rq_url->url_params, "gw", switch_core_session_get_pool(session));
11116 }
11117
11118 if (strstr(destination_number, "gw+")) {
11119 if (sofia_test_pflag(profile, PFLAG_FULL_ID)) {
11120 char *tmp;
11121 gw_name = switch_core_session_strdup(session, destination_number + 3);
11122 if ((tmp = strchr(gw_name, '@'))) {
11123 *tmp = '\0';
11124 }
11125 } else {
11126 gw_name = destination_number + 3;
11127 }
11128 }
11129
11130 if (gw_name || gw_param_name) {
11131 sofia_gateway_t *gateway = NULL;
11132 char *extension = NULL;
11133
11134 if (gw_name && ((gateway = sofia_reg_find_gateway(gw_name)))) {
11135 gw_param_name = NULL;
11136 extension = gateway->extension;
11137 }
11138
11139 if (!gateway && gw_param_name) {
11140 if ((gateway = sofia_reg_find_gateway(gw_param_name))) {
11141 extension = gateway->real_extension;
11142 }
11143 }
11144
11145 if (gateway) {
11146 context = switch_core_session_strdup(session, gateway->register_context);
11147 switch_channel_set_variable(channel, "sip_gateway", gateway->name);
11148
11149 if (!zstr(extension)) {
11150 if (!strcasecmp(extension, "auto_to_user") && sip->sip_to) {
11151 destination_number = sip->sip_to->a_url->url_user;
11152 } else if (!strcasecmp(extension, "auto")) {
11153 if (gw_name && sip->sip_to) {
11154 destination_number = sip->sip_to->a_url->url_user;
11155 }
11156 } else {
11157 destination_number = switch_core_session_strdup(session, extension);
11158 }
11159 } else if (!gw_param_name && sip->sip_to) {
11160 destination_number = sip->sip_to->a_url->url_user;
11161 }
11162
11163 gateway->ib_calls++;
11164
11165 if (gateway->ib_vars) {
11166 switch_event_header_t *hp;
11167 for (hp = gateway->ib_vars->headers; hp; hp = hp->next) {
11168 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n",
11169 switch_channel_get_name(channel), hp->name, hp->value);
11170 switch_channel_set_variable(channel, hp->name, hp->value);
11171 }
11172 }
11173
11174 sofia_reg_release_gateway(gateway);
11175 }
11176 }
11177
11178 if (call_info_str) {
11179 char *sql;
11180 char cid[512] = "";
11181 char *str;
11182 char *p = NULL;
11183 const char *user = NULL, *host = NULL, *from_user = NULL, *from_host = NULL;
11184
11185 if (sip->sip_to) {
11186 user = sip->sip_to->a_url->url_user;
11187 host = sip->sip_to->a_url->url_host;
11188 }
11189
11190 if (sip->sip_from) {
11191 from_user = sip->sip_from->a_url->url_user;
11192 from_host = sip->sip_from->a_url->url_host;
11193 }
11194
11195 if (!user) user = from_user;
11196 if (!host) user = from_host;
11197
11198 if (user && host && from_user && !strcmp(user, from_user)) {
11199 if ((p = strchr(call_info_str, ';'))) {
11200 p++;
11201 }
11202
11203 sql = switch_mprintf(
11204 "select call_id from sip_dialogs where (call_info='%q' or call_info='%q;appearance-state=held') and "
11205 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') and call_id is not null",
11206 switch_str_nil(p), switch_str_nil(p), user, host, user, host);
11207
11208 if ((str = sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, cid, sizeof(cid)))) {
11209 bnh = nua_handle_by_call_id(nua, str);
11210 }
11211
11212 if (mod_sofia_globals.debug_sla > 1) {
11213 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PICK SQL %s [%s] [%s] %d\n", sql, str, cid, !!bnh);
11214 }
11215
11216 free(sql);
11217 }
11218 }
11219
11220
11221 check_decode(displayname, session);
11222
11223 profile_dup_clean(from_user, tech_pvt->caller_profile->username, tech_pvt->caller_profile->pool);
11224 profile_dup_clean(dialplan, tech_pvt->caller_profile->dialplan, tech_pvt->caller_profile->pool);
11225 profile_dup_clean(displayname, tech_pvt->caller_profile->caller_id_name, tech_pvt->caller_profile->pool);
11226 profile_dup_clean(from_user, tech_pvt->caller_profile->caller_id_number, tech_pvt->caller_profile->pool);
11227 profile_dup_clean(displayname, tech_pvt->caller_profile->orig_caller_id_name, tech_pvt->caller_profile->pool);
11228 profile_dup_clean(from_user, tech_pvt->caller_profile->orig_caller_id_number, tech_pvt->caller_profile->pool);
11229 profile_dup_clean(network_ip, tech_pvt->caller_profile->network_addr, tech_pvt->caller_profile->pool);
11230 profile_dup_clean(from_user, tech_pvt->caller_profile->ani, tech_pvt->caller_profile->pool);
11231 profile_dup_clean(aniii, tech_pvt->caller_profile->aniii, tech_pvt->caller_profile->pool);
11232 profile_dup_clean(context, tech_pvt->caller_profile->context, tech_pvt->caller_profile->pool);
11233 profile_dup_clean(destination_number, tech_pvt->caller_profile->destination_number, tech_pvt->caller_profile->pool);
11234
11235 if (!bnh && sip->sip_replaces) {
11236 if (!(bnh = nua_handle_by_replaces(nua, sip->sip_replaces))) {
11237 if (!(bnh = nua_handle_by_call_id(nua, sip->sip_replaces->rp_call_id))) {
11238 bnh = sofia_global_nua_handle_by_replaces(sip->sip_replaces);
11239 }
11240 }
11241 }
11242
11243 if (sip->sip_replaces) {
11244 msg_common_t *rp_common = sip->sip_replaces->rp_common;
11245 switch_channel_set_variable(channel, "sip_replaces_call_id", sip->sip_replaces->rp_call_id);
11246 if (rp_common->h_class->hc_params) {
11247 int i, n;
11248 msg_param_t const *params = * (msg_param_t const **) ((char *)rp_common + rp_common->h_class->hc_params);
11249 for (i = 0; params[i]; i++) {
11250 msg_param_t param = params[i];
11251 if (strchr(param, '=')) {
11252 n = strcspn(param, "=");
11253 switch_channel_set_variable_name_printf(channel, param + n + 1, "sip_replaces_%.*s", n, param);
11254 } else {
11255 switch_channel_set_variable_name_printf(channel, "true", "sip_replaces_%s", param);
11256 }
11257 }
11258 }
11259 }
11260
11261 if (bnh) {
11262 sofia_private_t *b_private = NULL;
11263 if ((b_private = nua_handle_magic(bnh))) {
11264 switch_core_session_t *b_session = NULL;
11265 if ((b_session = switch_core_session_locate(b_private->uuid))) {
11266 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
11267 sofia_handle_sip_i_invite_replaces(session, channel, b_channel, b_private->uuid, tech_pvt, call_info, profile, is_nat, sip);
11268 switch_core_session_rwunlock(b_session);
11269 }
11270 }
11271 nua_handle_unref(bnh);
11272 } else if (sip->sip_replaces && sip->sip_replaces->rp_call_id) {
11273 switch_core_session_t *b_session = NULL;
11274 if ((b_session = switch_core_session_locate((char*) sip->sip_replaces->rp_call_id))) {
11275 switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
11276 sofia_handle_sip_i_invite_replaces(session, channel, b_channel, (char*) sip->sip_replaces->rp_call_id, tech_pvt, call_info, profile, is_nat, sip);
11277 switch_core_session_rwunlock(b_session);
11278 }
11279 }
11280
11281 if (tech_pvt->caller_profile) {
11282
11283 int first_history_info = 1;
11284
11285 if (rpid) {
11286 if (rpid->rpid_privacy) {
11287 if (!strcasecmp(rpid->rpid_privacy, "yes")) {
11288 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
11289 } else if (!strcasecmp(rpid->rpid_privacy, "full")) {
11290 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
11291 } else if (!strcasecmp(rpid->rpid_privacy, "name")) {
11292 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
11293 } else if (!strcasecmp(rpid->rpid_privacy, "number")) {
11294 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
11295 } else {
11296 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
11297 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
11298 }
11299 }
11300
11301 if (rpid->rpid_screen && !strcasecmp(rpid->rpid_screen, "no")) {
11302 switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
11303 }
11304 }
11305
11306 if ((privacy = sip_privacy(sip))) {
11307 char *full_priv_header = sip_header_as_string(nh->nh_home, (void *) privacy);
11308 if (!zstr(full_priv_header)) {
11309 switch_channel_set_variable(channel, "sip_Privacy", full_priv_header);
11310 }
11311 if (msg_params_find(privacy->priv_values, "id")) {
11312 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
11313 }
11314 }
11315
11316 /* Loop thru unknown Headers Here so we can do something with them */
11317 for (un = sip->sip_unknown; un; un = un->un_next) {
11318 if (!strncasecmp(un->un_name, "Accept-Language", 15)) {
11319 if (!zstr(un->un_value)) {
11320 char *tmp_name;
11321 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX, un->un_name))) {
11322 switch_channel_set_variable(channel, tmp_name, un->un_value);
11323 free(tmp_name);
11324 }
11325 }
11326 } else if (!strncasecmp(un->un_name, "Diversion", 9)) {
11327 /* Basic Diversion Support for Diversion Indication in SIP */
11328 /* draft-levy-sip-diversion-08 */
11329 if (!zstr(un->un_value)) {
11330 char *tmp_name;
11331 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX, un->un_name))) {
11332 switch_channel_set_variable(channel, tmp_name, un->un_value);
11333 free(tmp_name);
11334 }
11335 }
11336 } else if (!strncasecmp(un->un_name, "History-Info", 12)) {
11337 if (first_history_info) {
11338 /* If the header exists first time, make sure to remove old info and re-set the variable */
11339 switch_channel_set_variable(channel, "sip_history_info", un->un_value);
11340 first_history_info = 0;
11341 } else {
11342 /* Append the History-Info into one long string */
11343 const char *history_var = switch_channel_get_variable(channel, "sip_history_info");
11344 if (!zstr(history_var)) {
11345 char *tmp_str;
11346 if ((tmp_str = switch_mprintf("%s, %s", history_var, un->un_value))) {
11347 switch_channel_set_variable(channel, "sip_history_info", tmp_str);
11348 free(tmp_str);
11349 } else {
11350 switch_channel_set_variable(channel, "sip_history_info", un->un_value);
11351 }
11352 } else {
11353 switch_channel_set_variable(channel, "sip_history_info", un->un_value);
11354 }
11355 }
11356 } else if (!strcasecmp(un->un_name, "X-FS-Channel-Name") && !zstr(un->un_value)) {
11357 switch_channel_set_name(channel, un->un_value);
11358 switch_channel_set_variable(channel, "push_channel_name", "true");
11359 } else if (!strcasecmp(un->un_name, "X-FS-Support")) {
11360 tech_pvt->x_freeswitch_support_remote = switch_core_session_strdup(session, un->un_value);
11361 } else if (!strcasecmp(un->un_name, "Geolocation")) {
11362 switch_channel_set_variable(channel, "sip_geolocation", un->un_value);
11363 } else if (!strcasecmp(un->un_name, "Geolocation-Error")) {
11364 switch_channel_set_variable(channel, "sip_geolocation_error", un->un_value);
11365 } else if (!strcasecmp(un->un_name, "userLocation")) {
11366 switch_channel_set_variable(channel, "sip_user_location", un->un_value);
11367 } else if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2) || !strcasecmp(un->un_name, "User-to-User") || !strncasecmp(un->un_name, "On", 2) || !strncasecmp(un->un_name, "K-", 2)) {
11368 if (!zstr(un->un_value)) {
11369 char new_name[512] = "";
11370 int reps = 0;
11371 for (;;) {
11372 char postfix[25] = "";
11373 if (reps > 0) {
11374 switch_snprintf(postfix, sizeof(postfix), "-%d", reps);
11375 }
11376 reps++;
11377 switch_snprintf(new_name, sizeof(new_name), "%s%s%s", SOFIA_SIP_HEADER_PREFIX, un->un_name, postfix);
11378
11379 if (switch_channel_get_variable(channel, new_name)) {
11380 continue;
11381 }
11382
11383 switch_channel_set_variable(channel, new_name, un->un_value);
11384 break;
11385 }
11386 }
11387 }
11388 }
11389
11390 }
11391
11392 tech_pvt->sofia_private = sofia_private;
11393 tech_pvt->nh = nh;
11394
11395 if (profile->pres_type && sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)) {
11396 sofia_presence_set_chat_hash(tech_pvt, sip);
11397 }
11398
11399 if (sofia_test_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS)) {
11400 sofia_parse_all_invite_headers(sip, session, nh);
11401 }
11402
11403 if (sip->sip_to) {
11404 to = sip->sip_to->a_url;
11405 }
11406 if (sip->sip_from) {
11407 from = sip->sip_from->a_url;
11408 }
11409 contact = sip->sip_contact->m_url;
11410
11411 if (sip->sip_user_agent) {
11412 user_agent = switch_str_nil(sip->sip_user_agent->g_string);
11413 }
11414
11415 if (sip->sip_call_id) {
11416 call_id = switch_str_nil(sip->sip_call_id->i_id);
11417 }
11418
11419 if (to) {
11420 to_user = switch_str_nil(to->url_user);
11421 to_host = switch_str_nil(to->url_host);
11422 to_tag = switch_str_nil(sip->sip_to->a_tag);
11423 }
11424
11425 if (from) {
11426 dialog_from_user = switch_str_nil(from->url_user);
11427 dialog_from_host = switch_str_nil(from->url_host);
11428 from_tag = switch_str_nil(sip->sip_from->a_tag);
11429 }
11430
11431 contact_user = switch_str_nil(contact->url_user);
11432 contact_host = switch_str_nil(contact->url_host);
11433
11434 if (profile->pres_type) {
11435 const char *presence_data = switch_channel_get_variable(channel, "presence_data");
11436 const char *presence_id = switch_channel_get_variable(channel, "presence_id");
11437 char *full_contact = "";
11438 char *p = NULL;
11439 time_t now;
11440
11441 full_contact = sip_header_as_string(nua_handle_home(tech_pvt->nh), (void *) sip->sip_contact);
11442
11443 if (call_info_str && switch_stristr("appearance", call_info_str)) {
11444 switch_channel_set_variable(channel, "presence_call_info_full", call_info_str);
11445 if ((p = strchr(call_info_str, ';'))) {
11446 p++;
11447 switch_channel_set_variable(channel, "presence_call_info", p);
11448 }
11449 }
11450
11451 now = switch_epoch_time_now(NULL);
11452
11453 sql = switch_mprintf("insert into sip_dialogs "
11454 "(call_id,uuid,sip_to_user,sip_to_host,sip_to_tag,sip_from_user,sip_from_host,sip_from_tag,contact_user,"
11455 "contact_host,state,direction,user_agent,profile_name,hostname,contact,presence_id,presence_data,"
11456 "call_info,rcd,call_info_state) "
11457 "values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'')",
11458 call_id,
11459 tech_pvt->sofia_private->uuid,
11460 to_user, to_host, to_tag, dialog_from_user, dialog_from_host, from_tag,
11461 contact_user, contact_host, "confirmed", "inbound", user_agent,
11462 profile->name, mod_sofia_globals.hostname, switch_str_nil(full_contact),
11463 switch_str_nil(presence_id), switch_str_nil(presence_data), switch_str_nil(p), now);
11464
11465 switch_assert(sql);
11466
11467 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11468
11469 if ( full_contact ) {
11470 su_free(nua_handle_home(tech_pvt->nh), full_contact);
11471 }
11472 }
11473
11474 if (is_nat) {
11475 sofia_set_flag(tech_pvt, TFLAG_NAT);
11476 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting NAT mode based on %s\n", is_nat);
11477 switch_channel_set_variable(channel, "sip_nat_detected", "true");
11478 }
11479
11480 return;
11481
11482 fail:
11483 profile->ib_failed_calls++;
11484
11485 return;
11486
11487 }
11488
sofia_handle_sip_i_invite_replaces(switch_core_session_t * session,switch_channel_t * channel,switch_channel_t * b_channel,char * uuid,private_object_t * tech_pvt,sip_call_info_t * call_info,sofia_profile_t * profile,char * is_nat,sip_t const * sip)11489 void sofia_handle_sip_i_invite_replaces(switch_core_session_t *session, switch_channel_t *channel, switch_channel_t *b_channel, char* uuid, private_object_t *tech_pvt, sip_call_info_t *call_info, sofia_profile_t *profile, char *is_nat, sip_t const *sip)
11490 {
11491 const char *bridge_uuid;
11492 switch_caller_profile_t *orig_cp, *cp;
11493 //const char *sent_name, *sent_number;
11494 orig_cp = switch_channel_get_caller_profile(b_channel);
11495
11496 if (orig_cp) {
11497 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name);
11498 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number);
11499
11500 if (!call_info) {
11501 tech_pvt->caller_profile->caller_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name);
11502 tech_pvt->caller_profile->caller_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number);
11503 }
11504
11505 cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool, orig_cp);
11506 switch_channel_set_originator_caller_profile(channel, cp);
11507 }
11508
11509 #if 0
11510 sent_name = switch_channel_get_variable(b_channel, "last_sent_callee_id_name");
11511 sent_number = switch_channel_get_variable(b_channel, "last_sent_callee_id_number");
11512
11513 if (!zstr(sent_name) && !zstr(sent_number)) {
11514 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, sent_name);
11515 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, sent_number);
11516 } else {
11517 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
11518 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name);
11519 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number);
11520 } else {
11521 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name);
11522 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number);
11523 }
11524 }
11525 #endif
11526
11527 if (is_nat) {
11528 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Setting NAT mode based on %s\n", is_nat);
11529 }
11530
11531 tech_pvt->caller_profile->dialplan = "inline";
11532
11533 bridge_uuid = switch_channel_get_partner_uuid(b_channel);
11534 if (bridge_uuid) {
11535 switch_core_session_t *bridge_session = NULL;
11536 if ((bridge_session = switch_core_session_locate(bridge_uuid))) {
11537 switch_core_session_rwunlock(bridge_session);
11538 } else {
11539 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "could not locate partner_uuid %s, resetting\n", bridge_uuid);
11540 bridge_uuid = NULL;
11541 }
11542 }
11543
11544 if (call_info) {
11545 switch_event_t *event = NULL;
11546
11547 if (!zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) {
11548 const char *b_call_id = switch_channel_get_variable(b_channel, "sip_call_id");
11549
11550 if (b_call_id) {
11551 char *sql = switch_mprintf("update sip_dialogs set call_info_state='idle' where call_id='%q'", b_call_id);
11552 if (mod_sofia_globals.debug_sla > 1) {
11553 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
11554 }
11555 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
11556
11557 switch_channel_presence(b_channel, "unknown", "idle", NULL);
11558 }
11559 switch_channel_set_flag(tech_pvt->channel, CF_SLA_INTERCEPT);
11560 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
11561 "answer,intercept:%s", bridge_uuid);
11562
11563 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
11564 && sip && sip->sip_call_id
11565 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED) == SWITCH_STATUS_SUCCESS) {
11566 switch_channel_event_set_data(b_channel, event);
11567 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", sip->sip_call_id->i_id);
11568 switch_event_fire(&event);
11569 }
11570 } else {
11571 switch_caller_profile_t *bcp = switch_channel_get_caller_profile(b_channel);
11572
11573 if (switch_channel_test_flag(b_channel, CF_BRIDGE_ORIGINATOR)) {
11574 switch_channel_set_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR);
11575 }
11576
11577 if (!zstr(bcp->callee_id_name)) {
11578 tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->callee_id_name);
11579 }
11580
11581 if (!zstr(bcp->callee_id_number)) {
11582 tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->callee_id_number);
11583 }
11584
11585
11586 if (!zstr(bcp->caller_id_name)) {
11587 tech_pvt->caller_profile->caller_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->caller_id_name);
11588 }
11589
11590 if (!zstr(bcp->caller_id_number)) {
11591 tech_pvt->caller_profile->caller_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->caller_id_number);
11592 }
11593
11594 if (bcp->originatee_caller_profile) {
11595 switch_caller_profile_t *cp;
11596
11597 cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool,
11598 bcp->originatee_caller_profile);
11599
11600 switch_channel_set_originatee_caller_profile(tech_pvt->channel, cp);
11601 }
11602
11603 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
11604 "answer,sofia_sla:%s", uuid);
11605 }
11606 } else {
11607 char const *nightmare_xfer_uuid = NULL;
11608 switch_event_t *event = NULL;
11609 if (switch_channel_var_true(channel, "sip_replaces_a-leg")) {
11610 switch_channel_mark_hold(b_channel, SWITCH_FALSE);
11611 if (sip) {
11612 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", sip->sip_replaces->rp_call_id);
11613 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s picked up on a-leg\n", sip->sip_replaces->rp_call_id);
11614 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
11615 && sip->sip_call_id
11616 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED) == SWITCH_STATUS_SUCCESS) {
11617 switch_channel_event_set_data(b_channel, event);
11618 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id);
11619 switch_event_fire(&event);
11620 }
11621 }
11622 } else {
11623 if (sip) {
11624 if ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-For"))) {
11625 switch_channel_set_variable(b_channel, "transfer_refer_for", nightmare_xfer_uuid);
11626 }
11627 if ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-From"))) {
11628 switch_channel_set_variable(b_channel, "transfer_refer_from", nightmare_xfer_uuid);
11629 }
11630 }
11631
11632 if (!zstr(bridge_uuid)) {
11633 if (sip && sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id && switch_channel_test_flag(b_channel, CF_BRIDGED) &&
11634 switch_true(switch_find_parameter(*(sip->sip_replaces->rp_params), "early-only", switch_core_session_get_pool(session)))) {
11635 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercept rejected\n", bridge_uuid);
11636 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "hangup:CALL_REJECTED");
11637 } else {
11638 switch_channel_mark_hold(b_channel, SWITCH_FALSE);
11639 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid);
11640 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercepted\n", bridge_uuid);
11641 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
11642 && sip && sip->sip_call_id
11643 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED) == SWITCH_STATUS_SUCCESS) {
11644 switch_channel_event_set_data(b_channel, event);
11645 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id);
11646 switch_event_fire(&event);
11647 }
11648 }
11649 } else {
11650 const char *b_app = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_VARIABLE);
11651 const char *b_data = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE);
11652 if (b_data && b_app) {
11653 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s:%s", b_app, b_data);
11654 } else if (b_app) {
11655 tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s", b_app);
11656 }
11657 if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
11658 && sip && sip->sip_call_id
11659 && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED) == SWITCH_STATUS_SUCCESS) {
11660 switch_channel_event_set_data(b_channel, event);
11661 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", sip->sip_call_id->i_id);
11662 switch_event_fire(&event);
11663 }
11664 switch_channel_hangup(b_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
11665 }
11666 }
11667 }
11668
11669 }
11670
sofia_handle_sip_i_options(int status,char const * phrase,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[])11671 void sofia_handle_sip_i_options(int status,
11672 char const *phrase,
11673 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
11674 sofia_dispatch_event_t *de,
11675 tagi_t tags[])
11676 {
11677 uint32_t sess_count = switch_core_session_count();
11678 uint32_t sess_max = switch_core_session_limit(0);
11679
11680 if (sofia_test_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY) &&
11681 (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready_inbound())) {
11682 nua_respond(nh, 503, "Maximum Calls In Progress", NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
11683 } else {
11684 switch_assert(sip);
11685 nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg),
11686 TAG_IF(sip->sip_record_route, SIPTAG_RECORD_ROUTE(sip->sip_record_route)), TAG_END());
11687 }
11688
11689 }
11690
11691 /*
11692 * This subroutine will take the a_params of a sip_addr_s structure and spin through them.
11693 * Each param will be used to create a channel variable.
11694 * In the SIP RFC's, this data is called generic-param.
11695 * Note that the tag-param is also included in the a_params list.
11696 *
11697 * From: "John Doe" <sip:5551212@1.2.3.4>;tag=ed23266b52cbb17eo2;ref=101;mbid=201
11698 *
11699 * For example, the header above will produce an a_params list with three entries
11700 * tag=ed23266b52cbb17eo2
11701 * ref=101
11702 * mbid=201
11703 *
11704 * The a_params list is parsed and the lvalue is used to create the channel variable name while the
11705 * rvalue is used to create the channel variable value.
11706 *
11707 * If no equal (=) sign is found during parsing, a channel variable name is created with the param and
11708 * the value is set to NULL.
11709 *
11710 * Pointers are used for copying the sip_header_name for performance reasons. There are no calls to
11711 * any string functions and no memory is allocated/dealocated. The only limiter is the size of the
11712 * sip_header_name array.
11713 */
set_variable_sip_param(switch_channel_t * channel,char * header_type,sip_param_t const * params)11714 static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params)
11715 {
11716 char sip_header_name[128] = "";
11717 char var1[] = "sip_";
11718 char *cp, *sh, *sh_end, *sh_save;
11719
11720 /* Build the static part of the sip_header_name variable from */
11721 /* the header_type. If the header type is "referred_by" then */
11722 /* sip_header_name = "sip_referred_by_". */
11723 sh = sip_header_name;
11724 sh_end = sh + sizeof(sip_header_name) - 1;
11725 for (cp = var1; *cp; cp++, sh++) {
11726 *sh = *cp;
11727 }
11728 *sh = '\0';
11729
11730 /* Copy the header_type to the sip_header_name. Before copying */
11731 /* each character, check that we aren't going to overflow the */
11732 /* the sip_header_name buffer. We have to account for the */
11733 /* trailing underscore and NULL that will be added to the end. */
11734 for (cp = header_type; (*cp && (sh < (sh_end - 1))); cp++, sh++) {
11735 *sh = *cp;
11736 }
11737 *sh++ = '_';
11738 *sh = '\0';
11739
11740 /* sh now points to the NULL at the end of the partially built */
11741 /* sip_header_name variable. This is also the start of the */
11742 /* variable part of the sip_header_name built from the lvalue */
11743 /* of the params data. */
11744 sh_save = sh;
11745
11746 while (params && params[0]) {
11747
11748 /* Copy the params data to the sip_header_name variable until */
11749 /* the end of the params string is reached, an '=' is detected */
11750 /* or until the sip_header_name buffer has been exhausted. */
11751 for (cp = (char *) (*params); ((*cp != '=') && *cp && (sh < sh_end)); cp++, sh++) {
11752 *sh = *cp;
11753 }
11754
11755 /* cp now points to either the end of the params data or the */
11756 /* equal (=) sign separating the lvalue and rvalue. */
11757 if (*cp == '=')
11758 cp++;
11759 *sh = '\0';
11760 switch_channel_set_variable(channel, sip_header_name, cp);
11761
11762 /* Bump pointer to next param in the list. Also reset the */
11763 /* sip_header_name pointer to the beginning of the dynamic area */
11764 params++;
11765 sh = sh_save;
11766 }
11767 }
11768
11769 /* For Emacs:
11770 * Local Variables:
11771 * mode:c
11772 * indent-tabs-mode:t
11773 * tab-width:4
11774 * c-basic-offset:4
11775 * End:
11776 * For VIM:
11777 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
11778 */
11779