FreeSWITCH API Documentation  1.7.0
switch_ivr.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  * Paul D. Tinsley <pdt at jackhammer.org>
28  * Neal Horman <neal at wanlink dot com>
29  * Matt Klein <mklein@nmedia.net>
30  * Michael Jerris <mike@jerris.com>
31  * Ken Rice <krice at suspicious dot org>
32  * Marc Olivier Chouinard <mochouinard@moctel.com>
33  *
34  * switch_ivr.c -- IVR Library
35  *
36  */
37 
38 #include <switch.h>
39 #include <switch_ivr.h>
40 
42 {
43 
45  switch_codec_t codec = { 0 };
46  int16_t peak = 0;
47  int16_t *data;
48  switch_frame_t *read_frame = NULL;
49  uint32_t i;
52  int64_t global_total = 0, global_sum = 0, period_sum = 0;
53  int period_total = 0;
54  int period_avg = 0, global_avg = 0;
55  int avg = 0;
56  int period_len;
57 
58  switch_core_session_get_read_impl(session, &imp);
59 
60  period_len = imp.actual_samples_per_second / imp.samples_per_packet;
61 
62  if (switch_core_codec_init(&codec,
63  "L16",
64  NULL,
65  NULL,
67  imp.microseconds_per_packet / 1000,
71  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
73  return SWITCH_STATUS_FALSE;
74  }
75 
76  while (switch_channel_ready(channel)) {
77  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
78 
79  if (!SWITCH_READ_ACCEPTABLE(status)) {
80  break;
81  }
82 
83  if (switch_test_flag(read_frame, SFF_CNG) || !read_frame->samples) {
84  continue;
85  }
86 
87 
88  data = (int16_t *) read_frame->data;
89  peak = 0;
90  avg = 0;
91  for (i = 0; i < read_frame->samples; i++) {
92  const int16_t s = (int16_t) abs(data[i]);
93  if (s > peak) {
94  peak = s;
95  }
96  avg += s;
97  }
98 
99  avg /= read_frame->samples;
100 
101  period_sum += peak;
102  global_sum += peak;
103 
104  global_total++;
105  period_total++;
106 
107  period_avg = (int) (period_sum / period_total);
108 
110  "\npacket_avg=%d packet_peak=%d period_avg=%d global_avg=%d\n\n", avg, peak, period_avg, global_avg);
111 
112  if (period_total >= period_len) {
113  global_avg = (int) (global_sum / global_total);
114  period_total = 0;
115  period_sum = 0;
116  }
117 
118  }
119 
120 
122 
123  return SWITCH_STATUS_SUCCESS;
124 
125 }
126 
128 {
131  switch_time_t start = switch_micro_time_now(), now, done = switch_micro_time_now() + (ms * 1000);
132  switch_frame_t *read_frame, cng_frame = { 0 };
133  int32_t left;
134  uint32_t elapsed;
135  char data[2] = "";
136 
137  switch_frame_t write_frame = { 0 };
138  unsigned char *abuf = NULL;
139  switch_codec_implementation_t imp = { 0 };
140  switch_codec_t codec = { 0 };
141  int sval = 0;
142  const char *var;
143 
145 
147 
148  switch_core_session_get_read_impl(session, &imp);
149 
150  /*
151  if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_PROXY_MODE) &&
152  !switch_channel_media_ready(channel) && !switch_channel_test_flag(channel, CF_SERVICE)) {
153  if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) {
154  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot establish media.\n");
155  return SWITCH_STATUS_FALSE;
156  }
157  }
158  */
159 
160  if (!switch_channel_media_ready(channel)) {
161 
162  for (elapsed=0; switch_channel_ready(channel) && elapsed<(ms/20); elapsed++) {
163  if (switch_channel_test_flag(channel, CF_BREAK)) {
166  }
167 
168  switch_yield(20 * 1000);
169  }
171  }
172 
174  && (sval = atoi(var))) {
176  }
177 
178  if (ms > 10 && sval) {
179 
180  if (switch_core_codec_init(&codec,
181  "L16",
182  NULL,
183  NULL,
185  imp.microseconds_per_packet / 1000,
186  imp.number_of_channels,
189  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
192  }
193 
194 
195  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
197 
198  write_frame.codec = &codec;
200  write_frame.data = abuf;
202  write_frame.datalen = imp.decoded_bytes_per_packet;
203  write_frame.samples = write_frame.datalen / sizeof(int16_t);
204 
205  }
206 
207  if (!write_frame.datalen) {
208  sval = 0;
209  }
210 
211  cng_frame.data = data;
212  cng_frame.datalen = 2;
213  cng_frame.buflen = 2;
214  switch_set_flag((&cng_frame), SFF_CNG);
215 
216  if (sync) {
217  switch_channel_audio_sync(channel);
218  }
219 
220  if (!ms) {
222  }
223 
224  for (;;) {
225  now = switch_micro_time_now();
226  elapsed = (int32_t) ((now - start) / 1000);
227  left = ms - elapsed;
228 
229  if (!switch_channel_ready(channel)) {
230  status = SWITCH_STATUS_FALSE;
231  break;
232  }
233 
234  if (switch_channel_test_flag(channel, CF_BREAK)) {
236  status = SWITCH_STATUS_BREAK;
237  break;
238  }
239 
240  if (now > done || left <= 0) {
241  break;
242  }
243 
244 
246 
247 
248  if (args) {
249  switch_dtmf_t dtmf = {0};
250 
251  /*
252  dtmf handler function you can hook up to be executed when a digit is dialed during playback
253  if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
254  */
255  if (switch_channel_has_dtmf(channel)) {
256  if (!args->input_callback && !args->buf && !args->dmachine) {
257  status = SWITCH_STATUS_BREAK;
258  break;
259  }
260  switch_channel_dequeue_dtmf(channel, &dtmf);
261 
262  if (args->dmachine) {
263  char ds[2] = {dtmf.digit, '\0'};
264  if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
265  break;
266  }
267  }
268 
269  if (args->input_callback) {
270  status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
271  } else if (args->buf) {
272  *((char *) args->buf) = dtmf.digit;
273  status = SWITCH_STATUS_BREAK;
274  }
275  }
276 
277  if (args->input_callback) {
278  switch_event_t *event = NULL;
279 
281  switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
282  if (ostatus != SWITCH_STATUS_SUCCESS) {
283  status = ostatus;
284  }
285  switch_event_destroy(&event);
286  }
287  }
288 
289  if (status != SWITCH_STATUS_SUCCESS) {
290  break;
291  }
292  }
293 
294  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
295 
296  if (!SWITCH_READ_ACCEPTABLE(status)) {
297  break;
298  }
299 
300  if (args && args->dmachine) {
301  if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
302  break;
303  }
304  }
305 
306  if (sval && write_frame.datalen) {
307  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, imp.number_of_channels, sval);
308  switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
309  } else {
310  switch_core_session_write_frame(session, &cng_frame, SWITCH_IO_FLAG_NONE, 0);
311  }
312  }
313 
314 
315  end:
316 
318 
320 
321  if (write_frame.codec) {
323  }
324 
325  switch_safe_free(abuf);
326 
327  return status;
328 }
329 
331 {
333  switch_size_t len;
334 
335  if (!conninfo) {
336  return NULL;
337  }
338 
339  while (switch_test_flag(conninfo, SUF_READY) && switch_test_flag(conninfo, SUF_THREAD_RUNNING)) {
340  len = conninfo->write_frame.buflen;
341  if (switch_socket_recv(conninfo->socket, conninfo->write_frame.data, &len) != SWITCH_STATUS_SUCCESS || len == 0) {
342  break;
343  }
344  conninfo->write_frame.datalen = (uint32_t) len;
345  conninfo->write_frame.samples = conninfo->write_frame.datalen / 2;
347  }
348 
351 
352  return NULL;
353 }
354 
356 {
357  switch_threadattr_t *thd_attr = NULL;
358 
362  switch_thread_create(&conninfo->thread, thd_attr, unicast_thread_run, conninfo, switch_core_session_get_pool(conninfo->session));
363 }
364 
366 {
368  switch_unicast_conninfo_t *conninfo;
369  int sanity = 0;
370 
371  if (!switch_channel_test_flag(channel, CF_UNICAST)) {
372  return SWITCH_STATUS_FALSE;
373  }
374 
375  if ((conninfo = switch_channel_get_private(channel, "unicast"))) {
376  switch_status_t st;
377 
378  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Shutting down unicast connection\n");
381  switch_thread_join(&st, conninfo->thread);
382 
383  while (switch_test_flag(conninfo, SUF_THREAD_RUNNING)) {
384  switch_yield(10000);
385  if (++sanity >= 10000) {
386  break;
387  }
388  }
389  if (switch_core_codec_ready(&conninfo->read_codec)) {
391  }
392  switch_socket_close(conninfo->socket);
393  }
395  return SWITCH_STATUS_SUCCESS;
396 }
397 
399  char *local_ip,
400  switch_port_t local_port,
401  char *remote_ip, switch_port_t remote_port, char *transport, char *flags)
402 {
404  switch_unicast_conninfo_t *conninfo = switch_core_session_alloc(session, sizeof(*conninfo));
405  switch_codec_t *read_codec;
406 
407  switch_assert(conninfo != NULL);
408 
409  conninfo->local_ip = switch_core_session_strdup(session, local_ip);
410  conninfo->local_port = local_port;
411 
412  conninfo->remote_ip = switch_core_session_strdup(session, remote_ip);
413  conninfo->remote_port = remote_port;
414  conninfo->session = session;
415 
416  if (!strcasecmp(transport, "udp")) {
417  conninfo->type = AF_INET;
418  conninfo->transport = SOCK_DGRAM;
419  } else if (!strcasecmp(transport, "tcp")) {
420  conninfo->type = AF_INET;
421  conninfo->transport = SOCK_STREAM;
422  } else {
423  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid transport %s\n", transport);
424  goto fail;
425  }
426 
427  if (flags) {
428  if (strstr(flags, "native")) {
429  switch_set_flag(conninfo, SUF_NATIVE);
430  }
431  }
432 
434 
435  read_codec = switch_core_session_get_read_codec(session);
436 
437  if (!switch_test_flag(conninfo, SUF_NATIVE)) {
438  if (switch_core_codec_init(&conninfo->read_codec,
439  "L16",
440  NULL,
441  NULL,
443  read_codec->implementation->microseconds_per_packet / 1000,
447  "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
449  } else {
450  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n",
452  goto fail;
453  }
454  }
455 
456  conninfo->write_frame.data = conninfo->write_frame_data;
457  conninfo->write_frame.buflen = sizeof(conninfo->write_frame_data);
458  conninfo->write_frame.codec = switch_test_flag(conninfo, SUF_NATIVE) ? read_codec : &conninfo->read_codec;
459 
460  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "connect %s:%d->%s:%d\n",
461  conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
462 
463  if (switch_sockaddr_info_get(&conninfo->local_addr,
464  conninfo->local_ip, SWITCH_UNSPEC, conninfo->local_port, 0,
466  goto fail;
467  }
468 
469  if (switch_sockaddr_info_get(&conninfo->remote_addr,
470  conninfo->remote_ip, SWITCH_UNSPEC, conninfo->remote_port, 0,
472  goto fail;
473  }
474 
475  if (switch_socket_create(&conninfo->socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
476  if (switch_socket_bind(conninfo->socket, conninfo->local_addr) != SWITCH_STATUS_SUCCESS) {
477  goto fail;
478  }
479  } else {
480  goto fail;
481  }
482 
483  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Created unicast connection %s:%d->%s:%d\n",
484  conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
485  switch_channel_set_private(channel, "unicast", conninfo);
488  return SWITCH_STATUS_SUCCESS;
489 
490  fail:
491 
492  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure creating unicast connection %s:%d->%s:%d\n",
493  conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
494  return SWITCH_STATUS_FALSE;
495 }
496 
498 {
500  char *cmd = switch_event_get_header(event, "call-command");
501  unsigned long cmd_hash;
502  switch_ssize_t hlen = -1;
503  unsigned long CMD_EXECUTE = switch_hashfunc_default("execute", &hlen);
504  unsigned long CMD_HANGUP = switch_hashfunc_default("hangup", &hlen);
505  unsigned long CMD_NOMEDIA = switch_hashfunc_default("nomedia", &hlen);
506  unsigned long CMD_UNICAST = switch_hashfunc_default("unicast", &hlen);
507  unsigned long CMD_XFEREXT = switch_hashfunc_default("xferext", &hlen);
508  char *lead_frames = switch_event_get_header(event, "lead-frames");
509  char *event_lock = switch_event_get_header(event, "event-lock");
510  char *event_lock_pri = switch_event_get_header(event, "event-lock-pri");
512  int el = 0, elp = 0;
513 
514  if (zstr(cmd)) {
515  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Command!\n");
516  return SWITCH_STATUS_FALSE;
517  }
518 
519  cmd_hash = switch_hashfunc_default(cmd, &hlen);
520 
522 
523  if (switch_true(event_lock)) {
525  el = 1;
526  }
527 
528  if (switch_true(event_lock_pri)) {
530  elp = 1;
531  }
532 
533  if (lead_frames && switch_channel_media_ready(channel)) {
534  switch_frame_t *read_frame;
535  int frame_count = atoi(lead_frames);
536  int max_frames = frame_count * 2;
537 
538  while (frame_count > 0 && --max_frames > 0) {
539  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
540  if (!SWITCH_READ_ACCEPTABLE(status)) {
541  goto done;
542  }
543  if (!switch_test_flag(read_frame, SFF_CNG)) {
544  frame_count--;
545  }
546  }
547  }
548 
549  if (cmd_hash == CMD_EXECUTE) {
550  char *app_name = switch_event_get_header(event, "execute-app-name");
551  char *event_uuid = switch_event_get_header(event, "event-uuid");
552  char *app_arg = switch_event_get_header(event, "execute-app-arg");
553  char *content_type = switch_event_get_header(event, "content-type");
554  char *loop_h = switch_event_get_header(event, "loops");
555  char *hold_bleg = switch_event_get_header(event, "hold-bleg");
556  int loops = 1;
557  int inner = 0;
558 
559  if (zstr(app_arg) && !zstr(content_type) && !strcasecmp(content_type, "text/plain")) {
560  app_arg = switch_event_get_body(event);
561  }
562 
563  if (loop_h) {
564  loops = atoi(loop_h);
565  }
566 
567  if (app_name) {
568  int x;
569  const char *b_uuid = NULL;
570  switch_core_session_t *b_session = NULL;
571 
573 
575  inner++;
576  hold_bleg = NULL;
577  }
578 
579  if (!switch_channel_test_flag(channel, CF_BROADCAST)) {
581  if (inner) {
582  inner--;
583  }
584  }
585 
586  if (hold_bleg && switch_true(hold_bleg)) {
587  if ((b_uuid = switch_channel_get_partner_uuid(channel))) {
588  const char *stream;
589  b_uuid = switch_core_session_strdup(session, b_uuid);
590 
591  if (!(stream = switch_channel_get_hold_music_partner(channel))) {
592  stream = switch_channel_get_hold_music(channel);
593  }
594 
595  if (stream && switch_is_moh(stream)) {
596  if ((b_session = switch_core_session_locate(b_uuid))) {
597  switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
598  switch_status_t st;
599 
600  switch_ivr_broadcast(b_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP);
601  st = switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000, NULL);
602  if (st != SWITCH_STATUS_SUCCESS &&
603  switch_channel_ready(channel) && switch_channel_ready(b_channel) && !switch_channel_test_flag(b_channel, CF_BROADCAST)) {
605  st = switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000, NULL);
606 
607  if (st != SWITCH_STATUS_SUCCESS &&
608  switch_channel_ready(channel) && switch_channel_ready(b_channel) && !switch_channel_test_flag(b_channel, CF_BROADCAST)) {
610  }
611  }
612  switch_core_session_rwunlock(b_session);
613  }
614  } else {
615  b_uuid = NULL;
616  }
617  }
618  }
619 
620  for (x = 0; x < loops || loops < 0; x++) {
621  switch_time_t b4, aftr;
622 
623  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Command Execute %s(%s)\n",
624  switch_channel_get_name(channel), app_name, switch_str_nil(app_arg));
625  b4 = switch_micro_time_now();
626 
627  if (event_uuid) {
628  switch_channel_set_variable(channel, "app_uuid", event_uuid);
629  }
630 
631  switch_channel_set_variable_printf(channel, "current_loop", "%d", x + 1);
632  switch_channel_set_variable_printf(channel, "total_loops", "%d", loops);
633 
634  if (switch_core_session_execute_application(session, app_name, app_arg) != SWITCH_STATUS_SUCCESS) {
636  break;
637  }
638 
639  aftr = switch_micro_time_now();
640  if (!switch_channel_ready(channel) || switch_channel_test_flag(channel, CF_STOP_BROADCAST) || aftr - b4 < 500000) {
641  break;
642  }
643  }
644 
645  switch_channel_set_variable(channel, "current_loop", NULL);
646  switch_channel_set_variable(channel, "total_loops", NULL);
647 
648  if (b_uuid) {
649  if ((b_session = switch_core_session_locate(b_uuid))) {
650  switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
652  switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
653  switch_core_session_rwunlock(b_session);
654  }
655  }
656 
657  if (!inner) {
659  }
660 
664  }
665 
666  switch_channel_audio_sync(channel);
667  }
668  } else if (cmd_hash == CMD_UNICAST) {
669  char *local_ip = switch_event_get_header(event, "local-ip");
670  char *local_port = switch_event_get_header(event, "local-port");
671  char *remote_ip = switch_event_get_header(event, "remote-ip");
672  char *remote_port = switch_event_get_header(event, "remote-port");
673  char *transport = switch_event_get_header(event, "transport");
674  char *flags = switch_event_get_header(event, "flags");
675 
676  if (zstr(local_ip)) {
677  local_ip = "127.0.0.1";
678  }
679  if (zstr(remote_ip)) {
680  remote_ip = "127.0.0.1";
681  }
682  if (zstr(local_port)) {
683  local_port = "8025";
684  }
685  if (zstr(remote_port)) {
686  remote_port = "8026";
687  }
688  if (zstr(transport)) {
689  transport = "udp";
690  }
691 
692  switch_ivr_activate_unicast(session, local_ip, (switch_port_t) atoi(local_port), remote_ip, (switch_port_t) atoi(remote_port), transport, flags);
693 
694  } else if (cmd_hash == CMD_XFEREXT) {
696  switch_caller_extension_t *extension = NULL;
697 
698 
699  if ((extension = switch_caller_extension_new(session, "xferext", "xferext")) == 0) {
700  abort();
701  }
702 
703  for (hp = event->headers; hp; hp = hp->next) {
704  char *app;
705  char *data;
706 
707  if (!strcasecmp(hp->name, "application")) {
708  app = strdup(hp->value);
709  if (app) {
710  data = strchr(app, ' ');
711 
712  if (data) {
713  *data++ = '\0';
714  }
715 
716  switch_caller_extension_add_application(session, extension, app, data);
717  free(app);
718  }
719  }
720  }
721 
722  switch_channel_transfer_to_extension(channel, extension);
723 
724  } else if (cmd_hash == CMD_HANGUP) {
725  char *cause_name = switch_event_get_header(event, "hangup-cause");
727 
728  if (cause_name) {
729  cause = switch_channel_str2cause(cause_name);
730  }
731 
732  switch_channel_hangup(channel, cause);
733  } else if (cmd_hash == CMD_NOMEDIA) {
734  char *uuid = switch_event_get_header(event, "nomedia-uuid");
736  }
737 
738  status = SWITCH_STATUS_SUCCESS;
739 
740  done:
741 
743 
744  if (el) {
746  }
747 
748  if (elp) {
750  }
751 
752  return switch_channel_test_flag(channel, CF_BREAK) ? SWITCH_STATUS_BREAK : status;
753 }
754 
756 {
757  switch_event_t *event;
759 
761  status = switch_ivr_parse_event(session, event);
762  event->event_id = SWITCH_EVENT_PRIVATE_COMMAND;
765  switch_event_fire(&event);
766  }
767 
768  return status;
769 
770 }
771 
773 {
776 
777  switch(message->message_id) {
781  }
782  break;
786  }
787  break;
791  }
792  break;
793  default:
794  status = SWITCH_STATUS_FALSE;
795  break;
796  }
797 
798  return status;
799 }
800 
802 {
804  int i = 0;
805 
807 
808  while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) {
809  i++;
810 
811  if (switch_ivr_process_indications(session, message) == SWITCH_STATUS_SUCCESS) {
813  } else {
814  switch_core_session_receive_message(session, message);
815  message = NULL;
816  }
817  }
818 
820 }
821 
822 
824 {
825  void *data;
826  switch_core_session_message_t msg = { 0 };
827  int i = 0;
829 
830  if (only_session_thread && !switch_core_session_in_thread(session)) {
831  return SWITCH_STATUS_FALSE;
832  }
833 
835  return SWITCH_STATUS_FALSE;
836  }
837 
839 
841  msg.from = __FILE__;
842 
844  i++;
845 
846  msg.pointer_arg = data;
848 
849  data = NULL;
850  if (!all)
851  break;
852  }
853 
855 
857 }
858 
861 }
862 
865 }
866 
868 {
869  int x = 0;
870  switch_channel_t *channel;
871 
873 
874  channel = switch_core_session_get_channel(session);
875 
877  if (switch_channel_media_up(channel)) {
879  } else {
880  return SWITCH_STATUS_SUCCESS;
881  }
882  }
883 
885  x++;
886  }
887 
888  return SWITCH_STATUS_SUCCESS;
889 }
890 
891 
893 {
896  switch_frame_t *read_frame = NULL;
897  int stream_id = 0;
898  switch_event_t *event;
899  switch_unicast_conninfo_t *conninfo = NULL;
900  uint32_t rate = 0;
901  uint32_t bpf = 0;
902  const char *to;
903  int timeout = 0;
904  time_t expires = 0;
905  switch_codec_implementation_t read_impl = { 0 };
907  switch_codec_t codec = { 0 };
908  int sval = 0;
909  const char *var;
910  switch_frame_t write_frame = { 0 };
911  unsigned char *abuf = NULL;
912  switch_codec_implementation_t imp = { 0 };
913 
914 
915 
918  }
919 
920  if (switch_channel_test_flag(channel, CF_CONTROLLED)) {
921  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot park channels that are under control already.\n");
922  return SWITCH_STATUS_FALSE;
923  }
924 
925  if (switch_channel_get_state(channel) == CS_RESET) {
926  return SWITCH_STATUS_FALSE;
927  }
928 
930 
931  if ((to = switch_channel_get_variable(channel, "park_timeout"))) {
932  char *cause_str;
933 
934  if ((cause_str = strchr(to, ':'))) {
935  timeout_cause = switch_channel_str2cause(cause_str + 1);
936  }
937 
938  if ((timeout = atoi(to)) < 0) {
939  timeout = 0;
940  } else {
941  expires = switch_epoch_time_now(NULL) + timeout;
942  }
943  switch_channel_set_variable(channel, "park_timeout", NULL);
945  }
946 
949 
951  switch_channel_event_set_data(channel, event);
952  switch_event_fire(&event);
953  }
954 
956 
957  if (!rate && switch_channel_media_ready(channel)) {
958  switch_core_session_get_read_impl(session, &read_impl);
959  rate = read_impl.actual_samples_per_second;
960  bpf = read_impl.decoded_bytes_per_packet;
961 
962  if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
963  switch_core_session_get_read_impl(session, &imp);
964 
965  if (switch_core_codec_init(&codec,
966  "L16",
967  NULL,
968  NULL,
970  imp.microseconds_per_packet / 1000,
971  imp.number_of_channels,
974  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
977  }
978 
979 
980  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
982 
983  write_frame.codec = &codec;
985  write_frame.data = abuf;
987  write_frame.datalen = imp.decoded_bytes_per_packet;
988  write_frame.samples = write_frame.datalen / sizeof(int16_t);
989  }
990  }
991 
992  if (rate) {
993  if (switch_channel_test_flag(channel, CF_SERVICE)) {
995  status = SWITCH_STATUS_SUCCESS;
996  } else {
997  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
998  }
999  } else {
1000  switch_yield(20000);
1001 
1003  switch_ivr_parse_event(session, event);
1004  switch_event_destroy(&event);
1005  }
1006 
1007  status = SWITCH_STATUS_SUCCESS;
1008  }
1009 
1010  if (!SWITCH_READ_ACCEPTABLE(status)) {
1011  break;
1012  }
1013 
1014  if (rate && write_frame.data && sval) {
1015  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, sval);
1016  switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
1017  }
1018 
1019  if (expires && switch_epoch_time_now(NULL) >= expires) {
1020  switch_channel_hangup(channel, timeout_cause);
1021  break;
1022  }
1023 
1024  if (switch_channel_test_flag(channel, CF_UNICAST)) {
1025  if (!switch_channel_media_ready(channel)) {
1028  }
1029  }
1030 
1031  if (!conninfo) {
1032  if (!(conninfo = switch_channel_get_private(channel, "unicast"))) {
1034  }
1035 
1036  if (conninfo) {
1037  unicast_thread_launch(conninfo);
1038  }
1039  }
1040 
1041  if (conninfo) {
1042  switch_size_t len = 0;
1043  uint32_t flags = 0;
1045  uint32_t dlen = sizeof(decoded);
1046  switch_status_t tstatus;
1047  switch_byte_t *sendbuf = NULL;
1048  uint32_t sendlen = 0;
1049 
1050  switch_assert(read_frame);
1051 
1052  if (switch_test_flag(read_frame, SFF_CNG)) {
1053  sendlen = bpf;
1055  memset(decoded, 255, sendlen);
1056  sendbuf = decoded;
1057  tstatus = SWITCH_STATUS_SUCCESS;
1058  } else {
1059  if (switch_test_flag(conninfo, SUF_NATIVE)) {
1060  tstatus = SWITCH_STATUS_NOOP;
1061  } else {
1062  switch_codec_t *read_codec = switch_core_session_get_read_codec(session);
1063  tstatus = switch_core_codec_decode(read_codec,
1064  &conninfo->read_codec,
1065  read_frame->data,
1066  read_frame->datalen, read_impl.actual_samples_per_second, decoded, &dlen, &rate, &flags);
1067  }
1068  switch (tstatus) {
1069  case SWITCH_STATUS_NOOP:
1070  case SWITCH_STATUS_BREAK:
1071  sendbuf = read_frame->data;
1072  sendlen = read_frame->datalen;
1073  tstatus = SWITCH_STATUS_SUCCESS;
1074  break;
1075  case SWITCH_STATUS_SUCCESS:
1076  sendbuf = decoded;
1077  sendlen = dlen;
1078  tstatus = SWITCH_STATUS_SUCCESS;
1079  break;
1080  default:
1083  break;
1084  }
1085  }
1086 
1087  if (tstatus == SWITCH_STATUS_SUCCESS) {
1088  len = sendlen;
1089  if (switch_socket_sendto(conninfo->socket, conninfo->remote_addr, 0, (void *) sendbuf, &len) != SWITCH_STATUS_SUCCESS) {
1091  }
1092  }
1093  }
1094  }
1095 
1096  switch_ivr_parse_all_events(session);
1097 
1098 
1099  if (switch_channel_has_dtmf(channel)) {
1100  switch_dtmf_t dtmf = { 0 };
1101 
1102  if (args && !args->input_callback && !args->buf && !args->dmachine) {
1103  status = SWITCH_STATUS_BREAK;
1104  break;
1105  }
1106 
1107  switch_channel_dequeue_dtmf(channel, &dtmf);
1108 
1109  if (args) {
1110  if (args->dmachine) {
1111  char ds[2] = {dtmf.digit, '\0'};
1112  if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
1113  break;
1114  }
1115  }
1116 
1117  if (args->input_callback) {
1118  if ((status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) {
1119  break;
1120  }
1121  }
1122  }
1123  }
1124 
1126  if (args && args->input_callback) {
1127  switch_status_t ostatus;
1128 
1129  if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) {
1130  status = ostatus;
1131  break;
1132  }
1133  } else {
1134  switch_channel_event_set_data(channel, event);
1135  switch_event_fire(&event);
1136  }
1137  }
1138 
1139  if (args && args->dmachine) {
1140  if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
1141  break;
1142  }
1143  }
1144 
1145 
1146  }
1147 
1148  end:
1149 
1151 
1152  if (write_frame.codec) {
1153  switch_core_codec_destroy(&codec);
1154  }
1155 
1156  switch_safe_free(abuf);
1157 
1160 
1162  switch_channel_event_set_data(channel, event);
1163  switch_event_fire(&event);
1164  }
1165 
1166  if (switch_channel_test_flag(channel, CF_UNICAST)) {
1168  }
1169 
1170  return status;
1171 }
1172 
1174  uint32_t abs_timeout)
1175 {
1178  switch_time_t abs_started = 0, digit_started = 0;
1179  uint32_t abs_elapsed = 0, digit_elapsed = 0;
1180 
1181  if (!args) {
1182  return SWITCH_STATUS_GENERR;
1183  }
1184 
1186 
1187  if (abs_timeout) {
1188  abs_started = switch_micro_time_now();
1189  }
1190  if (digit_timeout) {
1191  digit_started = switch_micro_time_now();
1192  }
1193 
1194  while (switch_channel_ready(channel)) {
1195  switch_frame_t *read_frame = NULL;
1196  switch_event_t *event;
1197  switch_dtmf_t dtmf = { 0 };
1198 
1199  if (switch_channel_test_flag(channel, CF_BREAK)) {
1201  status = SWITCH_STATUS_BREAK;
1202  break;
1203  }
1204 
1205  if (abs_timeout) {
1206  abs_elapsed = (uint32_t) ((switch_micro_time_now() - abs_started) / 1000);
1207  if (abs_elapsed >= abs_timeout) {
1208  status = SWITCH_STATUS_TIMEOUT;
1209  break;
1210  }
1211  }
1212  if (digit_timeout) {
1213  digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000);
1214  if (digit_elapsed >= digit_timeout) {
1215  status = SWITCH_STATUS_TIMEOUT;
1216  break;
1217  }
1218  }
1219 
1220 
1221  switch_ivr_parse_all_events(session);
1222 
1223 
1224  if (switch_channel_has_dtmf(channel)) {
1225  if (!args->input_callback && !args->buf && !args->dmachine) {
1226  status = SWITCH_STATUS_BREAK;
1227  break;
1228  }
1229  switch_channel_dequeue_dtmf(channel, &dtmf);
1230 
1231  if (args->dmachine) {
1232  char ds[2] = {dtmf.digit, '\0'};
1233  if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
1234  break;
1235  }
1236  }
1237 
1238  if (args->input_callback) {
1239  status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
1240  }
1241 
1242  if (digit_timeout) {
1243  digit_started = switch_micro_time_now();
1244  }
1245  }
1246 
1248  switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
1249  if (ostatus != SWITCH_STATUS_SUCCESS) {
1250  status = ostatus;
1251  }
1252  switch_event_destroy(&event);
1253  }
1254 
1255  if (status != SWITCH_STATUS_SUCCESS) {
1256  break;
1257  }
1258 
1259  if (switch_channel_test_flag(channel, CF_SERVICE)) {
1260  switch_cond_next();
1261  } else {
1262  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1263  }
1264 
1265  if (!SWITCH_READ_ACCEPTABLE(status)) {
1266  break;
1267  }
1268 
1269  if (args && args->dmachine) {
1270  if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
1271  break;
1272  }
1273  }
1274 
1275  if (read_frame && args && (args->read_frame_callback)) {
1276  if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
1277  break;
1278  }
1279  }
1280  }
1281 
1283 
1284  return status;
1285 }
1286 
1288  char *buf,
1290  switch_size_t maxdigits,
1291  const char *terminators, char *terminator,
1292  uint32_t first_timeout, uint32_t digit_timeout, uint32_t abs_timeout)
1293 {
1294  switch_size_t i = 0, x = strlen(buf);
1297  switch_time_t started = 0, digit_started = 0;
1298  uint32_t abs_elapsed = 0, digit_elapsed = 0;
1299  uint32_t eff_timeout = 0;
1300  switch_frame_t write_frame = { 0 };
1301  unsigned char *abuf = NULL;
1302  switch_codec_implementation_t imp = { 0 };
1303  switch_codec_t codec = { 0 };
1304  int sval = 0;
1305  const char *var;
1306 
1307  if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
1308  switch_core_session_get_read_impl(session, &imp);
1309 
1310  if (switch_core_codec_init(&codec,
1311  "L16",
1312  NULL,
1313  NULL,
1314  imp.samples_per_second,
1315  imp.microseconds_per_packet / 1000,
1316  imp.number_of_channels,
1319  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
1321  return SWITCH_STATUS_FALSE;
1322  }
1323 
1324 
1325  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
1327 
1328  write_frame.codec = &codec;
1330  write_frame.data = abuf;
1331  write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
1332  write_frame.datalen = imp.decoded_bytes_per_packet;
1333  write_frame.samples = write_frame.datalen / sizeof(int16_t);
1334  }
1335 
1336  if (terminator != NULL) {
1337  *terminator = '\0';
1338  }
1339 
1340  if (!zstr(terminators)) {
1341  for (i = 0; i < x; i++) {
1342  if (strchr(terminators, buf[i]) && terminator != NULL) {
1343  *terminator = buf[i];
1344  buf[i] = '\0';
1345  switch_safe_free(abuf);
1346  return SWITCH_STATUS_SUCCESS;
1347  }
1348  }
1349  }
1350 
1351  if (abs_timeout) {
1352  started = switch_micro_time_now();
1353  }
1354 
1355  if (digit_timeout && first_timeout) {
1356  eff_timeout = first_timeout;
1357  } else if (digit_timeout && !first_timeout) {
1358  first_timeout = eff_timeout = digit_timeout;
1359  } else if (first_timeout) {
1360  digit_timeout = eff_timeout = first_timeout;
1361  }
1362 
1363 
1364  if (eff_timeout) {
1365  digit_started = switch_micro_time_now();
1366  }
1367 
1368  while (switch_channel_ready(channel)) {
1369  switch_frame_t *read_frame;
1370 
1371  if (abs_timeout) {
1372  abs_elapsed = (uint32_t) ((switch_micro_time_now() - started) / 1000);
1373  if (abs_elapsed >= abs_timeout) {
1374  status = SWITCH_STATUS_TIMEOUT;
1375  break;
1376  }
1377  }
1378 
1379 
1380  switch_ivr_parse_all_events(session);
1381 
1382 
1383 
1384  if (eff_timeout) {
1385  digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000);
1386 
1387  if (digit_elapsed >= eff_timeout) {
1388  status = SWITCH_STATUS_TIMEOUT;
1389  break;
1390  }
1391  }
1392 
1393  if (switch_channel_has_dtmf(channel)) {
1394  switch_dtmf_t dtmf = { 0 };
1395  switch_size_t y;
1396 
1397  if (eff_timeout) {
1398  eff_timeout = digit_timeout;
1399  digit_started = switch_micro_time_now();
1400  }
1401 
1402  for (y = 0; y <= maxdigits; y++) {
1403  if (switch_channel_dequeue_dtmf(channel, &dtmf) != SWITCH_STATUS_SUCCESS) {
1404  break;
1405  }
1406 
1407  if (!zstr(terminators) && strchr(terminators, dtmf.digit) && terminator != NULL) {
1408  *terminator = dtmf.digit;
1409  switch_safe_free(abuf);
1410  return SWITCH_STATUS_SUCCESS;
1411  }
1412 
1413 
1414  buf[x++] = dtmf.digit;
1415  buf[x] = '\0';
1416 
1417  if (x >= buflen || x >= maxdigits) {
1418  switch_safe_free(abuf);
1419  return SWITCH_STATUS_SUCCESS;
1420  }
1421  }
1422  }
1423 
1424  if (switch_channel_test_flag(channel, CF_SERVICE)) {
1425  switch_cond_next();
1426  } else {
1427  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1428  if (!SWITCH_READ_ACCEPTABLE(status)) {
1429  break;
1430  }
1431 
1432  if (write_frame.data) {
1433  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, imp.number_of_channels, sval);
1434  switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
1435  }
1436 
1437  }
1438  }
1439 
1440  if (write_frame.codec) {
1441  switch_core_codec_destroy(&codec);
1442  }
1443 
1444  switch_safe_free(abuf);
1445 
1446  return status;
1447 }
1448 
1450 {
1451  switch_core_session_message_t msg = { 0 };
1453  const char *stream;
1454  const char *other_uuid;
1455  switch_event_t *event;
1456 
1458  msg.string_arg = message;
1459  msg.from = __FILE__;
1460 
1461  switch_channel_set_flag(channel, CF_HOLD);
1463 
1464  switch_core_session_receive_message(session, &msg);
1465 
1466  if (moh && (stream = switch_channel_get_hold_music(channel))) {
1467  if ((other_uuid = switch_channel_get_partner_uuid(channel))) {
1468  switch_ivr_broadcast(other_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP);
1469  }
1470  }
1471 
1473  switch_channel_event_set_data(channel, event);
1474  switch_event_fire(&event);
1475  }
1476 
1477 
1478  return SWITCH_STATUS_SUCCESS;
1479 }
1480 
1481 SWITCH_DECLARE(switch_status_t) switch_ivr_hold_uuid(const char *uuid, const char *message, switch_bool_t moh)
1482 {
1483  switch_core_session_t *session;
1484 
1485  if ((session = switch_core_session_locate(uuid))) {
1486  switch_ivr_hold(session, message, moh);
1488  }
1489 
1490  return SWITCH_STATUS_SUCCESS;
1491 }
1492 
1493 SWITCH_DECLARE(switch_status_t) switch_ivr_hold_toggle_uuid(const char *uuid, const char *message, switch_bool_t moh)
1494 {
1495  switch_core_session_t *session;
1496  switch_channel_t *channel;
1497  switch_channel_callstate_t callstate;
1498 
1499  if ((session = switch_core_session_locate(uuid))) {
1500  if ((channel = switch_core_session_get_channel(session))) {
1501  callstate = switch_channel_get_callstate(channel);
1502 
1503  if (callstate == CCS_ACTIVE) {
1504  switch_ivr_hold(session, message, moh);
1505  } else if (callstate == CCS_HELD) {
1506  switch_ivr_unhold(session);
1507  }
1508  }
1510  }
1511 
1512  return SWITCH_STATUS_SUCCESS;
1513 }
1514 
1516 {
1517  switch_core_session_message_t msg = { 0 };
1519  const char *other_uuid;
1520  switch_core_session_t *b_session;
1521  switch_event_t *event;
1522 
1524  msg.from = __FILE__;
1525 
1528 
1529  switch_core_session_receive_message(session, &msg);
1530 
1531 
1532  if ((other_uuid = switch_channel_get_partner_uuid(channel)) && (b_session = switch_core_session_locate(other_uuid))) {
1533  switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
1534  switch_channel_stop_broadcast(b_channel);
1535  switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
1536  switch_core_session_rwunlock(b_session);
1537  }
1538 
1539 
1541  switch_channel_event_set_data(channel, event);
1542  switch_event_fire(&event);
1543  }
1544 
1545  return SWITCH_STATUS_SUCCESS;
1546 }
1547 
1549 {
1550  switch_core_session_t *session;
1551 
1552  if ((session = switch_core_session_locate(uuid))) {
1553  switch_ivr_unhold(session);
1555  }
1556 
1557  return SWITCH_STATUS_SUCCESS;
1558 }
1559 
1560 
1561 
1562 
1563 
1565 {
1566  const char *other_uuid = NULL;
1567  switch_channel_t *channel, *other_channel = NULL;
1568  switch_core_session_t *session, *other_session;
1569  switch_core_session_message_t msg = { 0 };
1571  uint8_t swap = 0;
1572  //switch_frame_t *read_frame = NULL;
1573 
1575  msg.from = __FILE__;
1576 
1577  if ((session = switch_core_session_locate(uuid))) {
1578  channel = switch_core_session_get_channel(session);
1579 
1581  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Operation is invalid\n");
1583  return SWITCH_STATUS_INUSE;
1584  }
1585 
1587 
1588  if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1589  swap = 1;
1590  }
1591 
1592 
1593  status = SWITCH_STATUS_SUCCESS;
1594 
1595  /* If we had early media in bypass mode before, it is no longer relevant */
1596  if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
1597  switch_core_session_message_t msg2 = { 0 };
1598 
1600  msg2.from = __FILE__;
1601  switch_core_session_receive_message(session, &msg2);
1602  }
1603 
1604  if ((flags & SMF_REPLYONLY_A)) {
1605  msg.numeric_arg = 1;
1606  }
1607 
1609 
1611  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel));
1614  return SWITCH_STATUS_GENERR;
1615  }
1616 
1617  if ((flags & SMF_REPLYONLY_B)) {
1618  msg.numeric_arg = 1;
1619  } else {
1620  msg.numeric_arg = 0;
1621  }
1622 
1623  if ((flags & SMF_IMMEDIATE)) {
1625  switch_yield(250000);
1626  } else {
1627  switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1628  switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1629  switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
1631  //switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1632  }
1633 
1634  if ((flags & SMF_REBRIDGE)
1636  && (other_session = switch_core_session_locate(other_uuid))) {
1637 
1638  other_channel = switch_core_session_get_channel(other_session);
1639  switch_assert(other_channel != NULL);
1640 
1642  switch_channel_set_variable(other_channel, "rtp_secure_media", "optional");
1643 
1644  switch_core_session_receive_message(other_session, &msg);
1645  switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1646  switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1647  switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
1648  switch_channel_wait_for_flag(other_channel, CF_3P_MEDIA_REQUESTED, SWITCH_FALSE, 10000, NULL);
1649  //switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1650  switch_channel_clear_state_handler(other_channel, NULL);
1651  switch_core_session_rwunlock(other_session);
1652  }
1653  if (other_channel) {
1654  switch_channel_clear_state_handler(channel, NULL);
1655  }
1656 
1659 
1660  if (other_channel) {
1661  if (swap) {
1662  switch_ivr_uuid_bridge(other_uuid, uuid);
1663  } else {
1664  switch_ivr_uuid_bridge(uuid, other_uuid);
1665  }
1666  switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
1667  switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
1668  }
1669  }
1670 
1671  return status;
1672 }
1673 
1675 {
1676  const char *other_uuid = NULL;
1677  switch_channel_t *channel, *other_channel = NULL;
1678  switch_core_session_t *session, *other_session;
1679  switch_core_session_message_t msg = { 0 };
1681  uint8_t swap = 0;
1682  switch_frame_t *read_frame = NULL;
1683 
1685  msg.from = __FILE__;
1686 
1687  if ((session = switch_core_session_locate(uuid))) {
1688  channel = switch_core_session_get_channel(session);
1689 
1690  if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) {
1692  return SWITCH_STATUS_INUSE;
1693  }
1694 
1696 
1697  if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1698  swap = 1;
1699  }
1700 
1701  if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
1702  status = SWITCH_STATUS_SUCCESS;
1703 
1704  /* If we had early media in bypass mode before, it is no longer relevant */
1705  if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
1706  switch_core_session_message_t msg2 = { 0 };
1707 
1709  msg2.from = __FILE__;
1710  switch_core_session_receive_message(session, &msg2);
1711  }
1712 
1713  if ((flags & SMF_REPLYONLY_A)) {
1714  msg.numeric_arg = 1;
1715  }
1716 
1718  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel));
1720  return SWITCH_STATUS_GENERR;
1721  }
1722 
1723  if ((flags & SMF_REPLYONLY_B)) {
1724  msg.numeric_arg = 1;
1725  } else {
1726  msg.numeric_arg = 0;
1727  }
1728 
1729  if ((flags & SMF_IMMEDIATE)) {
1731  switch_yield(250000);
1732  } else {
1733  switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1734  switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1735  switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
1736  switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1737  }
1738 
1739  if ((flags & SMF_REBRIDGE)
1741  && (other_session = switch_core_session_locate(other_uuid))) {
1742  other_channel = switch_core_session_get_channel(other_session);
1743  switch_assert(other_channel != NULL);
1744  switch_core_session_receive_message(other_session, &msg);
1745  switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1746  switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1747  switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
1748  switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1749  switch_channel_clear_state_handler(other_channel, NULL);
1750  switch_core_session_rwunlock(other_session);
1751  }
1752  if (other_channel) {
1753  switch_channel_clear_state_handler(channel, NULL);
1754  }
1755  }
1756 
1759 
1760  if (other_channel) {
1761  if (swap) {
1762  switch_ivr_uuid_bridge(other_uuid, uuid);
1763  } else {
1764  switch_ivr_uuid_bridge(uuid, other_uuid);
1765  }
1766  switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
1767  switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
1768  }
1769  }
1770 
1771  return status;
1772 }
1773 
1775 {
1776  const char *other_uuid;
1777  switch_channel_t *channel, *other_channel = NULL;
1778  switch_core_session_t *session, *other_session = NULL;
1779  switch_core_session_message_t msg = { 0 };
1781  uint8_t swap = 0;
1782 
1784  msg.from = __FILE__;
1785 
1786  if ((session = switch_core_session_locate(uuid))) {
1787  status = SWITCH_STATUS_SUCCESS;
1788  channel = switch_core_session_get_channel(session);
1789 
1790  if (switch_channel_test_flag(channel, CF_MEDIA_TRANS) || (!(flags & SMF_FORCE) && switch_channel_test_flag(channel, CF_PROXY_MODE))) {
1791  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Operation is invalid\n");
1793  return SWITCH_STATUS_INUSE;
1794  }
1795 
1797 
1798  if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1799  swap = 1;
1800  }
1801 
1802  if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
1803  if ((flags & SMF_REBRIDGE) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) &&
1804  (other_session = switch_core_session_locate(other_uuid))) {
1805  other_channel = switch_core_session_get_channel(other_session);
1806 
1809 
1810  switch_channel_set_flag(other_channel, CF_RESET);
1811  switch_channel_set_flag(other_channel, CF_REDIRECT);
1812 
1815  switch_core_session_receive_message(session, &msg);
1816 
1817  if (!switch_core_session_in_thread(session)) {
1819  }
1820 
1821  switch_channel_set_state(other_channel, CS_PARK);
1822 
1823  if (switch_core_session_in_thread(session)) {
1824  switch_yield(100000);
1825  } else {
1826  switch_channel_wait_for_state(other_channel, channel, CS_PARK);
1827  }
1828 
1829 
1830  if (!switch_core_session_in_thread(session)) {
1831  switch_channel_wait_for_state(channel, NULL, CS_PARK);
1832  }
1833 
1834  switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1835  switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1837 
1841 
1842 
1843  switch_core_session_receive_message(other_session, &msg);
1844  switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1845  switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1847  }
1848 
1849  if (other_channel) {
1850  if (swap) {
1851  switch_ivr_signal_bridge(other_session, session);
1852  } else {
1853  switch_ivr_signal_bridge(session, other_session);
1854  }
1855 
1856  if (switch_core_session_in_thread(session)) {
1857  switch_yield(100000);
1858  } else {
1859  switch_channel_wait_for_state(other_channel, channel, CS_HIBERNATE);
1860  }
1861 
1862  if (!switch_core_session_in_thread(session)) {
1863  switch_channel_wait_for_state(channel, other_channel, CS_HIBERNATE);
1864  }
1865  switch_core_session_rwunlock(other_session);
1866  }
1867  }
1868 
1871  }
1872 
1873 
1874 
1875  return status;
1876 }
1877 
1878 
1879 
1881 {
1882  const char *other_uuid;
1883  switch_channel_t *channel, *other_channel = NULL;
1884  switch_core_session_t *session, *other_session = NULL;
1885  switch_core_session_message_t msg = { 0 };
1887  uint8_t swap = 0;
1888 
1890  msg.from = __FILE__;
1891 
1892  if ((session = switch_core_session_locate(uuid))) {
1893 
1894  status = SWITCH_STATUS_SUCCESS;
1895  channel = switch_core_session_get_channel(session);
1896 
1897  if (switch_channel_test_flag(channel, CF_SECURE)) {
1900  "Cannot bypass %s due to secure connection.\n", switch_channel_get_name(channel));
1901  return SWITCH_STATUS_FALSE;
1902  }
1903 
1904  if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) {
1906  return SWITCH_STATUS_INUSE;
1907  }
1908 
1910 
1911  if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1912  swap = 1;
1913  }
1914 
1917 
1918  if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
1919  if ((flags & SMF_REBRIDGE) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) &&
1920  (other_session = switch_core_session_locate(other_uuid))) {
1921  other_channel = switch_core_session_get_channel(other_session);
1922 
1923  switch_channel_set_flag(other_channel, CF_RESET);
1924  switch_channel_set_flag(other_channel, CF_REDIRECT);
1925 
1926  if (!switch_core_session_in_thread(session)) {
1928  }
1929  switch_channel_set_state(other_channel, CS_PARK);
1930  if (switch_core_session_in_thread(session)) {
1931  switch_yield(100000);
1932  } else {
1933  switch_channel_wait_for_state(other_channel, channel, CS_PARK);
1934  }
1935  switch_core_session_receive_message(other_session, &msg);
1936  switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1937  //switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1938  switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
1939  }
1940 
1941  switch_core_session_receive_message(session, &msg);
1942 
1943  if (other_channel) {
1944  if (!switch_core_session_in_thread(session)) {
1945  switch_channel_wait_for_state(channel, NULL, CS_PARK);
1946  switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1947  switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1948  switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
1949  }
1950 
1951  if (swap) {
1952  switch_ivr_signal_bridge(other_session, session);
1953  } else {
1954  switch_ivr_signal_bridge(session, other_session);
1955  }
1956 
1957  if (switch_core_session_in_thread(session)) {
1958  switch_yield(100000);
1959  } else {
1960  switch_channel_wait_for_state(other_channel, channel, CS_HIBERNATE);
1961  }
1962 
1963  if (!switch_core_session_in_thread(session)) {
1964  switch_channel_wait_for_state(channel, other_channel, CS_HIBERNATE);
1965  }
1966  switch_core_session_rwunlock(other_session);
1967  }
1968  }
1969 
1972  }
1973 
1974 
1975 
1976  return status;
1977 }
1978 
1979 typedef struct {
1981  const char *uuid;
1985  uint32_t delay;
1986 } media_job_t;
1987 
1989 {
1990  media_job_t *job = (media_job_t *) obj;
1991 
1992  if (job->delay) {
1993  switch_yield(job->delay * 1000);
1994  }
1995 
1996  if (job->on) {
1997  if (job->is3p) {
1998  switch_ivr_3p_media(job->uuid, job->flags);
1999  } else {
2000  switch_ivr_media(job->uuid, job->flags);
2001  }
2002  } else {
2003  if (job->is3p) {
2004  switch_ivr_3p_nomedia(job->uuid, job->flags);
2005  } else {
2006  switch_ivr_nomedia(job->uuid, job->flags);
2007  }
2008  }
2009 
2010  return NULL;
2011 }
2012 
2013 
2014 SWITCH_DECLARE(void) switch_ivr_bg_media(const char *uuid, switch_media_flag_t flags, switch_bool_t on, switch_bool_t is3p, uint32_t delay)
2015 {
2018  media_job_t *job;
2019 
2021  td = switch_core_alloc(pool, sizeof(*td));
2022  job = switch_core_alloc(pool, sizeof(*job));
2023  td->func = media_thread_run;
2024  job->pool = pool;
2025  job->uuid = switch_core_strdup(pool, uuid);
2026  job->flags = flags;
2027  job->on = on;
2028  job->is3p = is3p;
2029  job->delay = delay;
2030  td->obj = job;
2031  td->pool = pool;
2033 
2034 }
2035 
2036 
2037 SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_t *session, const char *extension, const char *dialplan,
2038  const char *context)
2039 {
2041  switch_caller_profile_t *profile, *new_profile;
2042  switch_core_session_message_t msg = { 0 };
2043  switch_core_session_t *other_session;
2044  switch_channel_t *other_channel = NULL;
2045  const char *uuid = NULL;
2046  const char *max_forwards;
2047  const char *forwardvar_name = SWITCH_MAX_SESSION_TRANSFERS_VARIABLE; /* max_session_transfers has first priority for setting maximum */
2048  const char *forwardvar = switch_channel_get_variable(channel, forwardvar_name);
2049  int forwardval = 70;
2050  const char *use_dialplan = dialplan, *use_context = context;
2051 
2052  if (zstr(forwardvar)) {
2053  forwardvar_name = SWITCH_MAX_FORWARDS_VARIABLE; /* fall back to max_forwards variable for setting maximum */
2054  forwardvar = switch_channel_get_variable(channel, forwardvar_name);
2055  }
2056  if (!zstr(forwardvar)) {
2057  forwardval = atoi(forwardvar) - 1;
2058  }
2059  if (forwardval <= 0) {
2061  return SWITCH_STATUS_FALSE;
2062  }
2063 
2064  max_forwards = switch_core_session_sprintf(session, "%d", forwardval);
2065  switch_channel_set_variable(channel, forwardvar_name, max_forwards);
2066 
2069 
2070  /* clear all state handlers */
2071  switch_channel_clear_state_handler(channel, NULL);
2072 
2073  /* reset temp hold music */
2075 
2076  switch_channel_execute_on(channel, "execute_on_blind_transfer");
2077 
2078  if ((profile = switch_channel_get_caller_profile(channel))) {
2079  const char *var;
2080 
2081  if (zstr(dialplan) && (var = switch_channel_get_variable(channel, "force_transfer_dialplan"))) {
2082  use_dialplan = var;
2083  }
2084 
2085  if (zstr(context) && (var = switch_channel_get_variable(channel, "force_transfer_context"))) {
2086  use_context = var;
2087  }
2088 
2089  if (zstr(use_dialplan)) {
2090  use_dialplan = profile->dialplan;
2091  if (!zstr(use_dialplan) && !strcasecmp(use_dialplan, "inline")) {
2092  use_dialplan = NULL;
2093  }
2094  }
2095 
2096  if (zstr(use_context)) {
2097  use_context = profile->context;
2098  }
2099 
2100  if (zstr(use_dialplan)) {
2101  use_dialplan = "XML";
2102  }
2103 
2104  if (zstr(use_context)) {
2105  use_context = "default";
2106  }
2107 
2108  if (zstr(extension)) {
2109  extension = "service";
2110  }
2111 
2112  new_profile = switch_caller_profile_clone(session, profile);
2113 
2114  new_profile->dialplan = switch_core_strdup(new_profile->pool, use_dialplan);
2115  new_profile->context = switch_core_strdup(new_profile->pool, use_context);
2116  new_profile->destination_number = switch_core_strdup(new_profile->pool, extension);
2117  new_profile->rdnis = switch_core_strdup(new_profile->pool, profile->destination_number);
2118 
2120 
2121  /* Set CF_TRANSFER flag before hanging up bleg to avoid race condition */
2123 
2124  /* If HANGUP_AFTER_BRIDGE is set to 'true', SWITCH_SIGNAL_BRIDGE_VARIABLE
2125  * will not have a value, so we need to check SWITCH_BRIDGE_VARIABLE */
2126 
2128 
2129  if (!uuid) {
2131  }
2132 
2133  if (uuid && (other_session = switch_core_session_locate(uuid))) {
2134  other_channel = switch_core_session_get_channel(other_session);
2136  switch_core_session_rwunlock(other_session);
2137  }
2138 
2140  && (other_session = switch_core_session_locate(uuid))) {
2141  other_channel = switch_core_session_get_channel(other_session);
2142 
2145 
2148 
2149  /* If we are transferring the CALLER out of the bridge, we do not want to hang up on them */
2151 
2153  switch_ivr_media(uuid, SMF_NONE);
2154 
2155  switch_core_session_rwunlock(other_session);
2156  }
2157 
2158  switch_channel_set_caller_profile(channel, new_profile);
2159 
2161  switch_channel_audio_sync(channel);
2162 
2164  msg.from = __FILE__;
2165  switch_core_session_receive_message(session, &msg);
2166 
2167  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Transfer %s to %s[%s@%s]\n", switch_channel_get_name(channel), use_dialplan,
2168  extension, use_context);
2169 
2170 
2171  new_profile->transfer_source = switch_core_sprintf(new_profile->pool, "%ld:%s:bl_xfer:%s/%s/%s",
2172  (long) switch_epoch_time_now(NULL), new_profile->uuid_str,
2173  extension, use_context, use_dialplan);
2176  return SWITCH_STATUS_SUCCESS;
2177  }
2178 
2179  return SWITCH_STATUS_FALSE;
2180 }
2181 
2183 {
2186  switch_event_t *var_event;
2187 
2188  const char *val = NULL;
2189  uint8_t prefix = 0;
2190 
2191  if (var && *var == '~') {
2192  var++;
2193  prefix = 1;
2194  }
2195 
2196  if (var && !prefix) {
2197  if ((val = switch_channel_get_variable(chana, var))) {
2198  switch_channel_set_variable(chanb, var, val);
2199  }
2200  } else {
2202 
2203  switch_channel_get_variables(chana, &var_event);
2204 
2205  for (hi = var_event->headers; hi; hi = hi->next) {
2206  char *vvar = hi->name;
2207  char *vval = hi->value;
2208  if (vvar && vval && (!prefix || (var && !strncmp((char *) vvar, var, strlen(var))))) {
2209  switch_channel_set_variable(chanb, (char *) vvar, (char *) vval);
2210  }
2211  }
2212 
2213  switch_event_destroy(&var_event);
2214  }
2215 
2216  return SWITCH_STATUS_SUCCESS;
2217 }
2218 
2219 /******************************************************************************************************/
2220 
2229  unsigned int digit_timeout_ms;
2230 };
2231 
2233  char *digits;
2235 };
2236 
2238 {
2240 
2241  if (parser != NULL) {
2242  int pool_auto_created = 0;
2243 
2244  /* if the caller didn't provide a pool, make one */
2245  if (pool == NULL) {
2247  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "created a memory pool\n");
2248  if (pool != NULL) {
2249  pool_auto_created = 1;
2250  }
2251  }
2252  /* if we have a pool, make a parser object */
2253  if (pool != NULL) {
2255  }
2256  /* if we have parser object, initialize it for the caller */
2257  if (pool && *parser != NULL) {
2258  memset(*parser, 0, sizeof(switch_ivr_digit_stream_parser_t));
2259  (*parser)->pool_auto_created = pool_auto_created;
2260  (*parser)->pool = pool;
2261  (*parser)->digit_timeout_ms = 1000;
2262  switch_core_hash_init(&(*parser)->hash);
2263 
2264  status = SWITCH_STATUS_SUCCESS;
2265  } else {
2266  status = SWITCH_STATUS_MEMERR;
2267  /* if we can't create a parser object,clean up the pool if we created it */
2268  if (pool != NULL && pool_auto_created) {
2270  }
2271  }
2272  }
2273 
2274  return status;
2275 }
2276 
2278 {
2280 
2281  if (parser != NULL) {
2282  if (parser->hash != NULL) {
2283  switch_core_hash_destroy(&parser->hash);
2284  parser->hash = NULL;
2285  }
2286  /* free the memory pool if we created it */
2287  if (parser->pool_auto_created && parser->pool != NULL) {
2288  status = switch_core_destroy_memory_pool(&parser->pool);
2289  }
2290  }
2291 
2292  return status;
2293 }
2294 
2296 {
2298 
2299  /* if we have a parser object memory pool and a stream object pointer that is null */
2300  if (parser && stream && *stream == NULL) {
2301  *stream = (switch_ivr_digit_stream_t *) malloc(sizeof(**stream));
2302  switch_assert(*stream);
2303  memset(*stream, 0, sizeof(**stream));
2304  switch_zmalloc((*stream)->digits, parser->buflen + 1);
2305  status = SWITCH_STATUS_SUCCESS;
2306  }
2307 
2308  return status;
2309 }
2310 
2312 {
2314 
2315  if (*stream) {
2316  switch_safe_free((*stream)->digits);
2317  free(*stream);
2318  *stream = NULL;
2319  status = SWITCH_STATUS_SUCCESS;
2320  }
2321 
2322  return status;
2323 }
2324 
2326 {
2328 
2329  if (parser != NULL && digits != NULL && *digits && parser->hash != NULL) {
2330 
2331  status = switch_core_hash_insert(parser->hash, digits, data);
2332  if (status == SWITCH_STATUS_SUCCESS) {
2333  switch_size_t len = strlen(digits);
2334 
2335  /* if we don't have a terminator, then we have to try and
2336  * figure out when a digit set is completed, therefore we
2337  * keep track of the min and max digit lengths
2338  */
2339 
2340  if (len > parser->buflen) {
2341  parser->buflen = len;
2342  }
2343 
2344  if (parser->terminator == '\0') {
2345  if (len > parser->maxlen) {
2346  parser->maxlen = len;
2347  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "max len %u\n", (uint32_t) parser->maxlen);
2348  }
2349  if (parser->minlen == 0 || len < parser->minlen) {
2350  parser->minlen = len;
2351  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "min len %u\n", (uint32_t) parser->minlen);
2352  }
2353  } else {
2354  /* since we have a terminator, reset min and max */
2355  parser->minlen = 0;
2356  parser->maxlen = 0;
2357  }
2358  }
2359  }
2360  if (status != SWITCH_STATUS_SUCCESS) {
2361  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to add hash for '%s'\n", digits);
2362  }
2363 
2364  return status;
2365 }
2366 
2368 {
2370 
2371  if (parser != NULL && digits != NULL && *digits) {
2372  status = switch_core_hash_delete(parser->hash, digits) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
2373  }
2374 
2375  if (status != SWITCH_STATUS_SUCCESS) {
2376  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to del hash for '%s'\n", digits);
2377  }
2378 
2379  return status;
2380 }
2381 
2383 {
2384  void *result = NULL;
2385  switch_size_t len;
2386 
2387  switch_assert(parser);
2388  switch_assert(stream);
2389  switch_assert(stream->digits);
2390 
2391  len = strlen(stream->digits);
2392 
2393  /* handle new digit arrivals */
2394  if (digit) {
2395  /* if it's not a terminator digit, add it to the collected digits */
2396  if (digit != parser->terminator) {
2397  /* if collected digits length >= the max length of the keys
2398  * in the hash table, then left shift the digit string
2399  */
2400  if (len > 0 && parser->maxlen != 0 && len >= parser->maxlen) {
2401  char *src = stream->digits + 1;
2402  char *dst = stream->digits;
2403 
2404  while (*src) {
2405  *(dst++) = *(src++);
2406  }
2407  *dst = digit;
2408  } else {
2409  *(stream->digits + (len++)) = digit;
2410  *(stream->digits + len) = '\0';
2411  stream->last_digit_time = switch_micro_time_now() / 1000;
2412  }
2413  }
2414  }
2415 
2416  /* don't allow collected digit string testing if there are varying sized keys until timeout */
2417  if (parser->maxlen - parser->minlen > 0 && (switch_micro_time_now() / 1000) - stream->last_digit_time < parser->digit_timeout_ms) {
2418  len = 0;
2419  }
2420  /* if we have digits to test */
2421  if (len) {
2422  result = switch_core_hash_find(parser->hash, stream->digits);
2423  /* if we matched the digit string, or this digit is the terminator
2424  * reset the collected digits for next digit string
2425  */
2426  if (result != NULL || parser->terminator == digit) {
2427  *stream->digits = '\0';
2428  }
2429  }
2430 
2431 
2432  return result;
2433 }
2434 
2436 {
2438  switch_assert(stream);
2439  switch_assert(stream->digits);
2440 
2441  *stream->digits = '\0';
2442  stream->last_digit_time = 0;
2443  status = SWITCH_STATUS_SUCCESS;
2444 
2445  return status;
2446 }
2447 
2449 {
2451 
2452  if (parser != NULL) {
2453  parser->terminator = digit;
2454  /* since we have a terminator, reset min and max */
2455  parser->minlen = 0;
2456  parser->maxlen = 0;
2457  status = SWITCH_STATUS_SUCCESS;
2458  }
2459 
2460  return status;
2461 }
2462 
2464 {
2465  switch_xml_t param;
2466 
2467  if (!(param = switch_xml_add_child_d(xml, "username", off++))) {
2468  return -1;
2469  }
2470  switch_xml_set_txt_d(param, caller_profile->username);
2471 
2472  if (!(param = switch_xml_add_child_d(xml, "dialplan", off++))) {
2473  return -1;
2474  }
2475  switch_xml_set_txt_d(param, caller_profile->dialplan);
2476 
2477  if (!(param = switch_xml_add_child_d(xml, "caller_id_name", off++))) {
2478  return -1;
2479  }
2480  switch_xml_set_txt_d(param, caller_profile->caller_id_name);
2481 
2482  if (!(param = switch_xml_add_child_d(xml, "caller_id_number", off++))) {
2483  return -1;
2484  }
2485  switch_xml_set_txt_d(param, caller_profile->caller_id_number);
2486 
2487  if (!(param = switch_xml_add_child_d(xml, "callee_id_name", off++))) {
2488  return -1;
2489  }
2490  switch_xml_set_txt_d(param, caller_profile->callee_id_name);
2491 
2492  if (!(param = switch_xml_add_child_d(xml, "callee_id_number", off++))) {
2493  return -1;
2494  }
2495  switch_xml_set_txt_d(param, caller_profile->callee_id_number);
2496 
2497  if (!(param = switch_xml_add_child_d(xml, "ani", off++))) {
2498  return -1;
2499  }
2500  switch_xml_set_txt_d(param, caller_profile->ani);
2501 
2502  if (!(param = switch_xml_add_child_d(xml, "aniii", off++))) {
2503  return -1;
2504  }
2505  switch_xml_set_txt_d(param, caller_profile->aniii);
2506 
2507 
2508  if (!(param = switch_xml_add_child_d(xml, "network_addr", off++))) {
2509  return -1;
2510  }
2511  switch_xml_set_txt_d(param, caller_profile->network_addr);
2512 
2513  if (!(param = switch_xml_add_child_d(xml, "rdnis", off++))) {
2514  return -1;
2515  }
2516  switch_xml_set_txt_d(param, caller_profile->rdnis);
2517 
2518  if (!(param = switch_xml_add_child_d(xml, "destination_number", off++))) {
2519  return -1;
2520  }
2521  switch_xml_set_txt_d(param, caller_profile->destination_number);
2522 
2523  if (!(param = switch_xml_add_child_d(xml, "uuid", off++))) {
2524  return -1;
2525  }
2526  switch_xml_set_txt_d(param, caller_profile->uuid);
2527 
2528  if (!(param = switch_xml_add_child_d(xml, "source", off++))) {
2529  return -1;
2530  }
2531  switch_xml_set_txt_d(param, caller_profile->source);
2532 
2533  if (caller_profile->transfer_source) {
2534  if (!(param = switch_xml_add_child_d(xml, "transfer_source", off++))) {
2535  return -1;
2536  }
2537  switch_xml_set_txt_d(param, caller_profile->transfer_source);
2538  }
2539 
2540  if (!(param = switch_xml_add_child_d(xml, "context", off++))) {
2541  return -1;
2542  }
2543  switch_xml_set_txt_d(param, caller_profile->context);
2544 
2545  if (!(param = switch_xml_add_child_d(xml, "chan_name", off++))) {
2546  return -1;
2547  }
2548  switch_xml_set_txt_d(param, caller_profile->chan_name);
2549 
2550 
2551  if (caller_profile->soft) {
2552  profile_node_t *pn;
2553 
2554  for (pn = caller_profile->soft; pn; pn = pn->next) {
2555 
2556  if (!(param = switch_xml_add_child_d(xml, pn->var, off++))) {
2557  return -1;
2558  }
2559  switch_xml_set_txt_d(param, pn->val);
2560  }
2561 
2562  }
2563 
2564 
2565  return off;
2566 }
2567 
2568 
2569 #define add_stat(_x, _i, _s) \
2570  switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \
2571  x_tmp = switch_xml_add_child_d(_x, _s, loff++); \
2572  switch_xml_set_txt_d(x_tmp, var_val)
2573 
2574 #define add_stat_double(_x, _i, _s) \
2575  switch_snprintf(var_val, sizeof(var_val), "%0.2f", _i); \
2576  x_tmp = switch_xml_add_child_d(_x, _s, loff++); \
2577  switch_xml_set_txt_d(x_tmp, var_val)
2578 
2580 {
2581  const char *name = (type == SWITCH_MEDIA_TYPE_VIDEO) ? "video" : "audio";
2582  switch_xml_t x_stat, x_in, x_out, x_tmp = NULL;
2583  int loff = 0;
2584  switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL);
2585  char var_val[35] = "";
2586 
2587  if (!stats) return off;
2588 
2589  if (!(x_stat = switch_xml_add_child_d(xml, name, off++))) {
2590  abort();
2591  }
2592 
2593  if (!(x_in = switch_xml_add_child_d(x_stat, "inbound", off++))) {
2594  abort();
2595  }
2596 
2597  if (!(x_out = switch_xml_add_child_d(x_stat, "outbound", off++))) {
2598  abort();
2599  }
2600 
2601  stats->inbound.std_deviation = sqrt(stats->inbound.variance);
2602 
2603  add_stat(x_in, stats->inbound.raw_bytes, "raw_bytes");
2604  add_stat(x_in, stats->inbound.media_bytes, "media_bytes");
2605  add_stat(x_in, stats->inbound.packet_count, "packet_count");
2606  add_stat(x_in, stats->inbound.media_packet_count, "media_packet_count");
2607  add_stat(x_in, stats->inbound.skip_packet_count, "skip_packet_count");
2608  add_stat(x_in, stats->inbound.jb_packet_count, "jitter_packet_count");
2609  add_stat(x_in, stats->inbound.dtmf_packet_count, "dtmf_packet_count");
2610  add_stat(x_in, stats->inbound.cng_packet_count, "cng_packet_count");
2611  add_stat(x_in, stats->inbound.flush_packet_count, "flush_packet_count");
2612  add_stat(x_in, stats->inbound.largest_jb_size, "largest_jb_size");
2613  add_stat_double(x_in, stats->inbound.min_variance, "jitter_min_variance");
2614  add_stat_double(x_in, stats->inbound.max_variance, "jitter_max_variance");
2615  add_stat_double(x_in, stats->inbound.lossrate, "jitter_loss_rate");
2616  add_stat_double(x_in, stats->inbound.burstrate, "jitter_burst_rate");
2617  add_stat_double(x_in, stats->inbound.mean_interval, "mean_interval");
2618  add_stat(x_in, stats->inbound.flaws, "flaw_total");
2619  add_stat_double(x_in, stats->inbound.R, "quality_percentage");
2620  add_stat_double(x_in, stats->inbound.mos, "mos");
2621 
2622 
2623  if (stats->inbound.error_log) {
2624  switch_xml_t x_err_log, x_err;
2626  int eoff = 0;
2627 
2628  if (!(x_err_log = switch_xml_add_child_d(x_stat, "error-log", off++))) {
2629  abort();
2630  }
2631 
2632  for(ep = stats->inbound.error_log; ep; ep = ep->next) {
2633 
2634  if (!(ep->start && ep->stop)) continue;
2635 
2636  if (!(x_err = switch_xml_add_child_d(x_err_log, "error-period", eoff++))) {
2637  abort();
2638  }
2639 
2640  switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_TIME_T_FMT, ep->start);
2641  x_tmp = switch_xml_add_child_d(x_err, "start", 0);
2642  switch_xml_set_txt_d(x_tmp, var_val);
2643 
2644  switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_TIME_T_FMT, ep->stop);
2645  x_tmp = switch_xml_add_child_d(x_err, "stop", 1);
2646  switch_xml_set_txt_d(x_tmp, var_val);
2647 
2648  switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_TIME_T_FMT, (ep->stop - ep->start) / 1000);
2649  x_tmp = switch_xml_add_child_d(x_err, "duration-msec", 2);
2650  switch_xml_set_txt_d(x_tmp, var_val);
2651  }
2652  }
2653 
2654  add_stat(x_out, stats->outbound.raw_bytes, "raw_bytes");
2655  add_stat(x_out, stats->outbound.media_bytes, "media_bytes");
2656  add_stat(x_out, stats->outbound.packet_count, "packet_count");
2657  add_stat(x_out, stats->outbound.media_packet_count, "media_packet_count");
2658  add_stat(x_out, stats->outbound.skip_packet_count, "skip_packet_count");
2659  add_stat(x_out, stats->outbound.dtmf_packet_count, "dtmf_packet_count");
2660  add_stat(x_out, stats->outbound.cng_packet_count, "cng_packet_count");
2661  add_stat(x_out, stats->rtcp.packet_count, "rtcp_packet_count");
2662  add_stat(x_out, stats->rtcp.octet_count, "rtcp_octet_count");
2663 
2664  return off;
2665 }
2666 
2667 static int switch_ivr_set_xml_chan_var(switch_xml_t xml, const char *var, const char *val, int off)
2668 {
2669  char *data;
2670  switch_size_t dlen = strlen(val) * 3 + 1;
2671  switch_xml_t variable;
2672 
2673  if (!val) val = "";
2674 
2675  if (!zstr(var) && ((variable = switch_xml_add_child_d(xml, var, off++)))) {
2676  if ((data = malloc(dlen))) {
2677  memset(data, 0, dlen);
2678  switch_url_encode(val, data, dlen);
2679  switch_xml_set_txt_d(variable, data);
2680  free(data);
2681  } else abort();
2682  }
2683 
2684  return off;
2685 
2686 }
2687 
2688 
2690 {
2691 
2693 
2694  if (!hi)
2695  return off;
2696 
2697  for (; hi; hi = hi->next) {
2698  if (hi->idx) {
2699  int i;
2700 
2701  for (i = 0; i < hi->idx; i++) {
2702  off = switch_ivr_set_xml_chan_var(xml, hi->name, hi->array[i], off);
2703  }
2704  } else {
2705  off = switch_ivr_set_xml_chan_var(xml, hi->name, hi->value, off);
2706  }
2707  }
2709 
2710  return off;
2711 }
2712 
2714 {
2716  switch_caller_profile_t *caller_profile;
2717  switch_xml_t variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag,
2718  x_application, x_callflow, x_inner_extension, x_apps, x_o, x_channel_data, x_field, xhr, x_hold;
2719  switch_app_log_t *app_log;
2720  char tmp[512], *f;
2721  int cdr_off = 0, v_off = 0, cd_off = 0;
2722  switch_hold_record_t *hold_record = switch_channel_get_hold_record(channel), *hr;
2723 
2724  if (*xml_cdr) {
2725  cdr = *xml_cdr;
2726  } else {
2727  if (!(cdr = switch_xml_new("cdr"))) {
2728  return SWITCH_STATUS_SUCCESS;
2729  }
2730  }
2731 
2732  switch_xml_set_attr_d(cdr, "core-uuid", switch_core_get_uuid());
2733  switch_xml_set_attr_d(cdr, "switchname", switch_core_get_switchname());
2734 
2735  if (!(x_channel_data = switch_xml_add_child_d(cdr, "channel_data", cdr_off++))) {
2736  goto error;
2737  }
2738 
2739  x_field = switch_xml_add_child_d(x_channel_data, "state", cd_off++);
2741 
2742  x_field = switch_xml_add_child_d(x_channel_data, "direction", cd_off++);
2743  switch_xml_set_txt_d(x_field, switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
2744 
2745  x_field = switch_xml_add_child_d(x_channel_data, "state_number", cd_off++);
2746  switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel));
2747  switch_xml_set_txt_d(x_field, tmp);
2748 
2749  if ((f = switch_channel_get_flag_string(channel))) {
2750  x_field = switch_xml_add_child_d(x_channel_data, "flags", cd_off++);
2751  switch_xml_set_txt_d(x_field, f);
2752  free(f);
2753  }
2754 
2755  if ((f = switch_channel_get_cap_string(channel))) {
2756  x_field = switch_xml_add_child_d(x_channel_data, "caps", cd_off++);
2757  switch_xml_set_txt_d(x_field, f);
2758  free(f);
2759  }
2760 
2761  if (!(variables = switch_xml_add_child_d(cdr, "call-stats", cdr_off++))) {
2762  goto error;
2763  }
2764 
2765  switch_ivr_set_xml_call_stats(variables, session, v_off, SWITCH_MEDIA_TYPE_AUDIO);
2766  switch_ivr_set_xml_call_stats(variables, session, v_off, SWITCH_MEDIA_TYPE_VIDEO);
2767 
2768 
2769  if (!(variables = switch_xml_add_child_d(cdr, "variables", cdr_off++))) {
2770  goto error;
2771  }
2772 
2773  switch_ivr_set_xml_chan_vars(variables, channel, v_off);
2774 
2775 
2776  if ((app_log = switch_core_session_get_app_log(session))) {
2777  int app_off = 0;
2778  switch_app_log_t *ap;
2779 
2780  if (!(x_apps = switch_xml_add_child_d(cdr, "app_log", cdr_off++))) {
2781  goto error;
2782  }
2783  for (ap = app_log; ap; ap = ap->next) {
2784  char tmp[128];
2785 
2786  if (!(x_application = switch_xml_add_child_d(x_apps, "application", app_off++))) {
2787  goto error;
2788  }
2789 
2790  switch_xml_set_attr_d(x_application, "app_name", ap->app);
2791  switch_xml_set_attr_d(x_application, "app_data", ap->arg);
2792 
2793  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, ap->stamp);
2794  switch_xml_set_attr_d_buf(x_application, "app_stamp", tmp);
2795  }
2796  }
2797 
2798  if (hold_record) {
2799  int cf_off = 0;
2800 
2801  if (!(xhr = switch_xml_add_child_d(cdr, "hold-record", cdr_off++))) {
2802  goto error;
2803  }
2804 
2805  for (hr = hold_record; hr; hr = hr->next) {
2806  char *t = tmp;
2807  if (!(x_hold = switch_xml_add_child_d(xhr, "hold", cf_off++))) {
2808  goto error;
2809  }
2810 
2811  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, hr->on);
2812  switch_xml_set_attr_d(x_hold, "on", t);
2813 
2814  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, hr->off);
2815  switch_xml_set_attr_d(x_hold, "off", t);
2816 
2817  if (hr->uuid) {
2818  switch_xml_set_attr_d(x_hold, "bridged-to", hr->uuid);
2819  }
2820 
2821 
2822  }
2823 
2824 
2825  }
2826 
2827 
2828 
2829  caller_profile = switch_channel_get_caller_profile(channel);
2830 
2831  while (caller_profile) {
2832  int cf_off = 0;
2833  int cp_off = 0;
2834 
2835  if (!(x_callflow = switch_xml_add_child_d(cdr, "callflow", cdr_off++))) {
2836  goto error;
2837  }
2838 
2839  if (!zstr(caller_profile->dialplan)) {
2840  switch_xml_set_attr_d(x_callflow, "dialplan", caller_profile->dialplan);
2841  }
2842 
2843  if (!zstr(caller_profile->uuid_str)) {
2844  switch_xml_set_attr_d(x_callflow, "unique-id", caller_profile->uuid_str);
2845  }
2846 
2847  if (!zstr(caller_profile->clone_of)) {
2848  switch_xml_set_attr_d(x_callflow, "clone-of", caller_profile->clone_of);
2849  }
2850 
2851  if (!zstr(caller_profile->profile_index)) {
2852  switch_xml_set_attr_d(x_callflow, "profile_index", caller_profile->profile_index);
2853  }
2854 
2855  if (caller_profile->caller_extension) {
2857  int app_off = 0;
2858 
2859  if (!(x_caller_extension = switch_xml_add_child_d(x_callflow, "extension", cf_off++))) {
2860  goto error;
2861  }
2862 
2863  switch_xml_set_attr_d(x_caller_extension, "name", caller_profile->caller_extension->extension_name);
2864  switch_xml_set_attr_d(x_caller_extension, "number", caller_profile->caller_extension->extension_number);
2865  if (caller_profile->caller_extension->current_application) {
2866  switch_xml_set_attr_d(x_caller_extension, "current_app", caller_profile->caller_extension->current_application->application_name);
2867  }
2868 
2869  for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) {
2870  if (!(x_application = switch_xml_add_child_d(x_caller_extension, "application", app_off++))) {
2871  goto error;
2872  }
2873  if (ap == caller_profile->caller_extension->current_application) {
2874  switch_xml_set_attr_d(x_application, "last_executed", "true");
2875  }
2876  switch_xml_set_attr_d(x_application, "app_name", ap->application_name);
2877  switch_xml_set_attr_d(x_application, "app_data", ap->application_data);
2878  }
2879 
2880  if (caller_profile->caller_extension->children) {
2881  switch_caller_profile_t *cp = NULL;
2882  int i_off = 0, i_app_off = 0;
2883  for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) {
2884 
2885  if (!cp->caller_extension) {
2886  continue;
2887  }
2888  if (!(x_inner_extension = switch_xml_add_child_d(x_caller_extension, "sub_extensions", app_off++))) {
2889  goto error;
2890  }
2891 
2892  if (!(x_caller_extension = switch_xml_add_child_d(x_inner_extension, "extension", i_off++))) {
2893  goto error;
2894  }
2895  switch_xml_set_attr_d(x_caller_extension, "name", cp->caller_extension->extension_name);
2896  switch_xml_set_attr_d(x_caller_extension, "number", cp->caller_extension->extension_number);
2897  switch_xml_set_attr_d(x_caller_extension, "dialplan", cp->dialplan);
2899  switch_xml_set_attr_d(x_caller_extension, "current_app", cp->caller_extension->current_application->application_name);
2900  }
2901 
2902  for (ap = cp->caller_extension->applications; ap; ap = ap->next) {
2903  if (!(x_application = switch_xml_add_child_d(x_caller_extension, "application", i_app_off++))) {
2904  goto error;
2905  }
2906  if (ap == cp->caller_extension->current_application) {
2907  switch_xml_set_attr_d(x_application, "last_executed", "true");
2908  }
2909  switch_xml_set_attr_d(x_application, "app_name", ap->application_name);
2910  switch_xml_set_attr_d(x_application, "app_data", ap->application_data);
2911  }
2912  }
2913  }
2914  }
2915 
2916  if (!(x_main_cp = switch_xml_add_child_d(x_callflow, "caller_profile", cf_off++))) {
2917  goto error;
2918  }
2919 
2920  cp_off += switch_ivr_set_xml_profile_data(x_main_cp, caller_profile, 0);
2921 
2922  if (caller_profile->origination_caller_profile) {
2923  switch_caller_profile_t *cp = NULL;
2924  int off = 0;
2925  if (!(x_o = switch_xml_add_child_d(x_main_cp, "origination", cp_off++))) {
2926  goto error;
2927  }
2928 
2929  for (cp = caller_profile->origination_caller_profile; cp; cp = cp->next) {
2930  if (!(x_caller_profile = switch_xml_add_child_d(x_o, "origination_caller_profile", off++))) {
2931  goto error;
2932  }
2933  switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0);
2934  }
2935  }
2936 
2937  if (caller_profile->originator_caller_profile) {
2938  switch_caller_profile_t *cp = NULL;
2939  int off = 0;
2940  if (!(x_o = switch_xml_add_child_d(x_main_cp, "originator", cp_off++))) {
2941  goto error;
2942  }
2943 
2944  for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) {
2945  if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originator_caller_profile", off++))) {
2946  goto error;
2947  }
2948  switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0);
2949  }
2950  }
2951 
2952  if (caller_profile->originatee_caller_profile) {
2953  switch_caller_profile_t *cp = NULL;
2954  int off = 0;
2955  if (!(x_o = switch_xml_add_child_d(x_main_cp, "originatee", cp_off++))) {
2956  goto error;
2957  }
2958  for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) {
2959  if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originatee_caller_profile", off++))) {
2960  goto error;
2961  }
2962  switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0);
2963  }
2964  }
2965 
2966  if (caller_profile->times) {
2967  int t_off = 0;
2968  if (!(x_times = switch_xml_add_child_d(x_callflow, "times", cf_off++))) {
2969  goto error;
2970  }
2971  if (!(time_tag = switch_xml_add_child_d(x_times, "created_time", t_off++))) {
2972  goto error;
2973  }
2974  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->created);
2975  switch_xml_set_txt_d(time_tag, tmp);
2976 
2977  if (!(time_tag = switch_xml_add_child_d(x_times, "profile_created_time", t_off++))) {
2978  goto error;
2979  }
2980  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created);
2981  switch_xml_set_txt_d(time_tag, tmp);
2982 
2983  if (!(time_tag = switch_xml_add_child_d(x_times, "progress_time", t_off++))) {
2984  goto error;
2985  }
2986  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress);
2987  switch_xml_set_txt_d(time_tag, tmp);
2988 
2989 
2990  if (!(time_tag = switch_xml_add_child_d(x_times, "progress_media_time", t_off++))) {
2991  goto error;
2992  }
2993  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress_media);
2994  switch_xml_set_txt_d(time_tag, tmp);
2995 
2996  if (!(time_tag = switch_xml_add_child_d(x_times, "answered_time", t_off++))) {
2997  goto error;
2998  }
2999  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered);
3000  switch_xml_set_txt_d(time_tag, tmp);
3001 
3002  if (!(time_tag = switch_xml_add_child_d(x_times, "bridged_time", t_off++))) {
3003  goto error;
3004  }
3005  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged);
3006  switch_xml_set_txt_d(time_tag, tmp);
3007 
3008  if (!(time_tag = switch_xml_add_child_d(x_times, "last_hold_time", t_off++))) {
3009  goto error;
3010  }
3011  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->last_hold);
3012  switch_xml_set_txt_d(time_tag, tmp);
3013 
3014  if (!(time_tag = switch_xml_add_child_d(x_times, "hold_accum_time", t_off++))) {
3015  goto error;
3016  }
3017  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hold_accum);
3018  switch_xml_set_txt_d(time_tag, tmp);
3019 
3020  if (!(time_tag = switch_xml_add_child_d(x_times, "hangup_time", t_off++))) {
3021  goto error;
3022  }
3023  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hungup);
3024  switch_xml_set_txt_d(time_tag, tmp);
3025 
3026  if (!(time_tag = switch_xml_add_child_d(x_times, "resurrect_time", t_off++))) {
3027  goto error;
3028  }
3029  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->resurrected);
3030  switch_xml_set_txt_d(time_tag, tmp);
3031 
3032  if (!(time_tag = switch_xml_add_child_d(x_times, "transfer_time", t_off++))) {
3033  goto error;
3034  }
3035  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->transferred);
3036  switch_xml_set_txt_d(time_tag, tmp);
3037  }
3038 
3039  caller_profile = caller_profile->next;
3040  }
3041 
3042  *xml_cdr = cdr;
3043 
3044  return SWITCH_STATUS_SUCCESS;
3045 
3046  error:
3047 
3048  if (cdr) {
3049  switch_xml_free(cdr);
3050  }
3051 
3052  return SWITCH_STATUS_FALSE;
3053 }
3054 
3056 {
3057  cJSON_AddItemToObject(json, "username", cJSON_CreateString((char *)caller_profile->username));
3058  cJSON_AddItemToObject(json, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan));
3059  cJSON_AddItemToObject(json, "caller_id_name", cJSON_CreateString((char *)caller_profile->caller_id_name));
3060  cJSON_AddItemToObject(json, "ani", cJSON_CreateString((char *)caller_profile->ani));
3061  cJSON_AddItemToObject(json, "aniii", cJSON_CreateString((char *)caller_profile->aniii));
3062  cJSON_AddItemToObject(json, "caller_id_number", cJSON_CreateString((char *)caller_profile->caller_id_number));
3063  cJSON_AddItemToObject(json, "network_addr", cJSON_CreateString((char *)caller_profile->network_addr));
3064  cJSON_AddItemToObject(json, "rdnis", cJSON_CreateString((char *)caller_profile->rdnis));
3065  cJSON_AddItemToObject(json, "destination_number", cJSON_CreateString(caller_profile->destination_number));
3066  cJSON_AddItemToObject(json, "uuid", cJSON_CreateString(caller_profile->uuid));
3067  cJSON_AddItemToObject(json, "source", cJSON_CreateString((char *)caller_profile->source));
3068  cJSON_AddItemToObject(json, "context", cJSON_CreateString((char *)caller_profile->context));
3069  cJSON_AddItemToObject(json, "chan_name", cJSON_CreateString(caller_profile->chan_name));
3070 }
3071 
3072 #define add_jstat(_j, _i, _s) \
3073  switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \
3074  cJSON_AddItemToObject(_j, _s, cJSON_CreateNumber(_i))
3075 
3077 {
3078  const char *name = (type == SWITCH_MEDIA_TYPE_VIDEO) ? "video" : "audio";
3079  cJSON *j_stat, *j_in, *j_out;
3080  switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL);
3081  char var_val[35] = "";
3082 
3083  if (!stats) return;
3084 
3085  j_stat = cJSON_CreateObject();
3086  j_in = cJSON_CreateObject();
3087  j_out = cJSON_CreateObject();
3088 
3089  cJSON_AddItemToObject(json, name, j_stat);
3090  cJSON_AddItemToObject(j_stat, "inbound", j_in);
3091  cJSON_AddItemToObject(j_stat, "outbound", j_out);
3092 
3093  stats->inbound.std_deviation = sqrt(stats->inbound.variance);
3094 
3095  add_jstat(j_in, stats->inbound.raw_bytes, "raw_bytes");
3096  add_jstat(j_in, stats->inbound.media_bytes, "media_bytes");
3097  add_jstat(j_in, stats->inbound.packet_count, "packet_count");
3098  add_jstat(j_in, stats->inbound.media_packet_count, "media_packet_count");
3099  add_jstat(j_in, stats->inbound.skip_packet_count, "skip_packet_count");
3100  add_jstat(j_in, stats->inbound.jb_packet_count, "jitter_packet_count");
3101  add_jstat(j_in, stats->inbound.dtmf_packet_count, "dtmf_packet_count");
3102  add_jstat(j_in, stats->inbound.cng_packet_count, "cng_packet_count");
3103  add_jstat(j_in, stats->inbound.flush_packet_count, "flush_packet_count");
3104  add_jstat(j_in, stats->inbound.largest_jb_size, "largest_jb_size");
3105  add_jstat(j_in, stats->inbound.min_variance, "jitter_min_variance");
3106  add_jstat(j_in, stats->inbound.max_variance, "jitter_max_variance");
3107  add_jstat(j_in, stats->inbound.lossrate, "jitter_loss_rate");
3108  add_jstat(j_in, stats->inbound.burstrate, "jitter_burst_rate");
3109  add_jstat(j_in, stats->inbound.mean_interval, "mean_interval");
3110  add_jstat(j_in, stats->inbound.flaws, "flaw_total");
3111  add_jstat(j_in, stats->inbound.R, "quality_percentage");
3112  add_jstat(j_in, stats->inbound.mos, "mos");
3113 
3114 
3115  if (stats->inbound.error_log) {
3116  cJSON *j_err_log, *j_err;
3118 
3119  j_err_log = cJSON_CreateArray();
3120  cJSON_AddItemToObject(j_in, "errorLog", j_err_log);
3121 
3122  for(ep = stats->inbound.error_log; ep; ep = ep->next) {
3123 
3124  if (!(ep->start && ep->stop)) continue;
3125 
3126  j_err = cJSON_CreateObject();
3127 
3128  cJSON_AddItemToObject(j_err, "start", cJSON_CreateNumber(ep->start));
3129  cJSON_AddItemToObject(j_err, "stop", cJSON_CreateNumber(ep->stop));
3130  cJSON_AddItemToObject(j_err, "durationMS", cJSON_CreateNumber((ep->stop - ep->start) / 1000));
3131  cJSON_AddItemToArray(j_err_log, j_err);
3132  }
3133  }
3134 
3135  add_jstat(j_out, stats->outbound.raw_bytes, "raw_bytes");
3136  add_jstat(j_out, stats->outbound.media_bytes, "media_bytes");
3137  add_jstat(j_out, stats->outbound.packet_count, "packet_count");
3138  add_jstat(j_out, stats->outbound.media_packet_count, "media_packet_count");
3139  add_jstat(j_out, stats->outbound.skip_packet_count, "skip_packet_count");
3140  add_jstat(j_out, stats->outbound.dtmf_packet_count, "dtmf_packet_count");
3141  add_jstat(j_out, stats->outbound.cng_packet_count, "cng_packet_count");
3142  add_jstat(j_out, stats->rtcp.packet_count, "rtcp_packet_count");
3143  add_jstat(j_out, stats->rtcp.octet_count, "rtcp_octet_count");
3144 }
3145 
3147 {
3149 
3150  if (!hi)
3151  return;
3152 
3153  for (; hi; hi = hi->next) {
3154  if (!zstr(hi->name) && !zstr(hi->value)) {
3155  char *data = hi->value;
3156  if (urlencode) {
3157  switch_size_t dlen = strlen(hi->value) * 3;
3158 
3159  if ((data = malloc(dlen))) {
3160  memset(data, 0, dlen);
3161  switch_url_encode(hi->value, data, dlen);
3162  }
3163  }
3164 
3165  cJSON_AddItemToObject(json, hi->name, cJSON_CreateString(data));
3166 
3167  if (data != hi->value) {
3168  switch_safe_free(data);
3169  }
3170  }
3171  }
3173 }
3174 
3175 
3176 
3178 {
3179  cJSON *cdr = cJSON_CreateObject();
3181  switch_caller_profile_t *caller_profile;
3182  cJSON *variables, *j_main_cp, *j_caller_profile, *j_caller_extension, *j_caller_extension_apps, *j_times, *j_application,
3183  *j_callflow, *j_profile, *j_inner_extension, *j_app_log, *j_apps, *j_o, *j_o_profiles, *j_channel_data, *callStats;
3184  switch_app_log_t *app_log;
3185  char tmp[512], *f;
3186 
3189  j_channel_data = cJSON_CreateObject();
3190 
3191  cJSON_AddItemToObject(cdr, "channel_data", j_channel_data);
3192 
3194  cJSON_AddItemToObject(j_channel_data, "direction", cJSON_CreateString(switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"));
3195 
3196  switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel));
3197  cJSON_AddItemToObject(j_channel_data, "state_number", cJSON_CreateString((char *) tmp));
3198 
3199  if ((f = switch_channel_get_flag_string(channel))) {
3200  cJSON_AddItemToObject(j_channel_data, "flags", cJSON_CreateString((char *) f));
3201  free(f);
3202  }
3203 
3204  if ((f = switch_channel_get_cap_string(channel))) {
3205  cJSON_AddItemToObject(j_channel_data, "caps", cJSON_CreateString((char *) f));
3206  free(f);
3207  }
3208 
3209  callStats = cJSON_CreateObject();
3210  cJSON_AddItemToObject(cdr, "callStats", callStats);
3213 
3214  variables = cJSON_CreateObject();
3215  cJSON_AddItemToObject(cdr, "variables", variables);
3216  switch_ivr_set_json_chan_vars(variables, channel, urlencode);
3217 
3218 
3219  if ((app_log = switch_core_session_get_app_log(session))) {
3220  switch_app_log_t *ap;
3221 
3222  j_app_log = cJSON_CreateObject();
3223  j_apps = cJSON_CreateArray();
3224 
3225  cJSON_AddItemToObject(cdr, "app_log", j_app_log);
3226  cJSON_AddItemToObject(j_app_log, "applications", j_apps);
3227 
3228  for (ap = app_log; ap; ap = ap->next) {
3229  j_application = cJSON_CreateObject();
3230 
3231  cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->app));
3232  cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(ap->arg));
3233 
3234  cJSON_AddItemToArray(j_apps, j_application);
3235  }
3236  }
3237 
3238 
3239  caller_profile = switch_channel_get_caller_profile(channel);
3240 
3241  j_callflow = cJSON_CreateArray();
3242  cJSON_AddItemToObject(cdr, "callflow", j_callflow);
3243 
3244  while (caller_profile) {
3245 
3246  j_profile = cJSON_CreateObject();
3247 
3248  if (!zstr(caller_profile->dialplan)) {
3249  cJSON_AddItemToObject(j_profile, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan));
3250  }
3251 
3252  if (!zstr(caller_profile->profile_index)) {
3253  cJSON_AddItemToObject(j_profile, "profile_index", cJSON_CreateString((char *)caller_profile->profile_index));
3254  }
3255 
3256  if (caller_profile->caller_extension) {
3258 
3259  j_caller_extension = cJSON_CreateObject();
3260  j_caller_extension_apps = cJSON_CreateArray();
3261 
3262  cJSON_AddItemToObject(j_profile, "extension", j_caller_extension);
3263 
3264  cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(caller_profile->caller_extension->extension_name));
3265  cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(caller_profile->caller_extension->extension_number));
3266  cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps);
3267 
3268  if (caller_profile->caller_extension->current_application) {
3269  cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(caller_profile->caller_extension->current_application->application_name));
3270  }
3271 
3272  for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) {
3273  j_application = cJSON_CreateObject();
3274 
3275  cJSON_AddItemToArray(j_caller_extension_apps, j_application);
3276 
3277  if (ap == caller_profile->caller_extension->current_application) {
3278  cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true"));
3279  }
3280  cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name));
3281  cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data)));
3282  }
3283 
3284  if (caller_profile->caller_extension->children) {
3285  switch_caller_profile_t *cp = NULL;
3286  j_inner_extension = cJSON_CreateArray();
3287  cJSON_AddItemToObject(j_caller_extension, "sub_extensions", j_inner_extension);
3288  for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) {
3289 
3290  if (!cp->caller_extension) {
3291  continue;
3292  }
3293 
3294  j_caller_extension = cJSON_CreateObject();
3295  cJSON_AddItemToArray(j_inner_extension, j_caller_extension);
3296 
3297  cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(cp->caller_extension->extension_name));
3298  cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(cp->caller_extension->extension_number));
3299 
3300  cJSON_AddItemToObject(j_caller_extension, "dialplan", cJSON_CreateString((char *)cp->dialplan));
3301 
3304  }
3305 
3306  j_caller_extension_apps = cJSON_CreateArray();
3307  cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps);
3308  for (ap = cp->caller_extension->applications; ap; ap = ap->next) {
3309  j_application = cJSON_CreateObject();
3310  cJSON_AddItemToArray(j_caller_extension_apps, j_application);
3311 
3312  if (ap == cp->caller_extension->current_application) {
3313  cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true"));
3314  }
3315  cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name));
3316  cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data)));
3317  }
3318  }
3319  }
3320  }
3321 
3322  j_main_cp = cJSON_CreateObject();
3323  cJSON_AddItemToObject(j_profile, "caller_profile", j_main_cp);
3324 
3325  switch_ivr_set_json_profile_data(j_main_cp, caller_profile);
3326 
3327  if (caller_profile->originator_caller_profile) {
3328  switch_caller_profile_t *cp = NULL;
3329 
3330  j_o = cJSON_CreateObject();
3331  cJSON_AddItemToObject(j_main_cp, "originator", j_o);
3332 
3333  j_o_profiles = cJSON_CreateArray();
3334  cJSON_AddItemToObject(j_o, "originator_caller_profiles", j_o_profiles);
3335 
3336  for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) {
3337  j_caller_profile = cJSON_CreateObject();
3338  cJSON_AddItemToArray(j_o_profiles, j_caller_profile);
3339 
3340  switch_ivr_set_json_profile_data(j_caller_profile, cp);
3341  }
3342  }
3343 
3344  if (caller_profile->originatee_caller_profile) {
3345  switch_caller_profile_t *cp = NULL;
3346 
3347  j_o = cJSON_CreateObject();
3348  cJSON_AddItemToObject(j_main_cp, "originatee", j_o);
3349 
3350  j_o_profiles = cJSON_CreateArray();
3351  cJSON_AddItemToObject(j_o, "originatee_caller_profiles", j_o_profiles);
3352 
3353  for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) {
3354  j_caller_profile = cJSON_CreateObject();
3355  cJSON_AddItemToArray(j_o_profiles, j_caller_profile);
3356 
3357  switch_ivr_set_json_profile_data(j_caller_profile, cp);
3358  }
3359  }
3360 
3361  if (caller_profile->times) {
3362 
3363  j_times = cJSON_CreateObject();
3364  cJSON_AddItemToObject(j_profile, "times", j_times);
3365 
3366  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->created);
3367  cJSON_AddItemToObject(j_times, "created_time", cJSON_CreateString(tmp));
3368 
3369  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created);
3370  cJSON_AddItemToObject(j_times, "profile_created_time", cJSON_CreateString(tmp));
3371 
3372  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress);
3373  cJSON_AddItemToObject(j_times, "progress_time", cJSON_CreateString(tmp));
3374 
3375  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress_media);
3376  cJSON_AddItemToObject(j_times, "progress_media_time", cJSON_CreateString(tmp));
3377 
3378  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered);
3379  cJSON_AddItemToObject(j_times, "answered_time", cJSON_CreateString(tmp));
3380 
3381  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged);
3382  cJSON_AddItemToObject(j_times, "bridged_time", cJSON_CreateString(tmp));
3383 
3384  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->last_hold);
3385  cJSON_AddItemToObject(j_times, "last_hold_time", cJSON_CreateString(tmp));
3386 
3387  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hold_accum);
3388  cJSON_AddItemToObject(j_times, "hold_accum_time", cJSON_CreateString(tmp));
3389 
3390  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hungup);
3391  cJSON_AddItemToObject(j_times, "hangup_time", cJSON_CreateString(tmp));
3392 
3393  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->resurrected);
3394  cJSON_AddItemToObject(j_times, "resurrect_time", cJSON_CreateString(tmp));
3395 
3396  switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->transferred);
3397  cJSON_AddItemToObject(j_times, "transfer_time", cJSON_CreateString(tmp));
3398 
3399  }
3400  cJSON_AddItemToArray(j_callflow, j_profile);
3401  caller_profile = caller_profile->next;
3402  }
3403 
3404  *json_cdr = cdr;
3405 
3406  return SWITCH_STATUS_SUCCESS;
3407 
3408 }
3409 
3410 
3412 {
3416 
3417 }
3418 
3420 {
3421  switch_jb_t *jb;
3422  int qlen = 0;
3423  switch_frame_t *read_frame, write_frame = { 0 };
3424  switch_status_t status;
3426  uint32_t interval;
3427  uint32_t ts = 0;
3428  uint16_t seq = 0;
3429  switch_codec_implementation_t read_impl = { 0 };
3430  int is_rtp = 0;
3431  int debug = 0;
3432  const char *var;
3433 
3434 
3435  switch_core_session_get_read_impl(session, &read_impl);
3436 
3437  if (delay_ms < 1 || delay_ms > 10000) {
3438  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid delay [%d] must be between 1 and 10000\n", delay_ms);
3439  return;
3440  }
3441 
3442  interval = read_impl.microseconds_per_packet / 1000;
3443 
3444  if (delay_ms < interval * 2) {
3445  delay_ms = interval * 2;
3446  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Minimum possible delay for this codec (%d) has been chosen\n", delay_ms);
3447  }
3448 
3449  qlen = delay_ms / (interval);
3450  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen);
3451 
3452  switch_jb_create(&jb, SJB_AUDIO, qlen, qlen, switch_core_session_get_pool(session));
3453 
3454  if ((var = switch_channel_get_variable(channel, "delay_echo_debug_level"))) {
3455  debug = atoi(var);
3456  }
3457 
3458  if (debug) {
3459  switch_jb_debug_level(jb, debug);
3460  }
3461 
3462  write_frame.codec = switch_core_session_get_read_codec(session);
3463 
3464  while (switch_channel_ready(channel)) {
3465  switch_rtp_packet_t packet = { {0} };
3466  switch_size_t plen = sizeof(packet);
3467 
3468  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
3469 
3470  if (!SWITCH_READ_ACCEPTABLE(status)) {
3471  break;
3472  }
3473 
3474  if (switch_test_flag(read_frame, SFF_CNG)) {
3475  continue;
3476  }
3477 
3478  if (read_frame->packet) {
3479  is_rtp = 1;
3480  switch_jb_put_packet(jb, (switch_rtp_packet_t *) read_frame->packet, read_frame->packetlen);
3481  } else if (is_rtp) {
3482  continue;
3483  } else {
3484  ts += read_impl.samples_per_packet;
3485  memcpy(packet.body, read_frame->data, read_frame->datalen);
3486  packet.header.ts = htonl(ts);
3487  packet.header.seq = htons(++seq);
3488  packet.header.version = 2;
3489  }
3490 
3491  if (switch_jb_get_packet(jb, (switch_rtp_packet_t *) &packet, &plen) == SWITCH_STATUS_SUCCESS) {
3492  write_frame.data = packet.body;
3493  write_frame.datalen = (uint32_t) plen - 12;
3494  write_frame.buflen = (uint32_t) plen;
3495 
3496  status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
3497 
3498  if (!SWITCH_READ_ACCEPTABLE(status)) {
3499  break;
3500  }
3501  }
3502  }
3503 
3504  switch_jb_destroy(&jb);
3505 }
3506 
3508  const char *tosay,
3509  const char *module_name,
3510  const char *say_type,
3511  const char *say_method,
3512  const char *say_gender,
3513  switch_input_args_t *args)
3514 {
3516  switch_channel_t *channel;
3518  const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *sound_path = NULL;
3519  switch_event_t *hint_data;
3520  switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
3521  char *p;
3522 
3523  switch_assert(session);
3524  channel = switch_core_session_get_channel(session);
3525  switch_assert(channel);
3526 
3528 
3529 
3530  if (zstr(module_name)) {
3531  module_name = "en";
3532  }
3533 
3534  if (module_name) {
3535  char *p;
3536  p = switch_core_session_strdup(session, module_name);
3537  module_name = p;
3538 
3539  if ((p = strchr(module_name, ':'))) {
3540  *p++ = '\0';
3541  chan_lang = p;
3542  }
3543  }
3544 
3545  if (!chan_lang) {
3546  lang = switch_channel_get_variable(channel, "language");
3547 
3548  if (!lang) {
3549  chan_lang = switch_channel_get_variable(channel, "default_language");
3550  if (!chan_lang) {
3551  chan_lang = module_name;
3552  }
3553  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
3554  } else {
3555  chan_lang = lang;
3556  }
3557  }
3558 
3560  switch_assert(hint_data);
3561 
3562  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
3563  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
3564  switch_channel_event_set_data(channel, hint_data);
3565 
3566  if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
3567  goto done;
3568  }
3569 
3570  if ((p = (char *) switch_xml_attr(language, "say-module"))) {
3571  module_name = switch_core_session_strdup(session, p);
3572  } else if ((p = (char *) switch_xml_attr(language, "module"))) {
3573  module_name = switch_core_session_strdup(session, p);
3574  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
3575  } else {
3576  module_name = chan_lang;
3577  }
3578 
3579  if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
3580  if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
3581  sound_path = (char *) switch_xml_attr(language, "sound_path");
3582  }
3583  }
3584 
3585  if (channel) {
3586  const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
3587  if (!switch_true(p)) {
3588  save_path = switch_channel_get_variable(channel, "sound_prefix");
3589  if (sound_path) {
3590  switch_channel_set_variable(channel, "sound_prefix", sound_path);
3591  }
3592  }
3593  }
3594 
3595  if ((si = switch_loadable_module_get_say_interface(module_name))) {
3596  /* should go back and proto all the say mods to const.... */
3597  switch_say_args_t say_args = {0};
3598 
3599  say_args.type = switch_ivr_get_say_type_by_name(say_type);
3600  say_args.method = switch_ivr_get_say_method_by_name(say_method);
3601  say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
3602 
3603  status = si->say_function(session, (char *) tosay, &say_args, args);
3604  } else {
3605  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
3606  status = SWITCH_STATUS_FALSE;
3607  }
3608 
3609  done:
3610 
3612 
3613 
3614  if (hint_data) {
3615  switch_event_destroy(&hint_data);
3616  }
3617 
3618  if (save_path) {
3619  switch_channel_set_variable(channel, "sound_prefix", save_path);
3620  }
3621 
3622  if (xml) {
3623  switch_xml_free(xml);
3624  }
3625 
3626  return status;
3627 }
3628 
3630  const char *lang,
3631  const char *ext,
3632  const char *tosay,
3633  const char *module_name,
3634  const char *say_type,
3635  const char *say_method,
3636  const char *say_gender,
3637  char **rstr)
3638 {
3640  switch_channel_t *channel = NULL;
3642  const char *save_path = NULL, *chan_lang = NULL, *sound_path = NULL;
3643  switch_event_t *hint_data;
3644  switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
3645 
3646  if (session) {
3647  channel = switch_core_session_get_channel(session);
3648 
3649  if (!lang) {
3650  lang = switch_channel_get_variable(channel, "language");
3651 
3652  if (!lang) {
3653  chan_lang = switch_channel_get_variable(channel, "default_language");
3654  if (!chan_lang) {
3655  chan_lang = "en";
3656  }
3657  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
3658  } else {
3659  chan_lang = lang;
3660  }
3661  }
3662  }
3663 
3664  if (!lang) lang = "en";
3665  if (!chan_lang) chan_lang = lang;
3666 
3668  switch_assert(hint_data);
3669 
3670  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
3671  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
3672 
3673  if (channel) {
3674  switch_channel_event_set_data(channel, hint_data);
3675  }
3676 
3677  if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
3678  goto done;
3679  }
3680 
3681  if ((module_name = switch_xml_attr(language, "say-module"))) {
3682  } else if ((module_name = switch_xml_attr(language, "module"))) {
3683  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
3684  } else {
3685  module_name = chan_lang;
3686  }
3687 
3688  if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
3689  if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
3690  sound_path = (char *) switch_xml_attr(language, "sound_path");
3691  }
3692  }
3693 
3694  if (channel) {
3695  const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
3696  if (!switch_true(p)) {
3697  save_path = switch_channel_get_variable(channel, "sound_prefix");
3698  if (sound_path) {
3699  switch_channel_set_variable(channel, "sound_prefix", sound_path);
3700  }
3701  }
3702  }
3703 
3704  if ((si = switch_loadable_module_get_say_interface(module_name)) && si->say_string_function) {
3705  /* should go back and proto all the say mods to const.... */
3706  switch_say_args_t say_args = {0};
3707 
3708  say_args.type = switch_ivr_get_say_type_by_name(say_type);
3709  say_args.method = switch_ivr_get_say_method_by_name(say_method);
3710  say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
3711  say_args.ext = ext;
3712  status = si->say_string_function(session, (char *) tosay, &say_args, rstr);
3713  } else {
3714  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
3715  status = SWITCH_STATUS_FALSE;
3716  }
3717 
3718  done:
3719 
3720  if (hint_data) {
3721  switch_event_destroy(&hint_data);
3722  }
3723 
3724  if (save_path && channel) {
3725  switch_channel_set_variable(channel, "sound_prefix", save_path);
3726  }
3727 
3728  if (xml) {
3729  switch_xml_free(xml);
3730  }
3731 
3732  return status;
3733 }
3734 
3735 
3736 static const char *get_prefixed_str(char *buffer, size_t buffer_size, const char *prefix, size_t prefix_size, const char *str)
3737 {
3738  size_t str_len;
3739 
3740  if (!buffer) {
3741  /*
3742  if buffer is null then it just returns the str without the prefix appended, otherwise buffer contains the prefix followed by the original string
3743  */
3744 
3745  return str;
3746  }
3747 
3748  str_len = strlen(str);
3749  memcpy(buffer, prefix, prefix_size);
3750 
3751  if (str_len + prefix_size + 1 > buffer_size) {
3752  memcpy(buffer + prefix_size, str, buffer_size - prefix_size - 1);
3753  buffer[buffer_size - prefix_size - 1] = '\0';
3754  } else {
3755  memcpy(buffer + prefix_size, str, str_len + 1);
3756  }
3757 
3758  return buffer;
3759 }
3760 
3762  const char *user, const char *domain, switch_xml_t x_user)
3763 {
3764  switch_xml_t x_params, x_param;
3765  char *number_alias;
3768 
3769  char *prefix_buffer = NULL;
3770  size_t buffer_size = 0;
3771  size_t prefix_size = 0;
3772 
3773 
3774  status = SWITCH_STATUS_SUCCESS;
3775 
3776  if (!zstr(prefix)) {
3777  prefix_size = strlen(prefix);
3778  buffer_size = 1024 + prefix_size + 1;
3779  prefix_buffer = switch_core_session_alloc(session, buffer_size);
3780  }
3781 
3782  if ((number_alias = (char *) switch_xml_attr(x_user, "number-alias"))) {
3783  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "number_alias"), number_alias);
3784  }
3785 
3786  if ((x_params = switch_xml_child(x_user, "variables"))) {
3787  for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
3788  const char *var = switch_xml_attr(x_param, "name");
3789  const char *val = switch_xml_attr(x_param, "value");
3790 
3791  if (var && val) {
3792  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
3793  }
3794  }
3795  }
3796 
3797  if (switch_channel_get_caller_profile(channel) && (x_params = switch_xml_child(x_user, "profile-variables"))) {
3798  for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
3799  const char *var = switch_xml_attr(x_param, "name");
3800  const char *val = switch_xml_attr(x_param, "value");
3801 
3802  if (var && val) {
3803  switch_channel_set_profile_var(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
3804  }
3805  }
3806  }
3807 
3808  if (user && domain) {
3809  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "user_name"), user);
3810  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "domain_name"), domain);
3811  }
3812 
3813  return status;
3814 }
3815 
3817 {
3818  switch_xml_t x_user = 0;
3819  char *user, *domain;
3821 
3822  char *prefix;
3823 
3824  if (zstr(data)) {
3825  goto error;
3826  }
3827 
3828  user = switch_core_session_strdup(session, data);
3829 
3830  if ((prefix = strchr(user, ' '))) {
3831  *prefix++ = 0;
3832  }
3833 
3834  if (!(domain = strchr(user, '@'))) {
3835  goto error;
3836  }
3837 
3838  *domain++ = '\0';
3839 
3840 
3841  if (switch_xml_locate_user_merged("id", user, domain, NULL, &x_user, NULL) != SWITCH_STATUS_SUCCESS) {
3842  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
3843  goto done;
3844  }
3845 
3846  status = switch_ivr_set_user_xml(session, prefix, user, domain, x_user);
3847 
3848  goto done;
3849 
3850  error:
3851  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No user@domain specified.\n");
3852 
3853  done:
3854 
3855  if (x_user) {
3856  switch_xml_free(x_user);
3857  }
3858 
3859  return status;
3860 }
3861 
3863 {
3864  switch_bool_t exists = SWITCH_FALSE;
3865  switch_core_session_t *psession = NULL;
3866 
3867  if ((psession = switch_core_session_locate(uuid))) {
3868  switch_core_session_rwunlock(psession);
3869  exists = 1;
3870  }
3871 
3872  return exists;
3873 }
3874 
3876 {
3877  switch_bool_t exists = SWITCH_FALSE;
3878  switch_core_session_t *psession = NULL;
3879 
3880  if ((psession = switch_core_session_force_locate(uuid))) {
3881  switch_core_session_rwunlock(psession);
3882  exists = 1;
3883  }
3884 
3885  return exists;
3886 }
3887 
3889 {
3890  if (zstr(cmd)) {
3891  return SWITCH_STATUS_SUCCESS;
3892  }
3893 
3894  if (fhp) {
3895  if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) {
3896  return SWITCH_STATUS_FALSE;
3897  }
3898 
3899  if (!strncasecmp(cmd, "speed", 5)) {
3900  char *p;
3901 
3902  if ((p = strchr(cmd, ':'))) {
3903  p++;
3904  if (*p == '+' || *p == '-') {
3905  int step;
3906  if (!(step = atoi(p))) {
3907  step = 1;
3908  }
3909  fhp->speed += step;
3910  } else {
3911  int speed = atoi(p);
3912  fhp->speed = speed;
3913  }
3914  return SWITCH_STATUS_SUCCESS;
3915  }
3916 
3917  return SWITCH_STATUS_FALSE;
3918 
3919  } else if (!strncasecmp(cmd, "volume", 6)) {
3920  char *p;
3921 
3922  if ((p = strchr(cmd, ':'))) {
3923  p++;
3924  if (*p == '+' || *p == '-') {
3925  int step;
3926  if (!(step = atoi(p))) {
3927  step = 1;
3928  }
3929  fhp->vol += step;
3930  } else {
3931  int vol = atoi(p);
3932  fhp->vol = vol;
3933  }
3934  return SWITCH_STATUS_SUCCESS;
3935  }
3936 
3937  if (fhp->vol) {
3938  switch_normalize_volume(fhp->vol);
3939  }
3940 
3941  return SWITCH_STATUS_FALSE;
3942  } else if (!strcasecmp(cmd, "pause")) {
3943  if (switch_test_flag(fhp, SWITCH_FILE_PAUSE)) {
3945  } else {
3947  }
3948 
3950 
3951  return SWITCH_STATUS_SUCCESS;
3952  } else if (!strcasecmp(cmd, "stop")) {
3954  return SWITCH_STATUS_FALSE;
3955  } else if (!strcasecmp(cmd, "truncate")) {
3956  switch_core_file_truncate(fhp, 0);
3957  } else if (!strcasecmp(cmd, "restart")) {
3958  unsigned int pos = 0;
3959  fhp->speed = 0;
3960  switch_core_file_seek(fhp, &pos, 0, SEEK_SET);
3961  return SWITCH_STATUS_SUCCESS;
3962  } else if (!strncasecmp(cmd, "seek", 4)) {
3963  //switch_codec_t *codec;
3964  unsigned int samps = 0;
3965  unsigned int pos = 0;
3966  char *p;
3967  //codec = switch_core_session_get_read_codec(session);
3968 
3969  if ((p = strchr(cmd, ':'))) {
3970  p++;
3971  if (*p == '+' || *p == '-') {
3972  int step;
3973  int32_t target;
3974  if (!(step = atoi(p))) {
3975  step = 1000;
3976  }
3977 
3978  samps = step * (fhp->native_rate / 1000);
3979  target = (int32_t)fhp->offset_pos + samps;
3980 
3981  if (target < 0) {
3982  target = 0;
3983  }
3984 
3985  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", target);
3986  switch_core_file_seek(fhp, &pos, target, SEEK_SET);
3987 
3988  } else {
3989  samps = switch_atoui(p) * (fhp->native_rate / 1000);
3990  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", samps);
3991  switch_core_file_seek(fhp, &pos, samps, SEEK_SET);
3992  }
3993  }
3994 
3995  return SWITCH_STATUS_SUCCESS;
3996  }
3997  }
3998 
3999  if (!strcmp(cmd, "true") || !strcmp(cmd, "undefined")) {
4000  return SWITCH_STATUS_SUCCESS;
4001  }
4002 
4003  return SWITCH_STATUS_FALSE;
4004 
4005 }
4006 
4007 #define START_SAMPLES 32768
4008 
4009 SWITCH_DECLARE(switch_status_t) switch_ivr_insert_file(switch_core_session_t *session, const char *file, const char *insert_file, switch_size_t sample_point)
4010 {
4011  switch_file_handle_t orig_fh = { 0 };
4012  switch_file_handle_t new_fh = { 0 };
4013  switch_codec_implementation_t read_impl = { 0 };
4014  char *tmp_file;
4015  switch_uuid_t uuid;
4016  char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
4017  int16_t *abuf = NULL;
4018  switch_size_t olen = 0;
4019  int asis = 0;
4021  switch_size_t sample_count = 0;
4022  uint32_t pos = 0;
4023  char *ext;
4024 
4025  switch_uuid_get(&uuid);
4026  switch_uuid_format(uuid_str, &uuid);
4027 
4028  if ((ext = strrchr(file, '.'))) {
4029  ext++;
4030  } else {
4031  ext = "wav";
4032  }
4033 
4034  tmp_file = switch_core_session_sprintf(session, "%s%smsg_%s.%s",
4036 
4037  switch_core_session_get_read_impl(session, &read_impl);
4038 
4039  new_fh.channels = read_impl.number_of_channels;
4040  new_fh.native_rate = read_impl.actual_samples_per_second;
4041 
4042 
4043  if (switch_core_file_open(&new_fh,
4044  tmp_file,
4045  new_fh.channels,
4047  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", tmp_file);
4048  goto end;
4049  }
4050 
4051 
4052  if (switch_core_file_open(&orig_fh,
4053  file,
4054  new_fh.channels,
4056  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4057  goto end;
4058  }
4059 
4060 
4061  switch_zmalloc(abuf, START_SAMPLES * sizeof(*abuf));
4062 
4063  if (switch_test_flag((&orig_fh), SWITCH_FILE_NATIVE)) {
4064  asis = 1;
4065  }
4066 
4067  while (switch_channel_ready(channel)) {
4068  olen = START_SAMPLES;
4069 
4070  if (!asis) {
4071  olen /= 2;
4072  }
4073 
4074  if ((sample_count + olen) > sample_point) {
4075  olen = sample_point - sample_count;
4076  }
4077 
4078  if (!olen || switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4079  break;
4080  }
4081 
4082  sample_count += olen;
4083 
4084  switch_core_file_write(&new_fh, abuf, &olen);
4085  }
4086 
4087  switch_core_file_close(&orig_fh);
4088 
4089 
4090  if (switch_core_file_open(&orig_fh,
4091  insert_file,
4092  new_fh.channels,
4094  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4095  goto end;
4096  }
4097 
4098 
4099  while (switch_channel_ready(channel)) {
4100  olen = START_SAMPLES;
4101 
4102  if (!asis) {
4103  olen /= 2;
4104  }
4105 
4106  if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4107  break;
4108  }
4109 
4110  sample_count += olen;
4111 
4112  switch_core_file_write(&new_fh, abuf, &olen);
4113  }
4114 
4115  switch_core_file_close(&orig_fh);
4116 
4117  if (switch_core_file_open(&orig_fh,
4118  file,
4119  new_fh.channels,
4121  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4122  goto end;
4123  }
4124 
4125  pos = 0;
4126  switch_core_file_seek(&orig_fh, &pos, sample_point, SEEK_SET);
4127 
4128  while (switch_channel_ready(channel)) {
4129  olen = START_SAMPLES;
4130 
4131  if (!asis) {
4132  olen /= 2;
4133  }
4134 
4135  if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4136  break;
4137  }
4138 
4139  sample_count += olen;
4140 
4141  switch_core_file_write(&new_fh, abuf, &olen);
4142  }
4143 
4144  end:
4145 
4146  if (switch_test_flag((&orig_fh), SWITCH_FILE_OPEN)) {
4147  switch_core_file_close(&orig_fh);
4148  }
4149 
4150  if (switch_test_flag((&new_fh), SWITCH_FILE_OPEN)) {
4151  switch_core_file_close(&new_fh);
4152  }
4153 
4154  switch_file_rename(tmp_file, file, switch_core_session_get_pool(session));
4155  unlink(tmp_file);
4156 
4157  switch_safe_free(abuf);
4158 
4159  return SWITCH_STATUS_SUCCESS;
4160 }
4161 
4162 
4164 {
4166 
4167  if ((status = switch_event_dup_reply(reply, message) != SWITCH_STATUS_SUCCESS)) {
4168  abort();
4169  }
4170 
4171  switch_event_add_header_string(*reply, SWITCH_STACK_BOTTOM, "proto", new_proto);
4172 
4173  return status;
4174 }
4175 
4176 SWITCH_DECLARE(char *) switch_ivr_check_presence_mapping(const char *exten_name, const char *domain_name)
4177 {
4178  char *cf = "presence_map.conf";
4179  switch_xml_t cfg, xml, x_domains, x_domain, x_exten;
4180  char *r = NULL;
4181  switch_event_t *params = NULL;
4182  switch_regex_t *re = NULL;
4183  int proceed = 0, ovector[100];
4184 
4186  switch_assert(params);
4187 
4188  if ( !zstr(domain_name) ) {
4189  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
4190  }
4191 
4192  if ( !zstr(exten_name) ) {
4193  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "exten", exten_name);
4194  }
4195 
4196  if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4197  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
4198  goto end;
4199  }
4200 
4201  if (!(x_domains = switch_xml_child(cfg, "domains"))) {
4202  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find any domains!\n");
4203  goto end;
4204  }
4205 
4206  for (x_domain = switch_xml_child(x_domains, "domain"); x_domain; x_domain = x_domain->next) {
4207  const char *dname = switch_xml_attr(x_domain, "name");
4208  if (!dname || (strcasecmp(dname, "*") && strcasecmp(domain_name, dname))) continue;
4209 
4210  for (x_exten = switch_xml_child(x_domain, "exten"); x_exten; x_exten = x_exten->next) {
4211  const char *regex = switch_xml_attr(x_exten, "regex");
4212  const char *proto = switch_xml_attr(x_exten, "proto");
4213 
4214  if (!zstr(regex) && !zstr(proto)) {
4215  proceed = switch_regex_perform(exten_name, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
4217 
4218  if (proceed) {
4219  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Mapping %s@%s to proto %s matching expression [%s]\n",
4220  exten_name, domain_name, proto, regex);
4221  r = strdup(proto);
4222  goto end;
4223  }
4224 
4225  }
4226  }
4227  }
4228 
4229  end:
4230  switch_event_destroy(&params);
4231 
4232  if (xml) {
4233  switch_xml_free(xml);
4234  }
4235 
4236  return r;
4237 
4238 }
4239 
4241 {
4242  switch_core_session_t *session;
4243 
4244  if (zstr(uuid) || !(session = switch_core_session_locate(uuid))) {
4245  return SWITCH_STATUS_FALSE;
4246  } else {
4248  switch_channel_hangup(channel, cause);
4250  return SWITCH_STATUS_SUCCESS;
4251  }
4252 }
4253 
4255 {
4258 
4260  switch_core_session_t *other_session;
4261  const char *uuid = switch_channel_get_variable(channel, "blind_transfer_uuid");
4262 
4264 
4265  if (!zstr(uuid) && (other_session = switch_core_session_locate(uuid))) {
4266  switch_core_session_message_t msg = { 0 };
4268  msg.from = __FILE__;
4269  msg.numeric_arg = success;
4270  switch_core_session_receive_message(other_session, &msg);
4271  switch_core_session_rwunlock(other_session);
4272  status = SWITCH_STATUS_SUCCESS;
4273  }
4274  }
4275 
4276  return status;
4277 
4278 }
4279 
4280 /* For Emacs:
4281  * Local Variables:
4282  * mode:c
4283  * indent-tabs-mode:t
4284  * tab-width:4
4285  * c-basic-offset:4
4286  * End:
4287  * For VIM:
4288  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
4289  */
#define switch_event_prep_for_delivery(_event)
Definition: switch_event.h:242
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,...)
switch_status_t switch_ivr_digit_stream_reset(switch_ivr_digit_stream_t *stream)
Reset the collected digit stream to nothing.
Definition: switch_ivr.c:2435
#define SWITCH_SIGNAL_BRIDGE_VARIABLE
Definition: switch_types.h:201
switch_time_t stamp
Definition: switch_core.h:61
const char * uuid
Definition: switch_ivr.c:1981
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
const char * switch_core_get_switchname(void)
Definition: switch_core.c:349
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
cJSON * cJSON_CreateObject(void)
Definition: switch_json.c:544
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
switch_status_t switch_jb_get_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len)
#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
#define switch_channel_answer(channel)
Answer a channel (initiate/acknowledge a successful connection)
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
switch_size_t flaws
Definition: switch_types.h:657
int switch_ivr_set_xml_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off)
Definition: switch_ivr.c:2463
#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_sockaddr_t * local_addr
Definition: switch_ivr.h:57
cJSON * cJSON_CreateNumber(double num)
Definition: switch_json.c:541
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.
unsigned int switch_atoui(const char *nptr)
switch_socket_t * socket
Definition: switch_ivr.h:52
void switch_ivr_bg_media(const char *uuid, switch_media_flag_t flags, switch_bool_t on, switch_bool_t is3p, uint32_t delay)
Definition: switch_ivr.c:2014
switch_status_t switch_ivr_digit_stream_parser_set_terminator(switch_ivr_digit_stream_parser_t *parser, char digit)
Set a digit string terminator.
Definition: switch_ivr.c:2448
switch_status_t switch_ivr_process_fh(switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp)
Definition: switch_ivr.c:3888
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_core_session_force_locate(uuid_str)
Locate a session based on it's uuid even if the channel is not ready.
Definition: switch_core.h:925
switch_say_type_t switch_ivr_get_say_type_by_name(const char *name)
An Abstract Representation of a dialplan extension.
switch_say_type_t type
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
switch_rtp_numbers_t inbound
Definition: switch_types.h:690
#define SWITCH_THREAD_FUNC
switch_status_t switch_ivr_set_user(switch_core_session_t *session, const char *data)
Definition: switch_ivr.c:3816
switch_rtp_stats_t * switch_core_media_get_stats(switch_core_session_t *session, switch_media_type_t type, switch_memory_pool_t *pool)
void switch_ivr_delay_echo(switch_core_session_t *session, uint32_t delay_ms)
Definition: switch_ivr.c:3419
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
#define SWITCH_CHANNEL_LOG
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
switch_status_t switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
switch_status_t switch_ivr_parse_all_signal_data(switch_core_session_t *session)
Definition: switch_ivr.c:859
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
switch_say_callback_t say_function
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
switch_status_t switch_socket_bind(switch_socket_t *sock, switch_sockaddr_t *sa)
Definition: switch_apr.c:719
switch_status_t switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message)
Definition: switch_ivr.c:772
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
#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.
switch_hold_record_t * switch_channel_get_hold_record(switch_channel_t *channel)
#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool)
Open a media file using file format modules.
Definition: switch_core.h:1865
#define SWITCH_TRANSFER_SOURCE_VARIABLE
Definition: switch_types.h:143
switch_bool_t switch_ivr_uuid_exists(const char *uuid)
Definition: switch_ivr.c:3862
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
struct switch_caller_profile * originatee_caller_profile
switch_status_t switch_ivr_session_transfer(switch_core_session_t *session, const char *extension, const char *dialplan, const char *context)
Definition: switch_ivr.c:2037
switch_rtp_hdr_t header
Definition: switch_rtp.h:53
switch_status_t switch_ivr_nomedia(const char *uuid, switch_media_flag_t flags)
Signal a session to request indirect media allowing it to exchange media directly with another device...
Definition: switch_ivr.c:1880
#define switch_channel_stop_broadcast(_channel)
switch_status_t switch_ivr_collect_digits_callback(switch_core_session_t *session, switch_input_args_t *args, uint32_t digit_timeout, uint32_t abs_timeout)
Wait for DTMF digits calling a pluggable callback function when digits are collected.
Definition: switch_ivr.c:1173
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_status_t switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language)
Definition: switch_xml.c:3147
static int switch_ivr_set_xml_chan_var(switch_xml_t xml, const char *var, const char *val, int off)
Definition: switch_ivr.c:2667
switch_bool_t
Definition: switch_types.h:405
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
static void switch_ivr_set_json_profile_data(cJSON *json, switch_caller_profile_t *caller_profile)
Definition: switch_ivr.c:3055
switch_size_t largest_jb_size
Definition: switch_types.h:637
struct error_period * next
Definition: switch_types.h:622
switch_status_t switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t **stream)
Destroys a digit stream object.
Definition: switch_ivr.c:2311
switch_status_t switch_xml_locate_user_merged(const char *key, const char *user_name, const char *domain_name, const char *ip, switch_xml_t *user, switch_event_t *params)
Definition: switch_xml.c:2034
switch_status_t switch_ivr_unhold_uuid(const char *uuid)
Signal the session with a protocol specific unhold message.
Definition: switch_ivr.c:1548
const char * network_addr
Definition: switch_caller.h:93
switch_status_t switch_core_file_command(switch_file_handle_t *fh, switch_file_command_t command)
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
switch_say_gender_t switch_ivr_get_say_gender_by_name(const char *name)
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
switch_say_method_t method
#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
#define switch_xml_add_child_d(xml, name, off)
wrapper for switch_xml_add_child() that strdup()s name
Definition: switch_xml.h:269
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
#define fail()
Definition: tone2wav.c:70
#define switch_channel_ready(_channel)
switch_say_string_callback_t say_string_function
#define arg_recursion_check_stop(_args)
switch_status_t switch_ivr_hold(switch_core_session_t *session, const char *message, switch_bool_t moh)
Signal the session with a protocol specific hold message.
Definition: switch_ivr.c:1449
An event Header.
Definition: switch_event.h:65
An Abstract Representation of a dialplan Application.
void switch_core_session_free_message(switch_core_session_message_t **message)
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_status_t switch_ivr_park(switch_core_session_t *session, switch_input_args_t *args)
Definition: switch_ivr.c:892
void switch_channel_set_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel's caller profile.
void switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
Generate static noise.
#define switch_channel_media_ready(_channel)
switch_status_t switch_core_file_seek(_In_ switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
Seek a position in a file.
switch_bool_t switch_ivr_uuid_force_exists(const char *uuid)
Definition: switch_ivr.c:3875
switch_status_t switch_ivr_insert_file(switch_core_session_t *session, const char *file, const char *insert_file, switch_size_t sample_point)
Definition: switch_ivr.c:4009
switch_sockaddr_t * remote_addr
Definition: switch_ivr.h:58
switch_status_t switch_core_codec_decode(switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, uint32_t encoded_data_len, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
Decode data using a codec handle.
A representation of an XML tree.
Definition: switch_xml.h:76
switch_memory_pool_t * pool
Definition: switch_core.h:69
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
struct switch_caller_profile * next
const char * switch_channel_state_name(_In_ switch_channel_state_t state)
Render the name of the provided state enum.
#define START_SAMPLES
Definition: switch_ivr.c:4007
switch_status_t switch_socket_recv(switch_socket_t *sock, char *buf, switch_size_t *len)
Definition: switch_apr.c:782
switch_status_t switch_jb_put_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len)
switch_status_t switch_core_file_read(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Read media from a file handle.
switch_status_t switch_jb_destroy(switch_jb_t **jbp)
switch_size_t media_bytes
Definition: switch_types.h:628
struct real_pcre switch_regex_t
Definition: switch_regex.h:43
const char * dialplan
Definition: switch_caller.h:77
char * switch_url_encode(const char *url, char *buf, size_t len)
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:867
switch_event_header_t * switch_channel_variable_first(switch_channel_t *channel)
Start iterating over the entries in the channel variable list.
switch_status_t switch_ivr_media(const char *uuid, switch_media_flag_t flags)
Signal a session to request direct media access to it's remote end.
Definition: switch_ivr.c:1674
switch_size_t dtmf_packet_count
Definition: switch_types.h:634
static switch_thread_t * thread
Definition: switch_log.c:279
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,...)
static const char * get_prefixed_str(char *buffer, size_t buffer_size, const char *prefix, size_t prefix_size, const char *str)
Definition: switch_ivr.c:3736
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
int switch_ivr_set_xml_call_stats(switch_xml_t xml, switch_core_session_t *session, int off, switch_media_type_t type)
Definition: switch_ivr.c:2579
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.
IVR Library.
switch_status_t switch_core_session_read_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a frame from a session.
switch_codec_t * codec
Definition: switch_frame.h:45
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
uint8_t switch_byte_t
Definition: switch_types.h:246
const char * username
Definition: switch_caller.h:75
#define zstr(x)
Definition: switch_utils.h:281
switch_codec_t * switch_core_session_get_read_codec(_In_ switch_core_session_t *session)
Retrieve the read codec from a given session.
#define SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE
Definition: switch_types.h:129
#define SWITCH_PARK_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:217
struct switch_caller_application * next
switch_memory_pool_t * pool
Definition: switch_ivr.c:1980
switch_status_t switch_core_session_write_frame(_In_ switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
Write a frame to a session.
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1255
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
#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.
switch_status_t switch_ivr_parse_next_event(switch_core_session_t *session)
Definition: switch_ivr.c:755
#define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:216
switch_status_t switch_file_rename(const char *from_path, const char *to_path, switch_memory_pool_t *pool)
Definition: switch_apr.c:424
switch_status_t switch_ivr_blind_transfer_ack(switch_core_session_t *session, switch_bool_t success)
Definition: switch_ivr.c:4254
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
void switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state)
static void unicast_thread_launch(switch_unicast_conninfo_t *conninfo)
Definition: switch_ivr.c:355
switch_status_t switch_ivr_kill_uuid(const char *uuid, switch_call_cause_t cause)
Definition: switch_ivr.c:4240
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
int64_t switch_time_t
Definition: switch_apr.h:188
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:59
switch_port_t remote_port
Definition: switch_ivr.h:56
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
switch_xml_t next
Definition: switch_xml.h:88
switch_status_t switch_ivr_collect_digits_count(switch_core_session_t *session, char *buf, switch_size_t buflen, switch_size_t maxdigits, const char *terminators, char *terminator, uint32_t first_timeout, uint32_t digit_timeout, uint32_t abs_timeout)
Wait for specified number of DTMF digits, untile terminator is received or until the channel hangs up...
Definition: switch_ivr.c:1287
switch_rtcp_numbers_t rtcp
Definition: switch_types.h:692
switch_byte_t switch_byte_t * buf
int64_t stop
Definition: switch_types.h:621
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
#define switch_channel_audio_sync(_c)
SWITCH_BEGIN_EXTERN_C switch_status_t switch_jb_create(switch_jb_t **jbp, switch_jb_type_t type, uint32_t min_frame_len, uint32_t max_frame_len, switch_memory_pool_t *pool)
switch_size_t raw_bytes
Definition: switch_types.h:627
uint32_t datalen
Definition: switch_frame.h:57
#define switch_normalize_volume(x)
const char * switch_channel_get_hold_music(switch_channel_t *channel)
switch_status_t switch_ivr_digit_stream_parser_del_event(switch_ivr_digit_stream_parser_t *parser, char *digits)
Delete a string to action mapping.
Definition: switch_ivr.c:2367
char * switch_core_get_uuid(void)
Retrieve the unique identifier from the core.
Definition: switch_core.c:482
uint32_t packetlen
Definition: switch_frame.h:51
switch_bool_t on
Definition: switch_ivr.c:1983
switch_status_t switch_socket_sendto(switch_socket_t *sock, switch_sockaddr_t *where, int32_t flags, const char *buf, switch_size_t *len)
Definition: switch_apr.c:773
static switch_bool_t switch_is_moh(const char *s)
Definition: switch_utils.h:286
switch_status_t switch_ivr_parse_event(switch_core_session_t *session, switch_event_t *event)
Definition: switch_ivr.c:497
Abstract interface to a say module.
void cJSON_AddItemToArray(cJSON *array, cJSON *item)
Definition: switch_json.c:519
switch_status_t switch_core_session_dequeue_signal_data(switch_core_session_t *session, void **signal_data)
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)
char * switch_event_get_body(switch_event_t *event)
Retrieve the body value from an event.
Definition: switch_event.c:838
uint32_t delay
Definition: switch_ivr.c:1985
intptr_t switch_ssize_t
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
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
#define switch_channel_get_variable(_c, _v)
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
switch_status_t switch_channel_dequeue_dtmf(_In_ switch_channel_t *channel, _In_ switch_dtmf_t *dtmf)
Retrieve DTMF digits from a given channel.
switch_caller_application_t * applications
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_ivr_digit_stream_parser_new(switch_memory_pool_t *pool, switch_ivr_digit_stream_parser_t **parser)
Create a digit stream parser object.
Definition: switch_ivr.c:2237
#define switch_zmalloc(ptr, len)
switch_codec_t read_codec
Definition: switch_ivr.h:49
const char * caller_id_name
Definition: switch_caller.h:79
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
#define add_stat(_x, _i, _s)
Definition: switch_ivr.c:2569
switch_rtp_numbers_t outbound
Definition: switch_types.h:691
switch_thread_start_t func
Definition: switch_core.h:66
switch_xml_t switch_xml_new(_In_opt_z_ const char *name)
returns a new empty switch_xml structure with the given root tag name
switch_status_t switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
Bridge two existing sessions.
struct switch_caller_profile * children
#define switch_channel_ring_ready(channel)
Send Ringing message to a channel.
uint32_t switch_core_session_flush_private_events(switch_core_session_t *session)
Flush the private event queue of a session.
switch_status_t switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event)
switch_status_t switch_ivr_hold_toggle_uuid(const char *uuid, const char *message, switch_bool_t moh)
Toggles channel hold state of session.
Definition: switch_ivr.c:1493
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
switch_status_t switch_core_session_dequeue_private_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event)
DE-Queue a private event on a given session.
#define SWITCH_TIME_T_FMT
switch_call_cause_t switch_channel_str2cause(_In_ const char *str)
return a cause code for a given string
switch_time_t last_digit_time
Definition: switch_ivr.c:2234
#define SWITCH_IVR_VERIFY_SILENCE_DIVISOR(divisor)
Definition: switch_ivr.h:68
struct profile_node_s * next
Definition: switch_caller.h:66
struct switch_caller_profile * origination_caller_profile
switch_time_t profile_created
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
#define arg_recursion_check_start(_args)
#define switch_set_flag_locked(obj, flag)
Set a flag on an arbitrary object while locked.
Definition: switch_utils.h:638
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.
uint16_t switch_port_t
switch_status_t switch_ivr_transfer_variable(switch_core_session_t *sessa, switch_core_session_t *sessb, char *var)
Transfer variables from one session to another.
Definition: switch_ivr.c:2182
static void *SWITCH_THREAD_FUNC media_thread_run(switch_thread_t *thread, void *obj)
Definition: switch_ivr.c:1988
switch_byte_t switch_byte_t uint32_t buflen
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
Definition: switch_core.h:1602
const char * profile_index
void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
Definition: switch_json.c:520
void switch_cond_next(void)
Definition: switch_time.c:638
struct switch_caller_profile * originator_caller_profile
const char * switch_channel_get_hold_music_partner(switch_channel_t *channel)
int64_t start
Definition: switch_types.h:620
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
switch_channel_callstate_t
switch_say_gender_t gender
switch_size_t packet_count
Definition: switch_types.h:629
#define SWITCH_BRIDGE_VARIABLE
Definition: switch_types.h:199
switch_call_cause_t
switch_caller_application_t * current_application
switch_status_t switch_ivr_sound_test(switch_core_session_t *session)
Definition: switch_ivr.c:41
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_mutex_t * flag_mutex
Definition: switch_ivr.h:59
switch_status_t switch_ivr_digit_stream_parser_set_event(switch_ivr_digit_stream_parser_t *parser, char *digits, void *data)
Set a digit string to action mapping.
Definition: switch_ivr.c:2325
switch_thread_t * thread
Definition: switch_ivr.h:64
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
void * switch_ivr_digit_stream_parser_feed(switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t *stream, char digit)
Feed digits collected into the stream for event match testing.
Definition: switch_ivr.c:2382
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
#define add_stat_double(_x, _i, _s)
Definition: switch_ivr.c:2574
switch_size_t jb_packet_count
Definition: switch_types.h:633
switch_status_t switch_ivr_parse_next_signal_data(switch_core_session_t *session)
Definition: switch_ivr.c:863
switch_status_t switch_channel_set_variable_var_check(switch_channel_t *channel, const char *varname, const char *value, switch_bool_t var_check)
cJSON * cJSON_CreateString(const char *string)
Definition: switch_json.c:542
switch_size_t skip_packet_count
Definition: switch_types.h:632
switch_status_t switch_ivr_digit_stream_new(switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t **stream)
Create a new digit stream object.
Definition: switch_ivr.c:2295
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
char * switch_ivr_check_presence_mapping(const char *exten_name, const char *domain_name)
Definition: switch_ivr.c:4176
switch_frame_t write_frame
Definition: switch_ivr.h:50
void switch_jb_debug_level(switch_jb_t *jb, uint8_t level)
void switch_ivr_park_session(switch_core_session_t *session)
Definition: switch_ivr.c:3411
#define switch_xml_set_attr_d_buf(xml, name, value)
Definition: switch_xml.h:302
void switch_uuid_format(char *buffer, const switch_uuid_t *uuid)
Definition: switch_apr.c:1055
#define SWITCH_R_SDP_VARIABLE
Definition: switch_types.h:196
void * packet
Definition: switch_frame.h:49
switch_status_t switch_ivr_3p_nomedia(const char *uuid, switch_media_flag_t flags)
Definition: switch_ivr.c:1774
switch_status_t switch_socket_create(switch_socket_t **new_sock, int family, int type, int protocol, switch_memory_pool_t *pool)
Definition: switch_apr.c:704
static const char * ep
Definition: switch_json.c:36
switch_status_t switch_ivr_activate_unicast(switch_core_session_t *session, char *local_ip, switch_port_t local_port, char *remote_ip, switch_port_t remote_port, char *transport, char *flags)
Definition: switch_ivr.c:398
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:648
switch_status_t switch_ivr_generate_json_cdr(switch_core_session_t *session, cJSON **json_cdr, switch_bool_t urlencode)
Generate an JSON CDR report.
Definition: switch_ivr.c:3177
switch_status_t
Common return values.
switch_status_t switch_core_file_write(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Write media to a file handle.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:256
struct error_period * error_log
Definition: switch_types.h:661
switch_status_t switch_core_session_dequeue_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event, switch_bool_t force)
DE-Queue an event on a given session.
switch_say_interface_t * switch_loadable_module_get_say_interface(const char *name)
Retrieve the say interface by it's registered name.
switch_status_t switch_ivr_unhold(switch_core_session_t *session)
Signal the session with a protocol specific unhold message.
Definition: switch_ivr.c:1515
struct switch_event_header * next
Definition: switch_event.h:76
#define SWITCH_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:202
switch_xml_t switch_xml_open_cfg(_In_z_ const char *file_path, _Out_ switch_xml_t *node, _In_opt_ switch_event_t *params)
open a config in the core registry
switch_status_t switch_ivr_create_message_reply(switch_event_t **reply, switch_event_t *message, const char *new_proto)
Definition: switch_ivr.c:4163
void switch_channel_variable_last(switch_channel_t *channel)
Stop iterating over channel variables.
switch_status_t switch_socket_close(switch_socket_t *sock)
Definition: switch_apr.c:714
switch_size_t switch_channel_has_dtmf(_In_ switch_channel_t *channel)
Test for presence of DTMF on a given channel.
#define SWITCH_UNSPEC
Definition: switch_apr.h:1022
switch_status_t switch_event_dup_reply(switch_event_t **event, switch_event_t *todup)
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
switch_status_t switch_socket_shutdown(switch_socket_t *sock, switch_shutdown_how_e how)
Definition: switch_apr.c:709
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
char body[SWITCH_RTP_MAX_BUF_LEN+4+sizeof(char *)]
Definition: switch_rtp.h:54
Main Library Header.
#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
switch_size_t flush_packet_count
Definition: switch_types.h:636
#define switch_xml_set_txt_d(xml, txt)
wrapper for switch_xml_set_txt() that strdup()s txt \ sets the character content for the given tag an...
Definition: switch_xml.h:283
#define SWITCH_DECLARE(type)
uint32_t samples
Definition: switch_frame.h:61
#define SWITCH_TEMP_HOLD_MUSIC_VARIABLE
Definition: switch_types.h:193
unsigned int switch_hashfunc_default(const char *key, switch_ssize_t *klen)
Definition: switch_apr.c:120
void switch_uuid_get(switch_uuid_t *uuid)
Definition: switch_apr.c:1067
void * user_data
Definition: switch_frame.h:75
switch_status_t switch_core_session_dequeue_message(_In_ switch_core_session_t *session, _Out_ switch_core_session_message_t **message)
DE-Queue an message on a given session.
void switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension)
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
#define switch_channel_set_flag(_c, _f)
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
switch_status_t switch_core_file_truncate(switch_file_handle_t *fh, int64_t offset)
switch_core_session_t * session
Definition: switch_ivr.h:48
switch_port_t local_port
Definition: switch_ivr.h:54
switch_size_t media_packet_count
Definition: switch_types.h:631
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)
struct switch_channel_timetable * times
int switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channel_t *channel, int off)
Definition: switch_ivr.c:2689
switch_status_t switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
#define SWITCH_TRANSFER_HISTORY_VARIABLE
Definition: switch_types.h:142
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
const char * caller_id_number
Definition: switch_caller.h:81
switch_say_method_t switch_ivr_get_say_method_by_name(const char *name)
cJSON * cJSON_CreateArray(void)
Definition: switch_json.c:543
#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
uint32_t switch_media_flag_t
Definition: switch_types.h:477
#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)
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
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.
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:675
A table of settings and callbacks that define a paticular implementation of a codec.
switch_channel_callstate_t switch_channel_get_callstate(switch_channel_t *channel)
switch_media_flag_t flags
Definition: switch_ivr.c:1982
#define SWITCH_MAX_SESSION_TRANSFERS_VARIABLE
Definition: switch_types.h:224
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
switch_status_t switch_ivr_deactivate_unicast(switch_core_session_t *session)
Definition: switch_ivr.c:365
#define switch_xml_set_attr_d(xml, name, value)
Wrapper for switch_xml_set_attr() that strdup()s name/value. Value cannot be NULL.
Definition: switch_xml.h:299
void switch_event_destroy(switch_event_t **event)
Destroy an event.
static void switch_ivr_set_json_chan_vars(cJSON *json, switch_channel_t *channel, switch_bool_t urlencode)
Definition: switch_ivr.c:3146
switch_bool_t is3p
Definition: switch_ivr.c:1984
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.
switch_status_t switch_ivr_signal_bridge(switch_core_session_t *session, switch_core_session_t *peer_session)
Bridge Signalling from one session to another.
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 ...
switch_status_t switch_ivr_3p_media(const char *uuid, switch_media_flag_t flags)
Definition: switch_ivr.c:1564
#define switch_assert(expr)
#define SWITCH_MAX_FORWARDS_VARIABLE
Definition: switch_types.h:223
#define switch_channel_set_variable(_channel, _var, _val)
switch_status_t switch_ivr_say(switch_core_session_t *session, const char *tosay, const char *module_name, const char *say_type, const char *say_method, const char *say_gender, switch_input_args_t *args)
Definition: switch_ivr.c:3507
switch_status_t switch_sockaddr_info_get(switch_sockaddr_t **sa, const char *hostname, int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:817
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
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
switch_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel's caller profile.
#define switch_core_session_kill_channel(session, sig)
Send a signal to a channel.
Definition: switch_core.h:1352
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_ivr_hold_uuid(const char *uuid, const char *message, switch_bool_t moh)
Signal the session with a protocol specific hold message.
Definition: switch_ivr.c:1481
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
memset(buf, 0, buflen)
#define switch_channel_media_up(_channel)
switch_byte_t write_frame_data[SWITCH_RECOMMENDED_BUFFER_SIZE]
Definition: switch_ivr.h:51
switch_status_t switch_ivr_say_string(switch_core_session_t *session, const char *lang, const char *ext, const char *tosay, const char *module_name, const char *say_type, const char *say_method, const char *say_gender, char **rstr)
Definition: switch_ivr.c:3629
const char * ext
switch_bool_t switch_core_session_in_thread(switch_core_session_t *session)
void switch_ivr_set_json_call_stats(cJSON *json, switch_core_session_t *session, switch_media_type_t type)
Definition: switch_ivr.c:3076
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
switch_status_t switch_ivr_digit_stream_parser_destroy(switch_ivr_digit_stream_parser_t *parser)
Destroy a digit stream parser object.
Definition: switch_ivr.c:2277
switch_status_t switch_ivr_set_user_xml(switch_core_session_t *session, const char *prefix, const char *user, const char *domain, switch_xml_t x_user)
Definition: switch_ivr.c:3761
#define SWITCH_UUID_FORMATTED_LENGTH
Definition: switch_apr.h:545
switch_event_header_t * headers
Definition: switch_event.h:90
switch_memory_pool_t * pool
Definition: switch_ivr.c:2223
struct switch_app_log * next
Definition: switch_core.h:62
struct switch_caller_extension * caller_extension
static void *SWITCH_THREAD_FUNC unicast_thread_run(switch_thread_t *thread, void *obj)
Definition: switch_ivr.c:330
switch_status_t switch_thread_pool_launch_thread(switch_thread_data_t **tdp)
switch_size_t cng_packet_count
Definition: switch_types.h:635
#define add_jstat(_j, _i, _s)
Definition: switch_ivr.c:3072
switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session)
Definition: switch_ivr.c:801
switch_memory_pool_t * pool
switch_media_type_t