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