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