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 * Michael Jerris <mike@jerris.com>
28 *
29 *
30 * switch_channel.c -- Media Channel Interface
31 *
32 */
33
34 #include <switch.h>
35 #include <switch_channel.h>
36 #include <pcre.h>
37
38 struct switch_cause_table {
39 const char *name;
40 switch_call_cause_t cause;
41 };
42
43 typedef struct switch_device_state_binding_s {
44 switch_device_state_function_t function;
45 void *user_data;
46 struct switch_device_state_binding_s *next;
47 } switch_device_state_binding_t;
48
49 static struct {
50 switch_memory_pool_t *pool;
51 switch_hash_t *device_hash;
52 switch_mutex_t *device_mutex;
53 switch_device_state_binding_t *device_bindings;
54 } globals;
55
56 static struct switch_cause_table CAUSE_CHART[] = {
57 {"NONE", SWITCH_CAUSE_NONE},
58 {"UNALLOCATED_NUMBER", SWITCH_CAUSE_UNALLOCATED_NUMBER},
59 {"NO_ROUTE_TRANSIT_NET", SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET},
60 {"NO_ROUTE_DESTINATION", SWITCH_CAUSE_NO_ROUTE_DESTINATION},
61 {"CHANNEL_UNACCEPTABLE", SWITCH_CAUSE_CHANNEL_UNACCEPTABLE},
62 {"CALL_AWARDED_DELIVERED", SWITCH_CAUSE_CALL_AWARDED_DELIVERED},
63 {"NORMAL_CLEARING", SWITCH_CAUSE_NORMAL_CLEARING},
64 {"USER_BUSY", SWITCH_CAUSE_USER_BUSY},
65 {"NO_USER_RESPONSE", SWITCH_CAUSE_NO_USER_RESPONSE},
66 {"NO_ANSWER", SWITCH_CAUSE_NO_ANSWER},
67 {"SUBSCRIBER_ABSENT", SWITCH_CAUSE_SUBSCRIBER_ABSENT},
68 {"CALL_REJECTED", SWITCH_CAUSE_CALL_REJECTED},
69 {"NUMBER_CHANGED", SWITCH_CAUSE_NUMBER_CHANGED},
70 {"REDIRECTION_TO_NEW_DESTINATION", SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION},
71 {"EXCHANGE_ROUTING_ERROR", SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR},
72 {"DESTINATION_OUT_OF_ORDER", SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER},
73 {"INVALID_NUMBER_FORMAT", SWITCH_CAUSE_INVALID_NUMBER_FORMAT},
74 {"FACILITY_REJECTED", SWITCH_CAUSE_FACILITY_REJECTED},
75 {"RESPONSE_TO_STATUS_ENQUIRY", SWITCH_CAUSE_RESPONSE_TO_STATUS_ENQUIRY},
76 {"NORMAL_UNSPECIFIED", SWITCH_CAUSE_NORMAL_UNSPECIFIED},
77 {"NORMAL_CIRCUIT_CONGESTION", SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION},
78 {"NETWORK_OUT_OF_ORDER", SWITCH_CAUSE_NETWORK_OUT_OF_ORDER},
79 {"NORMAL_TEMPORARY_FAILURE", SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE},
80 {"SWITCH_CONGESTION", SWITCH_CAUSE_SWITCH_CONGESTION},
81 {"ACCESS_INFO_DISCARDED", SWITCH_CAUSE_ACCESS_INFO_DISCARDED},
82 {"REQUESTED_CHAN_UNAVAIL", SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL},
83 {"PRE_EMPTED", SWITCH_CAUSE_PRE_EMPTED},
84 {"FACILITY_NOT_SUBSCRIBED", SWITCH_CAUSE_FACILITY_NOT_SUBSCRIBED},
85 {"OUTGOING_CALL_BARRED", SWITCH_CAUSE_OUTGOING_CALL_BARRED},
86 {"INCOMING_CALL_BARRED", SWITCH_CAUSE_INCOMING_CALL_BARRED},
87 {"BEARERCAPABILITY_NOTAUTH", SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH},
88 {"BEARERCAPABILITY_NOTAVAIL", SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL},
89 {"SERVICE_UNAVAILABLE", SWITCH_CAUSE_SERVICE_UNAVAILABLE},
90 {"BEARERCAPABILITY_NOTIMPL", SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL},
91 {"CHAN_NOT_IMPLEMENTED", SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED},
92 {"FACILITY_NOT_IMPLEMENTED", SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED},
93 {"SERVICE_NOT_IMPLEMENTED", SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED},
94 {"INVALID_CALL_REFERENCE", SWITCH_CAUSE_INVALID_CALL_REFERENCE},
95 {"INCOMPATIBLE_DESTINATION", SWITCH_CAUSE_INCOMPATIBLE_DESTINATION},
96 {"INVALID_MSG_UNSPECIFIED", SWITCH_CAUSE_INVALID_MSG_UNSPECIFIED},
97 {"MANDATORY_IE_MISSING", SWITCH_CAUSE_MANDATORY_IE_MISSING},
98 {"MESSAGE_TYPE_NONEXIST", SWITCH_CAUSE_MESSAGE_TYPE_NONEXIST},
99 {"WRONG_MESSAGE", SWITCH_CAUSE_WRONG_MESSAGE},
100 {"IE_NONEXIST", SWITCH_CAUSE_IE_NONEXIST},
101 {"INVALID_IE_CONTENTS", SWITCH_CAUSE_INVALID_IE_CONTENTS},
102 {"WRONG_CALL_STATE", SWITCH_CAUSE_WRONG_CALL_STATE},
103 {"RECOVERY_ON_TIMER_EXPIRE", SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE},
104 {"MANDATORY_IE_LENGTH_ERROR", SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR},
105 {"PROTOCOL_ERROR", SWITCH_CAUSE_PROTOCOL_ERROR},
106 {"INTERWORKING", SWITCH_CAUSE_INTERWORKING},
107 {"SUCCESS", SWITCH_CAUSE_SUCCESS},
108 {"ORIGINATOR_CANCEL", SWITCH_CAUSE_ORIGINATOR_CANCEL},
109 {"CRASH", SWITCH_CAUSE_CRASH},
110 {"SYSTEM_SHUTDOWN", SWITCH_CAUSE_SYSTEM_SHUTDOWN},
111 {"LOSE_RACE", SWITCH_CAUSE_LOSE_RACE},
112 {"MANAGER_REQUEST", SWITCH_CAUSE_MANAGER_REQUEST},
113 {"BLIND_TRANSFER", SWITCH_CAUSE_BLIND_TRANSFER},
114 {"ATTENDED_TRANSFER", SWITCH_CAUSE_ATTENDED_TRANSFER},
115 {"ALLOTTED_TIMEOUT", SWITCH_CAUSE_ALLOTTED_TIMEOUT},
116 {"USER_CHALLENGE", SWITCH_CAUSE_USER_CHALLENGE},
117 {"MEDIA_TIMEOUT", SWITCH_CAUSE_MEDIA_TIMEOUT},
118 {"PICKED_OFF", SWITCH_CAUSE_PICKED_OFF},
119 {"USER_NOT_REGISTERED", SWITCH_CAUSE_USER_NOT_REGISTERED},
120 {"PROGRESS_TIMEOUT", SWITCH_CAUSE_PROGRESS_TIMEOUT},
121 {"INVALID_GATEWAY", SWITCH_CAUSE_INVALID_GATEWAY},
122 {"GATEWAY_DOWN", SWITCH_CAUSE_GATEWAY_DOWN},
123 {"INVALID_URL", SWITCH_CAUSE_INVALID_URL},
124 {"INVALID_PROFILE", SWITCH_CAUSE_INVALID_PROFILE},
125 {"NO_PICKUP", SWITCH_CAUSE_NO_PICKUP},
126 {"SRTP_READ_ERROR", SWITCH_CAUSE_SRTP_READ_ERROR},
127 {"BOWOUT", SWITCH_CAUSE_BOWOUT},
128 {"BUSY_EVERYWHERE", SWITCH_CAUSE_BUSY_EVERYWHERE},
129 {"DECLINE", SWITCH_CAUSE_DECLINE},
130 {"DOES_NOT_EXIST_ANYWHERE", SWITCH_CAUSE_DOES_NOT_EXIST_ANYWHERE},
131 {"NOT_ACCEPTABLE", SWITCH_CAUSE_NOT_ACCEPTABLE},
132 {"UNWANTED", SWITCH_CAUSE_UNWANTED},
133 {NULL, 0}
134 };
135
136 typedef enum {
137 OCF_HANGUP = (1 << 0)
138 } opaque_channel_flag_t;
139
140 typedef enum {
141 LP_NEITHER,
142 LP_ORIGINATOR,
143 LP_ORIGINATEE
144 } switch_originator_type_t;
145
146 struct switch_channel {
147 char *name;
148 switch_call_direction_t direction;
149 switch_call_direction_t logical_direction;
150 switch_queue_t *dtmf_queue;
151 switch_queue_t *dtmf_log_queue;
152 switch_mutex_t*dtmf_mutex;
153 switch_mutex_t *flag_mutex;
154 switch_mutex_t *state_mutex;
155 switch_mutex_t *thread_mutex;
156 switch_mutex_t *profile_mutex;
157 switch_core_session_t *session;
158 switch_channel_state_t state;
159 switch_channel_state_t running_state;
160 switch_channel_callstate_t callstate;
161 uint32_t flags[CF_FLAG_MAX];
162 uint32_t caps[CC_FLAG_MAX];
163 uint8_t state_flags[CF_FLAG_MAX];
164 uint32_t private_flags;
165 switch_caller_profile_t *caller_profile;
166 const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
167 int state_handler_index;
168 switch_event_t *variables;
169 switch_event_t *scope_variables;
170 switch_hash_t *private_hash;
171 switch_hash_t *app_flag_hash;
172 switch_call_cause_t hangup_cause;
173 int vi;
174 int event_count;
175 int profile_index;
176 opaque_channel_flag_t opaque_flags;
177 switch_originator_type_t last_profile_type;
178 switch_caller_extension_t *queued_extension;
179 switch_event_t *app_list;
180 switch_event_t *api_list;
181 switch_event_t *var_list;
182 switch_hold_record_t *hold_record;
183 switch_device_node_t *device_node;
184 char *device_id;
185 switch_event_t *log_tags;
186 };
187
188 static void process_device_hup(switch_channel_t *channel);
189 static void switch_channel_check_device_state(switch_channel_t *channel, switch_channel_callstate_t callstate);
190
switch_channel_get_hold_record(switch_channel_t * channel)191 SWITCH_DECLARE(switch_hold_record_t *) switch_channel_get_hold_record(switch_channel_t *channel)
192 {
193 return channel->hold_record;
194 }
195
switch_channel_cause2str(switch_call_cause_t cause)196 SWITCH_DECLARE(const char *) switch_channel_cause2str(switch_call_cause_t cause)
197 {
198 uint8_t x;
199 const char *str = "UNKNOWN";
200
201 for (x = 0; x < (sizeof(CAUSE_CHART) / sizeof(struct switch_cause_table)) - 1; x++) {
202 if (CAUSE_CHART[x].cause == cause) {
203 str = CAUSE_CHART[x].name;
204 break;
205 }
206 }
207
208 return str;
209 }
210
switch_channel_str2cause(const char * str)211 SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2cause(const char *str)
212 {
213 uint8_t x;
214 switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
215
216 if (!zstr(str)) {
217 if (*str > 47 && *str < 58) {
218 cause = atoi(str);
219 } else {
220 for (x = 0; x < (sizeof(CAUSE_CHART) / sizeof(struct switch_cause_table)) - 1 && CAUSE_CHART[x].name; x++) {
221 if (!strcasecmp(CAUSE_CHART[x].name, str)) {
222 cause = CAUSE_CHART[x].cause;
223 break;
224 }
225 }
226 }
227 }
228
229 return cause;
230 }
231
switch_channel_get_cause(switch_channel_t * channel)232 SWITCH_DECLARE(switch_call_cause_t) switch_channel_get_cause(switch_channel_t *channel)
233 {
234 return channel->hangup_cause;
235 }
236
237
switch_channel_get_cause_ptr(switch_channel_t * channel)238 SWITCH_DECLARE(switch_call_cause_t *) switch_channel_get_cause_ptr(switch_channel_t *channel)
239 {
240 return &channel->hangup_cause;
241 }
242
243
244 struct switch_callstate_table {
245 const char *name;
246 switch_channel_callstate_t callstate;
247 };
248 static struct switch_callstate_table CALLSTATE_CHART[] = {
249 {"DOWN", CCS_DOWN},
250 {"DIALING", CCS_DIALING},
251 {"RINGING", CCS_RINGING},
252 {"EARLY", CCS_EARLY},
253 {"ACTIVE", CCS_ACTIVE},
254 {"HELD", CCS_HELD},
255 {"RING_WAIT", CCS_RING_WAIT},
256 {"HANGUP", CCS_HANGUP},
257 {"UNHELD", CCS_UNHELD},
258 {NULL, 0}
259 };
260
261 struct switch_device_state_table {
262 const char *name;
263 switch_device_state_t device_state;
264 };
265 static struct switch_device_state_table DEVICE_STATE_CHART[] = {
266 {"DOWN", SDS_DOWN},
267 {"RINGING", SDS_RINGING},
268 {"ACTIVE", SDS_ACTIVE},
269 {"ACTIVE_MULTI", SDS_ACTIVE_MULTI},
270 {"HELD", SDS_HELD},
271 {"UNHELD", SDS_UNHELD},
272 {"HANGUP", SDS_HANGUP},
273 {NULL, 0}
274 };
275
276
switch_channel_perform_set_callstate(switch_channel_t * channel,switch_channel_callstate_t callstate,const char * file,const char * func,int line)277 SWITCH_DECLARE(void) switch_channel_perform_set_callstate(switch_channel_t *channel, switch_channel_callstate_t callstate,
278 const char *file, const char *func, int line)
279 {
280 switch_event_t *event;
281 switch_channel_callstate_t o_callstate = channel->callstate;
282
283 if (o_callstate == callstate || o_callstate == CCS_HANGUP) return;
284
285 channel->callstate = callstate;
286 if (channel->device_node) {
287 channel->device_node->callstate = callstate;
288 }
289 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG,
290 "(%s) Callstate Change %s -> %s\n", channel->name,
291 switch_channel_callstate2str(o_callstate), switch_channel_callstate2str(callstate));
292
293 switch_channel_check_device_state(channel, channel->callstate);
294
295 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_CALLSTATE) == SWITCH_STATUS_SUCCESS) {
296 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Original-Channel-Call-State", switch_channel_callstate2str(o_callstate));
297 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Call-State-Number", "%d", callstate);
298 switch_channel_event_set_data(channel, event);
299 switch_event_fire(&event);
300 }
301 }
302
switch_channel_get_callstate(switch_channel_t * channel)303 SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_get_callstate(switch_channel_t *channel)
304 {
305 return channel->callstate;
306 }
307
308
switch_channel_callstate2str(switch_channel_callstate_t callstate)309 SWITCH_DECLARE(const char *) switch_channel_callstate2str(switch_channel_callstate_t callstate)
310 {
311 uint8_t x;
312 const char *str = "UNKNOWN";
313
314 for (x = 0; x < (sizeof(CALLSTATE_CHART) / sizeof(struct switch_cause_table)) - 1; x++) {
315 if (CALLSTATE_CHART[x].callstate == callstate) {
316 str = CALLSTATE_CHART[x].name;
317 break;
318 }
319 }
320
321 return str;
322 }
323
switch_channel_device_state2str(switch_device_state_t device_state)324 SWITCH_DECLARE(const char *) switch_channel_device_state2str(switch_device_state_t device_state)
325 {
326 uint8_t x;
327 const char *str = "UNKNOWN";
328
329 for (x = 0; x < (sizeof(DEVICE_STATE_CHART) / sizeof(struct switch_cause_table)) - 1; x++) {
330 if (DEVICE_STATE_CHART[x].device_state == device_state) {
331 str = DEVICE_STATE_CHART[x].name;
332 break;
333 }
334 }
335
336 return str;
337 }
338
339
switch_channel_str2callstate(const char * str)340 SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_str2callstate(const char *str)
341 {
342 uint8_t x;
343 switch_channel_callstate_t callstate = (switch_channel_callstate_t) SWITCH_CAUSE_NONE;
344
345 if (*str > 47 && *str < 58) {
346 callstate = atoi(str);
347 } else {
348 for (x = 0; x < (sizeof(CALLSTATE_CHART) / sizeof(struct switch_callstate_table)) - 1 && CALLSTATE_CHART[x].name; x++) {
349 if (!strcasecmp(CALLSTATE_CHART[x].name, str)) {
350 callstate = CALLSTATE_CHART[x].callstate;
351 break;
352 }
353 }
354 }
355 return callstate;
356 }
357
358
359
switch_channel_perform_audio_sync(switch_channel_t * channel,const char * file,const char * func,int line)360 SWITCH_DECLARE(void) switch_channel_perform_audio_sync(switch_channel_t *channel, const char *file, const char *func, int line)
361 {
362 if (switch_channel_media_up(channel)) {
363 switch_core_session_message_t *msg = NULL;
364
365 msg = switch_core_session_alloc(channel->session, sizeof(*msg));
366 MESSAGE_STAMP_FFL(msg);
367 msg->message_id = SWITCH_MESSAGE_INDICATE_AUDIO_SYNC;
368 msg->from = channel->name;
369 msg->_file = file;
370 msg->_func = func;
371 msg->_line = line;
372
373 switch_core_session_queue_message(channel->session, msg);
374 }
375 }
376
377
switch_channel_perform_video_sync(switch_channel_t * channel,const char * file,const char * func,int line)378 SWITCH_DECLARE(void) switch_channel_perform_video_sync(switch_channel_t *channel, const char *file, const char *func, int line)
379 {
380
381 if (switch_channel_media_up(channel)) {
382 switch_core_session_message_t *msg = NULL;
383
384 msg = switch_core_session_alloc(channel->session, sizeof(*msg));
385 MESSAGE_STAMP_FFL(msg);
386 msg->message_id = SWITCH_MESSAGE_INDICATE_VIDEO_SYNC;
387 msg->from = channel->name;
388 msg->_file = file;
389 msg->_func = func;
390 msg->_line = line;
391
392 switch_core_session_request_video_refresh(channel->session);
393 switch_core_session_queue_message(channel->session, msg);
394 }
395 }
396
397
398
switch_channel_cause_q850(switch_call_cause_t cause)399 SWITCH_DECLARE(switch_call_cause_t) switch_channel_cause_q850(switch_call_cause_t cause)
400 {
401 if (cause <= SWITCH_CAUSE_INTERWORKING) {
402 return cause;
403 } else {
404 return SWITCH_CAUSE_NORMAL_CLEARING;
405 }
406 }
407
switch_channel_get_cause_q850(switch_channel_t * channel)408 SWITCH_DECLARE(switch_call_cause_t) switch_channel_get_cause_q850(switch_channel_t *channel)
409 {
410 return switch_channel_cause_q850(channel->hangup_cause);
411 }
412
switch_channel_get_timetable(switch_channel_t * channel)413 SWITCH_DECLARE(switch_channel_timetable_t *) switch_channel_get_timetable(switch_channel_t *channel)
414 {
415 switch_channel_timetable_t *times = NULL;
416
417 if (channel->caller_profile) {
418 switch_mutex_lock(channel->profile_mutex);
419 times = channel->caller_profile->times;
420 switch_mutex_unlock(channel->profile_mutex);
421 }
422
423 return times;
424 }
425
switch_channel_set_direction(switch_channel_t * channel,switch_call_direction_t direction)426 SWITCH_DECLARE(void) switch_channel_set_direction(switch_channel_t *channel, switch_call_direction_t direction)
427 {
428 if (!switch_core_session_in_thread(channel->session)) {
429 channel->direction = channel->logical_direction = direction;
430 switch_channel_set_variable(channel, "direction", switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
431 }
432 }
433
switch_channel_direction(switch_channel_t * channel)434 SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel)
435 {
436 return channel->direction;
437 }
438
switch_channel_logical_direction(switch_channel_t * channel)439 SWITCH_DECLARE(switch_call_direction_t) switch_channel_logical_direction(switch_channel_t *channel)
440 {
441 return channel->logical_direction;
442 }
443
switch_channel_alloc(switch_channel_t ** channel,switch_call_direction_t direction,switch_memory_pool_t * pool)444 SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_call_direction_t direction, switch_memory_pool_t *pool)
445 {
446 switch_assert(pool != NULL);
447
448 if (((*channel) = switch_core_alloc(pool, sizeof(switch_channel_t))) == 0) {
449 return SWITCH_STATUS_MEMERR;
450 }
451
452 switch_event_create_plain(&(*channel)->variables, SWITCH_EVENT_CHANNEL_DATA);
453
454 switch_core_hash_init(&(*channel)->private_hash);
455 switch_queue_create(&(*channel)->dtmf_queue, SWITCH_DTMF_LOG_LEN, pool);
456 switch_queue_create(&(*channel)->dtmf_log_queue, SWITCH_DTMF_LOG_LEN, pool);
457
458 switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool);
459 switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool);
460 switch_mutex_init(&(*channel)->state_mutex, SWITCH_MUTEX_NESTED, pool);
461 switch_mutex_init(&(*channel)->thread_mutex, SWITCH_MUTEX_NESTED, pool);
462 switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool);
463 (*channel)->hangup_cause = SWITCH_CAUSE_NONE;
464 (*channel)->name = "";
465 (*channel)->direction = (*channel)->logical_direction = direction;
466 switch_channel_set_variable(*channel, "direction", switch_channel_direction(*channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
467
468 return SWITCH_STATUS_SUCCESS;
469 }
470
switch_channel_dtmf_lock(switch_channel_t * channel)471 SWITCH_DECLARE(switch_status_t) switch_channel_dtmf_lock(switch_channel_t *channel)
472 {
473 return switch_mutex_lock(channel->dtmf_mutex);
474 }
475
switch_channel_try_dtmf_lock(switch_channel_t * channel)476 SWITCH_DECLARE(switch_status_t) switch_channel_try_dtmf_lock(switch_channel_t *channel)
477 {
478 return switch_mutex_trylock(channel->dtmf_mutex);
479 }
480
switch_channel_dtmf_unlock(switch_channel_t * channel)481 SWITCH_DECLARE(switch_status_t) switch_channel_dtmf_unlock(switch_channel_t *channel)
482 {
483 return switch_mutex_unlock(channel->dtmf_mutex);
484 }
485
switch_channel_has_dtmf(switch_channel_t * channel)486 SWITCH_DECLARE(switch_size_t) switch_channel_has_dtmf(switch_channel_t *channel)
487 {
488 switch_size_t has;
489
490 switch_mutex_lock(channel->dtmf_mutex);
491 has = switch_queue_size(channel->dtmf_queue);
492 switch_mutex_unlock(channel->dtmf_mutex);
493
494 return has;
495 }
496
switch_channel_queue_dtmf(switch_channel_t * channel,const switch_dtmf_t * dtmf)497 SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *channel, const switch_dtmf_t *dtmf)
498 {
499 switch_status_t status;
500 void *pop;
501 switch_dtmf_t new_dtmf = { 0 };
502 switch_bool_t sensitive = switch_true(switch_channel_get_variable_dup(channel, SWITCH_SENSITIVE_DTMF_VARIABLE, SWITCH_FALSE, -1));
503
504 switch_assert(dtmf);
505
506 switch_mutex_lock(channel->dtmf_mutex);
507 new_dtmf = *dtmf;
508
509 if (sensitive) {
510 switch_set_flag((&new_dtmf), DTMF_FLAG_SENSITIVE);
511 }
512
513 if ((status = switch_core_session_recv_dtmf(channel->session, dtmf) != SWITCH_STATUS_SUCCESS)) {
514 goto done;
515 }
516
517 if (is_dtmf(new_dtmf.digit)) {
518 switch_dtmf_t *dt;
519 int x = 0;
520
521 if (!sensitive) {
522 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_INFO, "RECV DTMF %c:%d\n", new_dtmf.digit, new_dtmf.duration);
523 }
524
525 if (new_dtmf.digit != 'w' && new_dtmf.digit != 'W') {
526 if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
527 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s EXCESSIVE DTMF DIGIT LEN [%d]\n",
528 switch_channel_get_name(channel), new_dtmf.duration);
529 new_dtmf.duration = switch_core_max_dtmf_duration(0);
530 } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) {
531 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s SHORT DTMF DIGIT LEN [%d]\n",
532 switch_channel_get_name(channel), new_dtmf.duration);
533 new_dtmf.duration = switch_core_min_dtmf_duration(0);
534 }
535 }
536
537 if (!new_dtmf.duration) {
538 new_dtmf.duration = switch_core_default_dtmf_duration(0);
539 }
540
541
542 switch_zmalloc(dt, sizeof(*dt));
543 *dt = new_dtmf;
544
545
546 while (switch_queue_trypush(channel->dtmf_queue, dt) != SWITCH_STATUS_SUCCESS) {
547 if (switch_queue_trypop(channel->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) {
548 free(pop);
549 }
550 if (++x > 100) {
551 status = SWITCH_STATUS_FALSE;
552 free(dt);
553 goto done;
554 }
555 }
556 }
557
558 status = SWITCH_STATUS_SUCCESS;
559
560 done:
561
562 switch_mutex_unlock(channel->dtmf_mutex);
563
564 switch_core_media_break(channel->session, SWITCH_MEDIA_TYPE_AUDIO);
565
566 return status;
567 }
568
switch_channel_queue_dtmf_string(switch_channel_t * channel,const char * dtmf_string)569 SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf_string(switch_channel_t *channel, const char *dtmf_string)
570 {
571 char *p;
572 switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), 0, SWITCH_DTMF_APP };
573 int sent = 0, dur, bad_input = 0;
574 char *string;
575 int i, argc;
576 char *argv[256];
577
578 if (zstr(dtmf_string)) {
579 return SWITCH_STATUS_GENERR;
580 }
581
582
583 dtmf.flags = DTMF_FLAG_SKIP_PROCESS;
584
585 if (*dtmf_string == '~') {
586 dtmf_string++;
587 dtmf.flags = 0;
588 }
589
590 string = switch_core_session_strdup(channel->session, dtmf_string);
591 argc = switch_separate_string(string, '+', argv, (sizeof(argv) / sizeof(argv[0])));
592
593 for (i = 0; i < argc; i++) {
594 dtmf.duration = switch_core_default_dtmf_duration(0);
595 dur = switch_core_default_dtmf_duration(0) / 8;
596 if ((p = strchr(argv[i], '@'))) {
597 *p++ = '\0';
598 if ((dur = atoi(p)) > (int)switch_core_min_dtmf_duration(0) / 8) {
599 dtmf.duration = dur * 8;
600 }
601 }
602
603 for (p = argv[i]; p && *p; p++) {
604 if (is_dtmf(*p)) {
605 dtmf.digit = *p;
606
607 if (dtmf.duration > switch_core_max_dtmf_duration(0)) {
608 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "EXCESSIVE DTMF DIGIT LEN %c %d\n", dtmf.digit, dtmf.duration);
609 dtmf.duration = switch_core_max_dtmf_duration(0);
610 } else if (dtmf.duration < switch_core_min_dtmf_duration(0)) {
611 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "SHORT DTMF DIGIT LEN %c %d\n", dtmf.digit, dtmf.duration);
612 dtmf.duration = switch_core_min_dtmf_duration(0);
613 } else if (!dtmf.duration) {
614 dtmf.duration = switch_core_default_dtmf_duration(0);
615 }
616
617 if (switch_channel_queue_dtmf(channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
618 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s Queue dtmf\ndigit=%c ms=%u samples=%u\n",
619 switch_channel_get_name(channel), dtmf.digit, dur, dtmf.duration);
620 sent++;
621 }
622 } else {
623 bad_input++;
624 }
625 }
626
627 }
628 if (sent) {
629 return SWITCH_STATUS_SUCCESS;
630 }
631 return bad_input ? SWITCH_STATUS_GENERR : SWITCH_STATUS_FALSE;
632 }
633
switch_channel_dequeue_dtmf(switch_channel_t * channel,switch_dtmf_t * dtmf)634 SWITCH_DECLARE(switch_status_t) switch_channel_dequeue_dtmf(switch_channel_t *channel, switch_dtmf_t *dtmf)
635 {
636 switch_event_t *event;
637 void *pop;
638 switch_dtmf_t *dt;
639 switch_status_t status = SWITCH_STATUS_FALSE;
640 int sensitive = 0;
641
642 switch_mutex_lock(channel->dtmf_mutex);
643
644 if (switch_queue_trypop(channel->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) {
645 dt = (switch_dtmf_t *) pop;
646 *dtmf = *dt;
647 sensitive = switch_test_flag(dtmf, DTMF_FLAG_SENSITIVE);
648
649 if (!sensitive && switch_queue_trypush(channel->dtmf_log_queue, dt) != SWITCH_STATUS_SUCCESS) {
650 free(dt);
651 }
652
653 dt = NULL;
654
655 if (dtmf->duration > switch_core_max_dtmf_duration(0)) {
656 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
657 switch_channel_get_name(channel), sensitive ? 'S' : dtmf->digit, dtmf->duration);
658 dtmf->duration = switch_core_max_dtmf_duration(0);
659 } else if (dtmf->duration < switch_core_min_dtmf_duration(0)) {
660 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
661 switch_channel_get_name(channel), sensitive ? 'S' : dtmf->digit, dtmf->duration);
662 dtmf->duration = switch_core_min_dtmf_duration(0);
663 } else if (!dtmf->duration) {
664 dtmf->duration = switch_core_default_dtmf_duration(0);
665 }
666
667 status = SWITCH_STATUS_SUCCESS;
668 }
669 switch_mutex_unlock(channel->dtmf_mutex);
670
671 if (!sensitive && status == SWITCH_STATUS_SUCCESS && switch_event_create(&event, SWITCH_EVENT_DTMF) == SWITCH_STATUS_SUCCESS) {
672 const char *dtmf_source_str = NULL;
673 switch_channel_event_set_data(channel, event);
674 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Digit", "%c", dtmf->digit);
675 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Duration", "%u", dtmf->duration);
676 switch(dtmf->source) {
677 case SWITCH_DTMF_INBAND_AUDIO: /* From audio */
678 dtmf_source_str = "INBAND_AUDIO";
679 break;
680 case SWITCH_DTMF_RTP: /* From RTP as a telephone event */
681 dtmf_source_str = "RTP";
682 break;
683 case SWITCH_DTMF_ENDPOINT: /* From endpoint signaling */
684 dtmf_source_str = "ENDPOINT";
685 break;
686 case SWITCH_DTMF_APP: /* Injected by application */
687 dtmf_source_str = "APP";
688 break;
689 case SWITCH_DTMF_UNKNOWN: /* Unknown source */
690 default:
691 dtmf_source_str = "UNKNOWN";
692 break;
693 }
694 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Source", "%s", dtmf_source_str);
695 if (switch_channel_test_flag(channel, CF_DIVERT_EVENTS)) {
696 switch_core_session_queue_event(channel->session, &event);
697 } else {
698 switch_event_fire(&event);
699 }
700 }
701
702 return status;
703 }
704
switch_channel_dequeue_dtmf_string(switch_channel_t * channel,char * dtmf_str,switch_size_t len)705 SWITCH_DECLARE(switch_size_t) switch_channel_dequeue_dtmf_string(switch_channel_t *channel, char *dtmf_str, switch_size_t len)
706 {
707 switch_size_t x = 0;
708 switch_dtmf_t dtmf = { 0 };
709
710 memset(dtmf_str, 0, len);
711
712 while (x < len - 1 && switch_channel_dequeue_dtmf(channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
713 dtmf_str[x++] = dtmf.digit;
714 }
715
716 return x;
717
718 }
719
switch_channel_flush_dtmf(switch_channel_t * channel)720 SWITCH_DECLARE(void) switch_channel_flush_dtmf(switch_channel_t *channel)
721 {
722 void *pop;
723
724 switch_mutex_lock(channel->dtmf_mutex);
725 while (switch_queue_trypop(channel->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) {
726 switch_dtmf_t *dt = (switch_dtmf_t *) pop;
727 if (channel->state >= CS_HANGUP || switch_queue_trypush(channel->dtmf_log_queue, dt) != SWITCH_STATUS_SUCCESS) {
728 free(dt);
729 }
730 }
731 switch_mutex_unlock(channel->dtmf_mutex);
732 }
733
switch_channel_uninit(switch_channel_t * channel)734 SWITCH_DECLARE(void) switch_channel_uninit(switch_channel_t *channel)
735 {
736 void *pop;
737 switch_channel_flush_dtmf(channel);
738 while (switch_queue_trypop(channel->dtmf_log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
739 switch_safe_free(pop);
740 }
741
742 if (channel->private_hash) {
743 switch_core_hash_destroy(&channel->private_hash);
744 }
745
746 if (channel->app_flag_hash) {
747 switch_core_hash_destroy(&channel->app_flag_hash);
748 }
749
750 switch_mutex_lock(channel->profile_mutex);
751 switch_event_destroy(&channel->variables);
752 switch_event_destroy(&channel->api_list);
753 switch_event_destroy(&channel->var_list);
754 switch_event_destroy(&channel->app_list);
755 if (channel->log_tags) {
756 switch_event_destroy(&channel->log_tags);
757 }
758 switch_mutex_unlock(channel->profile_mutex);
759 }
760
switch_channel_init(switch_channel_t * channel,switch_core_session_t * session,switch_channel_state_t state,switch_channel_flag_t flag)761 SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel, switch_core_session_t *session, switch_channel_state_t state,
762 switch_channel_flag_t flag)
763 {
764 switch_assert(channel != NULL);
765 channel->state = state;
766 switch_channel_set_flag(channel, flag);
767 channel->session = session;
768 channel->running_state = CS_NONE;
769 return SWITCH_STATUS_SUCCESS;
770 }
771
switch_channel_perform_presence(switch_channel_t * channel,const char * rpid,const char * status,const char * id,const char * file,const char * func,int line)772 SWITCH_DECLARE(void) switch_channel_perform_presence(switch_channel_t *channel, const char *rpid, const char *status, const char *id,
773 const char *file, const char *func, int line)
774 {
775 switch_event_t *event;
776 switch_event_types_t type = SWITCH_EVENT_PRESENCE_IN;
777 const char *call_info = NULL;
778 char *call_info_state = "active";
779
780 if (switch_channel_test_flag(channel, CF_NO_PRESENCE)) {
781 return;
782 }
783
784 if (!status) {
785 type = SWITCH_EVENT_PRESENCE_OUT;
786 status = "idle";
787 }
788
789 if (!id) {
790 id = switch_channel_get_variable(channel, "presence_id");
791 }
792
793 if (!id) {
794 return;
795 }
796
797 call_info = switch_channel_get_variable(channel, "presence_call_info");
798
799 if (switch_event_create(&event, type) == SWITCH_STATUS_SUCCESS) {
800 switch_channel_event_set_data(channel, event);
801 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "any");
802 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", __FILE__);
803 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", id);
804 if (type == SWITCH_EVENT_PRESENCE_IN) {
805 if (!rpid) {
806 rpid = "unknown";
807 }
808 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
809 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
810 }
811 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
812 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
813
814
815 if (!strcasecmp(status, "idle") || !switch_channel_up_nosig(channel)) {
816 call_info_state = "idle";
817 } else if (!strcasecmp(status, "hold-private")) {
818 call_info_state = "held-private";
819 } else if (!strcasecmp(status, "hold")) {
820 call_info_state = "held";
821 } else if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
822 if (channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND) {
823 call_info_state = "progressing";
824 } else {
825 if (switch_channel_test_flag(channel, CF_SLA_INTERCEPT)) {
826 call_info_state = "idle";
827 } else {
828 call_info_state = "alerting";
829 }
830 }
831 }
832
833 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-call-info-state", call_info_state);
834
835 if (call_info) {
836 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-call-info", call_info);
837 }
838
839 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-call-direction",
840 channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
841
842 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", channel->event_count++);
843 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Calling-File", file);
844 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Calling-Function", func);
845 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Presence-Calling-Line", "%d", line);
846
847 if (switch_true(switch_channel_get_variable(channel, "presence_privacy"))) {
848 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Privacy", "true");
849 }
850
851 switch_event_fire(&event);
852 }
853 }
854
switch_channel_mark_hold(switch_channel_t * channel,switch_bool_t on)855 SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_bool_t on)
856 {
857 switch_event_t *event;
858
859 if (!!on == !!switch_channel_test_flag(channel, CF_LEG_HOLDING)) {
860 goto end;
861 }
862
863 if (on) {
864 switch_channel_set_flag(channel, CF_LEG_HOLDING);
865 } else {
866 switch_channel_clear_flag(channel, CF_LEG_HOLDING);
867 }
868
869 if (switch_event_create(&event, on ? SWITCH_EVENT_CHANNEL_HOLD : SWITCH_EVENT_CHANNEL_UNHOLD) == SWITCH_STATUS_SUCCESS) {
870 switch_channel_event_set_data(channel, event);
871 switch_event_fire(&event);
872 }
873
874 end:
875
876 if (on) {
877 if (switch_true(switch_channel_get_variable(channel, "flip_record_on_hold"))) {
878 switch_core_session_t *other_session;
879 if (switch_core_session_get_partner(channel->session, &other_session) == SWITCH_STATUS_SUCCESS) {
880 switch_ivr_transfer_recordings(channel->session, other_session);
881 switch_core_session_rwunlock(other_session);
882 }
883 }
884 }
885
886 }
887
switch_channel_get_hold_music(switch_channel_t * channel)888 SWITCH_DECLARE(const char *) switch_channel_get_hold_music(switch_channel_t *channel)
889 {
890 const char *var;
891
892 if (!(var = switch_channel_get_variable(channel, SWITCH_TEMP_HOLD_MUSIC_VARIABLE))) {
893 var = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE);
894 }
895
896 if (!zstr(var)) {
897 char *expanded = switch_channel_expand_variables(channel, var);
898
899 if (expanded != var) {
900 var = switch_core_session_strdup(channel->session, expanded);
901 free(expanded);
902 }
903 }
904
905
906 return var;
907 }
908
switch_channel_get_hold_music_partner(switch_channel_t * channel)909 SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channel_t *channel)
910 {
911 switch_core_session_t *session;
912 const char *r = NULL;
913
914 if (switch_core_session_get_partner(channel->session, &session) == SWITCH_STATUS_SUCCESS) {
915 r = switch_channel_get_hold_music(switch_core_session_get_channel(session));
916 switch_core_session_rwunlock(session);
917 }
918
919 return r;
920 }
921
switch_channel_set_scope_variables(switch_channel_t * channel,switch_event_t ** event)922 SWITCH_DECLARE(void) switch_channel_set_scope_variables(switch_channel_t *channel, switch_event_t **event)
923 {
924 switch_mutex_lock(channel->profile_mutex);
925
926 if (event && *event) { /* push */
927 (*event)->next = channel->scope_variables;
928 channel->scope_variables = *event;
929 *event = NULL;
930 } else if (channel->scope_variables) { /* pop */
931 switch_event_t *top_event = channel->scope_variables;
932 channel->scope_variables = channel->scope_variables->next;
933 switch_event_destroy(&top_event);
934 }
935
936 switch_mutex_unlock(channel->profile_mutex);
937
938 }
939
switch_channel_get_scope_variables(switch_channel_t * channel,switch_event_t ** event)940 SWITCH_DECLARE(switch_status_t) switch_channel_get_scope_variables(switch_channel_t *channel, switch_event_t **event)
941 {
942 switch_status_t status = SWITCH_STATUS_FALSE;
943 switch_event_t *new_event;
944
945 switch_mutex_lock(channel->profile_mutex);
946 if (channel->scope_variables) {
947 switch_event_t *ep;
948 switch_event_header_t *hp;
949
950 switch_event_create_plain(&new_event, SWITCH_EVENT_CHANNEL_DATA);
951 status = SWITCH_STATUS_SUCCESS;
952 *event = new_event;
953
954 for (ep = channel->scope_variables; ep; ep = ep->next) {
955 for (hp = ep->headers; hp; hp = hp->next) {
956 if (!switch_event_get_header(new_event, hp->value)) {
957 switch_event_add_header_string(new_event, SWITCH_STACK_BOTTOM, hp->name, hp->value);
958 }
959 }
960 }
961 }
962 switch_mutex_unlock(channel->profile_mutex);
963
964 return status;
965 }
966
switch_channel_get_variable_dup(switch_channel_t * channel,const char * varname,switch_bool_t dup,int idx)967 SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx)
968 {
969 const char *v = NULL, *r = NULL, *vdup = NULL;
970 switch_assert(channel != NULL);
971
972 switch_mutex_lock(channel->profile_mutex);
973
974 if (!zstr(varname)) {
975 if (channel->scope_variables) {
976 switch_event_t *ep;
977
978 for (ep = channel->scope_variables; ep; ep = ep->next) {
979 if ((v = switch_event_get_header_idx(ep, varname, idx))) {
980 break;
981 }
982 }
983 }
984
985 if (!v && (!channel->variables || !(v = switch_event_get_header_idx(channel->variables, varname, idx)))) {
986 switch_caller_profile_t *cp = switch_channel_get_caller_profile(channel);
987
988 if (cp) {
989 if (!strncmp(varname, "aleg_", 5)) {
990 cp = cp->originator_caller_profile;
991 varname += 5;
992 } else if (!strncmp(varname, "bleg_", 5)) {
993 cp = cp->originatee_caller_profile;
994 varname += 5;
995 }
996 }
997
998 if (!cp || !(v = switch_caller_get_field_by_name(cp, varname))) {
999 if ((vdup = switch_core_get_variable_pdup(varname, switch_core_session_get_pool(channel->session)))) {
1000 v = vdup;
1001 }
1002 }
1003 }
1004 }
1005
1006 if (dup && v != vdup) {
1007 if (v) {
1008 r = switch_core_session_strdup(channel->session, v);
1009 }
1010 } else {
1011 r = v;
1012 }
1013
1014 switch_mutex_unlock(channel->profile_mutex);
1015
1016 return r;
1017 }
1018
switch_channel_get_variable_partner(switch_channel_t * channel,const char * varname)1019 SWITCH_DECLARE(const char *) switch_channel_get_variable_partner(switch_channel_t *channel, const char *varname)
1020 {
1021 const char *uuid;
1022 const char *val = NULL, *r = NULL;
1023 switch_assert(channel != NULL);
1024
1025 if (!zstr(varname)) {
1026 if ((uuid = switch_channel_get_partner_uuid(channel))) {
1027 switch_core_session_t *session;
1028 if ((session = switch_core_session_locate(uuid))) {
1029 switch_channel_t *tchannel = switch_core_session_get_channel(session);
1030 val = switch_channel_get_variable(tchannel, varname);
1031 switch_core_session_rwunlock(session);
1032 }
1033 }
1034 }
1035
1036 if (val)
1037 r = switch_core_session_strdup(channel->session, val);
1038
1039 return r;
1040 }
1041
1042
switch_channel_variable_last(switch_channel_t * channel)1043 SWITCH_DECLARE(void) switch_channel_variable_last(switch_channel_t *channel)
1044 {
1045 switch_assert(channel != NULL);
1046 if (!channel->vi) {
1047 return;
1048 }
1049 channel->vi = 0;
1050 switch_mutex_unlock(channel->profile_mutex);
1051
1052 }
1053
switch_channel_variable_first(switch_channel_t * channel)1054 SWITCH_DECLARE(switch_event_header_t *) switch_channel_variable_first(switch_channel_t *channel)
1055 {
1056 switch_event_header_t *hi = NULL;
1057
1058 switch_assert(channel != NULL);
1059 switch_mutex_lock(channel->profile_mutex);
1060 if (channel->variables && (hi = channel->variables->headers)) {
1061 channel->vi = 1;
1062 } else {
1063 switch_mutex_unlock(channel->profile_mutex);
1064 }
1065
1066 return hi;
1067 }
1068
switch_channel_set_private(switch_channel_t * channel,const char * key,const void * private_info)1069 SWITCH_DECLARE(switch_status_t) switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
1070 {
1071 switch_assert(channel != NULL);
1072 switch_core_hash_insert_locked(channel->private_hash, key, private_info, channel->profile_mutex);
1073 return SWITCH_STATUS_SUCCESS;
1074 }
1075
switch_channel_get_private(switch_channel_t * channel,const char * key)1076 SWITCH_DECLARE(void *) switch_channel_get_private(switch_channel_t *channel, const char *key)
1077 {
1078 void *val;
1079 switch_assert(channel != NULL);
1080 val = switch_core_hash_find_locked(channel->private_hash, key, channel->profile_mutex);
1081 return val;
1082 }
1083
switch_channel_get_private_partner(switch_channel_t * channel,const char * key)1084 SWITCH_DECLARE(void *) switch_channel_get_private_partner(switch_channel_t *channel, const char *key)
1085 {
1086 const char *uuid;
1087 void *val = NULL;
1088
1089 switch_assert(channel != NULL);
1090
1091 if ((uuid = switch_channel_get_partner_uuid(channel))) {
1092 switch_core_session_t *session;
1093 if ((session = switch_core_session_locate(uuid))) {
1094 val = switch_core_hash_find_locked(channel->private_hash, key, channel->profile_mutex);
1095 switch_core_session_rwunlock(session);
1096 }
1097 }
1098
1099 return val;
1100 }
1101
switch_channel_set_name(switch_channel_t * channel,const char * name)1102 SWITCH_DECLARE(switch_status_t) switch_channel_set_name(switch_channel_t *channel, const char *name)
1103 {
1104 const char *old = NULL;
1105
1106 switch_assert(channel != NULL);
1107 if (!zstr(channel->name)) {
1108 old = channel->name;
1109 }
1110 channel->name = NULL;
1111 if (name) {
1112 char *uuid = switch_core_session_get_uuid(channel->session);
1113 channel->name = switch_core_session_strdup(channel->session, name);
1114 switch_channel_set_variable(channel, SWITCH_CHANNEL_NAME_VARIABLE, name);
1115 if (old) {
1116 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_NOTICE, "Rename Channel %s->%s [%s]\n", old, name, uuid);
1117 } else {
1118 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_NOTICE, "New Channel %s [%s]\n", name, uuid);
1119 }
1120 }
1121 return SWITCH_STATUS_SUCCESS;
1122 }
1123
switch_channel_get_name(switch_channel_t * channel)1124 SWITCH_DECLARE(char *) switch_channel_get_name(switch_channel_t *channel)
1125 {
1126 switch_assert(channel != NULL);
1127 return (!zstr(channel->name)) ? channel->name : "N/A";
1128 }
1129
switch_channel_set_profile_var(switch_channel_t * channel,const char * name,const char * val)1130 SWITCH_DECLARE(switch_status_t) switch_channel_set_profile_var(switch_channel_t *channel, const char *name, const char *val)
1131 {
1132 char *v;
1133 switch_status_t status = SWITCH_STATUS_SUCCESS;
1134
1135 switch_mutex_lock(channel->profile_mutex);
1136
1137
1138 if (!strcasecmp(name, "device_id") && !zstr(val)) {
1139 const char *device_id;
1140 if (!(device_id = switch_channel_set_device_id(channel, val))) {
1141 /* one time setting */
1142 switch_mutex_unlock(channel->profile_mutex);
1143 return status;
1144 }
1145
1146 val = device_id;
1147 }
1148
1149 if (!zstr(val)) {
1150 v = switch_core_strdup(channel->caller_profile->pool, val);
1151 } else {
1152 v = SWITCH_BLANK_STRING;
1153 }
1154
1155 if (!strcasecmp(name, "dialplan")) {
1156 channel->caller_profile->dialplan = v;
1157 } else if (!strcasecmp(name, "username")) {
1158 channel->caller_profile->username = v;
1159 } else if (!strcasecmp(name, "caller_id_name")) {
1160 channel->caller_profile->caller_id_name = v;
1161 } else if (!strcasecmp(name, "caller_id_number")) {
1162 channel->caller_profile->caller_id_number = v;
1163 } else if (!strcasecmp(name, "callee_id_name")) {
1164 channel->caller_profile->callee_id_name = v;
1165 } else if (!strcasecmp(name, "callee_id_number")) {
1166 channel->caller_profile->callee_id_number = v;
1167 } else if (val && !strcasecmp(name, "caller_ton")) {
1168 channel->caller_profile->caller_ton = (uint8_t) atoi(v);
1169 } else if (val && !strcasecmp(name, "caller_numplan")) {
1170 channel->caller_profile->caller_numplan = (uint8_t) atoi(v);
1171 } else if (val && !strcasecmp(name, "destination_number_ton")) {
1172 channel->caller_profile->destination_number_ton = (uint8_t) atoi(v);
1173 } else if (val && !strcasecmp(name, "destination_number_numplan")) {
1174 channel->caller_profile->destination_number_numplan = (uint8_t) atoi(v);
1175 } else if (!strcasecmp(name, "ani")) {
1176 channel->caller_profile->ani = v;
1177 } else if (!strcasecmp(name, "aniii")) {
1178 channel->caller_profile->aniii = v;
1179 } else if (!strcasecmp(name, "network_addr")) {
1180 channel->caller_profile->network_addr = v;
1181 } else if (!strcasecmp(name, "rdnis")) {
1182 channel->caller_profile->rdnis = v;
1183 } else if (!strcasecmp(name, "destination_number")) {
1184 channel->caller_profile->destination_number = v;
1185 } else if (!strcasecmp(name, "uuid")) {
1186 channel->caller_profile->uuid = v;
1187 } else if (!strcasecmp(name, "source")) {
1188 channel->caller_profile->source = v;
1189 } else if (!strcasecmp(name, "context")) {
1190 channel->caller_profile->context = v;
1191 } else if (!strcasecmp(name, "chan_name")) {
1192 channel->caller_profile->chan_name = v;
1193 } else {
1194 profile_node_t *pn, *n = switch_core_alloc(channel->caller_profile->pool, sizeof(*n));
1195 int var_found;
1196
1197 n->var = switch_core_strdup(channel->caller_profile->pool, name);
1198 n->val = v;
1199
1200 if (!channel->caller_profile->soft) {
1201 channel->caller_profile->soft = n;
1202 } else {
1203 var_found = 0;
1204
1205 for(pn = channel->caller_profile->soft; pn ; pn = pn->next) {
1206 if (!strcasecmp(pn->var,n->var)) {
1207 pn->val = n->val;
1208 var_found = 1;
1209 break;
1210 }
1211
1212 if(!pn->next) {
1213 break;
1214 }
1215 }
1216
1217 if (pn && !pn->next && !var_found) {
1218 pn->next = n;
1219 }
1220 }
1221 }
1222 switch_mutex_unlock(channel->profile_mutex);
1223
1224 return status;
1225 }
1226
1227
switch_channel_process_export(switch_channel_t * channel,switch_channel_t * peer_channel,switch_event_t * var_event,const char * export_varname)1228 SWITCH_DECLARE(void) switch_channel_process_export(switch_channel_t *channel, switch_channel_t *peer_channel,
1229 switch_event_t *var_event, const char *export_varname)
1230 {
1231
1232 const char *export_vars = switch_channel_get_variable(channel, export_varname);
1233 char *cptmp = switch_core_session_strdup(channel->session, export_vars);
1234 int argc;
1235 char *argv[256];
1236
1237 if (zstr(export_vars)) return;
1238
1239
1240 if (var_event) {
1241 switch_event_del_header(var_event, export_varname);
1242 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, export_varname, export_vars);
1243 }
1244
1245 if (peer_channel) {
1246 switch_channel_set_variable(peer_channel, export_varname, export_vars);
1247 }
1248
1249 if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1250 int x;
1251
1252 for (x = 0; x < argc; x++) {
1253 const char *vval;
1254 if ((vval = switch_channel_get_variable(channel, argv[x]))) {
1255 char *vvar = argv[x];
1256 if (!strncasecmp(vvar, "nolocal:", 8)) { /* remove this later ? */
1257 vvar += 8;
1258 } else if (!strncasecmp(vvar, "_nolocal_", 9)) {
1259 vvar += 9;
1260 }
1261 if (var_event) {
1262 switch_event_del_header(var_event, vvar);
1263 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval);
1264 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG,
1265 "%s EXPORTING[%s] [%s]=[%s] to event\n",
1266 switch_channel_get_name(channel),
1267 export_varname,
1268 vvar, vval);
1269 }
1270 if (peer_channel) {
1271 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG,
1272 "%s EXPORTING[%s] [%s]=[%s] to %s\n",
1273 switch_channel_get_name(channel),
1274 export_varname,
1275 vvar, vval, switch_channel_get_name(peer_channel));
1276 switch_channel_set_variable(peer_channel, vvar, vval);
1277 }
1278 }
1279 }
1280 }
1281
1282
1283 }
1284
switch_channel_export_variable_var_check(switch_channel_t * channel,const char * varname,const char * val,const char * export_varname,switch_bool_t var_check)1285 SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_channel_t *channel,
1286 const char *varname, const char *val,
1287 const char *export_varname, switch_bool_t var_check)
1288 {
1289 char *var_name = NULL;
1290 const char *exports;
1291 char *var, *new_exports, *new_exports_d = NULL;
1292 int local = 1;
1293
1294 exports = switch_channel_get_variable(channel, export_varname);
1295
1296 var = switch_core_session_strdup(channel->session, varname);
1297
1298 if (var) {
1299 if (!strncasecmp(var, "nolocal:", 8)) { /* remove this later ? */
1300 var_name = var + 8;
1301 local = 0;
1302 } else if (!strncasecmp(var, "_nolocal_", 9)) {
1303 var_name = var + 9;
1304 local = 0;
1305 } else {
1306 var_name = var;
1307 }
1308 }
1309
1310 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG, "EXPORT (%s) %s[%s]=[%s]\n",
1311 export_varname, local ? "" : "(REMOTE ONLY) ",
1312 var_name ? var_name : "", val ? val : "UNDEF");
1313
1314
1315 switch_channel_set_variable_var_check(channel, var, val, var_check);
1316
1317 if (var && val) {
1318 if (exports) {
1319 new_exports_d = switch_mprintf("%s,%s", exports, var);
1320 new_exports = new_exports_d;
1321 } else {
1322 new_exports = var;
1323 }
1324
1325 switch_channel_set_variable(channel, export_varname, new_exports);
1326
1327 switch_safe_free(new_exports_d);
1328 }
1329
1330 return SWITCH_STATUS_SUCCESS;
1331 }
1332
switch_channel_export_variable_printf(switch_channel_t * channel,const char * varname,const char * export_varname,const char * fmt,...)1333 SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname,
1334 const char *export_varname, const char *fmt, ...)
1335 {
1336 switch_status_t status = SWITCH_STATUS_FALSE;
1337 char *data = NULL;
1338 va_list ap;
1339 int ret;
1340
1341 switch_assert(channel != NULL);
1342
1343 va_start(ap, fmt);
1344 ret = switch_vasprintf(&data, fmt, ap);
1345 va_end(ap);
1346
1347 if (ret == -1) {
1348 return SWITCH_STATUS_FALSE;
1349 }
1350
1351 status = switch_channel_export_variable(channel, varname, data, export_varname);
1352
1353 free(data);
1354
1355 return status;
1356 }
1357
1358
switch_channel_del_variable_prefix(switch_channel_t * channel,const char * prefix)1359 SWITCH_DECLARE(uint32_t) switch_channel_del_variable_prefix(switch_channel_t *channel, const char *prefix)
1360 {
1361 switch_event_t *event;
1362 switch_event_header_t *hp;
1363 uint32_t r = 0;
1364
1365 switch_channel_get_variables(channel, &event);
1366
1367 if (event) {
1368 for (hp = event->headers; hp; hp = hp->next) {
1369 if (zstr(prefix) || !strncasecmp(hp->name, prefix, strlen(prefix))) {
1370 switch_channel_set_variable(channel, hp->name, NULL);
1371 }
1372 }
1373 }
1374
1375 switch_event_destroy(&event);
1376
1377 return r;
1378 }
1379
switch_channel_transfer_variable_prefix(switch_channel_t * orig_channel,switch_channel_t * new_channel,const char * prefix)1380 SWITCH_DECLARE(switch_status_t) switch_channel_transfer_variable_prefix(switch_channel_t *orig_channel, switch_channel_t *new_channel, const char *prefix)
1381 {
1382 switch_event_header_t *hi = NULL;
1383 int x = 0;
1384
1385 if ((hi = switch_channel_variable_first(orig_channel))) {
1386 for (; hi; hi = hi->next) {
1387 char *var = hi->name;
1388 char *val = hi->value;
1389
1390 if (zstr(prefix) || !strncasecmp(var, prefix, strlen(prefix))) {
1391 x++;
1392 switch_channel_set_variable(new_channel, var, val);
1393 }
1394 }
1395 switch_channel_variable_last(orig_channel);
1396 }
1397
1398 return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
1399 }
1400
switch_channel_set_presence_data_vals(switch_channel_t * channel,const char * presence_data_cols)1401 SWITCH_DECLARE(void) switch_channel_set_presence_data_vals(switch_channel_t *channel, const char *presence_data_cols)
1402 {
1403 char *cols[128] = { 0 };
1404 char header_name[128] = "";
1405 int col_count = 0, i = 0;
1406 char *data_copy = NULL;
1407
1408 if (zstr(presence_data_cols)) {
1409 presence_data_cols = switch_channel_get_variable_dup(channel, "presence_data_cols", SWITCH_FALSE, -1);
1410 if (zstr(presence_data_cols)) {
1411 return;
1412 }
1413 }
1414
1415 data_copy = strdup(presence_data_cols);
1416
1417 col_count = switch_split(data_copy, ':', cols);
1418
1419 for (i = 0; i < col_count; i++) {
1420 const char *val = NULL;
1421 switch_snprintf(header_name, sizeof(header_name), "PD-%s", cols[i]);
1422 val = switch_channel_get_variable(channel, cols[i]);
1423 switch_channel_set_profile_var(channel, header_name, val);
1424 }
1425
1426 switch_safe_free(data_copy);
1427 }
1428
switch_channel_set_log_tag(switch_channel_t * channel,const char * tagname,const char * tagvalue)1429 SWITCH_DECLARE(switch_status_t) switch_channel_set_log_tag(switch_channel_t *channel, const char *tagname, const char *tagvalue)
1430 {
1431 switch_status_t status = SWITCH_STATUS_FALSE;
1432 switch_assert(channel != NULL);
1433 switch_mutex_lock(channel->profile_mutex);
1434 if (!zstr(tagname)) {
1435 if (!channel->log_tags) {
1436 switch_event_create_plain(&channel->log_tags, SWITCH_EVENT_CHANNEL_DATA);
1437 }
1438 if (zstr(tagvalue)) {
1439 switch_event_del_header(channel->log_tags, tagname);
1440 } else {
1441 switch_event_add_header_string(channel->log_tags, SWITCH_STACK_BOTTOM, tagname, tagvalue);
1442 }
1443 status = SWITCH_STATUS_SUCCESS;
1444 }
1445 switch_mutex_unlock(channel->profile_mutex);
1446 return status;
1447 }
1448
switch_channel_get_log_tags(switch_channel_t * channel,switch_event_t ** log_tags)1449 SWITCH_DECLARE(switch_status_t) switch_channel_get_log_tags(switch_channel_t *channel, switch_event_t **log_tags)
1450 {
1451 switch_status_t status = SWITCH_STATUS_FALSE;
1452 switch_assert(channel != NULL);
1453 if (!channel->log_tags) {
1454 return status;
1455 }
1456 switch_mutex_lock(channel->profile_mutex);
1457 if (channel->log_tags && log_tags) {
1458 status = switch_event_dup(log_tags, channel->log_tags);
1459 }
1460 switch_mutex_unlock(channel->profile_mutex);
1461 return status;
1462 }
1463
switch_channel_set_variable_var_check(switch_channel_t * channel,const char * varname,const char * value,switch_bool_t var_check)1464 SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_var_check(switch_channel_t *channel,
1465 const char *varname, const char *value, switch_bool_t var_check)
1466 {
1467 switch_status_t status = SWITCH_STATUS_FALSE;
1468
1469 switch_assert(channel != NULL);
1470
1471 switch_mutex_lock(channel->profile_mutex);
1472 if (channel->variables && !zstr(varname)) {
1473 if (zstr(value)) {
1474 switch_event_del_header(channel->variables, varname);
1475 } else {
1476 int ok = 1;
1477
1478 if (var_check) {
1479 ok = !switch_string_var_check_const(value);
1480 }
1481 if (ok) {
1482 switch_event_add_header_string(channel->variables, SWITCH_STACK_BOTTOM, varname, value);
1483 } else {
1484 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "Invalid data (${%s} contains a variable)\n", varname);
1485 }
1486 }
1487 status = SWITCH_STATUS_SUCCESS;
1488 }
1489 switch_mutex_unlock(channel->profile_mutex);
1490
1491 return status;
1492 }
1493
1494
switch_channel_add_variable_var_check(switch_channel_t * channel,const char * varname,const char * value,switch_bool_t var_check,switch_stack_t stack)1495 SWITCH_DECLARE(switch_status_t) switch_channel_add_variable_var_check(switch_channel_t *channel,
1496 const char *varname, const char *value, switch_bool_t var_check, switch_stack_t stack)
1497 {
1498 switch_status_t status = SWITCH_STATUS_FALSE;
1499
1500 switch_assert(channel != NULL);
1501
1502 switch_mutex_lock(channel->profile_mutex);
1503 if (channel->variables && !zstr(varname)) {
1504 if (zstr(value)) {
1505 switch_event_del_header(channel->variables, varname);
1506 } else {
1507 int ok = 1;
1508
1509 if (var_check) {
1510 ok = !switch_string_var_check_const(value);
1511 }
1512 if (ok) {
1513 switch_event_add_header_string(channel->variables, stack, varname, value);
1514 } else {
1515 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "Invalid data (${%s} contains a variable)\n", varname);
1516 }
1517 }
1518 status = SWITCH_STATUS_SUCCESS;
1519 }
1520 switch_mutex_unlock(channel->profile_mutex);
1521
1522 return status;
1523 }
1524
1525
1526 switch_status_t switch_event_base_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, char *data);
1527
switch_channel_set_variable_printf(switch_channel_t * channel,const char * varname,const char * fmt,...)1528 SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt, ...)
1529 {
1530 int ret = 0;
1531 char *data;
1532 va_list ap;
1533 switch_status_t status = SWITCH_STATUS_FALSE;
1534
1535 switch_assert(channel != NULL);
1536
1537 switch_mutex_lock(channel->profile_mutex);
1538 if (channel->variables && !zstr(varname)) {
1539 switch_event_del_header(channel->variables, varname);
1540
1541 va_start(ap, fmt);
1542 ret = switch_vasprintf(&data, fmt, ap);
1543 va_end(ap);
1544
1545 if (ret == -1) {
1546 switch_mutex_unlock(channel->profile_mutex);
1547 return SWITCH_STATUS_MEMERR;
1548 }
1549
1550 status = switch_channel_set_variable(channel, varname, data);
1551 free(data);
1552 }
1553 switch_mutex_unlock(channel->profile_mutex);
1554
1555 return status;
1556 }
1557
1558
switch_channel_set_variable_name_printf(switch_channel_t * channel,const char * val,const char * fmt,...)1559 SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_name_printf(switch_channel_t *channel, const char *val, const char *fmt, ...)
1560 {
1561 int ret = 0;
1562 char *varname;
1563 va_list ap;
1564 switch_status_t status = SWITCH_STATUS_FALSE;
1565
1566 switch_assert(channel != NULL);
1567
1568 switch_mutex_lock(channel->profile_mutex);
1569
1570 va_start(ap, fmt);
1571 ret = switch_vasprintf(&varname, fmt, ap);
1572 va_end(ap);
1573
1574 if (ret == -1) {
1575 switch_mutex_unlock(channel->profile_mutex);
1576 return SWITCH_STATUS_MEMERR;
1577 }
1578
1579 status = switch_channel_set_variable(channel, varname, val);
1580
1581 free(varname);
1582
1583 switch_mutex_unlock(channel->profile_mutex);
1584
1585 return status;
1586 }
1587
1588
switch_channel_set_variable_partner_var_check(switch_channel_t * channel,const char * varname,const char * value,switch_bool_t var_check)1589 SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_partner_var_check(switch_channel_t *channel,
1590 const char *varname, const char *value, switch_bool_t var_check)
1591 {
1592 const char *uuid;
1593 switch_assert(channel != NULL);
1594
1595 if (!zstr(varname)) {
1596 if ((uuid = switch_channel_get_partner_uuid(channel))) {
1597 switch_core_session_t *session;
1598 if ((session = switch_core_session_locate(uuid))) {
1599 switch_channel_t *tchannel = switch_core_session_get_channel(session);
1600 switch_channel_set_variable_var_check(tchannel, varname, value, var_check);
1601 switch_core_session_rwunlock(session);
1602 }
1603 return SWITCH_STATUS_SUCCESS;
1604 }
1605 }
1606
1607 return SWITCH_STATUS_FALSE;
1608 }
1609
switch_channel_test_flag(switch_channel_t * channel,switch_channel_flag_t flag)1610 SWITCH_DECLARE(uint32_t) switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
1611 {
1612 uint32_t r = 0;
1613
1614 switch_assert(channel != NULL);
1615
1616 switch_mutex_lock(channel->flag_mutex);
1617 r = channel->flags[flag];
1618 switch_mutex_unlock(channel->flag_mutex);
1619
1620 return r;
1621 }
1622
switch_channel_set_flag_partner(switch_channel_t * channel,switch_channel_flag_t flag)1623 SWITCH_DECLARE(switch_bool_t) switch_channel_set_flag_partner(switch_channel_t *channel, switch_channel_flag_t flag)
1624 {
1625 const char *uuid;
1626
1627 switch_assert(channel != NULL);
1628
1629 if ((uuid = switch_channel_get_partner_uuid(channel))) {
1630 switch_core_session_t *session;
1631 if ((session = switch_core_session_locate(uuid))) {
1632 switch_channel_set_flag(switch_core_session_get_channel(session), flag);
1633 switch_core_session_rwunlock(session);
1634 return SWITCH_TRUE;
1635 }
1636 }
1637
1638 return SWITCH_FALSE;
1639 }
1640
switch_channel_test_flag_partner(switch_channel_t * channel,switch_channel_flag_t flag)1641 SWITCH_DECLARE(uint32_t) switch_channel_test_flag_partner(switch_channel_t *channel, switch_channel_flag_t flag)
1642 {
1643 const char *uuid;
1644 int r = 0;
1645
1646 switch_assert(channel != NULL);
1647
1648 if ((uuid = switch_channel_get_partner_uuid(channel))) {
1649 switch_core_session_t *session;
1650 if ((session = switch_core_session_locate(uuid))) {
1651 r = switch_channel_test_flag(switch_core_session_get_channel(session), flag);
1652 switch_core_session_rwunlock(session);
1653 }
1654 }
1655
1656 return r;
1657 }
1658
switch_channel_clear_flag_partner(switch_channel_t * channel,switch_channel_flag_t flag)1659 SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t *channel, switch_channel_flag_t flag)
1660 {
1661 const char *uuid;
1662
1663 switch_assert(channel != NULL);
1664
1665 if ((uuid = switch_channel_get_partner_uuid(channel))) {
1666 switch_core_session_t *session;
1667 if ((session = switch_core_session_locate(uuid))) {
1668 switch_channel_clear_flag(switch_core_session_get_channel(session), flag);
1669 switch_core_session_rwunlock(session);
1670 return SWITCH_TRUE;
1671 }
1672 }
1673
1674 return SWITCH_FALSE;
1675 }
1676
switch_channel_wait_for_state(switch_channel_t * channel,switch_channel_t * other_channel,switch_channel_state_t want_state)1677 SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state)
1678 {
1679
1680 switch_assert(channel);
1681
1682 for (;;) {
1683 if ((channel->state < CS_HANGUP && channel->state == channel->running_state && channel->running_state == want_state) ||
1684 (other_channel && switch_channel_down_nosig(other_channel)) || switch_channel_down(channel)) {
1685 break;
1686 }
1687 switch_cond_next();
1688 }
1689 }
1690
1691
switch_channel_wait_for_state_timeout(switch_channel_t * channel,switch_channel_state_t want_state,uint32_t timeout)1692 SWITCH_DECLARE(void) switch_channel_wait_for_state_timeout(switch_channel_t *channel, switch_channel_state_t want_state, uint32_t timeout)
1693 {
1694
1695 uint32_t count = 0;
1696
1697 for (;;) {
1698
1699 if ((channel->state == channel->running_state && channel->running_state == want_state) || channel->state >= CS_HANGUP) {
1700 break;
1701 }
1702
1703 switch_channel_check_signal(channel, SWITCH_TRUE);
1704
1705 switch_cond_next();
1706
1707 if (++count >= timeout) {
1708 break;
1709 }
1710 }
1711 }
1712
switch_channel_wait_for_flag(switch_channel_t * channel,switch_channel_flag_t want_flag,switch_bool_t pres,uint32_t to,switch_channel_t * super_channel)1713 SWITCH_DECLARE(switch_status_t) switch_channel_wait_for_flag(switch_channel_t *channel,
1714 switch_channel_flag_t want_flag,
1715 switch_bool_t pres, uint32_t to, switch_channel_t *super_channel)
1716 {
1717
1718 if (to) {
1719 to++;
1720 }
1721
1722 for (;;) {
1723 if (pres) {
1724 if (switch_channel_test_flag(channel, want_flag)) {
1725 break;
1726 }
1727 } else {
1728 if (!switch_channel_test_flag(channel, want_flag)) {
1729 break;
1730 }
1731 }
1732
1733 switch_cond_next();
1734
1735 if (super_channel && !switch_channel_ready(super_channel)) {
1736 return SWITCH_STATUS_FALSE;
1737 }
1738
1739 if (switch_channel_down(channel)) {
1740 return SWITCH_STATUS_FALSE;
1741 }
1742
1743 if (to && !--to) {
1744 return SWITCH_STATUS_TIMEOUT;
1745 }
1746 }
1747
1748 return SWITCH_STATUS_SUCCESS;
1749 }
1750
switch_channel_wait_for_app_flag(switch_channel_t * channel,uint32_t app_flag,const char * key,switch_bool_t pres,uint32_t to)1751 SWITCH_DECLARE(switch_status_t) switch_channel_wait_for_app_flag(switch_channel_t *channel,
1752 uint32_t app_flag,
1753 const char *key, switch_bool_t pres, uint32_t to)
1754 {
1755 int r = 0;
1756
1757 if (to) {
1758 to++;
1759 }
1760
1761 for (;;) {
1762 if (pres) {
1763 if ((r = switch_channel_test_app_flag_key(key, channel, app_flag))) {
1764 break;
1765 }
1766 } else {
1767 if (!(r = switch_channel_test_app_flag_key(key, channel, app_flag))) {
1768 break;
1769 }
1770 }
1771
1772 switch_cond_next();
1773
1774 if (switch_channel_down(channel)) {
1775 return r;
1776 }
1777
1778 if (to && !--to) {
1779 return r;
1780 }
1781 }
1782
1783 return r;
1784 }
1785
1786
switch_channel_set_cap_value(switch_channel_t * channel,switch_channel_cap_t cap,uint32_t value)1787 SWITCH_DECLARE(void) switch_channel_set_cap_value(switch_channel_t *channel, switch_channel_cap_t cap, uint32_t value)
1788 {
1789 switch_assert(channel);
1790 switch_assert(channel->flag_mutex);
1791
1792 switch_mutex_lock(channel->flag_mutex);
1793 channel->caps[cap] = value;
1794 switch_mutex_unlock(channel->flag_mutex);
1795 }
1796
switch_channel_clear_cap(switch_channel_t * channel,switch_channel_cap_t cap)1797 SWITCH_DECLARE(void) switch_channel_clear_cap(switch_channel_t *channel, switch_channel_cap_t cap)
1798 {
1799 switch_assert(channel != NULL);
1800 switch_assert(channel->flag_mutex);
1801
1802 switch_mutex_lock(channel->flag_mutex);
1803 channel->caps[cap] = 0;
1804 switch_mutex_unlock(channel->flag_mutex);
1805 }
1806
switch_channel_test_cap(switch_channel_t * channel,switch_channel_cap_t cap)1807 SWITCH_DECLARE(uint32_t) switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap)
1808 {
1809 switch_assert(channel != NULL);
1810 return channel->caps[cap] ? 1 : 0;
1811 }
1812
switch_channel_test_cap_partner(switch_channel_t * channel,switch_channel_cap_t cap)1813 SWITCH_DECLARE(uint32_t) switch_channel_test_cap_partner(switch_channel_t *channel, switch_channel_cap_t cap)
1814 {
1815 const char *uuid;
1816 int r = 0;
1817
1818 switch_assert(channel != NULL);
1819
1820 if ((uuid = switch_channel_get_partner_uuid(channel))) {
1821 switch_core_session_t *session;
1822 if ((session = switch_core_session_locate(uuid))) {
1823 r = switch_channel_test_cap(switch_core_session_get_channel(session), cap);
1824 switch_core_session_rwunlock(session);
1825 }
1826 }
1827
1828 return r;
1829 }
1830
switch_channel_get_flag_string(switch_channel_t * channel)1831 SWITCH_DECLARE(char *) switch_channel_get_flag_string(switch_channel_t *channel)
1832 {
1833 switch_stream_handle_t stream = { 0 };
1834 char *r;
1835 int i = 0;
1836
1837 SWITCH_STANDARD_STREAM(stream);
1838
1839 switch_mutex_lock(channel->flag_mutex);
1840 for (i = 0; i < CF_FLAG_MAX; i++) {
1841 if (channel->flags[i]) {
1842 stream.write_function(&stream, "%d=%d;", i, channel->flags[i]);
1843 }
1844 }
1845 switch_mutex_unlock(channel->flag_mutex);
1846
1847 r = (char *) stream.data;
1848
1849 if (end_of(r) == ';') {
1850 end_of(r) = '\0';
1851 }
1852
1853 return r;
1854
1855 }
1856
switch_channel_get_cap_string(switch_channel_t * channel)1857 SWITCH_DECLARE(char *) switch_channel_get_cap_string(switch_channel_t *channel)
1858 {
1859 switch_stream_handle_t stream = { 0 };
1860 char *r;
1861 int i = 0;
1862
1863 SWITCH_STANDARD_STREAM(stream);
1864
1865 switch_mutex_lock(channel->flag_mutex);
1866 for (i = 0; i < CC_FLAG_MAX; i++) {
1867 if (channel->caps[i]) {
1868 stream.write_function(&stream, "%d=%d;", i, channel->caps[i]);
1869 }
1870 }
1871 switch_mutex_unlock(channel->flag_mutex);
1872
1873 r = (char *) stream.data;
1874
1875 if (end_of(r) == ';') {
1876 end_of(r) = '\0';
1877 }
1878
1879 return r;
1880
1881 }
1882
switch_channel_set_flag_value(switch_channel_t * channel,switch_channel_flag_t flag,uint32_t value)1883 SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, switch_channel_flag_t flag, uint32_t value)
1884 {
1885 int HELD = 0;
1886 int just_set = 0;
1887
1888 switch_assert(channel);
1889 switch_assert(channel->flag_mutex);
1890
1891 switch_mutex_lock(channel->flag_mutex);
1892 if (flag == CF_LEG_HOLDING && !channel->flags[flag] && channel->flags[CF_ANSWERED]) {
1893 HELD = 1;
1894 }
1895 if (channel->flags[flag] != value) {
1896 just_set = 1;
1897 channel->flags[flag] = value;
1898 }
1899 switch_mutex_unlock(channel->flag_mutex);
1900
1901 if (flag == CF_VIDEO_READY && just_set) {
1902 switch_core_session_request_video_refresh(channel->session);
1903 }
1904
1905 if (flag == CF_ORIGINATOR && switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_up_nosig(channel)) {
1906 switch_channel_set_callstate(channel, CCS_RING_WAIT);
1907 }
1908
1909 if (flag == CF_DIALPLAN) {
1910 if (channel->direction == SWITCH_CALL_DIRECTION_INBOUND) {
1911 channel->logical_direction = SWITCH_CALL_DIRECTION_OUTBOUND;
1912 if (channel->device_node) {
1913 channel->device_node->direction = SWITCH_CALL_DIRECTION_INBOUND;
1914 }
1915 } else {
1916 channel->logical_direction = SWITCH_CALL_DIRECTION_INBOUND;
1917 if (channel->device_node) {
1918 channel->device_node->direction = SWITCH_CALL_DIRECTION_OUTBOUND;
1919 }
1920 }
1921 }
1922
1923 if (HELD) {
1924 switch_hold_record_t *hr;
1925 const char *brto = switch_channel_get_partner_uuid(channel);
1926
1927 switch_channel_set_callstate(channel, CCS_HELD);
1928 switch_mutex_lock(channel->profile_mutex);
1929 channel->caller_profile->times->last_hold = switch_time_now();
1930
1931 hr = switch_core_session_alloc(channel->session, sizeof(*hr));
1932 hr->on = switch_time_now();
1933 if (brto) {
1934 hr->uuid = switch_core_session_strdup(channel->session, brto);
1935 }
1936
1937 if (channel->hold_record) {
1938 hr->next = channel->hold_record;
1939 }
1940 channel->hold_record = hr;
1941
1942 switch_mutex_unlock(channel->profile_mutex);
1943 }
1944
1945 if (flag == CF_OUTBOUND) {
1946 switch_channel_set_variable(channel, "is_outbound", "true");
1947 }
1948
1949 if (flag == CF_RECOVERED) {
1950 switch_channel_set_variable(channel, "recovered", "true");
1951 }
1952
1953 if (flag == CF_VIDEO_ECHO || flag == CF_VIDEO_BLANK || flag == CF_VIDEO_DECODED_READ || flag == CF_VIDEO_PASSIVE) {
1954 switch_core_session_start_video_thread(channel->session);
1955 }
1956
1957 if (flag == CF_VIDEO_DECODED_READ && channel->flags[CF_VIDEO]) {
1958 switch_core_session_request_video_refresh(channel->session);
1959 }
1960 }
1961
switch_channel_set_flag_recursive(switch_channel_t * channel,switch_channel_flag_t flag)1962 SWITCH_DECLARE(void) switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
1963 {
1964 switch_assert(channel);
1965 switch_assert(channel->flag_mutex);
1966
1967 switch_mutex_lock(channel->flag_mutex);
1968 channel->flags[flag]++;
1969 switch_mutex_unlock(channel->flag_mutex);
1970
1971 if (flag == CF_OUTBOUND) {
1972 switch_channel_set_variable(channel, "is_outbound", "true");
1973 }
1974
1975 if (flag == CF_RECOVERED) {
1976 switch_channel_set_variable(channel, "recovered", "true");
1977 }
1978 }
1979
1980
switch_channel_set_private_flag(switch_channel_t * channel,uint32_t flags)1981 SWITCH_DECLARE(void) switch_channel_set_private_flag(switch_channel_t *channel, uint32_t flags)
1982 {
1983 switch_assert(channel != NULL);
1984 switch_mutex_lock(channel->flag_mutex);
1985 channel->private_flags |= flags;
1986 switch_mutex_unlock(channel->flag_mutex);
1987 }
1988
switch_channel_clear_private_flag(switch_channel_t * channel,uint32_t flags)1989 SWITCH_DECLARE(void) switch_channel_clear_private_flag(switch_channel_t *channel, uint32_t flags)
1990 {
1991 switch_assert(channel != NULL);
1992 switch_mutex_lock(channel->flag_mutex);
1993 channel->private_flags &= ~flags;
1994 switch_mutex_unlock(channel->flag_mutex);
1995 }
1996
switch_channel_test_private_flag(switch_channel_t * channel,uint32_t flags)1997 SWITCH_DECLARE(int) switch_channel_test_private_flag(switch_channel_t *channel, uint32_t flags)
1998 {
1999 switch_assert(channel != NULL);
2000 return (channel->private_flags & flags);
2001 }
2002
switch_channel_set_app_flag_key(const char * key,switch_channel_t * channel,uint32_t flags)2003 SWITCH_DECLARE(void) switch_channel_set_app_flag_key(const char *key, switch_channel_t *channel, uint32_t flags)
2004 {
2005 uint32_t *flagp = NULL;
2006 switch_byte_t new = 0;
2007
2008 switch_assert(channel != NULL);
2009 switch_mutex_lock(channel->flag_mutex);
2010
2011 if (!channel->app_flag_hash) {
2012 switch_core_hash_init(&channel->app_flag_hash);
2013 new++;
2014 }
2015
2016 if (new || !(flagp = switch_core_hash_find(channel->app_flag_hash, key))) {
2017 flagp = switch_core_session_alloc(channel->session, sizeof(uint32_t));
2018 switch_core_hash_insert(channel->app_flag_hash, key, flagp);
2019 }
2020
2021 switch_assert(flagp);
2022 *flagp |= flags;
2023
2024 switch_mutex_unlock(channel->flag_mutex);
2025 }
2026
switch_channel_clear_app_flag_key(const char * key,switch_channel_t * channel,uint32_t flags)2027 SWITCH_DECLARE(void) switch_channel_clear_app_flag_key(const char *key, switch_channel_t *channel, uint32_t flags)
2028 {
2029 uint32_t *flagp = NULL;
2030
2031 switch_assert(channel != NULL);
2032 switch_mutex_lock(channel->flag_mutex);
2033 if (channel->app_flag_hash && (flagp = switch_core_hash_find(channel->app_flag_hash, key))) {
2034 if (!flags) {
2035 *flagp = 0;
2036 } else {
2037 *flagp &= ~flags;
2038 }
2039 }
2040 switch_mutex_unlock(channel->flag_mutex);
2041 }
2042
switch_channel_test_app_flag_key(const char * key,switch_channel_t * channel,uint32_t flags)2043 SWITCH_DECLARE(int) switch_channel_test_app_flag_key(const char *key, switch_channel_t *channel, uint32_t flags)
2044 {
2045 int r = 0;
2046 uint32_t *flagp = NULL;
2047 switch_assert(channel != NULL);
2048
2049 switch_mutex_lock(channel->flag_mutex);
2050 if (channel->app_flag_hash && (flagp = switch_core_hash_find(channel->app_flag_hash, key))) {
2051 r = (*flagp & flags);
2052 }
2053 switch_mutex_unlock(channel->flag_mutex);
2054
2055
2056 return r;
2057 }
2058
switch_channel_set_state_flag(switch_channel_t * channel,switch_channel_flag_t flag)2059 SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, switch_channel_flag_t flag)
2060 {
2061 switch_assert(channel != NULL);
2062
2063 switch_mutex_lock(channel->flag_mutex);
2064 channel->state_flags[0] = 1;
2065 channel->state_flags[flag] = 1;
2066 switch_mutex_unlock(channel->flag_mutex);
2067 }
2068
switch_channel_clear_state_flag(switch_channel_t * channel,switch_channel_flag_t flag)2069 SWITCH_DECLARE(void) switch_channel_clear_state_flag(switch_channel_t *channel, switch_channel_flag_t flag)
2070 {
2071 switch_assert(channel != NULL);
2072
2073 switch_mutex_lock(channel->flag_mutex);
2074 channel->state_flags[flag] = 0;
2075 switch_mutex_unlock(channel->flag_mutex);
2076 }
2077
switch_channel_clear_flag(switch_channel_t * channel,switch_channel_flag_t flag)2078 SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
2079 {
2080 int ACTIVE = 0;
2081 int CLEAR = 0;
2082
2083 switch_assert(channel != NULL);
2084 switch_assert(channel->flag_mutex);
2085
2086 switch_mutex_lock(channel->flag_mutex);
2087 if (flag == CF_LEG_HOLDING && channel->flags[flag] && channel->flags[CF_ANSWERED]) {
2088 ACTIVE = 1;
2089 }
2090
2091 if (flag == CF_VIDEO_PASSIVE && channel->flags[CF_VIDEO]) {
2092 channel->flags[CF_VIDEO_READY] = 1;
2093
2094 if (channel->flags[flag]) {
2095 CLEAR = 1;
2096 }
2097 }
2098
2099 channel->flags[flag] = 0;
2100 switch_mutex_unlock(channel->flag_mutex);
2101
2102 if (flag == CF_DIALPLAN) {
2103 if (channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND) {
2104 channel->logical_direction = SWITCH_CALL_DIRECTION_OUTBOUND;
2105 if (channel->device_node) {
2106 channel->device_node->direction = SWITCH_CALL_DIRECTION_INBOUND;
2107 }
2108 }
2109 }
2110
2111 if (ACTIVE) {
2112 switch_channel_set_callstate(channel, CCS_UNHELD);
2113 switch_mutex_lock(channel->profile_mutex);
2114 if (channel->caller_profile->times->last_hold) {
2115 channel->caller_profile->times->hold_accum += (switch_time_now() - channel->caller_profile->times->last_hold);
2116 }
2117
2118 if (channel->hold_record) {
2119 channel->hold_record->off = switch_time_now();
2120 }
2121
2122 if (switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_channel_test_flag(channel, CF_BRIDGED)) {
2123 switch_channel_set_callstate(channel, CCS_ACTIVE);
2124 }
2125
2126 switch_mutex_unlock(channel->profile_mutex);
2127 }
2128
2129 if (flag == CF_ORIGINATOR && switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_up_nosig(channel)) {
2130 switch_channel_set_callstate(channel, CCS_ACTIVE);
2131 }
2132
2133 if (flag == CF_OUTBOUND) {
2134 switch_channel_set_variable(channel, "is_outbound", NULL);
2135 }
2136
2137 if (flag == CF_RECOVERED) {
2138 switch_channel_set_variable(channel, "recovered", NULL);
2139 }
2140
2141 if (flag == CF_VIDEO_PASSIVE && CLEAR) {
2142 switch_core_session_wake_video_thread(channel->session);
2143 }
2144
2145 if (flag == CF_RECOVERING && !channel->hangup_cause) {
2146 switch_core_recovery_track(channel->session);
2147 }
2148
2149 }
2150
2151
switch_channel_clear_flag_recursive(switch_channel_t * channel,switch_channel_flag_t flag)2152 SWITCH_DECLARE(void) switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
2153 {
2154 switch_assert(channel != NULL);
2155 switch_assert(channel->flag_mutex);
2156
2157 switch_mutex_lock(channel->flag_mutex);
2158 if (channel->flags[flag]) {
2159 channel->flags[flag]--;
2160 }
2161 switch_mutex_unlock(channel->flag_mutex);
2162
2163 if (flag == CF_OUTBOUND) {
2164 switch_channel_set_variable(channel, "is_outbound", NULL);
2165 }
2166 }
2167
switch_channel_get_state(switch_channel_t * channel)2168 SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_state(switch_channel_t *channel)
2169 {
2170 switch_channel_state_t state;
2171 switch_assert(channel != NULL);
2172
2173 state = channel->state;
2174
2175 return state;
2176 }
2177
switch_channel_get_running_state(switch_channel_t * channel)2178 SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_running_state(switch_channel_t *channel)
2179 {
2180 switch_channel_state_t state;
2181 switch_assert(channel != NULL);
2182
2183 state = channel->running_state;
2184
2185 return state;
2186 }
2187
switch_channel_state_change_pending(switch_channel_t * channel)2188 SWITCH_DECLARE(int) switch_channel_state_change_pending(switch_channel_t *channel)
2189 {
2190 if (switch_channel_down_nosig(channel) || !switch_core_session_in_thread(channel->session)) {
2191 return 0;
2192 }
2193
2194 return channel->running_state != channel->state;
2195 }
2196
switch_channel_check_signal(switch_channel_t * channel,switch_bool_t in_thread_only)2197 SWITCH_DECLARE(int) switch_channel_check_signal(switch_channel_t *channel, switch_bool_t in_thread_only)
2198 {
2199 switch_ivr_parse_signal_data(channel->session, SWITCH_FALSE, in_thread_only);
2200 return 0;
2201 }
2202
switch_channel_test_ready(switch_channel_t * channel,switch_bool_t check_ready,switch_bool_t check_media)2203 SWITCH_DECLARE(int) switch_channel_test_ready(switch_channel_t *channel, switch_bool_t check_ready, switch_bool_t check_media)
2204 {
2205 int ret = 0;
2206
2207 switch_assert(channel != NULL);
2208
2209 switch_channel_check_signal(channel, SWITCH_TRUE);
2210
2211 if (check_media) {
2212 ret = ((switch_channel_test_flag(channel, CF_ANSWERED) ||
2213 switch_channel_test_flag(channel, CF_EARLY_MEDIA)) && !switch_channel_test_flag(channel, CF_PROXY_MODE) &&
2214 switch_core_session_get_read_codec(channel->session) && switch_core_session_get_write_codec(channel->session));
2215
2216
2217 if (!ret)
2218 return ret;
2219 }
2220
2221 if (!check_ready)
2222 return ret;
2223
2224 ret = 0;
2225
2226 if (!channel->hangup_cause && channel->state > CS_ROUTING && channel->state < CS_HANGUP && channel->state != CS_RESET &&
2227 !switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_NOT_READY) &&
2228 !switch_channel_state_change_pending(channel)) {
2229 ret++;
2230 }
2231
2232
2233
2234 return ret;
2235 }
2236
2237 static const char *state_names[] = {
2238 "CS_NEW",
2239 "CS_INIT",
2240 "CS_ROUTING",
2241 "CS_SOFT_EXECUTE",
2242 "CS_EXECUTE",
2243 "CS_EXCHANGE_MEDIA",
2244 "CS_PARK",
2245 "CS_CONSUME_MEDIA",
2246 "CS_HIBERNATE",
2247 "CS_RESET",
2248 "CS_HANGUP",
2249 "CS_REPORTING",
2250 "CS_DESTROY",
2251 "CS_NONE",
2252 NULL
2253 };
2254
switch_channel_state_name(switch_channel_state_t state)2255 SWITCH_DECLARE(const char *) switch_channel_state_name(switch_channel_state_t state)
2256 {
2257 return state_names[state];
2258 }
2259
2260
switch_channel_name_state(const char * name)2261 SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *name)
2262 {
2263 uint32_t x = 0;
2264 for (x = 0; state_names[x]; x++) {
2265 if (!strcasecmp(state_names[x], name)) {
2266 return (switch_channel_state_t) x;
2267 }
2268 }
2269
2270 return CS_DESTROY;
2271 }
2272
careful_set(switch_channel_t * channel,switch_channel_state_t * state,switch_channel_state_t val)2273 static inline void careful_set(switch_channel_t *channel, switch_channel_state_t *state, switch_channel_state_t val) {
2274
2275 if (switch_mutex_trylock(channel->thread_mutex) == SWITCH_STATUS_SUCCESS) {
2276 *state = val;
2277 switch_mutex_unlock(channel->thread_mutex);
2278 } else {
2279 switch_mutex_t *mutex = switch_core_session_get_mutex(channel->session);
2280 int x = 0;
2281
2282 for (x = 0; x < 100; x++) {
2283 if (switch_mutex_trylock(mutex) == SWITCH_STATUS_SUCCESS) {
2284 *state = val;
2285 switch_mutex_unlock(mutex);
2286 break;
2287 } else {
2288 switch_cond_next();
2289 }
2290 }
2291
2292 if (x == 100) {
2293 *state = val;
2294 }
2295
2296 }
2297 }
2298
switch_channel_perform_set_running_state(switch_channel_t * channel,switch_channel_state_t state,const char * file,const char * func,int line)2299 SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel, switch_channel_state_t state,
2300 const char *file, const char *func, int line)
2301 {
2302 int x;
2303
2304 switch_mutex_lock(channel->flag_mutex);
2305 if (channel->state_flags[0]) {
2306 for (x = 1; x < CF_FLAG_MAX; x++) {
2307 if (channel->state_flags[x]) {
2308 channel->flags[x] = 1;
2309 channel->state_flags[x] = 0;
2310 }
2311 }
2312 channel->state_flags[0] = 0;
2313 }
2314 switch_mutex_unlock(channel->flag_mutex);
2315
2316 switch_channel_clear_flag(channel, CF_TAGGED);
2317
2318
2319 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG, "(%s) Running State Change %s (Cur %d Tot %" SWITCH_SIZE_T_FMT ")\n",
2320 channel->name, state_names[state], switch_core_session_count(), switch_core_session_id() - 1);
2321
2322 switch_mutex_lock(channel->state_mutex);
2323
2324 careful_set(channel, &channel->running_state, state);
2325
2326 if (state <= CS_DESTROY) {
2327 switch_event_t *event;
2328
2329 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
2330 if (state < CS_HANGUP) {
2331 if (state == CS_ROUTING) {
2332 switch_channel_set_callstate(channel, CCS_RINGING);
2333 } else if (switch_channel_test_flag(channel, CF_ANSWERED)) {
2334 switch_channel_set_callstate(channel, CCS_ACTIVE);
2335 } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
2336 switch_channel_set_callstate(channel, CCS_EARLY);
2337 }
2338 }
2339 }
2340
2341 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_STATE) == SWITCH_STATUS_SUCCESS) {
2342 switch_channel_event_set_data(channel, event);
2343 switch_event_fire(&event);
2344 }
2345 }
2346
2347 switch_mutex_unlock(channel->state_mutex);
2348
2349 return (switch_channel_state_t) SWITCH_STATUS_SUCCESS;
2350 }
2351
switch_channel_perform_set_state(switch_channel_t * channel,const char * file,const char * func,int line,switch_channel_state_t state)2352 SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_channel_t *channel,
2353 const char *file, const char *func, int line, switch_channel_state_t state)
2354 {
2355 switch_channel_state_t last_state;
2356 int ok = 0;
2357
2358 switch_assert(channel != NULL);
2359 switch_assert(state <= CS_DESTROY);
2360 switch_mutex_lock(channel->state_mutex);
2361
2362 last_state = channel->state;
2363 switch_assert(last_state <= CS_DESTROY);
2364
2365 if (last_state == state) {
2366 goto done;
2367 }
2368
2369 if (last_state >= CS_HANGUP && state < last_state) {
2370 goto done;
2371 }
2372
2373 /* STUB for more dev
2374 case CS_INIT:
2375 switch(state) {
2376
2377 case CS_NEW:
2378 case CS_INIT:
2379 case CS_EXCHANGE_MEDIA:
2380 case CS_SOFT_EXECUTE:
2381 case CS_ROUTING:
2382 case CS_EXECUTE:
2383 case CS_HANGUP:
2384 case CS_DESTROY:
2385
2386 default:
2387 break;
2388 }
2389 break;
2390 */
2391
2392 switch (last_state) {
2393 case CS_NEW:
2394 case CS_RESET:
2395 switch (state) {
2396 default:
2397 ok++;
2398 break;
2399 }
2400 break;
2401
2402 case CS_INIT:
2403 switch (state) {
2404 case CS_EXCHANGE_MEDIA:
2405 case CS_SOFT_EXECUTE:
2406 case CS_ROUTING:
2407 case CS_EXECUTE:
2408 case CS_PARK:
2409 case CS_CONSUME_MEDIA:
2410 case CS_HIBERNATE:
2411 case CS_RESET:
2412 ok++;
2413 default:
2414 break;
2415 }
2416 break;
2417
2418 case CS_EXCHANGE_MEDIA:
2419 switch (state) {
2420 case CS_SOFT_EXECUTE:
2421 case CS_ROUTING:
2422 case CS_EXECUTE:
2423 case CS_PARK:
2424 case CS_CONSUME_MEDIA:
2425 case CS_HIBERNATE:
2426 case CS_RESET:
2427 ok++;
2428 default:
2429 break;
2430 }
2431 break;
2432
2433 case CS_SOFT_EXECUTE:
2434 switch (state) {
2435 case CS_EXCHANGE_MEDIA:
2436 case CS_ROUTING:
2437 case CS_EXECUTE:
2438 case CS_PARK:
2439 case CS_CONSUME_MEDIA:
2440 case CS_HIBERNATE:
2441 case CS_RESET:
2442 ok++;
2443 default:
2444 break;
2445 }
2446 break;
2447
2448 case CS_PARK:
2449 switch (state) {
2450 case CS_EXCHANGE_MEDIA:
2451 case CS_ROUTING:
2452 case CS_EXECUTE:
2453 case CS_SOFT_EXECUTE:
2454 case CS_HIBERNATE:
2455 case CS_RESET:
2456 case CS_CONSUME_MEDIA:
2457 ok++;
2458 default:
2459 break;
2460 }
2461 break;
2462
2463 case CS_CONSUME_MEDIA:
2464 switch (state) {
2465 case CS_EXCHANGE_MEDIA:
2466 case CS_ROUTING:
2467 case CS_EXECUTE:
2468 case CS_SOFT_EXECUTE:
2469 case CS_HIBERNATE:
2470 case CS_RESET:
2471 case CS_PARK:
2472 ok++;
2473 default:
2474 break;
2475 }
2476 break;
2477 case CS_HIBERNATE:
2478 switch (state) {
2479 case CS_EXCHANGE_MEDIA:
2480 case CS_INIT:
2481 case CS_ROUTING:
2482 case CS_EXECUTE:
2483 case CS_SOFT_EXECUTE:
2484 case CS_PARK:
2485 case CS_CONSUME_MEDIA:
2486 case CS_RESET:
2487 ok++;
2488 default:
2489 break;
2490 }
2491 break;
2492
2493 case CS_ROUTING:
2494 switch (state) {
2495 case CS_EXCHANGE_MEDIA:
2496 case CS_EXECUTE:
2497 case CS_SOFT_EXECUTE:
2498 case CS_PARK:
2499 case CS_CONSUME_MEDIA:
2500 case CS_HIBERNATE:
2501 case CS_RESET:
2502 ok++;
2503 default:
2504 break;
2505 }
2506 break;
2507
2508 case CS_EXECUTE:
2509 switch (state) {
2510 case CS_EXCHANGE_MEDIA:
2511 case CS_SOFT_EXECUTE:
2512 case CS_ROUTING:
2513 case CS_PARK:
2514 case CS_CONSUME_MEDIA:
2515 case CS_HIBERNATE:
2516 case CS_RESET:
2517 ok++;
2518 default:
2519 break;
2520 }
2521 break;
2522
2523 case CS_HANGUP:
2524 switch (state) {
2525 case CS_REPORTING:
2526 case CS_DESTROY:
2527 ok++;
2528 default:
2529 break;
2530 }
2531 break;
2532
2533 case CS_REPORTING:
2534 switch (state) {
2535 case CS_DESTROY:
2536 ok++;
2537 default:
2538 break;
2539 }
2540 break;
2541
2542 default:
2543 break;
2544
2545 }
2546
2547 if (ok) {
2548 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG, "(%s) State Change %s -> %s\n",
2549 channel->name, state_names[last_state], state_names[state]);
2550
2551 careful_set(channel, &channel->state, state);
2552
2553 if (state == CS_HANGUP && !channel->hangup_cause) {
2554 channel->hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING;
2555 }
2556
2557 if (state <= CS_DESTROY) {
2558 switch_core_session_signal_state_change(channel->session);
2559 }
2560 } else {
2561 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_WARNING,
2562 "(%s) Invalid State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]);
2563 /* we won't tolerate an invalid state change so we can make sure we are as robust as a nice cup of dark coffee! */
2564 /* not cool lets crash this bad boy and figure out wtf is going on */
2565 switch_assert(channel->state >= CS_HANGUP);
2566 }
2567 done:
2568
2569 switch_mutex_unlock(channel->state_mutex);
2570 return channel->state;
2571 }
2572
switch_channel_state_thread_lock(switch_channel_t * channel)2573 SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel)
2574 {
2575 switch_mutex_lock(channel->thread_mutex);
2576 }
2577
2578
switch_channel_state_thread_trylock(switch_channel_t * channel)2579 SWITCH_DECLARE(switch_status_t) switch_channel_state_thread_trylock(switch_channel_t *channel)
2580 {
2581 return switch_mutex_trylock(channel->thread_mutex);
2582 }
2583
2584
switch_channel_state_thread_unlock(switch_channel_t * channel)2585 SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel)
2586 {
2587 switch_mutex_unlock(channel->thread_mutex);
2588 }
2589
switch_channel_event_set_basic_data(switch_channel_t * channel,switch_event_t * event)2590 SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *channel, switch_event_t *event)
2591 {
2592 switch_caller_profile_t *caller_profile, *originator_caller_profile = NULL, *originatee_caller_profile = NULL;
2593 switch_codec_implementation_t impl = { 0 };
2594 char state_num[25];
2595 const char *v;
2596
2597 switch_mutex_lock(channel->profile_mutex);
2598
2599 if ((caller_profile = channel->caller_profile)) {
2600 originator_caller_profile = caller_profile->originator_caller_profile;
2601 originatee_caller_profile = caller_profile->originatee_caller_profile;
2602 }
2603
2604 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", switch_channel_state_name(channel->running_state));
2605 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", switch_channel_callstate2str(channel->callstate));
2606 switch_snprintf(state_num, sizeof(state_num), "%d", channel->state);
2607 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", state_num);
2608 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Name", switch_channel_get_name(channel));
2609 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(channel->session));
2610
2611 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Call-Direction",
2612 channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
2613 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Call-Direction",
2614 channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
2615
2616 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-HIT-Dialplan",
2617 switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND ||
2618 switch_channel_test_flag(channel, CF_DIALPLAN) ? "true" : "false");
2619
2620
2621 if ((v = switch_channel_get_variable_dup(channel, "presence_id", SWITCH_FALSE, -1))) {
2622 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-ID", v);
2623 }
2624
2625 if ((v = switch_channel_get_variable_dup(channel, "presence_data", SWITCH_FALSE, -1))) {
2626 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-Data", v);
2627 }
2628
2629
2630 if ((v = switch_channel_get_variable_dup(channel, "presence_data_cols", SWITCH_FALSE, -1))) {
2631 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Data-Cols", v);
2632 switch_event_add_presence_data_cols(channel, event, "PD-");
2633 }
2634
2635 if ((v = switch_channel_get_variable_dup(channel, "call_uuid", SWITCH_FALSE, -1))) {
2636 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-UUID", v);
2637 } else {
2638 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-UUID", switch_core_session_get_uuid(channel->session));
2639 }
2640
2641 if (switch_channel_down_nosig(channel)) {
2642 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "hangup");
2643 } else if (switch_channel_test_flag(channel, CF_ANSWERED)) {
2644 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "answered");
2645 } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
2646 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "early");
2647 } else {
2648 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "ringing");
2649 }
2650
2651 if (channel->hangup_cause) {
2652 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(channel->hangup_cause));
2653 }
2654
2655
2656 switch_core_session_get_read_impl(channel->session, &impl);
2657
2658 if (impl.iananame) {
2659 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Name", impl.iananame);
2660 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Rate", "%u", impl.actual_samples_per_second);
2661 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Bit-Rate", "%d", impl.bits_per_second);
2662 }
2663
2664 switch_core_session_get_write_impl(channel->session, &impl);
2665
2666 if (impl.iananame) {
2667 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", impl.iananame);
2668 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%u", impl.actual_samples_per_second);
2669 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Bit-Rate", "%d", impl.bits_per_second);
2670 }
2671
2672 /* Index Caller's Profile */
2673 if (caller_profile) {
2674 switch_caller_profile_event_set_data(caller_profile, "Caller", event);
2675 }
2676
2677 /* Index Originator/ee's Profile */
2678 if (originator_caller_profile && channel->last_profile_type == LP_ORIGINATOR) {
2679 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Type", "originator");
2680 switch_caller_profile_event_set_data(originator_caller_profile, "Other-Leg", event);
2681 } else if (originatee_caller_profile && channel->last_profile_type == LP_ORIGINATEE) { /* Index Originatee's Profile */
2682 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Type", "originatee");
2683 switch_caller_profile_event_set_data(originatee_caller_profile, "Other-Leg", event);
2684 }
2685
2686
2687 switch_mutex_unlock(channel->profile_mutex);
2688 }
2689
switch_channel_event_set_extended_data(switch_channel_t * channel,switch_event_t * event)2690 SWITCH_DECLARE(void) switch_channel_event_set_extended_data(switch_channel_t *channel, switch_event_t *event)
2691 {
2692 switch_event_header_t *hi;
2693 int global_verbose_events = -1;
2694
2695 switch_mutex_lock(channel->profile_mutex);
2696
2697 switch_core_session_ctl(SCSC_VERBOSE_EVENTS, &global_verbose_events);
2698
2699 if (global_verbose_events ||
2700 switch_channel_test_flag(channel, CF_VERBOSE_EVENTS) ||
2701 switch_event_get_header(event, "presence-data-cols") ||
2702 event->event_id == SWITCH_EVENT_CHANNEL_CREATE ||
2703 event->event_id == SWITCH_EVENT_CHANNEL_ORIGINATE ||
2704 event->event_id == SWITCH_EVENT_CHANNEL_UUID ||
2705 event->event_id == SWITCH_EVENT_CHANNEL_ANSWER ||
2706 event->event_id == SWITCH_EVENT_CHANNEL_PARK ||
2707 event->event_id == SWITCH_EVENT_CHANNEL_UNPARK ||
2708 event->event_id == SWITCH_EVENT_CHANNEL_BRIDGE ||
2709 event->event_id == SWITCH_EVENT_CHANNEL_UNBRIDGE ||
2710 event->event_id == SWITCH_EVENT_CHANNEL_PROGRESS ||
2711 event->event_id == SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA ||
2712 event->event_id == SWITCH_EVENT_CHANNEL_HANGUP ||
2713 event->event_id == SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE ||
2714 event->event_id == SWITCH_EVENT_REQUEST_PARAMS ||
2715 event->event_id == SWITCH_EVENT_CHANNEL_DATA ||
2716 event->event_id == SWITCH_EVENT_CHANNEL_EXECUTE ||
2717 event->event_id == SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE ||
2718 event->event_id == SWITCH_EVENT_CHANNEL_DESTROY ||
2719 event->event_id == SWITCH_EVENT_SESSION_HEARTBEAT ||
2720 event->event_id == SWITCH_EVENT_API ||
2721 event->event_id == SWITCH_EVENT_RECORD_START ||
2722 event->event_id == SWITCH_EVENT_RECORD_STOP ||
2723 event->event_id == SWITCH_EVENT_PLAYBACK_START ||
2724 event->event_id == SWITCH_EVENT_PLAYBACK_STOP ||
2725 event->event_id == SWITCH_EVENT_CALL_UPDATE ||
2726 event->event_id == SWITCH_EVENT_MEDIA_BUG_START ||
2727 event->event_id == SWITCH_EVENT_MEDIA_BUG_STOP ||
2728 event->event_id == SWITCH_EVENT_CHANNEL_HOLD ||
2729 event->event_id == SWITCH_EVENT_CHANNEL_UNHOLD ||
2730 event->event_id == SWITCH_EVENT_TEXT ||
2731 event->event_id == SWITCH_EVENT_CUSTOM) {
2732
2733 /* Index Variables */
2734
2735 if (channel->scope_variables) {
2736 switch_event_t *ep;
2737
2738 for (ep = channel->scope_variables; ep; ep = ep->next) {
2739 for (hi = ep->headers; hi; hi = hi->next) {
2740 char buf[1024];
2741 char *vvar = NULL, *vval = NULL;
2742
2743 vvar = (char *) hi->name;
2744 vval = (char *) hi->value;
2745
2746 switch_assert(vvar && vval);
2747 switch_snprintf(buf, sizeof(buf), "scope_variable_%s", vvar);
2748
2749 if (!switch_event_get_header(event, buf)) {
2750 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, buf, vval);
2751 }
2752 }
2753 }
2754 }
2755
2756 if (channel->variables) {
2757 for (hi = channel->variables->headers; hi; hi = hi->next) {
2758 char buf[1024];
2759 char *vvar = NULL, *vval = NULL;
2760
2761 vvar = (char *) hi->name;
2762 vval = (char *) hi->value;
2763
2764 switch_assert(vvar && vval);
2765 switch_snprintf(buf, sizeof(buf), "variable_%s", vvar);
2766 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, buf, vval);
2767 }
2768 }
2769 }
2770
2771 switch_mutex_unlock(channel->profile_mutex);
2772 }
2773
2774
switch_channel_event_set_data(switch_channel_t * channel,switch_event_t * event)2775 SWITCH_DECLARE(void) switch_channel_event_set_data(switch_channel_t *channel, switch_event_t *event)
2776 {
2777 switch_mutex_lock(channel->profile_mutex);
2778 switch_channel_event_set_basic_data(channel, event);
2779 switch_channel_event_set_extended_data(channel, event);
2780 switch_mutex_unlock(channel->profile_mutex);
2781 }
2782
switch_channel_step_caller_profile(switch_channel_t * channel)2783 SWITCH_DECLARE(void) switch_channel_step_caller_profile(switch_channel_t *channel)
2784 {
2785 switch_caller_profile_t *cp;
2786
2787
2788 switch_mutex_lock(channel->profile_mutex);
2789 cp = switch_caller_profile_clone(channel->session, channel->caller_profile);
2790 switch_mutex_unlock(channel->profile_mutex);
2791
2792 switch_channel_set_caller_profile(channel, cp);
2793 }
2794
switch_channel_set_caller_profile(switch_channel_t * channel,switch_caller_profile_t * caller_profile)2795 SWITCH_DECLARE(void) switch_channel_set_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
2796 {
2797 char *uuid = NULL;
2798 switch_assert(channel != NULL);
2799 switch_assert(channel->session != NULL);
2800 switch_mutex_lock(channel->profile_mutex);
2801 switch_assert(caller_profile != NULL);
2802
2803 caller_profile->direction = channel->direction;
2804 caller_profile->logical_direction = channel->logical_direction;
2805 uuid = switch_core_session_get_uuid(channel->session);
2806
2807 if (!caller_profile->uuid || strcasecmp(caller_profile->uuid, uuid)) {
2808 caller_profile->uuid = switch_core_session_strdup(channel->session, uuid);
2809 }
2810
2811 if (!caller_profile->chan_name || strcasecmp(caller_profile->chan_name, channel->name)) {
2812 caller_profile->chan_name = switch_core_session_strdup(channel->session, channel->name);
2813 }
2814
2815 if (!caller_profile->context) {
2816 caller_profile->context = switch_core_session_strdup(channel->session, "default");
2817 }
2818
2819 if (!caller_profile->times) {
2820 caller_profile->times = (switch_channel_timetable_t *) switch_core_session_alloc(channel->session, sizeof(*caller_profile->times));
2821 caller_profile->times->profile_created = switch_micro_time_now();
2822 }
2823
2824 if (channel->caller_profile && channel->caller_profile->times) {
2825 channel->caller_profile->times->transferred = caller_profile->times->profile_created;
2826 caller_profile->times->answered = channel->caller_profile->times->answered;
2827 caller_profile->times->progress = channel->caller_profile->times->progress;
2828 caller_profile->times->progress_media = channel->caller_profile->times->progress_media;
2829 caller_profile->times->created = channel->caller_profile->times->created;
2830 caller_profile->times->hungup = channel->caller_profile->times->hungup;
2831 if (channel->caller_profile->caller_extension) {
2832 switch_caller_extension_clone(&caller_profile->caller_extension, channel->caller_profile->caller_extension, caller_profile->pool);
2833 }
2834 } else {
2835 caller_profile->times->created = switch_micro_time_now();
2836 }
2837
2838
2839 caller_profile->next = channel->caller_profile;
2840 channel->caller_profile = caller_profile;
2841 caller_profile->profile_index = switch_core_sprintf(caller_profile->pool, "%d", ++channel->profile_index);
2842
2843 switch_mutex_unlock(channel->profile_mutex);
2844 }
2845
switch_channel_get_caller_profile(switch_channel_t * channel)2846 SWITCH_DECLARE(switch_caller_profile_t *) switch_channel_get_caller_profile(switch_channel_t *channel)
2847 {
2848 switch_caller_profile_t *profile;
2849 switch_assert(channel != NULL);
2850 switch_mutex_lock(channel->profile_mutex);
2851 if ((profile = channel->caller_profile) && profile->hunt_caller_profile) {
2852 profile = profile->hunt_caller_profile;
2853 }
2854 switch_mutex_unlock(channel->profile_mutex);
2855 return profile;
2856 }
2857
switch_channel_set_originator_caller_profile(switch_channel_t * channel,switch_caller_profile_t * caller_profile)2858 SWITCH_DECLARE(void) switch_channel_set_originator_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
2859 {
2860 switch_assert(channel != NULL);
2861 switch_assert(channel->caller_profile != NULL);
2862 switch_mutex_lock(channel->profile_mutex);
2863
2864 if (!caller_profile->times) {
2865 caller_profile->times = (switch_channel_timetable_t *) switch_core_alloc(caller_profile->pool, sizeof(*caller_profile->times));
2866 }
2867
2868 if (channel->caller_profile) {
2869 caller_profile->next = channel->caller_profile->originator_caller_profile;
2870 channel->caller_profile->originator_caller_profile = caller_profile;
2871 channel->last_profile_type = LP_ORIGINATOR;
2872 }
2873 switch_assert(channel->caller_profile->originator_caller_profile->next != channel->caller_profile->originator_caller_profile);
2874 switch_mutex_unlock(channel->profile_mutex);
2875 }
2876
switch_channel_set_hunt_caller_profile(switch_channel_t * channel,switch_caller_profile_t * caller_profile)2877 SWITCH_DECLARE(void) switch_channel_set_hunt_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
2878 {
2879 switch_assert(channel != NULL);
2880 switch_assert(channel->caller_profile != NULL);
2881
2882 switch_mutex_lock(channel->profile_mutex);
2883
2884 channel->caller_profile->hunt_caller_profile = NULL;
2885 if (channel->caller_profile && caller_profile) {
2886 caller_profile->direction = channel->direction;
2887 caller_profile->logical_direction = channel->logical_direction;
2888 channel->caller_profile->hunt_caller_profile = caller_profile;
2889 }
2890 switch_mutex_unlock(channel->profile_mutex);
2891 }
2892
switch_channel_set_origination_caller_profile(switch_channel_t * channel,switch_caller_profile_t * caller_profile)2893 SWITCH_DECLARE(void) switch_channel_set_origination_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
2894 {
2895 switch_assert(channel != NULL);
2896 switch_assert(channel->caller_profile != NULL);
2897
2898 switch_mutex_lock(channel->profile_mutex);
2899
2900 if (channel->caller_profile) {
2901 caller_profile->next = channel->caller_profile->origination_caller_profile;
2902 channel->caller_profile->origination_caller_profile = caller_profile;
2903 }
2904 switch_assert(channel->caller_profile->origination_caller_profile->next != channel->caller_profile->origination_caller_profile);
2905 switch_mutex_unlock(channel->profile_mutex);
2906 }
2907
switch_channel_get_origination_caller_profile(switch_channel_t * channel)2908 SWITCH_DECLARE(switch_caller_profile_t *) switch_channel_get_origination_caller_profile(switch_channel_t *channel)
2909 {
2910 switch_caller_profile_t *profile = NULL;
2911 switch_assert(channel != NULL);
2912
2913 switch_mutex_lock(channel->profile_mutex);
2914 if (channel->caller_profile) {
2915 profile = channel->caller_profile->origination_caller_profile;
2916 }
2917 switch_mutex_unlock(channel->profile_mutex);
2918
2919 return profile;
2920 }
2921
2922
switch_channel_set_originatee_caller_profile(switch_channel_t * channel,switch_caller_profile_t * caller_profile)2923 SWITCH_DECLARE(void) switch_channel_set_originatee_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
2924 {
2925 switch_assert(channel != NULL);
2926 switch_assert(channel->caller_profile != NULL);
2927
2928 switch_mutex_lock(channel->profile_mutex);
2929
2930 if (channel->caller_profile) {
2931 caller_profile->next = channel->caller_profile->originatee_caller_profile;
2932 channel->caller_profile->originatee_caller_profile = caller_profile;
2933 channel->last_profile_type = LP_ORIGINATEE;
2934 }
2935 switch_assert(channel->caller_profile->originatee_caller_profile->next != channel->caller_profile->originatee_caller_profile);
2936 switch_mutex_unlock(channel->profile_mutex);
2937 }
2938
switch_channel_get_originator_caller_profile(switch_channel_t * channel)2939 SWITCH_DECLARE(switch_caller_profile_t *) switch_channel_get_originator_caller_profile(switch_channel_t *channel)
2940 {
2941 switch_caller_profile_t *profile = NULL;
2942 switch_assert(channel != NULL);
2943
2944 switch_mutex_lock(channel->profile_mutex);
2945
2946 if (channel->caller_profile) {
2947 profile = channel->caller_profile->originator_caller_profile;
2948 }
2949 switch_mutex_unlock(channel->profile_mutex);
2950
2951 return profile;
2952 }
2953
switch_channel_get_originatee_caller_profile(switch_channel_t * channel)2954 SWITCH_DECLARE(switch_caller_profile_t *) switch_channel_get_originatee_caller_profile(switch_channel_t *channel)
2955 {
2956 switch_caller_profile_t *profile = NULL;
2957 switch_assert(channel != NULL);
2958
2959 switch_mutex_lock(channel->profile_mutex);
2960 if (channel->caller_profile) {
2961 profile = channel->caller_profile->originatee_caller_profile;
2962 }
2963 switch_mutex_unlock(channel->profile_mutex);
2964
2965 return profile;
2966 }
2967
switch_channel_get_uuid(switch_channel_t * channel)2968 SWITCH_DECLARE(char *) switch_channel_get_uuid(switch_channel_t *channel)
2969 {
2970 switch_assert(channel != NULL);
2971 switch_assert(channel->session != NULL);
2972 return switch_core_session_get_uuid(channel->session);
2973 }
2974
switch_channel_add_state_handler(switch_channel_t * channel,const switch_state_handler_table_t * state_handler)2975 SWITCH_DECLARE(int) switch_channel_add_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler)
2976 {
2977 int x, index;
2978
2979 switch_assert(channel != NULL);
2980 switch_mutex_lock(channel->state_mutex);
2981 for (x = 0; x < SWITCH_MAX_STATE_HANDLERS; x++) {
2982 if (channel->state_handlers[x] == state_handler) {
2983 index = x;
2984 goto end;
2985 }
2986 }
2987 index = channel->state_handler_index++;
2988
2989 if (channel->state_handler_index >= SWITCH_MAX_STATE_HANDLERS) {
2990 index = -1;
2991 goto end;
2992 }
2993
2994 channel->state_handlers[index] = state_handler;
2995
2996 end:
2997 switch_mutex_unlock(channel->state_mutex);
2998 return index;
2999 }
3000
switch_channel_get_state_handler(switch_channel_t * channel,int index)3001 SWITCH_DECLARE(const switch_state_handler_table_t *) switch_channel_get_state_handler(switch_channel_t *channel, int index)
3002 {
3003 const switch_state_handler_table_t *h = NULL;
3004
3005 switch_assert(channel != NULL);
3006
3007 if (index >= SWITCH_MAX_STATE_HANDLERS || index > channel->state_handler_index) {
3008 return NULL;
3009 }
3010
3011 switch_mutex_lock(channel->state_mutex);
3012 h = channel->state_handlers[index];
3013 switch_mutex_unlock(channel->state_mutex);
3014
3015 return h;
3016 }
3017
switch_channel_clear_state_handler(switch_channel_t * channel,const switch_state_handler_table_t * state_handler)3018 SWITCH_DECLARE(void) switch_channel_clear_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler)
3019 {
3020 int index, i = channel->state_handler_index;
3021 const switch_state_handler_table_t *new_handlers[SWITCH_MAX_STATE_HANDLERS] = { 0 };
3022
3023 switch_assert(channel != NULL);
3024
3025 switch_mutex_lock(channel->state_mutex);
3026 channel->state_handler_index = 0;
3027
3028 if (state_handler) {
3029 for (index = 0; index < i; index++) {
3030 if (channel->state_handlers[index] != state_handler) {
3031 new_handlers[channel->state_handler_index++] = channel->state_handlers[index];
3032 }
3033 }
3034 } else {
3035 for (index = 0; index < i; index++) {
3036 if (channel->state_handlers[index] && switch_test_flag(channel->state_handlers[index], SSH_FLAG_STICKY)) {
3037 new_handlers[channel->state_handler_index++] = channel->state_handlers[index];
3038 }
3039 }
3040 }
3041
3042 for (index = 0; index < SWITCH_MAX_STATE_HANDLERS; index++) {
3043 channel->state_handlers[index] = NULL;
3044 }
3045
3046 if (channel->state_handler_index > 0) {
3047 for (index = 0; index < channel->state_handler_index; index++) {
3048 channel->state_handlers[index] = new_handlers[index];
3049 }
3050 }
3051
3052 switch_mutex_unlock(channel->state_mutex);
3053 }
3054
switch_channel_restart(switch_channel_t * channel)3055 SWITCH_DECLARE(void) switch_channel_restart(switch_channel_t *channel)
3056 {
3057 switch_channel_set_state(channel, CS_RESET);
3058 switch_channel_wait_for_state_timeout(channel, CS_RESET, 5000);
3059 switch_channel_set_state(channel, CS_EXECUTE);
3060 }
3061
3062 /* XXX This is a somewhat simple operation. Were essentially taking the extension that one channel
3063 was executing and generating a new extension for another channel that starts out where the
3064 original one left off with an optional forward offset. Since all we are really doing is
3065 copying a few basic pool-allocated structures from one channel to another there really is
3066 not much to worry about here in terms of threading since we use read-write locks.
3067 While the features are nice, they only really are needed in one specific crazy attended
3068 transfer scenario where one channel was in the middle of calling a particular extension
3069 when it was rudely cut off by a transfer key press. XXX */
3070
switch_channel_caller_extension_masquerade(switch_channel_t * orig_channel,switch_channel_t * new_channel,uint32_t offset)3071 SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switch_channel_t *orig_channel, switch_channel_t *new_channel, uint32_t offset)
3072 {
3073 switch_caller_profile_t *caller_profile;
3074 switch_caller_extension_t *extension = NULL, *orig_extension = NULL;
3075 switch_caller_application_t *ap;
3076 switch_status_t status = SWITCH_STATUS_FALSE;
3077 switch_event_header_t *hi = NULL;
3078 const char *no_copy = switch_channel_get_variable(orig_channel, "attended_transfer_no_copy");
3079 char *dup;
3080 int i, argc = 0;
3081 char *argv[128];
3082
3083 if (no_copy) {
3084 dup = switch_core_session_strdup(new_channel->session, no_copy);
3085 argc = switch_separate_string(dup, ',', argv, (sizeof(argv) / sizeof(argv[0])));
3086 }
3087
3088
3089 switch_mutex_lock(orig_channel->profile_mutex);
3090 switch_mutex_lock(new_channel->profile_mutex);
3091
3092
3093 caller_profile = switch_caller_profile_clone(new_channel->session, new_channel->caller_profile);
3094 switch_assert(caller_profile);
3095 extension = switch_caller_extension_new(new_channel->session, caller_profile->destination_number, caller_profile->destination_number);
3096 orig_extension = switch_channel_get_caller_extension(orig_channel);
3097
3098
3099 if (extension && orig_extension) {
3100 for (ap = orig_extension->current_application; ap && offset > 0; offset--) {
3101 ap = ap->next;
3102 }
3103
3104 for (; ap; ap = ap->next) {
3105 switch_caller_extension_add_application(new_channel->session, extension, ap->application_name, ap->application_data);
3106 }
3107
3108 caller_profile->destination_number = switch_core_strdup(caller_profile->pool, orig_channel->caller_profile->destination_number);
3109 switch_channel_set_caller_profile(new_channel, caller_profile);
3110 switch_channel_set_caller_extension(new_channel, extension);
3111
3112 for (hi = orig_channel->variables->headers; hi; hi = hi->next) {
3113 int ok = 1;
3114 for (i = 0; i < argc; i++) {
3115 if (!strcasecmp(argv[i], hi->name)) {
3116 ok = 0;
3117 break;
3118 }
3119 }
3120
3121 if (!ok)
3122 continue;
3123
3124 switch_channel_set_variable(new_channel, hi->name, hi->value);
3125 }
3126
3127 status = SWITCH_STATUS_SUCCESS;
3128 }
3129
3130
3131 switch_mutex_unlock(new_channel->profile_mutex);
3132 switch_mutex_unlock(orig_channel->profile_mutex);
3133
3134
3135 return status;
3136 }
3137
switch_channel_invert_cid(switch_channel_t * channel)3138 SWITCH_DECLARE(void) switch_channel_invert_cid(switch_channel_t *channel)
3139 {
3140 const char *tname, *tnum;
3141 switch_caller_profile_t *cp;
3142
3143 cp = switch_channel_get_caller_profile(channel);
3144
3145 tname = cp->caller_id_name;
3146 tnum = cp->caller_id_number;
3147
3148 #ifdef DEEP_DEBUG_CID
3149 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SWAP [%s][%s] [%s][%s]\n", cp->caller_id_name, cp->caller_id_number, cp->callee_id_name, cp->callee_id_number);
3150 #endif
3151
3152 cp->caller_id_name = cp->callee_id_name;
3153 cp->caller_id_number = cp->callee_id_number;
3154
3155 cp->callee_id_name = tname;
3156 cp->callee_id_number = tnum;
3157
3158 if (zstr(cp->caller_id_name)) {
3159 cp->caller_id_name = "Unknown";
3160 }
3161
3162 if (zstr(cp->caller_id_number)) {
3163 cp->caller_id_number = "Unknown";
3164 }
3165 }
3166
3167
switch_channel_flip_cid(switch_channel_t * channel)3168 SWITCH_DECLARE(void) switch_channel_flip_cid(switch_channel_t *channel)
3169 {
3170 switch_event_t *event;
3171 const char *tmp = NULL;
3172
3173 switch_mutex_lock(channel->profile_mutex);
3174 if (channel->caller_profile->callee_id_name) {
3175 tmp = channel->caller_profile->caller_id_name;
3176 switch_channel_set_variable(channel, "pre_transfer_caller_id_name", channel->caller_profile->caller_id_name);
3177 channel->caller_profile->caller_id_name = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_name);
3178 }
3179
3180 if (switch_channel_test_flag(channel, CF_BRIDGED)) {
3181 channel->caller_profile->callee_id_name = SWITCH_BLANK_STRING;
3182 } else if (tmp) {
3183 channel->caller_profile->callee_id_name = tmp;
3184 }
3185
3186 if (channel->caller_profile->callee_id_number) {
3187 tmp = channel->caller_profile->caller_id_number;
3188 switch_channel_set_variable(channel, "pre_transfer_caller_id_number", channel->caller_profile->caller_id_number);
3189 channel->caller_profile->caller_id_number = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_number);
3190 }
3191
3192 if (switch_channel_test_flag(channel, CF_BRIDGED)) {
3193 channel->caller_profile->callee_id_number = SWITCH_BLANK_STRING;
3194 } else if (tmp) {
3195 channel->caller_profile->callee_id_number = tmp;
3196 }
3197
3198 switch_mutex_unlock(channel->profile_mutex);
3199
3200
3201 if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) {
3202 const char *uuid = switch_channel_get_partner_uuid(channel);
3203 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "RECV");
3204
3205 if (uuid) {
3206 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
3207 }
3208 switch_channel_event_set_data(channel, event);
3209 switch_event_fire(&event);
3210 }
3211
3212
3213 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_INFO, "%s Flipping CID from \"%s\" <%s> to \"%s\" <%s>\n",
3214 switch_channel_get_name(channel),
3215 switch_str_nil(switch_channel_get_variable(channel, "pre_transfer_caller_id_name")),
3216 switch_str_nil(switch_channel_get_variable(channel, "pre_transfer_caller_id_number")),
3217 channel->caller_profile->caller_id_name,
3218 channel->caller_profile->caller_id_number
3219 );
3220
3221 }
3222
switch_channel_sort_cid(switch_channel_t * channel)3223 SWITCH_DECLARE(void) switch_channel_sort_cid(switch_channel_t *channel)
3224 {
3225
3226 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && switch_channel_test_flag(channel, CF_BLEG)) {
3227 switch_channel_flip_cid(channel);
3228 switch_channel_clear_flag(channel, CF_BLEG);
3229 } else if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(channel, CF_DIALPLAN)) {
3230 switch_channel_set_flag(channel, CF_DIALPLAN);
3231 switch_channel_flip_cid(channel);
3232 }
3233 }
3234
switch_channel_get_queued_extension(switch_channel_t * channel)3235 SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_queued_extension(switch_channel_t *channel)
3236 {
3237 switch_caller_extension_t *caller_extension;
3238
3239 switch_mutex_lock(channel->profile_mutex);
3240 caller_extension = channel->queued_extension;
3241 channel->queued_extension = NULL;
3242 switch_mutex_unlock(channel->profile_mutex);
3243
3244 return caller_extension;
3245 }
3246
switch_channel_transfer_to_extension(switch_channel_t * channel,switch_caller_extension_t * caller_extension)3247 SWITCH_DECLARE(void) switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension)
3248 {
3249 switch_mutex_lock(channel->profile_mutex);
3250 channel->queued_extension = caller_extension;
3251 switch_mutex_unlock(channel->profile_mutex);
3252
3253 switch_channel_set_flag(channel, CF_TRANSFER);
3254 switch_channel_set_state(channel, CS_ROUTING);
3255 }
3256
switch_channel_set_caller_extension(switch_channel_t * channel,switch_caller_extension_t * caller_extension)3257 SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension)
3258 {
3259 switch_assert(channel != NULL);
3260
3261 switch_channel_sort_cid(channel);
3262
3263 switch_mutex_lock(channel->profile_mutex);
3264 caller_extension->next = channel->caller_profile->caller_extension;
3265 channel->caller_profile->caller_extension = caller_extension;
3266 switch_mutex_unlock(channel->profile_mutex);
3267 }
3268
3269
switch_channel_get_caller_extension(switch_channel_t * channel)3270 SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_caller_extension(switch_channel_t *channel)
3271 {
3272 switch_caller_extension_t *extension = NULL;
3273
3274 switch_assert(channel != NULL);
3275 switch_mutex_lock(channel->profile_mutex);
3276 if (channel->caller_profile) {
3277 extension = channel->caller_profile->caller_extension;
3278 }
3279 switch_mutex_unlock(channel->profile_mutex);
3280 return extension;
3281 }
3282
3283
switch_channel_set_bridge_time(switch_channel_t * channel)3284 SWITCH_DECLARE(void) switch_channel_set_bridge_time(switch_channel_t *channel)
3285 {
3286 switch_mutex_lock(channel->profile_mutex);
3287 if (channel->caller_profile && channel->caller_profile->times) {
3288 channel->caller_profile->times->bridged = switch_micro_time_now();
3289 }
3290 switch_mutex_unlock(channel->profile_mutex);
3291 }
3292
3293
switch_channel_set_hangup_time(switch_channel_t * channel)3294 SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel)
3295 {
3296 if (channel->caller_profile && channel->caller_profile->times && !channel->caller_profile->times->hungup) {
3297 switch_mutex_lock(channel->profile_mutex);
3298 channel->caller_profile->times->hungup = switch_micro_time_now();
3299 switch_mutex_unlock(channel->profile_mutex);
3300 }
3301 }
3302
3303
switch_channel_perform_hangup(switch_channel_t * channel,const char * file,const char * func,int line,switch_call_cause_t hangup_cause)3304 SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_channel_t *channel,
3305 const char *file, const char *func, int line, switch_call_cause_t hangup_cause)
3306 {
3307 int ok = 0;
3308
3309 switch_assert(channel != NULL);
3310
3311 /* one per customer */
3312 switch_mutex_lock(channel->state_mutex);
3313 if (!(channel->opaque_flags & OCF_HANGUP)) {
3314 channel->opaque_flags |= OCF_HANGUP;
3315 ok = 1;
3316 }
3317 switch_mutex_unlock(channel->state_mutex);
3318
3319 if (switch_channel_test_flag(channel, CF_LEG_HOLDING)) {
3320 switch_channel_mark_hold(channel, SWITCH_FALSE);
3321 switch_channel_set_flag(channel, CF_HANGUP_HELD);
3322 }
3323
3324 if (!ok) {
3325 return channel->state;
3326 }
3327
3328 switch_channel_clear_flag(channel, CF_BLOCK_STATE);
3329
3330 if (channel->state < CS_HANGUP) {
3331 switch_channel_state_t last_state;
3332 switch_event_t *event;
3333 const char *var;
3334
3335
3336 switch_mutex_lock(channel->profile_mutex);
3337 if (channel->hold_record && !channel->hold_record->off) {
3338 channel->hold_record->off = switch_time_now();
3339 }
3340 switch_mutex_unlock(channel->profile_mutex);
3341
3342 switch_mutex_lock(channel->state_mutex);
3343 last_state = channel->state;
3344 channel->state = CS_HANGUP;
3345 switch_mutex_unlock(channel->state_mutex);
3346
3347 channel->hangup_cause = hangup_cause;
3348 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Hangup %s [%s] [%s]\n",
3349 channel->name, state_names[last_state], switch_channel_cause2str(channel->hangup_cause));
3350
3351
3352 switch_channel_set_variable_partner(channel, "last_bridge_hangup_cause", switch_channel_cause2str(hangup_cause));
3353
3354 if ((var = switch_channel_get_variable(channel, SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE))) {
3355 switch_channel_set_variable_partner(channel, "last_bridge_" SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE, var);
3356 }
3357
3358 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
3359 switch_channel_set_variable(channel, "last_bridge_role", "originator");
3360 } else if (switch_channel_test_flag(channel, CF_BRIDGED)) {
3361 switch_channel_set_variable(channel, "last_bridge_role", "originatee");
3362 }
3363
3364
3365 if (!switch_core_session_running(channel->session) && !switch_core_session_started(channel->session)) {
3366 switch_core_session_thread_launch(channel->session);
3367 }
3368
3369 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP) == SWITCH_STATUS_SUCCESS) {
3370 switch_channel_event_set_data(channel, event);
3371 switch_event_fire(&event);
3372 }
3373
3374 switch_core_session_kill_channel(channel->session, SWITCH_SIG_KILL);
3375 switch_core_session_signal_state_change(channel->session);
3376 switch_core_session_hangup_state(channel->session, SWITCH_FALSE);
3377 }
3378
3379 return channel->state;
3380 }
3381
send_ind(switch_channel_t * channel,switch_core_session_message_types_t msg_id,const char * file,const char * func,int line)3382 static switch_status_t send_ind(switch_channel_t *channel, switch_core_session_message_types_t msg_id, const char *file, const char *func, int line)
3383 {
3384 switch_core_session_message_t msg = { 0 };
3385
3386 msg.message_id = msg_id;
3387 msg.from = channel->name;
3388 return switch_core_session_perform_receive_message(channel->session, &msg, file, func, line);
3389 }
3390
switch_channel_perform_acknowledge_call(switch_channel_t * channel,const char * file,const char * func,int line)3391 SWITCH_DECLARE(switch_status_t) switch_channel_perform_acknowledge_call(switch_channel_t *channel,
3392 const char *file, const char *func, int line)
3393 {
3394 send_ind(channel, SWITCH_MESSAGE_INDICATE_ACKNOWLEDGE_CALL, file, func, line);
3395
3396 return SWITCH_STATUS_SUCCESS;
3397 }
3398
switch_channel_perform_mark_ring_ready_value(switch_channel_t * channel,switch_ring_ready_t rv,const char * file,const char * func,int line)3399 SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(switch_channel_t *channel,
3400 switch_ring_ready_t rv,
3401 const char *file, const char *func, int line)
3402 {
3403 switch_event_t *event;
3404
3405 if (!switch_channel_test_flag(channel, CF_RING_READY) && !switch_channel_test_flag(channel, CF_ANSWERED)) {
3406 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Ring-Ready %s!\n", channel->name);
3407 switch_channel_set_flag_value(channel, CF_RING_READY, rv);
3408
3409 switch_mutex_lock(channel->profile_mutex);
3410 if (channel->caller_profile && channel->caller_profile->times && !channel->caller_profile->times->progress) {
3411 channel->caller_profile->times->progress = switch_micro_time_now();
3412 if (channel->caller_profile->originator_caller_profile) {
3413 switch_core_session_t *other_session;
3414 if ((other_session = switch_core_session_locate(channel->caller_profile->originator_caller_profile->uuid))) {
3415 switch_channel_t *other_channel;
3416 other_channel = switch_core_session_get_channel(other_session);
3417 switch_mutex_lock(other_channel->profile_mutex);
3418 if (other_channel->caller_profile && !other_channel->caller_profile->times->progress) {
3419 other_channel->caller_profile->times->progress = channel->caller_profile->times->progress;
3420 }
3421 switch_mutex_unlock(other_channel->profile_mutex);
3422 switch_core_session_rwunlock(other_session);
3423 }
3424 channel->caller_profile->originator_caller_profile->times->progress = channel->caller_profile->times->progress;
3425 }
3426 }
3427 switch_mutex_unlock(channel->profile_mutex);
3428
3429 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_PROGRESS) == SWITCH_STATUS_SUCCESS) {
3430 switch_channel_event_set_data(channel, event);
3431 switch_event_fire(&event);
3432 }
3433
3434 switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE);
3435 switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_RING_VARIABLE);
3436
3437 switch_channel_set_callstate(channel, CCS_RINGING);
3438
3439 send_ind(channel, SWITCH_MESSAGE_RING_EVENT, file, func, line);
3440
3441 return SWITCH_STATUS_SUCCESS;
3442 }
3443
3444 return SWITCH_STATUS_FALSE;
3445 }
3446
switch_channel_check_zrtp(switch_channel_t * channel)3447 SWITCH_DECLARE(void) switch_channel_check_zrtp(switch_channel_t *channel)
3448 {
3449
3450 if (!switch_channel_test_flag(channel, CF_ZRTP_PASSTHRU)
3451 && switch_channel_test_flag(channel, CF_ZRTP_PASSTHRU_REQ)
3452 && switch_channel_test_flag(channel, CF_ZRTP_HASH)) {
3453 switch_core_session_t *other_session;
3454 switch_channel_t *other_channel;
3455 int doit = 1;
3456
3457 if (switch_core_session_get_partner(channel->session, &other_session) == SWITCH_STATUS_SUCCESS) {
3458 other_channel = switch_core_session_get_channel(other_session);
3459
3460 if (switch_channel_test_flag(other_channel, CF_ZRTP_HASH) && !switch_channel_test_flag(other_channel, CF_ZRTP_PASSTHRU)) {
3461
3462 switch_channel_set_flag(channel, CF_ZRTP_PASSTHRU);
3463 switch_channel_set_flag(other_channel, CF_ZRTP_PASSTHRU);
3464
3465 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_INFO,
3466 "%s Activating ZRTP passthru mode.\n", switch_channel_get_name(channel));
3467
3468 switch_channel_set_variable(channel, "zrtp_passthru_active", "true");
3469 switch_channel_set_variable(other_channel, "zrtp_passthru_active", "true");
3470 switch_channel_set_variable(channel, "zrtp_secure_media", "false");
3471 switch_channel_set_variable(other_channel, "zrtp_secure_media", "false");
3472 doit = 0;
3473 }
3474
3475 switch_core_session_rwunlock(other_session);
3476 }
3477
3478 if (doit) {
3479 switch_channel_set_variable(channel, "zrtp_passthru_active", "false");
3480 switch_channel_set_variable(channel, "zrtp_secure_media", "true");
3481 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_INFO,
3482 "%s ZRTP not negotiated on both sides; disabling ZRTP passthru mode.\n", switch_channel_get_name(channel));
3483
3484 switch_channel_clear_flag(channel, CF_ZRTP_PASSTHRU);
3485 switch_channel_clear_flag(channel, CF_ZRTP_HASH);
3486
3487 if (switch_core_session_get_partner(channel->session, &other_session) == SWITCH_STATUS_SUCCESS) {
3488 other_channel = switch_core_session_get_channel(other_session);
3489
3490 switch_channel_set_variable(other_channel, "zrtp_passthru_active", "false");
3491 switch_channel_set_variable(other_channel, "zrtp_secure_media", "true");
3492 switch_channel_clear_flag(other_channel, CF_ZRTP_PASSTHRU);
3493 switch_channel_clear_flag(other_channel, CF_ZRTP_HASH);
3494
3495 switch_core_session_rwunlock(other_session);
3496 }
3497
3498 }
3499 }
3500 }
3501
switch_channel_perform_mark_pre_answered(switch_channel_t * channel,const char * file,const char * func,int line)3502 SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_channel_t *channel, const char *file, const char *func, int line)
3503 {
3504 switch_event_t *event;
3505
3506 if (!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED)) {
3507 const char *uuid;
3508 switch_core_session_t *other_session;
3509
3510 switch_core_media_check_dtls(channel->session, SWITCH_MEDIA_TYPE_AUDIO);
3511
3512 switch_channel_check_zrtp(channel);
3513 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Pre-Answer %s!\n", channel->name);
3514 switch_channel_set_flag(channel, CF_EARLY_MEDIA);
3515
3516 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "EARLY MEDIA");
3517
3518 if (switch_true(switch_channel_get_variable(channel, "video_mirror_input"))) {
3519 switch_channel_set_flag(channel, CF_VIDEO_MIRROR_INPUT);
3520 }
3521
3522 if (channel->caller_profile && channel->caller_profile->times) {
3523 switch_mutex_lock(channel->profile_mutex);
3524 channel->caller_profile->times->progress_media = switch_micro_time_now();
3525 if (channel->caller_profile->originator_caller_profile) {
3526 switch_core_session_t *osession;
3527 if ((osession = switch_core_session_locate(channel->caller_profile->originator_caller_profile->uuid))) {
3528 switch_channel_t *other_channel;
3529 other_channel = switch_core_session_get_channel(osession);
3530 if (other_channel->caller_profile) {
3531 other_channel->caller_profile->times->progress_media = channel->caller_profile->times->progress_media;
3532 }
3533 switch_core_session_rwunlock(osession);
3534 }
3535 channel->caller_profile->originator_caller_profile->times->progress_media = channel->caller_profile->times->progress_media;
3536 }
3537 switch_mutex_unlock(channel->profile_mutex);
3538 }
3539
3540 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA) == SWITCH_STATUS_SUCCESS) {
3541 switch_channel_event_set_data(channel, event);
3542 switch_event_fire(&event);
3543 }
3544
3545 switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_PRE_ANSWER_VARIABLE);
3546 switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE);
3547
3548 switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE);
3549 switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE);
3550
3551 if (switch_true(switch_channel_get_variable(channel, SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE))) {
3552 switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH);
3553 }
3554
3555
3556 /* if we're the child of another channel and the other channel is in a blocking read they will never realize we have answered so send
3557 a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel
3558 */
3559 if ((uuid = switch_channel_get_variable(channel, SWITCH_ORIGINATOR_VARIABLE))
3560 && (other_session = switch_core_session_locate(uuid))) {
3561 switch_core_session_kill_channel(other_session, SWITCH_SIG_BREAK);
3562 switch_core_session_rwunlock(other_session);
3563 }
3564
3565 switch_channel_set_callstate(channel, CCS_EARLY);
3566
3567 send_ind(channel, SWITCH_MESSAGE_PROGRESS_EVENT, file, func, line);
3568
3569 switch_core_media_check_autoadj(channel->session);
3570
3571 return SWITCH_STATUS_SUCCESS;
3572 }
3573
3574 return SWITCH_STATUS_FALSE;
3575 }
3576
switch_channel_perform_pre_answer(switch_channel_t * channel,const char * file,const char * func,int line)3577 SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel_t *channel, const char *file, const char *func, int line)
3578 {
3579 switch_core_session_message_t msg = { 0 };
3580 switch_status_t status = SWITCH_STATUS_SUCCESS;
3581
3582 switch_assert(channel != NULL);
3583
3584 if (channel->hangup_cause || channel->state >= CS_HANGUP) {
3585 return SWITCH_STATUS_FALSE;
3586 }
3587
3588 if (switch_channel_test_flag(channel, CF_ANSWERED)) {
3589 return SWITCH_STATUS_SUCCESS;
3590 }
3591
3592 if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
3593 return SWITCH_STATUS_SUCCESS;
3594 }
3595
3596 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
3597 msg.message_id = SWITCH_MESSAGE_INDICATE_PROGRESS;
3598 msg.from = channel->name;
3599 status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line);
3600 }
3601
3602 if (status == SWITCH_STATUS_SUCCESS) {
3603 switch_channel_perform_mark_pre_answered(channel, file, func, line);
3604 switch_channel_audio_sync(channel);
3605 } else {
3606 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
3607 }
3608
3609 return status;
3610 }
3611
switch_channel_perform_ring_ready_value(switch_channel_t * channel,switch_ring_ready_t rv,const char * file,const char * func,int line)3612 SWITCH_DECLARE(switch_status_t) switch_channel_perform_ring_ready_value(switch_channel_t *channel, switch_ring_ready_t rv,
3613 const char *file, const char *func, int line)
3614 {
3615 switch_core_session_message_t msg = { 0 };
3616 switch_status_t status = SWITCH_STATUS_SUCCESS;
3617
3618 switch_assert(channel != NULL);
3619
3620 if (channel->hangup_cause || channel->state >= CS_HANGUP) {
3621 return SWITCH_STATUS_FALSE;
3622 }
3623
3624 if (switch_channel_test_flag(channel, CF_ANSWERED)) {
3625 return SWITCH_STATUS_SUCCESS;
3626 }
3627
3628 if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
3629 return SWITCH_STATUS_SUCCESS;
3630 }
3631
3632 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
3633 msg.message_id = SWITCH_MESSAGE_INDICATE_RINGING;
3634 msg.from = channel->name;
3635 msg.numeric_arg = rv;
3636 status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line);
3637 }
3638
3639 if (status == SWITCH_STATUS_SUCCESS) {
3640 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Ring Ready %s!\n", channel->name);
3641 switch_channel_perform_mark_ring_ready_value(channel, rv, file, func, line);
3642 } else {
3643 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
3644 }
3645
3646 return status;
3647 }
3648
do_api_on(switch_channel_t * channel,const char * variable)3649 static void do_api_on(switch_channel_t *channel, const char *variable)
3650 {
3651 char *app;
3652 char *arg = NULL;
3653 switch_stream_handle_t stream = { 0 };
3654
3655 app = switch_core_session_strdup(channel->session, variable);
3656
3657 if ((arg = strchr(app, ' '))) {
3658 *arg++ = '\0';
3659 }
3660
3661 SWITCH_STANDARD_STREAM(stream);
3662 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s process %s: %s(%s)\n%s\n",
3663 channel->name, variable, app, switch_str_nil(arg), (char *) stream.data);
3664 switch_api_execute(app, arg, NULL, &stream);
3665 free(stream.data);
3666 }
3667
3668
switch_channel_api_on(switch_channel_t * channel,const char * variable_prefix)3669 SWITCH_DECLARE(switch_status_t) switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)
3670 {
3671 switch_event_header_t *hp;
3672 switch_event_t *event;
3673 int x = 0;
3674
3675
3676 switch_channel_get_variables(channel, &event);
3677
3678 for (hp = event->headers; hp; hp = hp->next) {
3679 char *var = hp->name;
3680 char *val = hp->value;
3681
3682 if (!strncasecmp(var, variable_prefix, strlen(variable_prefix))) {
3683 if (hp->idx) {
3684 int i;
3685 for (i = 0; i < hp->idx; i++) {
3686 x++;
3687 do_api_on(channel, hp->array[i]);
3688 }
3689 } else {
3690 x++;
3691 do_api_on(channel, val);
3692 }
3693 }
3694 }
3695
3696 switch_event_destroy(&event);
3697
3698 return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
3699 }
3700
do_execute_on(switch_channel_t * channel,const char * variable)3701 static void do_execute_on(switch_channel_t *channel, const char *variable)
3702 {
3703 char *arg = NULL;
3704 char *p;
3705 int bg = 0;
3706 char *app;
3707
3708 app = switch_core_session_strdup(channel->session, variable);
3709
3710 for(p = app; p && *p; p++) {
3711 if (*p == ' ' || (*p == ':' && (*(p+1) != ':'))) {
3712 *p++ = '\0';
3713 arg = p;
3714 break;
3715 } else if (*p == ':' && (*(p+1) == ':')) {
3716 bg++;
3717 break;
3718 }
3719 }
3720
3721 switch_assert(app != NULL);
3722 if (!strncasecmp(app, "perl", 4)) {
3723 bg++;
3724 }
3725
3726 if (bg) {
3727 switch_core_session_execute_application_async(channel->session, app, arg);
3728 } else {
3729 switch_core_session_execute_application(channel->session, app, arg);
3730 }
3731 }
3732
switch_channel_execute_on(switch_channel_t * channel,const char * variable_prefix)3733 SWITCH_DECLARE(switch_status_t) switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
3734 {
3735 switch_event_header_t *hp;
3736 switch_event_t *event, *cevent;
3737 int x = 0;
3738
3739 switch_core_get_variables(&event);
3740 switch_channel_get_variables(channel, &cevent);
3741 switch_event_merge(event, cevent);
3742
3743 for (hp = event->headers; hp; hp = hp->next) {
3744 char *var = hp->name;
3745 char *val = hp->value;
3746
3747 if (!strncasecmp(var, variable_prefix, strlen(variable_prefix))) {
3748 if (hp->idx) {
3749 int i;
3750 for (i = 0; i < hp->idx; i++) {
3751 x++;
3752 do_execute_on(channel, hp->array[i]);
3753 }
3754 } else {
3755 x++;
3756 do_execute_on(channel, val);
3757 }
3758 }
3759 }
3760
3761 switch_event_destroy(&event);
3762 switch_event_destroy(&cevent);
3763
3764 return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
3765 }
3766
switch_channel_perform_mark_answered(switch_channel_t * channel,const char * file,const char * func,int line)3767 SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_channel_t *channel, const char *file, const char *func, int line)
3768 {
3769 switch_event_t *event;
3770 const char *uuid;
3771 switch_core_session_t *other_session;
3772 const char *var;
3773
3774 switch_assert(channel != NULL);
3775
3776 if (channel->hangup_cause || channel->state >= CS_HANGUP) {
3777 return SWITCH_STATUS_FALSE;
3778 }
3779
3780 if (switch_channel_test_flag(channel, CF_ANSWERED)) {
3781 return SWITCH_STATUS_SUCCESS;
3782 }
3783
3784 switch_core_media_check_dtls(channel->session, SWITCH_MEDIA_TYPE_AUDIO);
3785
3786 if (channel->caller_profile && channel->caller_profile->times) {
3787 switch_mutex_lock(channel->profile_mutex);
3788 channel->caller_profile->times->answered = switch_micro_time_now();
3789 switch_mutex_unlock(channel->profile_mutex);
3790 }
3791
3792 switch_channel_check_zrtp(channel);
3793 switch_channel_set_flag(channel, CF_ANSWERED);
3794
3795 if (switch_true(switch_channel_get_variable(channel, "video_mirror_input"))) {
3796 switch_channel_set_flag(channel, CF_VIDEO_MIRROR_INPUT);
3797 //switch_channel_set_flag(channel, CF_VIDEO_DECODED_READ);
3798 }
3799
3800
3801 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_ANSWER) == SWITCH_STATUS_SUCCESS) {
3802 switch_channel_event_set_data(channel, event);
3803 switch_event_fire(&event);
3804 }
3805
3806 /* if we're the child of another channel and the other channel is in a blocking read they will never realize we have answered so send
3807 a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel
3808 */
3809 if ((uuid = switch_channel_get_variable(channel, SWITCH_ORIGINATOR_VARIABLE))
3810 && (other_session = switch_core_session_locate(uuid))) {
3811 switch_core_session_kill_channel(other_session, SWITCH_SIG_BREAK);
3812 switch_core_session_rwunlock(other_session);
3813 }
3814
3815 if (switch_true(switch_channel_get_variable(channel, SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE))) {
3816 switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH);
3817 }
3818
3819 if ((var = switch_channel_get_variable(channel, SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE))) {
3820 uint32_t seconds = 60;
3821 int tmp;
3822
3823 if (switch_is_number(var)) {
3824 tmp = atoi(var);
3825 if (tmp > 0) {
3826 seconds = tmp;
3827 }
3828 } else if (!switch_true(var)) {
3829 seconds = 0;
3830 }
3831
3832 if (seconds) {
3833 switch_core_session_enable_heartbeat(channel->session, seconds);
3834 }
3835 }
3836
3837 switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ANSWER");
3838 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Channel [%s] has been answered\n",
3839 channel->name);
3840
3841
3842 if (switch_channel_get_variable(channel, "absolute_codec_string")) {
3843 /* inherit_codec == true will implicitly clear the absolute_codec_string
3844 variable if used since it was the reason it was set in the first place and is no longer needed */
3845 if (switch_true(switch_channel_get_variable(channel, "inherit_codec"))) {
3846 switch_channel_set_variable(channel, "absolute_codec_string", NULL);
3847 }
3848 }
3849
3850 switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_ANSWER_VARIABLE);
3851
3852 if (!switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
3853 switch_channel_execute_on(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE);
3854 switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE);
3855 }
3856
3857 switch_channel_api_on(channel, SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE);
3858
3859 switch_channel_presence(channel, "unknown", "answered", NULL);
3860
3861 //switch_channel_audio_sync(channel);
3862
3863 switch_core_recovery_track(channel->session);
3864
3865 switch_channel_set_callstate(channel, CCS_ACTIVE);
3866
3867 send_ind(channel, SWITCH_MESSAGE_ANSWER_EVENT, file, func, line);
3868
3869 switch_core_media_check_autoadj(channel->session);
3870
3871 if (switch_channel_test_flag(channel, CF_RTT)) {
3872 switch_channel_set_flag_partner(channel, CF_RTT);
3873 }
3874
3875 return SWITCH_STATUS_SUCCESS;
3876 }
3877
switch_channel_perform_answer(switch_channel_t * channel,const char * file,const char * func,int line)3878 SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel, const char *file, const char *func, int line)
3879 {
3880 switch_core_session_message_t msg = { 0 };
3881 switch_status_t status = SWITCH_STATUS_SUCCESS;
3882
3883 switch_assert(channel != NULL);
3884
3885 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
3886 return SWITCH_STATUS_SUCCESS;
3887 }
3888
3889 if (channel->hangup_cause || channel->state >= CS_HANGUP) {
3890 return SWITCH_STATUS_FALSE;
3891 }
3892
3893 if (switch_channel_test_flag(channel, CF_ANSWERED)) {
3894 return SWITCH_STATUS_SUCCESS;
3895 }
3896
3897 msg.message_id = SWITCH_MESSAGE_INDICATE_ANSWER;
3898 msg.from = channel->name;
3899 status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line);
3900
3901
3902 if (status == SWITCH_STATUS_SUCCESS) {
3903 switch_channel_perform_mark_answered(channel, file, func, line);
3904 if (!switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
3905 switch_channel_audio_sync(channel);
3906 }
3907 } else {
3908 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
3909 }
3910
3911
3912 if (switch_core_session_in_thread(channel->session) && !switch_channel_test_flag(channel, CF_PROXY_MODE) &&
3913 !switch_channel_test_flag(channel, CF_HAS_TEXT)) {
3914 const char *delay;
3915
3916 if ((delay = switch_channel_get_variable(channel, "answer_delay"))) {
3917 uint32_t msec = atoi(delay);
3918
3919 if (msec) {
3920 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG, "Answer delay for %u msec\n", msec);
3921 switch_ivr_sleep(channel->session, msec, SWITCH_TRUE, NULL);
3922 }
3923 }
3924 }
3925
3926 return status;
3927 }
3928
3929 #define resize(l) {\
3930 char *dp;\
3931 olen += (len + l + block);\
3932 cpos = c - data;\
3933 if ((dp = realloc(data, olen))) {\
3934 data = dp;\
3935 c = data + cpos;\
3936 memset(c, 0, olen - cpos);\
3937 }} \
3938
switch_channel_expand_variables_check(switch_channel_t * channel,const char * in,switch_event_t * var_list,switch_event_t * api_list,uint32_t recur)3939 SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *channel, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur)
3940 {
3941 char *p, *c = NULL;
3942 char *data, *indup, *endof_indup;
3943 size_t sp = 0, len = 0, olen = 0, vtype = 0, br = 0, cpos, block = 128;
3944 char *cloned_sub_val = NULL, *sub_val = NULL, *expanded_sub_val = NULL;
3945 char *func_val = NULL, *sb = NULL;
3946 int nv = 0;
3947
3948 if (recur > 100) {
3949 return (char *) in;
3950 }
3951
3952 if (zstr(in)) {
3953 return (char *) in;
3954 }
3955
3956 nv = switch_string_var_check_const(in) || switch_string_has_escaped_data(in);
3957
3958 if (!nv) {
3959 return (char *) in;
3960 }
3961
3962
3963 nv = 0;
3964 olen = strlen(in) + 1;
3965 indup = strdup(in);
3966 endof_indup = end_of_p(indup) + 1;
3967
3968 if ((data = malloc(olen))) {
3969 memset(data, 0, olen);
3970 c = data;
3971 for (p = indup; p && p < endof_indup && *p; p++) {
3972 int global = 0;
3973 vtype = 0;
3974
3975 if (*p == '\\') {
3976 if (*(p + 1) == '$') {
3977 nv = 1;
3978 p++;
3979 if (*(p + 1) == '$') {
3980 p++;
3981 }
3982 } else if (*(p + 1) == '\'') {
3983 p++;
3984 continue;
3985 } else if (*(p + 1) == '\\') {
3986 if (len + 1 >= olen) {
3987 resize(1);
3988 }
3989
3990 *c++ = *p++;
3991 len++;
3992 continue;
3993 }
3994 }
3995
3996 if (*p == '$' && !nv) {
3997
3998 if (*(p + 1) == '$') {
3999 p++;
4000 global++;
4001 }
4002
4003 if (*(p + 1)) {
4004 if (*(p + 1) == '{') {
4005 vtype = global ? 3 : 1;
4006 } else {
4007 nv = 1;
4008 }
4009 } else {
4010 nv = 1;
4011 }
4012 }
4013
4014 if (nv) {
4015 if (len + 1 >= olen) {
4016 resize(1);
4017 }
4018
4019 *c++ = *p;
4020 len++;
4021 nv = 0;
4022 continue;
4023 }
4024
4025 if (vtype) {
4026 char *s = p, *e, *vname, *vval = NULL;
4027 size_t nlen;
4028
4029 s++;
4030
4031 if ((vtype == 1 || vtype == 3) && *s == '{') {
4032 br = 1;
4033 s++;
4034 }
4035
4036 e = s;
4037 vname = s;
4038 while (*e) {
4039 if (br == 1 && *e == '}') {
4040 br = 0;
4041 *e++ = '\0';
4042 break;
4043 }
4044
4045 if (br > 0) {
4046 if (e != s && *e == '{') {
4047 br++;
4048 } else if (br > 1 && *e == '}') {
4049 br--;
4050 }
4051 }
4052
4053 e++;
4054 }
4055 p = e > endof_indup ? endof_indup : e;
4056
4057 vval = NULL;
4058 for(sb = vname; sb && *sb; sb++) {
4059 if (*sb == ' ') {
4060 vval = sb;
4061 break;
4062 } else if (*sb == '(') {
4063 vval = sb;
4064 br = 1;
4065 break;
4066 }
4067 }
4068
4069 if (vval) {
4070 e = vval - 1;
4071 *vval++ = '\0';
4072 while (*e == ' ') {
4073 *e-- = '\0';
4074 }
4075 e = vval;
4076
4077 while (e && *e) {
4078 if (*e == '(') {
4079 br++;
4080 } else if (br > 1 && *e == ')') {
4081 br--;
4082 } else if (br == 1 && *e == ')') {
4083 *e = '\0';
4084 break;
4085 }
4086 e++;
4087 }
4088
4089 vtype = 2;
4090 }
4091
4092 if (vtype == 1 || vtype == 3) {
4093 char *expanded = NULL;
4094 int offset = 0;
4095 int ooffset = 0;
4096 char *ptr;
4097 int idx = -1;
4098
4099 if ((expanded = switch_channel_expand_variables_check(channel, (char *) vname, var_list, api_list, recur+1)) == vname) {
4100 expanded = NULL;
4101 } else {
4102 vname = expanded;
4103 }
4104
4105 if ((ptr = strchr(vname, ':'))) {
4106 *ptr++ = '\0';
4107 offset = atoi(ptr);
4108 if ((ptr = strchr(ptr, ':'))) {
4109 ptr++;
4110 ooffset = atoi(ptr);
4111 }
4112 }
4113
4114 if ((ptr = strchr(vname, '[')) && strchr(ptr, ']')) {
4115 *ptr++ = '\0';
4116 idx = atoi(ptr);
4117 }
4118
4119 if ((sub_val = (char *) switch_channel_get_variable_dup(channel, vname, SWITCH_TRUE, idx))) {
4120 if (var_list && !switch_event_check_permission_list(var_list, vname)) {
4121 sub_val = "<Variable Expansion Permission Denied>";
4122 }
4123
4124 if ((expanded_sub_val = switch_channel_expand_variables_check(channel, sub_val, var_list, api_list, recur+1)) == sub_val) {
4125 expanded_sub_val = NULL;
4126 } else {
4127 sub_val = expanded_sub_val;
4128 }
4129
4130 if (offset || ooffset) {
4131 cloned_sub_val = strdup(sub_val);
4132 switch_assert(cloned_sub_val);
4133 sub_val = cloned_sub_val;
4134 }
4135
4136 if (offset >= 0) {
4137 if ((size_t) offset > strlen(sub_val)) {
4138 *sub_val = '\0';
4139 } else {
4140 sub_val += offset;
4141 }
4142 } else if ((size_t) abs(offset) <= strlen(sub_val)) {
4143 sub_val = cloned_sub_val + (strlen(cloned_sub_val) + offset);
4144 }
4145
4146 if (ooffset > 0 && (size_t) ooffset < strlen(sub_val)) {
4147 if ((ptr = (char *) sub_val + ooffset)) {
4148 *ptr = '\0';
4149 }
4150 }
4151 }
4152
4153 switch_safe_free(expanded);
4154 } else {
4155 switch_stream_handle_t stream = { 0 };
4156 char *expanded = NULL;
4157
4158 SWITCH_STANDARD_STREAM(stream);
4159
4160 if (stream.data) {
4161 char *expanded_vname = NULL;
4162
4163 if ((expanded_vname = switch_channel_expand_variables_check(channel, (char *) vname, var_list, api_list, recur+1)) == vname) {
4164 expanded_vname = NULL;
4165 } else {
4166 vname = expanded_vname;
4167 }
4168
4169 if ((expanded = switch_channel_expand_variables_check(channel, vval, var_list, api_list, recur+1)) == vval) {
4170 expanded = NULL;
4171 } else {
4172 vval = expanded;
4173 }
4174
4175 if (!switch_core_test_flag(SCF_API_EXPANSION) || (api_list && !switch_event_check_permission_list(api_list, vname))) {
4176 func_val = NULL;
4177 sub_val = "<API Execute Permission Denied>";
4178 } else {
4179 if (switch_api_execute(vname, vval, channel->session, &stream) == SWITCH_STATUS_SUCCESS) {
4180 func_val = stream.data;
4181 sub_val = func_val;
4182 } else {
4183 free(stream.data);
4184 }
4185 }
4186
4187 switch_safe_free(expanded);
4188 switch_safe_free(expanded_vname);
4189
4190 } else {
4191 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "Memory Error!\n");
4192 free(data);
4193 free(indup);
4194 return (char *) in;
4195 }
4196 }
4197 if ((nlen = sub_val ? strlen(sub_val) : 0)) {
4198 if (len + nlen >= olen) {
4199 resize(nlen);
4200 }
4201
4202 len += nlen;
4203 strcat(c, sub_val);
4204 c += nlen;
4205 }
4206
4207 switch_safe_free(func_val);
4208 switch_safe_free(cloned_sub_val);
4209 switch_safe_free(expanded_sub_val);
4210 sub_val = NULL;
4211 vname = NULL;
4212 br = 0;
4213 }
4214
4215 if (sp) {
4216 if (len + 1 >= olen) {
4217 resize(1);
4218 }
4219
4220 *c++ = ' ';
4221 sp = 0;
4222 len++;
4223 }
4224
4225 if (*p == '$') {
4226 p--;
4227 } else {
4228 if (len + 1 >= olen) {
4229 resize(1);
4230 }
4231
4232 *c++ = *p;
4233 len++;
4234 }
4235 }
4236 }
4237 free(indup);
4238
4239 return data;
4240 }
4241
switch_channel_build_param_string(switch_channel_t * channel,switch_caller_profile_t * caller_profile,const char * prefix)4242 SWITCH_DECLARE(char *) switch_channel_build_param_string(switch_channel_t *channel, switch_caller_profile_t *caller_profile, const char *prefix)
4243 {
4244 switch_stream_handle_t stream = { 0 };
4245 switch_size_t encode_len = 1024, new_len = 0;
4246 char *encode_buf = NULL;
4247 const char *prof[13] = { 0 }, *prof_names[13] = {
4248 0};
4249 char *e = NULL;
4250 switch_event_header_t *hi;
4251 uint32_t x = 0;
4252
4253 SWITCH_STANDARD_STREAM(stream);
4254
4255 if (prefix) {
4256 stream.write_function(&stream, "%s&", prefix);
4257 }
4258
4259 encode_buf = malloc(encode_len);
4260 switch_assert(encode_buf);
4261
4262 if (!caller_profile) {
4263 caller_profile = switch_channel_get_caller_profile(channel);
4264 }
4265
4266 switch_assert(caller_profile != NULL);
4267
4268 prof[0] = caller_profile->context;
4269 prof[1] = caller_profile->destination_number;
4270 prof[2] = caller_profile->caller_id_name;
4271 prof[3] = caller_profile->caller_id_number;
4272 prof[4] = caller_profile->network_addr;
4273 prof[5] = caller_profile->ani;
4274 prof[6] = caller_profile->aniii;
4275 prof[7] = caller_profile->rdnis;
4276 prof[8] = caller_profile->source;
4277 prof[9] = caller_profile->chan_name;
4278 prof[10] = caller_profile->uuid;
4279 prof[11] = caller_profile->transfer_source;
4280
4281 prof_names[0] = "context";
4282 prof_names[1] = "destination_number";
4283 prof_names[2] = "caller_id_name";
4284 prof_names[3] = "caller_id_number";
4285 prof_names[4] = "network_addr";
4286 prof_names[5] = "ani";
4287 prof_names[6] = "aniii";
4288 prof_names[7] = "rdnis";
4289 prof_names[8] = "source";
4290 prof_names[9] = "chan_name";
4291 prof_names[10] = "uuid";
4292 prof_names[11] = "transfer_source";
4293
4294 for (x = 0; prof[x]; x++) {
4295 if (zstr(prof[x])) {
4296 continue;
4297 }
4298 new_len = (strlen(prof[x]) * 3) + 1;
4299 if (encode_len < new_len) {
4300 char *tmp;
4301
4302 encode_len = new_len;
4303
4304 if (!(tmp = realloc(encode_buf, encode_len))) {
4305 abort();
4306 }
4307
4308 encode_buf = tmp;
4309 }
4310 switch_url_encode(prof[x], encode_buf, encode_len);
4311 stream.write_function(&stream, "%s=%s&", prof_names[x], encode_buf);
4312 }
4313
4314 if (channel->caller_profile->soft) {
4315 profile_node_t *pn;
4316
4317 for(pn = channel->caller_profile->soft; pn; pn = pn->next) {
4318 char *var = pn->var;
4319 char *val = pn->val;
4320
4321 new_len = (strlen((char *) var) * 3) + 1;
4322 if (encode_len < new_len) {
4323 char *tmp;
4324
4325 encode_len = new_len;
4326
4327 tmp = realloc(encode_buf, encode_len);
4328 switch_assert(tmp);
4329 encode_buf = tmp;
4330 }
4331
4332 switch_url_encode((char *) val, encode_buf, encode_len);
4333 stream.write_function(&stream, "%s=%s&", (char *) var, encode_buf);
4334
4335 }
4336 }
4337
4338 if ((hi = switch_channel_variable_first(channel))) {
4339 for (; hi; hi = hi->next) {
4340 char *var = hi->name;
4341 char *val = hi->value;
4342
4343 new_len = (strlen((char *) var) * 3) + 1;
4344 if (encode_len < new_len) {
4345 char *tmp;
4346
4347 encode_len = new_len;
4348
4349 tmp = realloc(encode_buf, encode_len);
4350 switch_assert(tmp);
4351 encode_buf = tmp;
4352 }
4353
4354 switch_url_encode((char *) val, encode_buf, encode_len);
4355 stream.write_function(&stream, "%s=%s&", (char *) var, encode_buf);
4356
4357 }
4358 switch_channel_variable_last(channel);
4359 }
4360
4361 e = (char *) stream.data + (strlen((char *) stream.data) - 1);
4362
4363 if (e && *e == '&') {
4364 *e = '\0';
4365 }
4366
4367 switch_safe_free(encode_buf);
4368
4369 return stream.data;
4370 }
4371
switch_channel_pass_callee_id(switch_channel_t * channel,switch_channel_t * other_channel)4372 SWITCH_DECLARE(switch_status_t) switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel)
4373 {
4374 int x = 0;
4375
4376 switch_assert(channel);
4377 switch_assert(other_channel);
4378
4379 switch_mutex_lock(channel->profile_mutex);
4380 switch_mutex_lock(other_channel->profile_mutex);
4381
4382 if (!zstr(channel->caller_profile->callee_id_name)) {
4383 other_channel->caller_profile->callee_id_name = switch_core_strdup(other_channel->caller_profile->pool, channel->caller_profile->callee_id_name);
4384 x++;
4385 }
4386
4387 if (!zstr(channel->caller_profile->callee_id_number)) {
4388 other_channel->caller_profile->callee_id_number = switch_core_strdup(other_channel->caller_profile->pool, channel->caller_profile->callee_id_number);
4389 x++;
4390 }
4391
4392 switch_mutex_unlock(other_channel->profile_mutex);
4393 switch_mutex_unlock(channel->profile_mutex);
4394
4395 return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
4396 }
4397
switch_channel_get_variables(switch_channel_t * channel,switch_event_t ** event)4398 SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event)
4399 {
4400 switch_status_t status;
4401 switch_mutex_lock(channel->profile_mutex);
4402 if (channel->variables) {
4403 status = switch_event_dup(event, channel->variables);
4404 } else {
4405 status = switch_event_create(event, SWITCH_EVENT_CHANNEL_DATA);
4406 }
4407 switch_mutex_unlock(channel->profile_mutex);
4408 return status;
4409 }
4410
switch_channel_get_session(switch_channel_t * channel)4411 SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel)
4412 {
4413 switch_assert(channel);
4414 return channel->session;
4415 }
4416
switch_channel_set_timestamps(switch_channel_t * channel)4417 SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *channel)
4418 {
4419 switch_status_t status = SWITCH_STATUS_SUCCESS;
4420 const char *cid_buf = NULL;
4421 switch_caller_profile_t *caller_profile;
4422 switch_app_log_t *app_log, *ap;
4423 char *last_app = NULL, *last_arg = NULL;
4424 char start[80] = "", resurrect[80] = "", answer[80] = "", hold[80],
4425 bridge[80] = "", progress[80] = "", progress_media[80] = "", end[80] = "", tmp[80] = "",
4426 profile_start[80] = "";
4427 int32_t duration = 0, legbillsec = 0, billsec = 0, mduration = 0, billmsec = 0, legbillmsec = 0, progressmsec = 0, progress_mediamsec = 0;
4428 int32_t answersec = 0, answermsec = 0, waitsec = 0, waitmsec = 0;
4429 switch_time_t answerusec = 0;
4430 switch_time_t uduration = 0, legbillusec = 0, billusec = 0, progresssec = 0, progressusec = 0, progress_mediasec = 0, progress_mediausec = 0, waitusec = 0;
4431 time_t tt_created = 0, tt_answered = 0, tt_resurrected = 0, tt_bridged, tt_last_hold, tt_hold_accum,
4432 tt_progress = 0, tt_progress_media = 0, tt_hungup = 0, mtt_created = 0, mtt_answered = 0, mtt_bridged = 0,
4433 mtt_hungup = 0, tt_prof_created, mtt_progress = 0, mtt_progress_media = 0;
4434 void *pop;
4435 char dtstr[SWITCH_DTMF_LOG_LEN + 1] = "";
4436 int x = 0;
4437
4438 switch_mutex_lock(channel->profile_mutex);
4439
4440 if (switch_channel_test_flag(channel, CF_TIMESTAMP_SET)) {
4441 switch_mutex_unlock(channel->profile_mutex);
4442 return SWITCH_STATUS_FALSE;
4443 }
4444
4445 if (!(caller_profile = channel->caller_profile) || !channel->variables) {
4446 switch_mutex_unlock(channel->profile_mutex);
4447 return SWITCH_STATUS_FALSE;
4448 }
4449
4450 switch_channel_set_flag(channel, CF_TIMESTAMP_SET);
4451
4452 if ((app_log = switch_core_session_get_app_log(channel->session))) {
4453 for (ap = app_log; ap && ap->next; ap = ap->next);
4454 last_app = ap->app;
4455 last_arg = ap->arg;
4456 }
4457
4458 if (!zstr(caller_profile->caller_id_name)) {
4459 cid_buf = switch_core_session_sprintf(channel->session, "\"%s\" <%s>", caller_profile->caller_id_name,
4460 switch_str_nil(caller_profile->caller_id_number));
4461 } else {
4462 cid_buf = caller_profile->caller_id_number;
4463 }
4464
4465 while (x < SWITCH_DTMF_LOG_LEN && switch_queue_trypop(channel->dtmf_log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
4466 switch_dtmf_t *dt = (switch_dtmf_t *) pop;
4467
4468 if (dt) {
4469 dtstr[x++] = dt->digit;
4470 free(dt);
4471 dt = NULL;
4472 }
4473 }
4474
4475 if (x) {
4476 const char *var = switch_channel_get_variable(channel, "digits_dialed_filter");
4477 char *digit_string = dtstr;
4478 char *X = NULL;
4479 switch_regex_t *re = NULL;
4480 char *substituted = NULL;
4481
4482 if (!zstr(var)) {
4483 int proceed = 0;
4484 int ovector[30];
4485
4486 if ((proceed = switch_regex_perform(dtstr, var, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
4487 int len = (strlen(dtstr) + strlen(var) + 10) * proceed;
4488 int i = 0;
4489 const char *replace = NULL;
4490
4491 X = malloc(len);
4492
4493 for (i = 0; i < proceed; i++) {
4494 if (pcre_get_substring(dtstr, ovector, proceed, i, &replace) >= 0) {
4495 if (replace) {
4496 switch_size_t plen = strlen(replace);
4497 memset(X, 'X', plen);
4498 *(X+plen) = '\0';
4499
4500 switch_safe_free(substituted);
4501 substituted = switch_string_replace(substituted ? substituted : dtstr, replace, X);
4502
4503 pcre_free_substring(replace);
4504 }
4505 }
4506 }
4507
4508 if (!zstr(substituted)) {
4509 digit_string = substituted;
4510 }
4511 }
4512 }
4513
4514 switch_channel_set_variable(channel, "digits_dialed", digit_string);
4515 switch_regex_safe_free(re);
4516 switch_safe_free(substituted);
4517 switch_safe_free(X);
4518 } else {
4519 switch_channel_set_variable(channel, "digits_dialed", "none");
4520 }
4521
4522 if (caller_profile->times) {
4523 switch_time_exp_t tm;
4524 switch_size_t retsize;
4525 const char *fmt = "%Y-%m-%d %T";
4526
4527 switch_time_exp_lt(&tm, caller_profile->times->created);
4528 switch_strftime_nocheck(start, &retsize, sizeof(start), fmt, &tm);
4529 switch_channel_set_variable(channel, "start_stamp", start);
4530
4531 switch_time_exp_lt(&tm, caller_profile->times->profile_created);
4532 switch_strftime_nocheck(profile_start, &retsize, sizeof(profile_start), fmt, &tm);
4533 switch_channel_set_variable(channel, "profile_start_stamp", profile_start);
4534
4535 if (caller_profile->times->answered) {
4536 switch_time_exp_lt(&tm, caller_profile->times->answered);
4537 switch_strftime_nocheck(answer, &retsize, sizeof(answer), fmt, &tm);
4538 switch_channel_set_variable(channel, "answer_stamp", answer);
4539 }
4540
4541 if (caller_profile->times->bridged) {
4542 switch_time_exp_lt(&tm, caller_profile->times->bridged);
4543 switch_strftime_nocheck(bridge, &retsize, sizeof(bridge), fmt, &tm);
4544 switch_channel_set_variable(channel, "bridge_stamp", bridge);
4545 }
4546
4547 if (caller_profile->times->last_hold) {
4548 switch_time_exp_lt(&tm, caller_profile->times->last_hold);
4549 switch_strftime_nocheck(hold, &retsize, sizeof(hold), fmt, &tm);
4550 switch_channel_set_variable(channel, "hold_stamp", hold);
4551 }
4552
4553 if (caller_profile->times->resurrected) {
4554 switch_time_exp_lt(&tm, caller_profile->times->resurrected);
4555 switch_strftime_nocheck(resurrect, &retsize, sizeof(resurrect), fmt, &tm);
4556 switch_channel_set_variable(channel, "resurrect_stamp", resurrect);
4557 }
4558
4559 if (caller_profile->times->progress) {
4560 switch_time_exp_lt(&tm, caller_profile->times->progress);
4561 switch_strftime_nocheck(progress, &retsize, sizeof(progress), fmt, &tm);
4562 switch_channel_set_variable(channel, "progress_stamp", progress);
4563 }
4564
4565 if (caller_profile->times->progress_media) {
4566 switch_time_exp_lt(&tm, caller_profile->times->progress_media);
4567 switch_strftime_nocheck(progress_media, &retsize, sizeof(progress_media), fmt, &tm);
4568 switch_channel_set_variable(channel, "progress_media_stamp", progress_media);
4569 }
4570
4571 if (channel->hold_record) {
4572 switch_hold_record_t *hr;
4573 switch_stream_handle_t stream = { 0 };
4574
4575 SWITCH_STANDARD_STREAM(stream);
4576
4577 stream.write_function(&stream, "{", SWITCH_VA_NONE);
4578
4579 for (hr = channel->hold_record; hr; hr = hr->next) {
4580 stream.write_function(&stream, "{%"SWITCH_TIME_T_FMT",%"SWITCH_TIME_T_FMT"},", hr->on, hr->off);
4581 }
4582 end_of((char *)stream.data) = '}';
4583
4584 switch_channel_set_variable(channel, "hold_events", (char *)stream.data);
4585 free(stream.data);
4586 }
4587
4588 switch_time_exp_lt(&tm, caller_profile->times->hungup);
4589 switch_strftime_nocheck(end, &retsize, sizeof(end), fmt, &tm);
4590 switch_channel_set_variable(channel, "end_stamp", end);
4591
4592 tt_created = (time_t) (caller_profile->times->created / 1000000);
4593 mtt_created = (time_t) (caller_profile->times->created / 1000);
4594 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_created);
4595 switch_channel_set_variable(channel, "start_epoch", tmp);
4596 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->created);
4597 switch_channel_set_variable(channel, "start_uepoch", tmp);
4598
4599 tt_prof_created = (time_t) (caller_profile->times->profile_created / 1000000);
4600 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_prof_created);
4601 switch_channel_set_variable(channel, "profile_start_epoch", tmp);
4602 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created);
4603 switch_channel_set_variable(channel, "profile_start_uepoch", tmp);
4604
4605 tt_answered = (time_t) (caller_profile->times->answered / 1000000);
4606 mtt_answered = (time_t) (caller_profile->times->answered / 1000);
4607 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_answered);
4608 switch_channel_set_variable(channel, "answer_epoch", tmp);
4609 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered);
4610 switch_channel_set_variable(channel, "answer_uepoch", tmp);
4611
4612 tt_bridged = (time_t) (caller_profile->times->bridged / 1000000);
4613 mtt_bridged = (time_t) (caller_profile->times->bridged / 1000);
4614 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_bridged);
4615 switch_channel_set_variable(channel, "bridge_epoch", tmp);
4616 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged);
4617 switch_channel_set_variable(channel, "bridge_uepoch", tmp);
4618
4619 tt_last_hold = (time_t) (caller_profile->times->last_hold / 1000000);
4620 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_last_hold);
4621 switch_channel_set_variable(channel, "last_hold_epoch", tmp);
4622 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->last_hold);
4623 switch_channel_set_variable(channel, "last_hold_uepoch", tmp);
4624
4625 tt_hold_accum = (time_t) (caller_profile->times->hold_accum / 1000000);
4626 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_hold_accum);
4627 switch_channel_set_variable(channel, "hold_accum_seconds", tmp);
4628 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hold_accum);
4629 switch_channel_set_variable(channel, "hold_accum_usec", tmp);
4630 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hold_accum / 1000);
4631 switch_channel_set_variable(channel, "hold_accum_ms", tmp);
4632
4633 tt_resurrected = (time_t) (caller_profile->times->resurrected / 1000000);
4634 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_resurrected);
4635 switch_channel_set_variable(channel, "resurrect_epoch", tmp);
4636 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->resurrected);
4637 switch_channel_set_variable(channel, "resurrect_uepoch", tmp);
4638
4639 tt_progress = (time_t) (caller_profile->times->progress / 1000000);
4640 mtt_progress = (time_t) (caller_profile->times->progress / 1000);
4641 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_progress);
4642 switch_channel_set_variable(channel, "progress_epoch", tmp);
4643 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress);
4644 switch_channel_set_variable(channel, "progress_uepoch", tmp);
4645
4646 tt_progress_media = (time_t) (caller_profile->times->progress_media / 1000000);
4647 mtt_progress_media = (time_t) (caller_profile->times->progress_media / 1000);
4648 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_progress_media);
4649 switch_channel_set_variable(channel, "progress_media_epoch", tmp);
4650 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress_media);
4651 switch_channel_set_variable(channel, "progress_media_uepoch", tmp);
4652
4653 tt_hungup = (time_t) (caller_profile->times->hungup / 1000000);
4654 mtt_hungup = (time_t) (caller_profile->times->hungup / 1000);
4655 switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_hungup);
4656 switch_channel_set_variable(channel, "end_epoch", tmp);
4657 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hungup);
4658 switch_channel_set_variable(channel, "end_uepoch", tmp);
4659
4660 duration = (int32_t) (tt_hungup - tt_created);
4661 mduration = (int32_t) (mtt_hungup - mtt_created);
4662 uduration = caller_profile->times->hungup - caller_profile->times->created;
4663
4664 if (caller_profile->times->bridged > caller_profile->times->created) {
4665 waitsec = (int32_t) (tt_bridged - tt_created);
4666 waitmsec = (int32_t) (mtt_bridged - mtt_created);
4667 waitusec = caller_profile->times->bridged - caller_profile->times->created;
4668 } else {
4669 waitsec = 0;
4670 waitmsec = 0;
4671 waitusec = 0;
4672 }
4673
4674 if (caller_profile->times->answered) {
4675 billsec = (int32_t) (tt_hungup - tt_answered);
4676 billmsec = (int32_t) (mtt_hungup - mtt_answered);
4677 billusec = caller_profile->times->hungup - caller_profile->times->answered;
4678
4679 legbillsec = (int32_t) (tt_hungup - tt_created);
4680 legbillmsec = (int32_t) (mtt_hungup - mtt_created);
4681 legbillusec = caller_profile->times->hungup - caller_profile->times->created;
4682
4683 answersec = (int32_t) (tt_answered - tt_created);
4684 answermsec = (int32_t) (mtt_answered - mtt_created);
4685 answerusec = caller_profile->times->answered - caller_profile->times->created;
4686 }
4687
4688 if (caller_profile->times->progress) {
4689 progresssec = (int32_t) (tt_progress - tt_created);
4690 progressmsec = (int32_t) (mtt_progress - mtt_created);
4691 progressusec = caller_profile->times->progress - caller_profile->times->created;
4692 }
4693
4694 if (caller_profile->times->progress_media) {
4695 progress_mediasec = (int32_t) (tt_progress_media - tt_created);
4696 progress_mediamsec = (int32_t) (mtt_progress_media - mtt_created);
4697 progress_mediausec = caller_profile->times->progress_media - caller_profile->times->created;
4698 }
4699
4700 }
4701
4702 switch_channel_set_variable(channel, "last_app", last_app);
4703 switch_channel_set_variable(channel, "last_arg", last_arg);
4704 switch_channel_set_variable(channel, "caller_id", cid_buf);
4705
4706 switch_snprintf(tmp, sizeof(tmp), "%d", duration);
4707 switch_channel_set_variable(channel, "duration", tmp);
4708
4709 switch_snprintf(tmp, sizeof(tmp), "%d", billsec);
4710 switch_channel_set_variable(channel, "billsec", tmp);
4711
4712 switch_snprintf(tmp, sizeof(tmp), "%"SWITCH_TIME_T_FMT, progresssec);
4713 switch_channel_set_variable(channel, "progresssec", tmp);
4714
4715 switch_snprintf(tmp, sizeof(tmp), "%d", answersec);
4716 switch_channel_set_variable(channel, "answersec", tmp);
4717
4718 switch_snprintf(tmp, sizeof(tmp), "%d", waitsec);
4719 switch_channel_set_variable(channel, "waitsec", tmp);
4720
4721 switch_snprintf(tmp, sizeof(tmp), "%"SWITCH_TIME_T_FMT, progress_mediasec);
4722 switch_channel_set_variable(channel, "progress_mediasec", tmp);
4723
4724 switch_snprintf(tmp, sizeof(tmp), "%d", legbillsec);
4725 switch_channel_set_variable(channel, "flow_billsec", tmp);
4726
4727 switch_snprintf(tmp, sizeof(tmp), "%d", mduration);
4728 switch_channel_set_variable(channel, "mduration", tmp);
4729
4730 switch_snprintf(tmp, sizeof(tmp), "%d", billmsec);
4731 switch_channel_set_variable(channel, "billmsec", tmp);
4732
4733 switch_snprintf(tmp, sizeof(tmp), "%d", progressmsec);
4734 switch_channel_set_variable(channel, "progressmsec", tmp);
4735
4736 switch_snprintf(tmp, sizeof(tmp), "%d", answermsec);
4737 switch_channel_set_variable(channel, "answermsec", tmp);
4738
4739 switch_snprintf(tmp, sizeof(tmp), "%d", waitmsec);
4740 switch_channel_set_variable(channel, "waitmsec", tmp);
4741
4742 switch_snprintf(tmp, sizeof(tmp), "%d", progress_mediamsec);
4743 switch_channel_set_variable(channel, "progress_mediamsec", tmp);
4744
4745 switch_snprintf(tmp, sizeof(tmp), "%d", legbillmsec);
4746 switch_channel_set_variable(channel, "flow_billmsec", tmp);
4747
4748 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, uduration);
4749 switch_channel_set_variable(channel, "uduration", tmp);
4750
4751 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, billusec);
4752 switch_channel_set_variable(channel, "billusec", tmp);
4753
4754 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, progressusec);
4755 switch_channel_set_variable(channel, "progressusec", tmp);
4756
4757 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, answerusec);
4758 switch_channel_set_variable(channel, "answerusec", tmp);
4759
4760 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, waitusec);
4761 switch_channel_set_variable(channel, "waitusec", tmp);
4762
4763 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, progress_mediausec);
4764 switch_channel_set_variable(channel, "progress_mediausec", tmp);
4765
4766 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, legbillusec);
4767 switch_channel_set_variable(channel, "flow_billusec", tmp);
4768
4769 switch_mutex_unlock(channel->profile_mutex);
4770
4771 return status;
4772 }
4773
switch_channel_get_partner_uuid_copy(switch_channel_t * channel,char * buf,switch_size_t blen)4774 SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid_copy(switch_channel_t *channel, char *buf, switch_size_t blen)
4775 {
4776 const char *uuid = NULL;
4777
4778 switch_mutex_lock(channel->profile_mutex);
4779 if (!(uuid = switch_channel_get_variable_dup(channel, SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_TRUE, -1))) {
4780 uuid = switch_channel_get_variable_dup(channel, SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE, SWITCH_TRUE, -1);
4781 }
4782
4783 if (uuid) {
4784 strncpy(buf, uuid, blen);
4785 uuid = (const char *) buf;
4786 }
4787 switch_mutex_unlock(channel->profile_mutex);
4788
4789 return uuid;
4790 }
4791
4792
switch_channel_get_partner_uuid(switch_channel_t * channel)4793 SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid(switch_channel_t *channel)
4794 {
4795 const char *uuid = NULL;
4796
4797 if (!(uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
4798 uuid = switch_channel_get_variable(channel, SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE);
4799 }
4800
4801 return uuid;
4802 }
4803
switch_channel_handle_cause(switch_channel_t * channel,switch_call_cause_t cause)4804 SWITCH_DECLARE(void) switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause)
4805 {
4806 switch_core_session_t *session = channel->session;
4807 const char *transfer_on_fail = NULL;
4808 char *tof_data = NULL;
4809 char *tof_array[4] = { 0 };
4810 //int tof_arrayc = 0;
4811
4812 if (!switch_channel_up_nosig(channel)) {
4813 return;
4814 }
4815
4816 transfer_on_fail = switch_channel_get_variable(channel, "transfer_on_fail");
4817 tof_data = switch_core_session_strdup(session, transfer_on_fail);
4818 switch_split(tof_data, ' ', tof_array);
4819 transfer_on_fail = tof_array[0];
4820
4821 /*
4822 if the variable continue_on_fail is set it can be:
4823 'true' to continue on all failures.
4824 'false' to not continue.
4825 A list of codes either names or numbers eg "user_busy,normal_temporary_failure,603"
4826 failure_causes acts as the opposite version
4827 EXCEPTION... ATTENDED_TRANSFER never is a reason to continue.......
4828 */
4829 if (cause != SWITCH_CAUSE_ATTENDED_TRANSFER) {
4830 const char *continue_on_fail = NULL, *failure_causes = NULL;
4831
4832 continue_on_fail = switch_channel_get_variable(channel, "continue_on_fail");
4833 failure_causes = switch_channel_get_variable(channel, "failure_causes");
4834
4835 if (continue_on_fail || failure_causes) {
4836 const char *cause_str;
4837 char cause_num[35] = "";
4838
4839 cause_str = switch_channel_cause2str(cause);
4840 switch_snprintf(cause_num, sizeof(cause_num), "%u", cause);
4841
4842 if (failure_causes) {
4843 char *lbuf = switch_core_session_strdup(session, failure_causes);
4844 char *argv[256] = { 0 };
4845 int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
4846 int i, x = 0;
4847
4848 for (i = 0; i < argc; i++) {
4849 if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
4850 x++;
4851 break;
4852 }
4853 }
4854 if (!x) {
4855 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
4856 "Failure causes [%s]: Cause: %s\n", failure_causes, cause_str);
4857 return;
4858 }
4859 }
4860
4861 if (continue_on_fail) {
4862 if (switch_true(continue_on_fail)) {
4863 return;
4864 } else {
4865 char *lbuf = switch_core_session_strdup(session, continue_on_fail);
4866 char *argv[256] = { 0 };
4867 int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
4868 int i;
4869
4870 for (i = 0; i < argc; i++) {
4871 if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
4872 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
4873 "Continue on fail [%s]: Cause: %s\n", continue_on_fail, cause_str);
4874 return;
4875 }
4876 }
4877 }
4878 }
4879 } else {
4880 /* no answer is *always* a reason to continue */
4881 if (cause == SWITCH_CAUSE_NO_ANSWER || cause == SWITCH_CAUSE_NO_USER_RESPONSE || cause == SWITCH_CAUSE_ORIGINATOR_CANCEL) {
4882 return;
4883 }
4884 }
4885
4886 if (transfer_on_fail || failure_causes) {
4887 const char *cause_str;
4888 char cause_num[35] = "";
4889
4890 cause_str = switch_channel_cause2str(cause);
4891 switch_snprintf(cause_num, sizeof(cause_num), "%u", cause);
4892
4893 if ((tof_array[1] == NULL ) || (!strcasecmp(tof_array[1], "auto_cause"))){
4894 tof_array[1] = (char *) cause_str;
4895 }
4896
4897 if (failure_causes) {
4898 char *lbuf = switch_core_session_strdup(session, failure_causes);
4899 char *argv[256] = { 0 };
4900 int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
4901 int i, x = 0;
4902
4903 for (i = 0; i < argc; i++) {
4904 if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
4905 x++;
4906 break;
4907 }
4908 }
4909 if (!x) {
4910 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
4911 "Failure causes [%s]: Cause: %s\n", failure_causes, cause_str);
4912
4913 switch_ivr_session_transfer(session, tof_array[1], tof_array[2], tof_array[3]);
4914 }
4915 }
4916
4917 if (transfer_on_fail) {
4918 if (switch_true(transfer_on_fail)) {
4919 return;
4920 } else {
4921 char *lbuf = switch_core_session_strdup(session, transfer_on_fail);
4922 char *argv[256] = { 0 };
4923 int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
4924 int i;
4925
4926 for (i = 0; i < argc; i++) {
4927 if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
4928 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
4929 "Transfer on fail [%s]: Cause: %s\n", transfer_on_fail, cause_str);
4930 switch_ivr_session_transfer(session, tof_array[1], tof_array[2], tof_array[3]);
4931 }
4932 }
4933 }
4934 }
4935 }
4936 }
4937
4938
4939 if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_CONFIRM_BLIND_TRANSFER) &&
4940 switch_channel_get_state(channel) != CS_ROUTING) {
4941 switch_channel_hangup(channel, cause);
4942 }
4943 }
4944
switch_channel_global_init(switch_memory_pool_t * pool)4945 SWITCH_DECLARE(void) switch_channel_global_init(switch_memory_pool_t *pool)
4946 {
4947 memset(&globals, 0, sizeof(globals));
4948 globals.pool = pool;
4949
4950 switch_mutex_init(&globals.device_mutex, SWITCH_MUTEX_NESTED, pool);
4951 switch_core_hash_init(&globals.device_hash);
4952 }
4953
switch_channel_global_uninit(void)4954 SWITCH_DECLARE(void) switch_channel_global_uninit(void)
4955 {
4956 switch_core_hash_destroy(&globals.device_hash);
4957 }
4958
4959
fetch_device_stats(switch_device_record_t * drec)4960 static void fetch_device_stats(switch_device_record_t *drec)
4961 {
4962 switch_device_node_t *np;
4963
4964
4965 memset(&drec->stats, 0, sizeof(switch_device_stats_t));
4966
4967 switch_mutex_lock(drec->mutex);
4968 for(np = drec->uuid_list; np; np = np->next) {
4969 drec->stats.total++;
4970 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
4971 drec->stats.total_in++;
4972 } else {
4973 drec->stats.total_out++;
4974 }
4975
4976 if (!np->hup_profile) {
4977 drec->stats.offhook++;
4978 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
4979 drec->stats.offhook_in++;
4980 } else {
4981 drec->stats.offhook_out++;
4982 }
4983
4984 if (np->callstate == CCS_HELD) {
4985 drec->stats.held++;
4986 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
4987 drec->stats.held_in++;
4988 } else {
4989 drec->stats.held_out++;
4990 }
4991 } else if (np->callstate == CCS_UNHELD) {
4992 drec->stats.unheld++;
4993 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
4994 drec->stats.unheld_in++;
4995 } else {
4996 drec->stats.unheld_out++;
4997 }
4998 } else {
4999 if (np->callstate == CCS_EARLY) {
5000 drec->stats.early++;
5001 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
5002 drec->stats.early_in++;
5003 } else {
5004 drec->stats.early_out++;
5005 }
5006 } else if (np->callstate == CCS_RINGING) {
5007 drec->stats.ringing++;
5008 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
5009 drec->stats.ringing_in++;
5010 } else {
5011 drec->stats.ringing_out++;
5012 }
5013 } else if (np->callstate == CCS_RING_WAIT) {
5014 drec->stats.ring_wait++;
5015 } else if (np->callstate == CCS_HANGUP) {
5016 drec->stats.hup++;
5017 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
5018 drec->stats.hup_in++;
5019 } else {
5020 drec->stats.hup_out++;
5021 }
5022 } else if (np->callstate != CCS_DOWN) {
5023 drec->stats.active++;
5024 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
5025 drec->stats.active_in++;
5026 } else {
5027 drec->stats.active_out++;
5028 }
5029 }
5030 }
5031 } else {
5032 drec->stats.hup++;
5033 if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) {
5034 drec->stats.hup_in++;
5035 } else {
5036 drec->stats.hup_out++;
5037 }
5038 }
5039 }
5040 switch_mutex_unlock(drec->mutex);
5041
5042 }
5043
switch_channel_clear_device_record(switch_channel_t * channel)5044 SWITCH_DECLARE(void) switch_channel_clear_device_record(switch_channel_t *channel)
5045 {
5046 switch_memory_pool_t *pool;
5047 int sanity = 100;
5048 switch_device_node_t *np;
5049 switch_event_t *event;
5050
5051 if (!channel->device_node || !switch_channel_test_flag(channel, CF_FINAL_DEVICE_LEG)) {
5052 return;
5053 }
5054
5055 while(--sanity && channel->device_node->parent->refs) {
5056 switch_yield(100000);
5057 }
5058
5059 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Destroying device cdr %s on device [%s]\n",
5060 channel->device_node->parent->uuid,
5061 channel->device_node->parent->device_id);
5062
5063 if (switch_event_create(&event, SWITCH_EVENT_CALL_DETAIL) == SWITCH_STATUS_SUCCESS) {
5064 int x = 0;
5065 char prefix[80] = "";
5066
5067 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Type", "device");
5068 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Device-ID", channel->device_node->parent->device_id);
5069
5070 switch_mutex_lock(channel->device_node->parent->mutex);
5071 for(np = channel->device_node->parent->uuid_list; np; np = np->next) {
5072 switch_snprintf(prefix, sizeof(prefix), "Call-%d", ++x);
5073 switch_caller_profile_event_set_data(np->hup_profile, prefix, event);
5074 }
5075 switch_mutex_unlock(channel->device_node->parent->mutex);
5076
5077 switch_event_fire(&event);
5078 }
5079
5080 switch_mutex_lock(channel->device_node->parent->mutex);
5081 for(np = channel->device_node->parent->uuid_list; np; np = np->next) {
5082 if (np->xml_cdr) {
5083 switch_xml_free(np->xml_cdr);
5084 }
5085 if (np->event) {
5086 switch_event_destroy(&np->event);
5087 }
5088 }
5089 switch_mutex_unlock(channel->device_node->parent->mutex);
5090
5091 pool = channel->device_node->parent->pool;
5092
5093 switch_mutex_lock(globals.device_mutex);
5094 switch_core_destroy_memory_pool(&pool);
5095
5096 switch_mutex_unlock(globals.device_mutex);
5097
5098
5099 }
5100
switch_channel_process_device_hangup(switch_channel_t * channel)5101 SWITCH_DECLARE(void) switch_channel_process_device_hangup(switch_channel_t *channel)
5102 {
5103
5104 switch_channel_check_device_state(channel, channel->callstate);
5105 process_device_hup(channel);
5106
5107 }
5108
process_device_hup(switch_channel_t * channel)5109 static void process_device_hup(switch_channel_t *channel)
5110 {
5111 switch_hold_record_t *hr, *newhr, *last = NULL;
5112 switch_device_record_t *drec = NULL;
5113 switch_device_node_t *node;
5114
5115 if (!channel->device_node) {
5116 return;
5117 }
5118
5119 switch_mutex_lock(globals.device_mutex);
5120 node = channel->device_node;
5121 drec = channel->device_node->parent;
5122
5123 node->hup_profile = switch_caller_profile_dup(drec->pool, channel->caller_profile);
5124 fetch_device_stats(drec);
5125
5126 switch_ivr_generate_xml_cdr(channel->session, &node->xml_cdr);
5127 if (switch_event_create(&node->event, SWITCH_EVENT_CALL_DETAIL) == SWITCH_STATUS_SUCCESS) {
5128 switch_channel_event_set_extended_data(channel, node->event);
5129 }
5130
5131 for (hr = channel->hold_record; hr; hr = hr->next) {
5132 newhr = switch_core_alloc(drec->pool, sizeof(*newhr));
5133 newhr->on = hr->on;
5134 newhr->off = hr->off;
5135
5136 if (hr->uuid) {
5137 newhr->uuid = switch_core_strdup(drec->pool, hr->uuid);
5138 }
5139
5140 if (!node->hold_record) {
5141 node->hold_record = newhr;
5142 } else if (last) {
5143 last->next = newhr;
5144 }
5145
5146 last = newhr;
5147 }
5148
5149 if (!drec->stats.offhook) { /* this is final call */
5150
5151 switch_core_hash_delete(globals.device_hash, drec->device_id);
5152 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Processing last call from device [%s]\n",
5153 drec->device_id);
5154 switch_channel_set_flag(channel, CF_FINAL_DEVICE_LEG);
5155 } else {
5156 channel->device_node = NULL;
5157 }
5158
5159 drec->refs--;
5160
5161 switch_mutex_unlock(globals.device_mutex);
5162
5163 }
5164
switch_channel_check_device_state(switch_channel_t * channel,switch_channel_callstate_t callstate)5165 static void switch_channel_check_device_state(switch_channel_t *channel, switch_channel_callstate_t callstate)
5166 {
5167 switch_device_record_t *drec = NULL;
5168 switch_device_state_binding_t *ptr = NULL;
5169 switch_event_t *event = NULL;
5170
5171 if (!channel->device_node) {
5172 return;
5173 }
5174
5175 drec = channel->device_node->parent;
5176
5177 switch_mutex_lock(globals.device_mutex);
5178 switch_mutex_lock(drec->mutex);
5179
5180 fetch_device_stats(drec);
5181
5182 if (drec->state != SDS_HANGUP) {
5183 if (drec->stats.offhook == 0 || drec->stats.hup == drec->stats.total) {
5184 drec->state = SDS_HANGUP;
5185 } else {
5186 if (drec->stats.active == 0) {
5187 if ((drec->stats.ringing_out + drec->stats.early_out) > 0 || drec->stats.ring_wait > 0) {
5188 drec->state = SDS_RINGING;
5189 } else {
5190 if (drec->stats.held > 0) {
5191 drec->state = SDS_HELD;
5192 } else if (drec->stats.unheld > 0) {
5193 drec->state = SDS_UNHELD;
5194 } else {
5195 drec->state = SDS_DOWN;
5196 }
5197 }
5198 } else if (drec->stats.active == 1) {
5199 drec->state = SDS_ACTIVE;
5200 } else {
5201 drec->state = SDS_ACTIVE_MULTI;
5202 }
5203 }
5204 }
5205
5206 if ((drec->state == SDS_DOWN && drec->last_state == SDS_DOWN) || (drec->state == SDS_HANGUP && drec->last_state == SDS_HANGUP)) {
5207 switch_mutex_unlock(drec->mutex);
5208 switch_mutex_unlock(globals.device_mutex);
5209 return;
5210 }
5211
5212 if (!drec->call_start) {
5213 drec->call_start = switch_micro_time_now();
5214 }
5215
5216 switch(drec->state) {
5217 case SDS_RINGING:
5218 if (!drec->ring_start) {
5219 drec->ring_start = switch_micro_time_now();
5220 drec->ring_stop = 0;
5221 }
5222 break;
5223 case SDS_ACTIVE:
5224 case SDS_ACTIVE_MULTI:
5225 if (!drec->active_start) {
5226 drec->active_start = switch_micro_time_now();
5227 drec->active_stop = 0;
5228 }
5229 break;
5230 case SDS_HELD:
5231 if (!drec->hold_start) {
5232 drec->hold_start = switch_micro_time_now();
5233 drec->hold_stop = 0;
5234 }
5235 break;
5236 default:
5237 break;
5238 }
5239
5240 if (callstate != CCS_UNHELD && drec->active_start && drec->state != SDS_ACTIVE && drec->state != SDS_ACTIVE_MULTI) {
5241 drec->active_stop = switch_micro_time_now();
5242 }
5243
5244 if (drec->ring_start && !drec->ring_stop && drec->state != SDS_RINGING) {
5245 drec->ring_stop = switch_micro_time_now();
5246 }
5247
5248 if (drec->hold_start && !drec->hold_stop && drec->state != SDS_HELD) {
5249 drec->hold_stop = switch_micro_time_now();
5250 }
5251
5252
5253 if (switch_event_create(&event, SWITCH_EVENT_DEVICE_STATE) == SWITCH_STATUS_SUCCESS) {
5254 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Device-ID", drec->device_id);
5255 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Last-Device-State", switch_channel_device_state2str(drec->last_state));
5256 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Device-State", switch_channel_device_state2str(drec->state));
5257 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Device-Call-State", switch_channel_callstate2str(callstate));
5258 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Total-Legs", "%u", drec->stats.total);
5259 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Offhook", "%u", drec->stats.offhook);
5260 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Ringing", "%u", drec->stats.ringing);
5261 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Early", "%u", drec->stats.early);
5262 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Active", "%u", drec->stats.active);
5263 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Held", "%u", drec->stats.held);
5264 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-UnHeld", "%u", drec->stats.unheld);
5265 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Hup", "%u", drec->stats.hup);
5266 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Talk-Time-Start-Uepoch", "%"SWITCH_TIME_T_FMT, drec->active_start);
5267 if (drec->active_stop) {
5268 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Talk-Time-Stop-Uepoch", "%"SWITCH_TIME_T_FMT, drec->active_stop);
5269 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Talk-Time-Milliseconds", "%u", (uint32_t)(drec->active_stop - drec->active_start) / 1000);
5270 }
5271 }
5272
5273 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1,
5274 "%s device: %s\nState: %s Dev State: %s/%s Total:%u Offhook:%u "
5275 "Ringing:%u Early:%u Active:%u Held:%u Unheld:%u Hungup:%u Dur: %u Ringtime: %u Holdtime: %u %s\n",
5276 switch_channel_get_name(channel),
5277 drec->device_id,
5278 switch_channel_callstate2str(callstate),
5279 switch_channel_device_state2str(drec->last_state),
5280 switch_channel_device_state2str(drec->state),
5281 drec->stats.total,
5282 drec->stats.offhook,
5283 drec->stats.ringing,
5284 drec->stats.early,
5285 drec->stats.active,
5286 drec->stats.held,
5287 drec->stats.unheld,
5288 drec->stats.hup,
5289 drec->active_stop ? (uint32_t)(drec->active_stop - drec->active_start) / 1000 : 0,
5290 drec->ring_stop ? (uint32_t)(drec->ring_stop - drec->ring_start) / 1000 : 0,
5291 drec->hold_stop ? (uint32_t)(drec->hold_stop - drec->hold_start) / 1000 : 0,
5292 switch_channel_test_flag(channel, CF_FINAL_DEVICE_LEG) ? "FINAL LEG" : "");
5293
5294 for (ptr = globals.device_bindings; ptr; ptr = ptr->next) {
5295 ptr->function(channel->session, callstate, drec);
5296 }
5297
5298 drec->last_stats = drec->stats;
5299
5300 if (drec->active_stop) {
5301 drec->active_start = drec->active_stop = 0;
5302 if (drec->state == SDS_ACTIVE || drec->state == SDS_ACTIVE_MULTI) {
5303 drec->active_start = switch_micro_time_now();
5304 }
5305 }
5306
5307 if (drec->hold_stop) {
5308 drec->hold_start = drec->hold_stop = 0;
5309 if (drec->state == SDS_HELD) {
5310 drec->hold_start = switch_micro_time_now();
5311 }
5312 }
5313
5314 if (drec->ring_stop) {
5315 drec->ring_start = drec->ring_stop = 0;
5316 if (drec->state == SDS_RINGING) {
5317 drec->ring_start = switch_micro_time_now();
5318 }
5319 }
5320
5321 drec->last_call_time = switch_micro_time_now();
5322
5323 drec->last_state = drec->state;
5324
5325 switch_mutex_unlock(drec->mutex);
5326 switch_mutex_unlock(globals.device_mutex);
5327
5328
5329 if (event) {
5330 switch_event_fire(&event);
5331 }
5332
5333 }
5334
5335 /* assumed to be called under a lock */
add_uuid(switch_device_record_t * drec,switch_channel_t * channel)5336 static void add_uuid(switch_device_record_t *drec, switch_channel_t *channel)
5337 {
5338 switch_device_node_t *node;
5339
5340 switch_assert(drec);
5341
5342 switch_channel_set_flag(channel, CF_DEVICE_LEG);
5343 node = switch_core_alloc(drec->pool, sizeof(*node));
5344
5345 node->uuid = switch_core_strdup(drec->pool, switch_core_session_get_uuid(channel->session));
5346 node->parent = drec;
5347 node->callstate = channel->callstate;
5348 node->direction = channel->logical_direction == SWITCH_CALL_DIRECTION_INBOUND ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND;
5349
5350 channel->device_node = node;
5351
5352 if (!drec->uuid_list) {
5353 drec->uuid_list = node;
5354 drec->uuid = node->uuid;
5355 } else {
5356 drec->uuid_tail->next = node;
5357 }
5358
5359 drec->uuid_tail = node;
5360 drec->refs++;
5361 }
5362
create_device_record(switch_device_record_t ** drecp,const char * device_id)5363 static switch_status_t create_device_record(switch_device_record_t **drecp, const char *device_id)
5364 {
5365 switch_device_record_t *drec;
5366 switch_memory_pool_t *pool;
5367
5368 switch_assert(drecp);
5369
5370 switch_core_new_memory_pool(&pool);
5371 drec = switch_core_alloc(pool, sizeof(*drec));
5372 drec->pool = pool;
5373 drec->device_id = switch_core_strdup(drec->pool, device_id);
5374 switch_mutex_init(&drec->mutex, SWITCH_MUTEX_NESTED, drec->pool);
5375
5376 *drecp = drec;
5377
5378 return SWITCH_STATUS_SUCCESS;
5379 }
5380
5381
switch_channel_set_device_id(switch_channel_t * channel,const char * device_id)5382 SWITCH_DECLARE(const char *) switch_channel_set_device_id(switch_channel_t *channel, const char *device_id)
5383 {
5384 switch_device_record_t *drec;
5385
5386 if (channel->device_node) {
5387 return NULL;
5388 }
5389
5390 channel->device_id = switch_core_session_strdup(channel->session, device_id);
5391
5392 switch_mutex_lock(globals.device_mutex);
5393
5394 if (!(drec = switch_core_hash_find(globals.device_hash, channel->device_id))) {
5395 create_device_record(&drec, channel->device_id);
5396 switch_core_hash_insert(globals.device_hash, drec->device_id, drec);
5397 }
5398
5399 add_uuid(drec, channel);
5400
5401 switch_mutex_unlock(globals.device_mutex);
5402
5403 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Setting DEVICE ID to [%s]\n", device_id);
5404
5405 switch_channel_check_device_state(channel, channel->callstate);
5406
5407 return device_id;
5408 }
5409
switch_channel_get_device_record(switch_channel_t * channel)5410 SWITCH_DECLARE(switch_device_record_t *) switch_channel_get_device_record(switch_channel_t *channel)
5411 {
5412 if (channel->device_node) {
5413 switch_mutex_lock(channel->device_node->parent->mutex);
5414 return channel->device_node->parent;
5415 }
5416
5417 return NULL;
5418 }
5419
switch_channel_release_device_record(switch_device_record_t ** drecp)5420 SWITCH_DECLARE(void) switch_channel_release_device_record(switch_device_record_t **drecp)
5421 {
5422 if (drecp && *drecp) {
5423 switch_mutex_unlock((*drecp)->mutex);
5424 *drecp = NULL;
5425 }
5426 }
5427
switch_channel_bind_device_state_handler(switch_device_state_function_t function,void * user_data)5428 SWITCH_DECLARE(switch_status_t) switch_channel_bind_device_state_handler(switch_device_state_function_t function, void *user_data)
5429 {
5430 switch_device_state_binding_t *binding = NULL, *ptr = NULL;
5431 assert(function != NULL);
5432
5433 if (!(binding = (switch_device_state_binding_t *) switch_core_alloc(globals.pool, sizeof(*binding)))) {
5434 return SWITCH_STATUS_MEMERR;
5435 }
5436
5437 binding->function = function;
5438 binding->user_data = user_data;
5439
5440 switch_mutex_lock(globals.device_mutex);
5441 for (ptr = globals.device_bindings; ptr && ptr->next; ptr = ptr->next);
5442
5443 if (ptr) {
5444 ptr->next = binding;
5445 } else {
5446 globals.device_bindings = binding;
5447 }
5448
5449 switch_mutex_unlock(globals.device_mutex);
5450
5451 return SWITCH_STATUS_SUCCESS;
5452 }
5453
switch_channel_unbind_device_state_handler(switch_device_state_function_t function)5454 SWITCH_DECLARE(switch_status_t) switch_channel_unbind_device_state_handler(switch_device_state_function_t function)
5455 {
5456 switch_device_state_binding_t *ptr, *last = NULL;
5457 switch_status_t status = SWITCH_STATUS_FALSE;
5458
5459 switch_mutex_lock(globals.device_mutex);
5460 for (ptr = globals.device_bindings; ptr; ptr = ptr->next) {
5461 if (ptr->function == function) {
5462 status = SWITCH_STATUS_SUCCESS;
5463
5464 if (last) {
5465 last->next = ptr->next;
5466 } else {
5467 globals.device_bindings = ptr->next;
5468 last = NULL;
5469 continue;
5470 }
5471 }
5472 last = ptr;
5473 }
5474 switch_mutex_unlock(globals.device_mutex);
5475
5476 return status;
5477 }
5478
switch_channel_pass_sdp(switch_channel_t * from_channel,switch_channel_t * to_channel,const char * sdp)5479 SWITCH_DECLARE(switch_status_t) switch_channel_pass_sdp(switch_channel_t *from_channel, switch_channel_t *to_channel, const char *sdp)
5480 {
5481 switch_status_t status = SWITCH_STATUS_FALSE;
5482 char *use_sdp = (char *) sdp;
5483 char *patched_sdp = NULL;
5484
5485 if (!switch_channel_get_variable(to_channel, SWITCH_B_SDP_VARIABLE)) {
5486 const char *var;
5487
5488 if ((var = switch_channel_get_variable(from_channel, "bypass_media_sdp_filter"))) {
5489 if ((patched_sdp = switch_core_media_process_sdp_filter(use_sdp, var, from_channel->session))) {
5490 use_sdp = patched_sdp;
5491 }
5492 }
5493
5494 switch_channel_set_variable(to_channel, SWITCH_B_SDP_VARIABLE, use_sdp);
5495 }
5496
5497 switch_safe_free(patched_sdp);
5498
5499 return status;
5500 }
5501
5502 /* For Emacs:
5503 * Local Variables:
5504 * mode:c
5505 * indent-tabs-mode:t
5506 * tab-width:4
5507 * c-basic-offset:4
5508 * End:
5509 * For VIM:
5510 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
5511 */
5512