RTS API Documentation  1.10.11
switch_core_io.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Moular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Michael Jerris <mike@jerris.com>
28  * Paul D. Tinsley <pdt at jackhammer.org>
29  * Seven Du <dujinfang@gmail.com>
30  *
31  *
32  * switch_core_io.c -- Main Core Library (Media I/O)
33  *
34  */
35 
36 #include <switch.h>
38 
40 {
41  unsigned char g729_filler[] = {
42  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
43  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
44  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
45  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
46  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
47  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
48  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
49  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
50  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
51  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
52  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
53  229, 127, 79, 96, 207, 82, 216, 110, 245, 81,
54  114, 170, 250, 103, 54, 211, 203, 194, 94, 64,
55  229, 127, 79, 96, 207, 82, 216, 110, 245, 81
56  };
57 
58 
59  if (read_impl->ianacode == 18 || switch_stristr("g729", read_impl->iananame)) {
60  memcpy(data, g729_filler, len);
61  } else {
62  memset(data, 255, len);
63  }
64 
65 }
66 
68  int stream_id)
69 {
72  int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0, tap_only = 0;
74  unsigned int flag = 0;
75  int i;
76 
77  switch_assert(session != NULL);
78 
79  tap_only = switch_test_flag(session, SSF_MEDIA_BUG_TAP_ONLY);
80 
82 
85  } else {
87  *frame = &runtime.dummy_cng_frame;
88  return SWITCH_STATUS_SUCCESS;
89  }
90 
91  if (!(session->read_codec && session->read_codec->implementation && switch_core_codec_ready(session->read_codec))) {
93  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s reading on a session with no media!\n",
96  *frame = &runtime.dummy_cng_frame;
97  return SWITCH_STATUS_SUCCESS;
98  }
99 
101  switch_yield(20000);
102  *frame = &runtime.dummy_cng_frame;
103  // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Media Paused!!!!\n");
104  return SWITCH_STATUS_SUCCESS;
105  }
106 
107  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
109  return SWITCH_STATUS_FALSE;
110  }
111 
113 
114  if (!switch_core_codec_ready(session->read_codec)) {
116  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
118  *frame = &runtime.dummy_cng_frame;
119  return SWITCH_STATUS_FALSE;
120  }
121 
123 
124  top:
125 
126  for(i = 0; i < 2; i++) {
127  if (session->dmachine[i]) {
129  switch_ivr_dmachine_ping(session->dmachine[i], NULL);
131  }
132  }
133 
134  if (switch_channel_down(session->channel) || !switch_core_codec_ready(session->read_codec)) {
135  *frame = NULL;
136  status = SWITCH_STATUS_FALSE;
137  goto even_more_done;
138  }
139 
140 
141  status = SWITCH_STATUS_FALSE;
142  need_codec = perfect = 0;
143 
144  *frame = NULL;
145 
146  if (session->read_codec && !session->track_id && session->track_duration) {
147  if (session->read_frame_count == 0) {
148  switch_event_t *event;
149  switch_core_session_message_t msg = { 0 };
150 
151  session->read_frame_count = (session->read_impl.samples_per_second / session->read_impl.samples_per_packet) * session->track_duration;
152 
154  msg.numeric_arg = session->track_duration;
156 
158  switch_channel_event_set_data(session->channel, event);
159  switch_event_fire(&event);
160  } else {
161  session->read_frame_count--;
162  }
163  }
164 
165 
166  if (switch_channel_test_flag(session->channel, CF_HOLD)) {
168  status = SWITCH_STATUS_BREAK;
169  goto even_more_done;
170  }
171 
172  if (session->endpoint_interface->io_routines->read_frame) {
175  if ((status = session->endpoint_interface->io_routines->read_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
176  for (ptr = session->event_hooks.read_frame; ptr; ptr = ptr->next) {
177  if ((status = ptr->read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
178  break;
179  }
180  }
181  }
182 
183  if (status == SWITCH_STATUS_INUSE) {
184  *frame = &runtime.dummy_cng_frame;
185  switch_yield(20000);
186  return SWITCH_STATUS_SUCCESS;
187  }
188 
189  if (!SWITCH_READ_ACCEPTABLE(status) || !session->read_codec || !switch_core_codec_ready(session->read_codec)) {
190  *frame = NULL;
191  return SWITCH_STATUS_FALSE;
192  }
193 
195 
196  if (!switch_core_codec_ready(session->read_codec)) {
198  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
200  *frame = &runtime.dummy_cng_frame;
201  return SWITCH_STATUS_FALSE;
202  }
203 
205  if (!switch_core_codec_ready(session->read_codec)) {
206  *frame = NULL;
207  status = SWITCH_STATUS_FALSE;
208  goto even_more_done;
209  }
210  }
211 
212  if (status != SWITCH_STATUS_SUCCESS) {
213  goto done;
214  }
215 
216  if (!(*frame)) {
217  goto done;
218  }
219 
220  switch_assert(*frame != NULL);
221 
222  if (switch_test_flag(*frame, SFF_PROXY_PACKET)) {
223  /* Fast PASS! */
224  status = SWITCH_STATUS_SUCCESS;
225  goto done;
226  }
227 
228  switch_assert((*frame)->codec != NULL);
229 
230  if (!switch_core_codec_ready(session->read_codec) || !switch_core_codec_ready((*frame)->codec)) {
231  status = SWITCH_STATUS_FALSE;
232  goto done;
233  }
234 
235  if (session->bugs && !((*frame)->flags & SFF_CNG) && !((*frame)->flags & SFF_NOT_AUDIO)) {
236  switch_media_bug_t *bp;
238  int prune = 0;
239 
241 
242  for (bp = session->bugs; bp; bp = bp->next) {
243  ok = SWITCH_TRUE;
244 
246  continue;
247  }
248 
250  continue;
251  }
252  if (switch_test_flag(bp, SMBF_PRUNE)) {
253  prune++;
254  continue;
255  }
256 
257  if (bp->ready) {
259  if ((*frame)->codec && (*frame)->codec->implementation &&
260  (*frame)->codec->implementation->encoded_bytes_per_packet &&
261  (*frame)->datalen != (*frame)->codec->implementation->encoded_bytes_per_packet) {
262  switch_set_flag((*frame), SFF_CNG);
263  break;
264  }
265  if (bp->callback) {
266  bp->native_read_frame = *frame;
268  bp->native_read_frame = NULL;
269  }
270  }
271  }
272 
273  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
275  prune++;
276  }
277  }
279 
280  if (prune) {
282  }
283  }
284 
285  codec_impl = *(*frame)->codec->implementation;
286 
287  if (session->read_codec->implementation->impl_id != codec_impl.impl_id) {
288  need_codec = TRUE;
289  tap_only = 0;
290  }
291 
293  do_resample = 1;
294  }
295 
296  if (tap_only) {
297  switch_media_bug_t *bp;
299  int prune = 0;
300 
301  if (session->bugs && switch_test_flag((*frame), SFF_CNG)) {
303  for (bp = session->bugs; bp; bp = bp->next) {
304  ok = SWITCH_TRUE;
305 
307  continue;
308  }
309 
311  continue;
312  }
313  if (switch_test_flag(bp, SMBF_PRUNE)) {
314  prune++;
315  continue;
316  }
317 
318  if (bp->ready && (*frame)->codec && (*frame)->codec->implementation && (*frame)->codec->implementation->encoded_bytes_per_packet) {
320  if (bp->callback) {
321  switch_frame_t tmp_frame = {0};
322  unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
323 
324 
325  tmp_frame.codec = (*frame)->codec;
326  tmp_frame.datalen = (*frame)->codec->implementation->encoded_bytes_per_packet;
327  tmp_frame.samples = (*frame)->codec->implementation->samples_per_packet;
328  tmp_frame.channels = (*frame)->codec->implementation->number_of_channels;
329  tmp_frame.data = data;
330 
331  switch_core_gen_encoded_silence(data, (*frame)->codec->implementation, tmp_frame.datalen);
332 
333  bp->native_read_frame = &tmp_frame;
335  bp->native_read_frame = NULL;
336  }
337  }
338  }
339 
340  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
342  prune++;
343  }
344  }
346 
347  if (prune) {
349  }
350 
351 
352  }
353 
354 
355  goto done;
356  } else if (session->bugs && !need_codec) {
357  do_bugs = 1;
358  need_codec = 1;
359  }
360 
361  if (switch_test_flag(*frame, SFF_CNG)) {
362  if (!session->bugs && !session->plc) {
363  /* Check if other session has bugs */
364  unsigned int other_session_bugs = 0;
365  switch_core_session_t *other_session = NULL;
367  switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
368  if (other_session->bugs && !switch_test_flag(other_session, SSF_MEDIA_BUG_TAP_ONLY)) {
369  other_session_bugs = 1;
370  }
371  switch_core_session_rwunlock(other_session);
372  }
373 
374  /* Don't process CNG frame */
375  if (!other_session_bugs) {
376  status = SWITCH_STATUS_SUCCESS;
377  goto done;
378  }
379  }
380  is_cng = 1;
381  need_codec = 1;
382  } else if (switch_test_flag(*frame, SFF_NOT_AUDIO)) {
383  do_resample = 0;
384  do_bugs = 0;
385  need_codec = 0;
386  }
387 
388  if (switch_test_flag(session, SSF_READ_TRANSCODE) && !need_codec && switch_core_codec_ready(session->read_codec)) {
389  switch_core_session_t *other_session;
392 
393  if (uuid && (other_session = switch_core_session_locate(uuid))) {
394  switch_set_flag(other_session, SSF_READ_CODEC_RESET);
395  switch_set_flag(other_session, SSF_READ_CODEC_RESET);
396  switch_set_flag(other_session, SSF_WRITE_CODEC_RESET);
397  switch_core_session_rwunlock(other_session);
398  }
399  }
400 
401  if (switch_test_flag(session, SSF_READ_CODEC_RESET)) {
404  }
405 
406 
407  if (status == SWITCH_STATUS_SUCCESS && need_codec) {
408  switch_frame_t *enc_frame, *read_frame = *frame;
409 
411 
412  if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
413  switch_core_session_message_t msg = { 0 };
414 
418  }
419 
420  if (read_frame->codec || (is_cng && session->plc)) {
421  session->raw_read_frame.datalen = session->raw_read_frame.buflen;
422 
423  if (is_cng) {
424  if (session->plc) {
426  is_cng = 0;
427  flag &= ~SFF_CNG;
428  } else {
430  }
431 
432  session->raw_read_frame.timestamp = 0;
434  session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
436  read_frame = &session->raw_read_frame;
437  status = SWITCH_STATUS_SUCCESS;
438  } else {
439  switch_codec_t *use_codec = read_frame->codec;
440  if (do_bugs) {
442  if (!session->bugs) {
444  goto done;
445  }
446 
447  if (!switch_core_codec_ready(&session->bug_codec) && switch_core_codec_ready(read_frame->codec)) {
448  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting BUG Codec %s:%d\n",
449  read_frame->codec->implementation->iananame, read_frame->codec->implementation->ianacode);
450  switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL, NULL);
451  if (!switch_core_codec_ready(&session->bug_codec)) {
452  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Error setting BUG codec %s!\n",
454  }
455  }
456 
457  if (switch_core_codec_ready(&session->bug_codec)) {
458  use_codec = &session->bug_codec;
459  }
461 
463  if (!session->bugs) {
464  do_bugs = 0;
465  }
467  if (!do_bugs) goto done;
468  }
469 
470  if (!switch_test_flag(read_frame->codec, SWITCH_CODEC_FLAG_HAS_PLC) &&
472  switch_channel_test_flag(session->channel, CF_CNG_PLC)) && !session->plc) {
473  session->plc = switch_plc_init(NULL);
474  }
475 
476  if (!switch_test_flag(read_frame->codec, SWITCH_CODEC_FLAG_HAS_PLC) && session->plc && switch_test_flag(read_frame, SFF_PLC)) {
478  session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
480  memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen);
481  status = SWITCH_STATUS_SUCCESS;
482  } else {
483  switch_codec_t *codec = use_codec;
484 
486 
487  if (!switch_core_codec_ready(codec)) {
488  codec = read_frame->codec;
489  }
490 
491  if (!switch_core_codec_ready(codec)) {
493  goto done;
494  }
495 
496  codec->cur_frame = read_frame;
497  session->read_codec->cur_frame = read_frame;
498  status = switch_core_codec_decode(codec,
499  session->read_codec,
500  read_frame->data,
501  read_frame->datalen,
503  session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate,
504  &read_frame->flags);
505 
506  if (status == SWITCH_STATUS_NOT_INITALIZED) {
508  goto done;
509  }
510 
511  session->raw_read_frame.samples = session->raw_read_frame.datalen / 2;
513  codec->cur_frame = NULL;
514  session->read_codec->cur_frame = NULL;
516 
517  }
518 
519  if (status == SWITCH_STATUS_SUCCESS && session->read_impl.number_of_channels == 1) {
520  if (session->plc) {
521  if (switch_test_flag(read_frame, SFF_PLC)) {
522  switch_plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
523  switch_clear_flag(read_frame, SFF_PLC);
524  } else {
525  switch_plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
526  }
527  }
528  }
529 
530 
531  }
532 
533  if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) {
534  status = SWITCH_STATUS_RESAMPLE;
535  }
536 
537  /* mux or demux to match */
538  if (session->raw_read_frame.channels != session->read_impl.number_of_channels) {
539  uint32_t rlen = session->raw_read_frame.datalen / 2 / session->raw_read_frame.channels;
540  switch_mux_channels((int16_t *) session->raw_read_frame.data, rlen, session->raw_read_frame.channels, session->read_impl.number_of_channels);
541  session->raw_read_frame.datalen = rlen * 2 * session->read_impl.number_of_channels;
542  session->raw_read_frame.samples = session->raw_read_frame.datalen / 2;
544  }
545 
546 
547  switch (status) {
549  if (!session->read_resampler) {
551 
552  status = switch_resample_create(&session->read_resampler,
556  session->read_impl.number_of_channels);
557 
559 
560  if (status != SWITCH_STATUS_SUCCESS) {
561  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
562  status = SWITCH_STATUS_FALSE;
563  goto done;
564  } else {
565  switch_core_session_message_t msg = { 0 };
566  msg.numeric_arg = 1;
569 
570  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating read resampler\n");
571  }
572  }
574  session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
576  session->raw_read_frame.rate = read_frame->rate;
578  session->raw_read_frame.timestamp = 0;
579  } else {
580  session->raw_read_frame.timestamp = read_frame->timestamp;
581  }
582  session->raw_read_frame.ssrc = read_frame->ssrc;
583  session->raw_read_frame.seq = read_frame->seq;
584  session->raw_read_frame.m = read_frame->m;
585  session->raw_read_frame.payload = read_frame->payload;
586  session->raw_read_frame.flags = 0;
587  if (switch_test_flag(read_frame, SFF_PLC)) {
588  session->raw_read_frame.flags |= SFF_PLC;
589  }
590  read_frame = &session->raw_read_frame;
591  break;
592  case SWITCH_STATUS_NOOP:
593  if (session->read_resampler) {
596  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
598 
599  {
600  switch_core_session_message_t msg = { 0 };
601  msg.numeric_arg = 0;
604  }
605 
606  }
607 
608  status = SWITCH_STATUS_SUCCESS;
609  break;
610  case SWITCH_STATUS_BREAK:
613  session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
615  session->raw_read_frame.timestamp = read_frame->timestamp;
616  session->raw_read_frame.rate = read_frame->rate;
617  session->raw_read_frame.ssrc = read_frame->ssrc;
618  session->raw_read_frame.seq = read_frame->seq;
619  session->raw_read_frame.m = read_frame->m;
620  session->raw_read_frame.payload = read_frame->payload;
621  session->raw_read_frame.flags = 0;
622  if (switch_test_flag(read_frame, SFF_PLC)) {
623  session->raw_read_frame.flags |= SFF_PLC;
624  }
625 
626  read_frame = &session->raw_read_frame;
627  status = SWITCH_STATUS_SUCCESS;
628  break;
630  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
631  goto done;
632  default:
633  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error! [%d]\n",
634  session->read_codec->codec_interface->interface_name, status);
635 
636  if (++session->decoder_errors < 10) {
637  status = SWITCH_STATUS_SUCCESS;
638  } else {
639  goto done;
640  }
641  }
642 
643  session->decoder_errors = 0;
644  }
645 
646  if (session->bugs) {
647  switch_media_bug_t *bp;
649  int prune = 0;
651 
652  for (bp = session->bugs; bp; bp = bp->next) {
653  ok = SWITCH_TRUE;
654 
656  continue;
657  }
658 
660  continue;
661  }
662 
664  continue;
665  }
666 
667  if (switch_test_flag(bp, SMBF_PRUNE)) {
668  prune++;
669  continue;
670  }
671 
673  do_bugs = 0;
674  if (bp->callback) {
675  bp->read_replace_frame_in = read_frame;
676  bp->read_replace_frame_out = read_frame;
677  bp->read_demux_frame = NULL;
678  if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) {
679  read_frame = bp->read_replace_frame_out;
680  }
681  }
682  }
683 
684  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
686  prune++;
687  }
688 
689 
690  }
692  if (prune) {
694  }
695  }
696 
697  if (session->bugs) {
698  switch_media_bug_t *bp;
700  int prune = 0;
702 
703  for (bp = session->bugs; bp; bp = bp->next) {
704  ok = SWITCH_TRUE;
705 
707  continue;
708  }
709 
711  continue;
712  }
713 
715  continue;
716  }
717 
718  if (switch_test_flag(bp, SMBF_PRUNE)) {
719  prune++;
720  continue;
721  }
722 
723  if (bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) {
725  if (bp->read_demux_frame) {
726  uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
727  int bytes = read_frame->datalen;
728  uint32_t datalen = 0;
729  uint32_t samples = bytes / 2 / bp->read_demux_frame->channels;
730 
731  memcpy(data, read_frame->data, read_frame->datalen);
732  datalen = switch_unmerge_sln((int16_t *)data, samples,
733  bp->read_demux_frame->data, samples,
735 
736  switch_buffer_write(bp->raw_read_buffer, data, datalen);
737  } else {
738  switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen);
739  }
740 
741  if (bp->callback) {
742  ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ);
743  }
745  }
746 
747  if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
749  prune++;
750  }
751  }
753  if (prune) {
755  }
756  }
757 
758  if (do_bugs) {
759  goto done;
760  }
761 
762  if (session->read_codec) {
763  if (session->read_resampler) {
764  short *data = read_frame->data;
766  switch_resample_process(session->read_resampler, data, (int) read_frame->datalen / 2 / session->read_resampler->channels);
767  memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2 * session->read_resampler->channels);
768  read_frame->samples = session->read_resampler->to_len;
769  read_frame->channels = session->read_resampler->channels;
770  read_frame->datalen = session->read_resampler->to_len * 2 * session->read_resampler->channels;
771  read_frame->rate = session->read_resampler->to_rate;
773  }
774 
775  if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) {
776  perfect = TRUE;
777  } else {
778  if (!session->raw_read_buffer) {
780  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes vs %u\n",
781  (uint32_t) bytes, (uint32_t) (*frame)->datalen);
783  }
784 
785  if (read_frame->datalen && (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen))) {
786  status = SWITCH_STATUS_MEMERR;
787  goto done;
788  }
789  }
790 
791  if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) {
792  if (perfect) {
793  enc_frame = read_frame;
794  session->raw_read_frame.rate = read_frame->rate;
795  } else {
796  session->raw_read_frame.datalen = (uint32_t) switch_buffer_read(session->raw_read_buffer,
797  session->raw_read_frame.data,
799 
801  enc_frame = &session->raw_read_frame;
802  }
803  session->enc_read_frame.datalen = session->enc_read_frame.buflen;
804 
805  switch_assert(session->read_codec != NULL);
806  switch_assert(enc_frame != NULL);
807  switch_assert(enc_frame->data != NULL);
808  session->read_codec->cur_frame = enc_frame;
809  enc_frame->codec->cur_frame = enc_frame;
812  status = switch_core_codec_encode(session->read_codec,
813  enc_frame->codec,
814  enc_frame->data,
815  enc_frame->datalen,
817  session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag);
819 
820  session->read_codec->cur_frame = NULL;
821  enc_frame->codec->cur_frame = NULL;
822  switch (status) {
826  session->enc_read_frame.samples = session->read_impl.decoded_bytes_per_packet / sizeof(int16_t) / session->read_impl.number_of_channels;
828  if (perfect) {
829  if (enc_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) {
830  session->enc_read_frame.timestamp = 0;
831  } else {
832  session->enc_read_frame.timestamp = read_frame->timestamp;
833  }
834  session->enc_read_frame.rate = read_frame->rate;
835  session->enc_read_frame.ssrc = read_frame->ssrc;
836  session->enc_read_frame.seq = read_frame->seq;
837  session->enc_read_frame.m = read_frame->m;
838  session->enc_read_frame.payload = session->read_impl.ianacode;
839  }
840  *frame = &session->enc_read_frame;
841  break;
842  case SWITCH_STATUS_NOOP:
845  session->raw_read_frame.timestamp = read_frame->timestamp;
846  session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode;
847  session->raw_read_frame.m = read_frame->m;
848  session->raw_read_frame.ssrc = read_frame->ssrc;
849  session->raw_read_frame.seq = read_frame->seq;
850  *frame = enc_frame;
851  status = SWITCH_STATUS_SUCCESS;
852  break;
854  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
855  *frame = NULL;
856  status = SWITCH_STATUS_GENERR;
857  break;
858  default:
859  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
861  *frame = NULL;
862  status = SWITCH_STATUS_GENERR;
863  break;
864  }
865  } else {
866  goto top;
867  }
868  }
869  }
870 
871  done:
872  if (!(*frame)) {
873  status = SWITCH_STATUS_FALSE;
874  } else {
875  if (flag & SFF_CNG) {
876  switch_set_flag((*frame), SFF_CNG);
877  }
878  if (session->bugs) {
879  switch_media_bug_t *bp;
881  int prune = 0;
883  for (bp = session->bugs; bp; bp = bp->next) {
884  ok = SWITCH_TRUE;
885 
887  continue;
888  }
889 
891  continue;
892  }
893 
895  continue;
896  }
897 
898  if (switch_test_flag(bp, SMBF_PRUNE)) {
899  prune++;
900  continue;
901  }
902 
903  if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) {
905  bp->ping_frame = *frame;
906  if (bp->callback) {
908  || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) {
909  ok = SWITCH_FALSE;
910  }
911  }
912  bp->ping_frame = NULL;;
914  }
915 
916  if (ok == SWITCH_FALSE) {
918  prune++;
919  }
920  }
922  if (prune) {
924  }
925  }
926  }
927 
928  even_more_done:
929 
930  if (!*frame ||
931  (!switch_test_flag(*frame, SFF_PROXY_PACKET) &&
932  (!(*frame)->codec || !(*frame)->codec->implementation || !switch_core_codec_ready((*frame)->codec)))) {
933  *frame = &runtime.dummy_cng_frame;
934  }
935 
938 
939 
942  }
943 
944 
945  return status;
946 }
947 
948 static char *SIG_NAMES[] = {
949  "NONE",
950  "KILL",
951  "XFER",
952  "BREAK",
953  NULL
954 };
955 
957  const char *file, const char *func, int line, switch_signal_t sig)
958 {
961 
962  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG10, "Send signal %s [%s]\n",
963  switch_channel_get_name(session->channel), SIG_NAMES[sig]);
964 
966  if ((status = session->endpoint_interface->io_routines->kill_channel(session, sig)) == SWITCH_STATUS_SUCCESS) {
967  for (ptr = session->event_hooks.kill_channel; ptr; ptr = ptr->next) {
968  if ((status = ptr->kill_channel(session, sig)) != SWITCH_STATUS_SUCCESS) {
969  break;
970  }
971  }
972  }
973  }
974  return status;
975 }
976 
978 {
980  switch_status_t status;
981  switch_dtmf_t new_dtmf;
982  int fed = 0;
983 
984  if (switch_channel_down(session->channel)) {
985  return SWITCH_STATUS_FALSE;
986  }
987 
988  switch_assert(dtmf);
989 
991  return SWITCH_STATUS_SUCCESS;
992  }
993 
994  new_dtmf = *dtmf;
995 
996  if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
997  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
998  switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
1000  } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) {
1001  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
1002  switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
1004  } else if (!new_dtmf.duration) {
1006  }
1007 
1009  if (session->dmachine[0]) {
1010  char str[2] = { dtmf->digit, '\0' };
1011  switch_ivr_dmachine_feed(session->dmachine[0], str, NULL);
1012  fed = 1;
1013  }
1014 
1015  for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) {
1016  if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) {
1017  return status;
1018  }
1019  }
1020  }
1021 
1023 }
1024 
1026 {
1029  switch_dtmf_t new_dtmf;
1030 
1031  if (switch_channel_down(session->channel)) {
1032  return SWITCH_STATUS_FALSE;
1033  }
1034 
1036  return SWITCH_STATUS_SUCCESS;
1037  }
1038 
1040  const char *file = switch_channel_get_variable_dup(session->channel, "drop_dtmf_masking_file", SWITCH_FALSE, -1);
1041  const char *digits;
1042 
1043  if (!zstr(file)) {
1045  }
1046 
1047  if ((digits = switch_channel_get_variable_dup(session->channel, "drop_dtmf_masking_digits", SWITCH_FALSE, -1)) && !zstr(digits)) {
1048  const char *p;
1050 
1052  for(p = digits; p && *p; p++) {
1053  if (is_dtmf(*p)) {
1054  x_dtmf.digit = *p;
1055  switch_core_session_send_dtmf(session, &x_dtmf);
1056  }
1057  }
1059  }
1060 
1061  return SWITCH_STATUS_SUCCESS;
1062  }
1063 
1064  switch_assert(dtmf);
1065 
1066  new_dtmf = *dtmf;
1067 
1068  if (new_dtmf.digit != 'w' && new_dtmf.digit != 'W') {
1069  if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) {
1070  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
1071  switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
1073  } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) {
1074  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
1075  switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration);
1077  }
1078  }
1079 
1080  if (!new_dtmf.duration) {
1082  }
1083 
1085  for (ptr = session->event_hooks.send_dtmf; ptr; ptr = ptr->next) {
1086  if ((status = ptr->send_dtmf(session, dtmf, SWITCH_DTMF_SEND)) != SWITCH_STATUS_SUCCESS) {
1087  return SWITCH_STATUS_SUCCESS;
1088  }
1089  }
1090  if (session->dmachine[1]) {
1091  char str[2] = { new_dtmf.digit, '\0' };
1092  switch_ivr_dmachine_feed(session->dmachine[1], str, NULL);
1093  return SWITCH_STATUS_SUCCESS;
1094  }
1095  }
1096 
1097 
1098  if (session->endpoint_interface->io_routines->send_dtmf) {
1099  int send = 0;
1100  status = SWITCH_STATUS_SUCCESS;
1101 
1102  if (switch_channel_test_cap(session->channel, CC_QUEUEABLE_DTMF_DELAY) && (dtmf->digit == 'w' || dtmf->digit == 'W')) {
1103  send = 1;
1104  } else {
1105  if (dtmf->digit == 'w') {
1106  switch_yield(500000);
1107  } else if (dtmf->digit == 'W') {
1108  switch_yield(1000000);
1109  } else {
1110  send = 1;
1111  }
1112  }
1113 
1114  if (send) {
1115  status = session->endpoint_interface->io_routines->send_dtmf(session, &new_dtmf);
1116  }
1117  }
1118  return status;
1119 }
1120 
1122 {
1123  char *p;
1125  int sent = 0, dur;
1126  char *string;
1127  int i, argc;
1128  char *argv[256];
1129  int dur_total = 0;
1130  int rate_mult = 8;
1131 
1132  switch_codec_implementation_t write_impl = { 0 };
1133 
1134  switch_assert(session != NULL);
1135 
1136  if (zstr(dtmf_string)) {
1137  return SWITCH_STATUS_FALSE;
1138  }
1139 
1140  if (*dtmf_string == '~') {
1141  dtmf_string++;
1142  dtmf.flags = 0;
1143  }
1144 
1145  if (switch_channel_down(session->channel)) {
1146  return SWITCH_STATUS_FALSE;
1147  }
1148 
1149 
1150  if (strlen(dtmf_string) > 99) {
1151  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Attempt to send very large dtmf string ignored!\n");
1152  return SWITCH_STATUS_FALSE;
1153  }
1154 
1155  string = switch_core_session_strdup(session, dtmf_string);
1156  argc = switch_separate_string(string, '+', argv, (sizeof(argv) / sizeof(argv[0])));
1157 
1158  if (argc) {
1160  }
1161 
1162  switch_core_session_get_write_impl(session, &write_impl);
1163 
1164  if (write_impl.actual_samples_per_second >= 1000) {
1165  rate_mult = (write_impl.actual_samples_per_second / 1000);
1166  }
1167 
1168  for (i = 0; i < argc; i++) {
1170  dur = switch_core_default_dtmf_duration(0) / rate_mult;
1171  if ((p = strchr(argv[i], '@'))) {
1172  *p++ = '\0';
1173  if ((dur = atoi(p)) > (int)switch_core_min_dtmf_duration(0) / rate_mult) {
1174  dtmf.duration = dur * rate_mult;
1175  }
1176  }
1177 
1178 
1179  for (p = argv[i]; p && *p; p++) {
1180  if (is_dtmf(*p)) {
1181  dtmf.digit = *p;
1182 
1183  if (dtmf.digit != 'w' && dtmf.digit != 'W') {
1184  if (dtmf.duration > switch_core_max_dtmf_duration(0)) {
1185  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n",
1186  switch_channel_get_name(session->channel), dtmf.digit, dtmf.duration);
1188  } else if (dtmf.duration < switch_core_min_dtmf_duration(0)) {
1189  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n",
1190  switch_channel_get_name(session->channel), dtmf.digit, dtmf.duration);
1192  }
1193  }
1194 
1195  if (!dtmf.duration) {
1197  }
1198 
1199 
1200  if (switch_core_session_send_dtmf(session, &dtmf) == SWITCH_STATUS_SUCCESS) {
1201  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s send dtmf\ndigit=%c ms=%u samples=%u\n",
1202  switch_channel_get_name(session->channel), dtmf.digit, dur, dtmf.duration);
1203  sent++;
1204  dur_total += dtmf.duration + (250 * rate_mult); /* account for 250ms pause */
1205  }
1206  }
1207  }
1208 
1209  if (dur_total) {
1210  char tmp[32] = "";
1211  switch_snprintf(tmp, sizeof(tmp), "%d", dur_total / rate_mult);
1212  switch_channel_set_variable(session->channel, "last_dtmf_duration", tmp);
1213  }
1214 
1215  }
1217 }
1218 
1219 /* For Emacs:
1220  * Local Variables:
1221  * mode:c
1222  * indent-tabs-mode:t
1223  * tab-width:4
1224  * c-basic-offset:4
1225  * End:
1226  * For VIM:
1227  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
1228  */
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
switch_bool_t m
Definition: switch_frame.h:83
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
switch_frame_t dummy_cng_frame
#define SWITCH_BUFFER_START_FRAMES
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:700
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_frame_t * read_replace_frame_in
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:318
switch_status_t switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
switch_frame_t enc_read_frame
uint32_t switch_io_flag_t
switch_io_send_dtmf_t send_dtmf
switch_read_frame_hook_t read_frame
switch_io_read_frame_t read_frame
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_mutex_t * codec_read_mutex
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_bool_t
Definition: switch_types.h:437
uint32_t timestamp
Definition: switch_frame.h:80
struct switch_io_event_hook_send_dtmf * next
switch_status_t switch_core_codec_encode(switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
Encode data using a codec handle.
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
switch_kill_channel_hook_t kill_channel
switch_codec_t * read_codec
Representation of an event.
Definition: switch_event.h:80
switch_frame_t * cur_frame
switch_io_routines_t * io_routines
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.
#define SWITCH_RESAMPLE_QUALITY
switch_codec_implementation_t read_impl
const char * switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx)
Retrieve a variable from a given channel.
struct switch_io_event_hook_read_frame * next
#define switch_core_session_get_name(_s)
Definition: switch_core.h:265
uint32_t duration
Definition: switch_types.h:298
uint32_t ssrc
Definition: switch_frame.h:82
switch_plc_state_t * plc
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
struct switch_runtime runtime
Definition: switch_core.c:86
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.
switch_codec_t * codec
Definition: switch_frame.h:56
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
switch_media_bug_callback_t callback
#define zstr(x)
Definition: switch_utils.h:314
uint32_t switch_core_max_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1704
uint32_t switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels)
#define is_dtmf(key)
determine if a character is a valid DTMF key
Definition: switch_utils.h:683
switch_status_t switch_core_codec_reset(switch_codec_t *codec)
switch_io_event_hooks_t event_hooks
switch_mutex_t * read_mutex
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:250
_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.
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:724
uint32_t switch_core_min_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1744
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:260
SWITCH_BEGIN_EXTERN_C switch_plc_state_t * switch_plc_init(switch_plc_state_t *s)
uint16_t seq
Definition: switch_frame.h:81
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:70
void switch_os_yield(void)
Definition: switch_time.c:142
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
uint32_t switch_core_media_bug_prune(switch_core_session_t *session)
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
switch_channel_t * channel
switch_audio_resampler_t * read_resampler
uint32_t datalen
Definition: switch_frame.h:68
switch_codec_interface_t * codec_interface
switch_frame_t * ping_frame
const char *const string
Definition: switch_cJSON.h:162
switch_frame_flag_t flags
Definition: switch_frame.h:85
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
int switch_plc_rx(switch_plc_state_t *s, int16_t amp[], int len)
uint32_t rate
Definition: switch_frame.h:74
void switch_core_gen_encoded_silence(unsigned char *data, const switch_codec_implementation_t *read_impl, switch_size_t len)
switch_status_t switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool)
static char * SIG_NAMES[]
switch_media_bug_t * bugs
switch_mutex_t * resample_mutex
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
struct switch_io_event_hook_kill_channel * next
struct switch_media_bug * next
void switch_cond_next(void)
Definition: switch_time.c:658
#define switch_core_session_get_partner(_session, _partner)
Definition: switch_core.h:1028
switch_status_t switch_core_session_get_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
switch_buffer_t * raw_read_buffer
Node in which to store custom read frame channel callback hooks.
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1247
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t switch_channel_dtmf_lock(switch_channel_t *channel)
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
uint32_t switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap)
switch_codec_t bug_codec
switch_frame_t raw_read_frame
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
switch_status_t switch_core_session_perform_kill_channel(switch_core_session_t *session, const char *file, const char *func, int line, switch_signal_t sig)
uint32_t switch_core_default_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1721
#define switch_channel_down(_channel)
#define switch_channel_set_callstate(channel, state)
switch_status_t
Common return values.
Node in which to store custom send dtmf channel callback hooks.
switch_status_t switch_core_session_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
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:384
#define SWITCH_DECLARE(type)
uint32_t samples
Definition: switch_frame.h:72
#define switch_channel_set_flag(_c, _f)
switch_status_t switch_core_session_send_dtmf_string(switch_core_session_t *session, const char *dtmf_string)
Send DTMF to a session.
uint32_t channels
Definition: switch_frame.h:76
switch_signal_t
Signals to send to channels.
struct switch_io_event_hook_recv_dtmf * next
Node in which to store custom kill channel callback hooks.
switch_io_kill_channel_t kill_channel
switch_status_t switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
int switch_plc_fillin(switch_plc_state_t *s, int16_t amp[], int len)
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:322
switch_ivr_dmachine_t * dmachine[2]
switch_payload_t payload
Definition: switch_frame.h:78
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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.
const char * switch_stristr(const char *instr, const char *str)
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_endpoint_interface_t * endpoint_interface
switch_mutex_t * mutex
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
#define TRUE
switch_status_t switch_core_session_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
switch_buffer_t * raw_read_buffer
#define switch_assert(expr)
switch_frame_t * read_replace_frame_out
#define switch_channel_set_variable(_channel, _var, _val)
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
switch_frame_t * read_demux_frame
Node in which to store custom recv dtmf channel callback hooks.
#define SWITCH_BUFFER_BLOCK_FRAMES
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_core_session_recv_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
#define SWITCH_READ_ACCEPTABLE(status)
memset(buf, 0, buflen)
#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c)
switch_frame_t * native_read_frame
uint32_t switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
Resample one float buffer into another using specifications of a given handle.
switch_status_t switch_channel_dtmf_unlock(switch_channel_t *channel)