SWITCH_DECLARE(switch_status_t) switch_core_speech_open(switch_speech_handle_t *sh, const char *module_name, const char *voice_name, unsigned int rate, unsigned int interval, switch_speech_flag_t *flags, switch_memory_pool_t *pool) { switch_status_t status; char buf[256] = ""; char *param = NULL; if (!sh || !flags || zstr(module_name)) { return SWITCH_STATUS_FALSE; } if (strchr(module_name, ':')) { switch_set_string(buf, module_name); if ((param = strchr(buf, ':'))) { *param++ = '\0'; module_name = buf; } } if ((sh->speech_interface = switch_loadable_module_get_speech_interface(module_name)) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid speech module [%s]!\n", module_name); return SWITCH_STATUS_GENERR; } sh->flags = *flags; if (pool) { sh->memory_pool = pool; } else { if ((status = switch_core_new_memory_pool(&sh->memory_pool)) != SWITCH_STATUS_SUCCESS) { UNPROTECT_INTERFACE(sh->speech_interface); return status; } switch_set_flag(sh, SWITCH_SPEECH_FLAG_FREE_POOL); } sh->engine = switch_core_strdup(sh->memory_pool, module_name); if (param) { sh->param = switch_core_strdup(sh->memory_pool, param); } sh->rate = rate; sh->name = switch_core_strdup(sh->memory_pool, module_name); sh->samples = switch_samples_per_packet(rate, interval); sh->samplerate = rate; sh->native_rate = rate; if ((status = sh->speech_interface->speech_open(sh, voice_name, rate, flags)) == SWITCH_STATUS_SUCCESS) { switch_set_flag(sh, SWITCH_SPEECH_FLAG_OPEN); } else { UNPROTECT_INTERFACE(sh->speech_interface); } return status; }
SWITCH_DECLARE(uint32_t) switch_core_media_bug_set_flag(switch_media_bug_t *bug, uint32_t flag) { if ((flag & SMBF_PRUNE)) { switch_clear_flag(bug, SMBF_LOCK); } return switch_set_flag(bug, flag); }
/*! function to close the asr interface */ static switch_status_t pocketsphinx_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags) { pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, ">>>>>>>>pocketsphinx_asr_close<<<<<<<<<\n"); switch_mutex_lock(ps->flag_mutex); if (switch_test_flag(ps, PSFLAG_ALLOCATED)) { if (switch_test_flag(ps, PSFLAG_READY)) { ps_end_utt(ps->ps); } ps_free(ps->ps); ps->ps = NULL; } switch_safe_free(ps->grammar); switch_mutex_unlock(ps->flag_mutex); switch_clear_flag(ps, PSFLAG_HAS_TEXT); switch_clear_flag(ps, PSFLAG_READY); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Port Closed.\n"); switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED); /* ifly end session */ QISRSessionEnd(ps->ifly_session_id, ps->ifly_hints); return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(switch_status_t) switch_core_timer_init(switch_timer_t *timer, const char *timer_name, int interval, int samples, switch_memory_pool_t *pool) { switch_timer_interface_t *timer_interface; switch_status_t status; memset(timer, 0, sizeof(*timer)); if ((timer_interface = switch_loadable_module_get_timer_interface(timer_name)) == 0 || !timer_interface->timer_init) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid timer %s!\n", timer_name); return SWITCH_STATUS_GENERR; } timer->interval = interval; timer->samples = samples; timer->samplecount = samples; timer->timer_interface = timer_interface; if (pool) { timer->memory_pool = pool; } else { if ((status = switch_core_new_memory_pool(&timer->memory_pool)) != SWITCH_STATUS_SUCCESS) { UNPROTECT_INTERFACE(timer->timer_interface); return status; } switch_set_flag(timer, SWITCH_TIMER_FLAG_FREE_POOL); } return timer->timer_interface->timer_init(timer); }
SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, switch_memory_pool_t *pool) { switch_status_t status; switch_assert(codec != NULL); switch_assert(new_codec != NULL); if (pool) { new_codec->memory_pool = pool; } else { if ((status = switch_core_new_memory_pool(&new_codec->memory_pool)) != SWITCH_STATUS_SUCCESS) { return status; } } new_codec->codec_interface = codec->codec_interface; new_codec->implementation = codec->implementation; new_codec->flags = codec->flags; if (!pool) { switch_set_flag(new_codec, SWITCH_CODEC_FLAG_FREE_POOL); } if (codec->fmtp_in) { new_codec->fmtp_in = switch_core_strdup(new_codec->memory_pool, codec->fmtp_in); } new_codec->implementation->init(new_codec, new_codec->flags, NULL); switch_mutex_init(&new_codec->mutex, SWITCH_MUTEX_NESTED, new_codec->memory_pool); return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(switch_status_t) switch_buffer_create_dynamic(switch_buffer_t **buffer, switch_size_t blocksize, switch_size_t start_len, switch_size_t max_len) { switch_buffer_t *new_buffer; if ((new_buffer = malloc(sizeof(*new_buffer)))) { memset(new_buffer, 0, sizeof(*new_buffer)); if (start_len) { if (!(new_buffer->data = malloc(start_len))) { free(new_buffer); return SWITCH_STATUS_MEMERR; } memset(new_buffer->data, 0, start_len); } new_buffer->max_len = max_len; new_buffer->datalen = start_len; new_buffer->id = buffer_id++; new_buffer->blocksize = blocksize; new_buffer->head = new_buffer->data; switch_set_flag(new_buffer, SWITCH_BUFFER_FLAG_DYNAMIC); *buffer = new_buffer; return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_MEMERR; }
SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession(char *nuuid, CoreSession *a_leg) { switch_channel_t *other_channel = NULL; init_vars(); if (a_leg && a_leg->session) { other_channel = switch_core_session_get_channel(a_leg->session); } if (!strchr(nuuid, '/') && (session = switch_core_session_force_locate(nuuid))) { uuid = strdup(nuuid); channel = switch_core_session_get_channel(session); allocated = 1; } else { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; if (switch_ivr_originate(a_leg ? a_leg->session : NULL, &session, &cause, nuuid, 60, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL) == SWITCH_STATUS_SUCCESS) { channel = switch_core_session_get_channel(session); allocated = 1; switch_set_flag(this, S_HUP); uuid = strdup(switch_core_session_get_uuid(session)); switch_channel_set_state(switch_core_session_get_channel(session), CS_SOFT_EXECUTE); switch_channel_wait_for_state(channel, other_channel, CS_SOFT_EXECUTE); } } }
/*! function to read results from the ASR */ static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags) { pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; switch_status_t status = SWITCH_STATUS_SUCCESS; if (switch_test_flag(ps, PSFLAG_BARGE)) { switch_clear_flag_locked(ps, PSFLAG_BARGE); status = SWITCH_STATUS_BREAK; } if (switch_test_flag(ps, PSFLAG_HAS_TEXT)) { switch_mutex_lock(ps->flag_mutex); switch_clear_flag(ps, PSFLAG_HAS_TEXT); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Recognized: %s, Confidence: %d, Confidence-Threshold: %d\n", ps->hyp, ps->confidence, ps->confidence_threshold); switch_mutex_unlock(ps->flag_mutex); *xmlstr = switch_mprintf("<?xml version=\"1.0\"?>\n" "<result grammar=\"%s\">\n" " <interpretation grammar=\"%s\" confidence=\"%d\">\n" " <input mode=\"speech\">%s</input>\n" " </interpretation>\n" "</result>\n", ps->grammar, ps->grammar, ps->confidence, ps->hyp); if (!switch_test_flag(ps, PSFLAG_INPUT_TIMERS) && switch_test_flag(ah, SWITCH_ASR_FLAG_AUTO_RESUME)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto Resuming\n"); switch_set_flag(ps, PSFLAG_READY); ps_start_utt(ps->ps, NULL); } status = SWITCH_STATUS_SUCCESS; } else if (switch_test_flag(ps, PSFLAG_NOINPUT)) { switch_clear_flag_locked(ps, PSFLAG_NOINPUT); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO INPUT\n"); *xmlstr = switch_mprintf("<?xml version=\"1.0\"?>\n" "<result grammar=\"%s\">\n" " <interpretation>\n" " <input mode=\"speech\"><noinput/></input>\n" " </interpretation>\n" "</result>\n", ps->grammar); status = SWITCH_STATUS_SUCCESS; } else if (switch_test_flag(ps, PSFLAG_NOMATCH)) { switch_clear_flag_locked(ps, PSFLAG_NOMATCH); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO MATCH\n"); *xmlstr = switch_mprintf("<?xml version=\"1.0\"?>\n" "<result grammar=\"%s\">\n" " <interpretation>\n" " <input mode=\"speech\"><nomatch/></input>\n" " </interpretation>\n" "</result>\n", ps->grammar); status = SWITCH_STATUS_SUCCESS; } return status; }
/*! function to feed audio to the ASR */ static switch_status_t pocketsphinx_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags) { pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; int rv = 0; if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) return SWITCH_STATUS_BREAK; if (!switch_test_flag(ps, PSFLAG_HAS_TEXT) && switch_test_flag(ps, PSFLAG_READY)) { if (stop_detect(ps, (int16_t *) data, len / 2)) { char const *hyp; switch_mutex_lock(ps->flag_mutex); if ((hyp = ps_get_hyp(ps->ps, &ps->score, &ps->uttid))) { if (!zstr(hyp)) { ps_end_utt(ps->ps); switch_clear_flag(ps, PSFLAG_READY); if ((hyp = ps_get_hyp(ps->ps, &ps->score, &ps->uttid))) { if (zstr(hyp)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Lost the text, never mind....\n"); ps_start_utt(ps->ps, NULL); switch_set_flag(ps, PSFLAG_READY); } else { ps->hyp = switch_core_strdup(ah->memory_pool, hyp); switch_set_flag(ps, PSFLAG_HAS_TEXT); } } } } switch_mutex_unlock(ps->flag_mutex); } /* only feed ps_process_raw when we are listening */ if (ps->listening) { switch_mutex_lock(ps->flag_mutex); rv = ps_process_raw(ps->ps, (int16 *) data, len / 2, FALSE, FALSE); switch_mutex_unlock(ps->flag_mutex); } if (rv < 0) { return SWITCH_STATUS_FALSE; } } return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(switch_caller_profile_t *) switch_caller_profile_new(switch_memory_pool_t *pool, const char *username, const char *dialplan, const char *caller_id_name, const char *caller_id_number, const char *network_addr, const char *ani, const char *aniii, const char *rdnis, const char *source, const char *context, const char *destination_number) { switch_caller_profile_t *profile = NULL; profile = switch_core_alloc(pool, sizeof(*profile)); switch_assert(profile != NULL); memset(profile, 0, sizeof(*profile)); if (!context) { context = "default"; } if (zstr(caller_id_name)) { caller_id_name = SWITCH_DEFAULT_CLID_NAME; } if (zstr(caller_id_number)) { caller_id_number = "0000000000"; } profile_dup_clean(username, profile->username, pool); profile_dup_clean(dialplan, profile->dialplan, pool); profile_dup_clean(caller_id_name, profile->caller_id_name, pool); profile_dup_clean(caller_id_number, profile->caller_id_number, pool); profile->caller_ton = SWITCH_TON_UNDEF; profile->caller_numplan = SWITCH_NUMPLAN_UNDEF; profile_dup_clean(network_addr, profile->network_addr, pool); profile_dup_clean(ani, profile->ani, pool); profile->ani_ton = SWITCH_TON_UNDEF; profile->ani_numplan = SWITCH_NUMPLAN_UNDEF; profile_dup_clean(aniii, profile->aniii, pool); profile_dup_clean(rdnis, profile->rdnis, pool); profile->rdnis_ton = SWITCH_TON_UNDEF; profile->rdnis_numplan = SWITCH_NUMPLAN_UNDEF; profile_dup_clean(source, profile->source, pool); profile_dup_clean(context, profile->context, pool); profile_dup_clean(destination_number, profile->destination_number, pool); profile->destination_number_ton = SWITCH_TON_UNDEF; profile->destination_number_numplan = SWITCH_NUMPLAN_UNDEF; profile->uuid = SWITCH_BLANK_STRING; profile->chan_name = SWITCH_BLANK_STRING; profile->callee_id_name = SWITCH_BLANK_STRING; profile->callee_id_number = SWITCH_BLANK_STRING; switch_set_flag(profile, SWITCH_CPF_SCREEN); profile->pool = pool; return profile; }
static JSBool teletone_on_dtmf(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { struct teletone_obj *tto = JS_GetPrivate(cx, obj); if (argc > 0) { tto->function = JS_ValueToFunction(cx, argv[0]); if (argc > 1) { tto->arg = argv[1]; } switch_set_flag(tto, TTF_DTMF); } return JS_TRUE; }
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session_t *session, switch_media_bug_t **bug) { switch_media_bug_t *bp = NULL, *bp2 = NULL, *last = NULL; switch_status_t status = SWITCH_STATUS_FALSE; int tap_only = 0; if (switch_core_media_bug_test_flag(*bug, SMBF_LOCK)) { return status; } switch_thread_rwlock_wrlock(session->bug_rwlock); if (session->bugs) { for (bp = session->bugs; bp; bp = bp->next) { if ((!bp->thread_id || bp->thread_id == switch_thread_self()) && bp->ready && bp == *bug) { if (last) { last->next = bp->next; } else { session->bugs = bp->next; } break; } last = bp; } } if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) { switch_core_codec_destroy(&session->bug_codec); } if (session->bugs) { for(bp2 = session->bugs; bp2; bp2 = bp2->next) { if (bp2->ready && !switch_test_flag(bp2, SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp2, SMBF_TAP_NATIVE_WRITE)) { tap_only = 0; } } } if (tap_only) { switch_set_flag(session, SSF_MEDIA_BUG_TAP_ONLY); } else { switch_clear_flag(session, SSF_MEDIA_BUG_TAP_ONLY); } switch_thread_rwlock_unlock(session->bug_rwlock); if (bp) { status = switch_core_media_bug_close(&bp); } return status; }
SWITCH_DECLARE(switch_status_t) switch_core_asr_open(switch_asr_handle_t *ah, const char *module_name, const char *codec, int rate, const char *dest, switch_asr_flag_t *flags, switch_memory_pool_t *pool) { switch_status_t status; char buf[256] = ""; char *param = NULL; if (strchr(module_name, ':')) { switch_set_string(buf, module_name); if ((param = strchr(buf, ':'))) { *param++ = '\0'; module_name = buf; } } switch_assert(ah != NULL); if ((ah->asr_interface = switch_loadable_module_get_asr_interface(module_name)) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ASR module [%s]!\n", module_name); return SWITCH_STATUS_GENERR; } ah->flags = *flags; if (pool) { ah->memory_pool = pool; } else { if ((status = switch_core_new_memory_pool(&ah->memory_pool)) != SWITCH_STATUS_SUCCESS) { UNPROTECT_INTERFACE(ah->asr_interface); return status; } switch_set_flag(ah, SWITCH_ASR_FLAG_FREE_POOL); } if (param) { ah->param = switch_core_strdup(ah->memory_pool, param); } ah->rate = rate; ah->name = switch_core_strdup(ah->memory_pool, module_name); ah->samplerate = rate; ah->native_rate = rate; status = ah->asr_interface->asr_open(ah, codec, rate, dest, flags); if (status != SWITCH_STATUS_SUCCESS) { UNPROTECT_INTERFACE(ah->asr_interface); } return status; }
static switch_status_t load_config(void) { char *cf = "reference.conf"; switch_xml_t cfg, xml, settings, param; memset(&globals, 0, sizeof(globals)); switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); return SWITCH_STATUS_TERM; } if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcmp(var, "debug")) { globals.debug = atoi(val); } else if (!strcmp(var, "port")) { globals.port = atoi(val); } else if (!strcmp(var, "ip")) { set_global_ip(val); } else if (!strcmp(var, "codec-master")) { if (!strcasecmp(val, "us")) { switch_set_flag(&globals, GFLAG_MY_CODEC_PREFS); } } else if (!strcmp(var, "dialplan")) { set_global_dialplan(val); } else if (!strcmp(var, "codec-prefs")) { set_global_codec_string(val); globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS); } else if (!strcmp(var, "codec-rates")) { set_global_codec_rates_string(val); globals.codec_rates_last = switch_separate_string(globals.codec_rates_string, ',', globals.codec_rates, SWITCH_MAX_CODECS); } } } if (!globals.dialplan) { set_global_dialplan("default"); } if (!globals.port) { globals.port = 4569; } switch_xml_free(xml); return SWITCH_STATUS_SUCCESS; }
static switch_status_t switch_speex_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) { struct speex_context *context = codec->private_info; short *buf; int is_speech = 1; if (!context) { return SWITCH_STATUS_FALSE; } buf = decoded_data; if (context->pp) { is_speech = speex_preprocess(context->pp, buf, NULL); } if (is_speech) { is_speech = speex_encode_int(context->encoder_state, buf, &context->encoder_bits) || !context->codec_settings.dtx; } else { speex_bits_pack(&context->encoder_bits, 0, 5); } if (is_speech) { switch_clear_flag(context, SWITCH_CODEC_FLAG_SILENCE); *flag |= SWITCH_CODEC_FLAG_SILENCE_STOP; } else { if (switch_test_flag(context, SWITCH_CODEC_FLAG_SILENCE)) { *encoded_data_len = 0; *flag |= SWITCH_CODEC_FLAG_SILENCE; return SWITCH_STATUS_SUCCESS; } switch_set_flag(context, SWITCH_CODEC_FLAG_SILENCE); *flag |= SWITCH_CODEC_FLAG_SILENCE_START; } speex_bits_pack(&context->encoder_bits, 15, 5); *encoded_data_len = speex_bits_write(&context->encoder_bits, (char *) encoded_data, context->encoder_frame_size); speex_bits_reset(&context->encoder_bits); (*encoded_data_len)--; return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(switch_status_t) switch_core_file_seek(switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence) { switch_status_t status; int ok = 1; switch_assert(fh != NULL); if (!switch_test_flag(fh, SWITCH_FILE_OPEN) || !fh->file_interface->file_seek) { ok = 0; } else if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) { if (!(switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || switch_test_flag(fh, SWITCH_FILE_WRITE_OVER))) { ok = 0; } } else if (!switch_test_flag(fh, SWITCH_FILE_FLAG_READ)) { ok = 0; } if (!ok) { return SWITCH_STATUS_FALSE; } if (fh->buffer) { switch_buffer_zero(fh->buffer); } if (fh->pre_buffer) { switch_buffer_zero(fh->pre_buffer); } if (whence == SWITCH_SEEK_CUR) { unsigned int cur = 0; if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) { fh->file_interface->file_seek(fh, &cur, fh->samples_out, SEEK_SET); } else { fh->file_interface->file_seek(fh, &cur, fh->offset_pos, SEEK_SET); } } switch_set_flag(fh, SWITCH_FILE_SEEK); status = fh->file_interface->file_seek(fh, cur_pos, samples, whence); fh->offset_pos = *cur_pos; if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) { fh->samples_out = *cur_pos; } return status; }
SWITCH_DECLARE(int) CoreSession::setAutoHangup(bool val) { this_check(-1); sanity_check(-1); if (!session) { return SWITCH_STATUS_FALSE; } if (val) { switch_set_flag(this, S_HUP); } else { switch_clear_flag(this, S_HUP); } return SWITCH_STATUS_SUCCESS; }
/*! function to read results from the ASR */ static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags) { pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; switch_status_t status = SWITCH_STATUS_SUCCESS; //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, ">>>>>>>>pocketsphinx_asr_get_results<<<<<<<<<\n"); if (switch_test_flag(ps, PSFLAG_BARGE)) { switch_clear_flag_locked(ps, PSFLAG_BARGE); status = SWITCH_STATUS_BREAK; } if (switch_test_flag(ps, PSFLAG_HAS_TEXT)) { switch_mutex_lock(ps->flag_mutex); switch_clear_flag(ps, PSFLAG_HAS_TEXT); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Recognized: %s, Confidence: %d, Confidence-Threshold: %d\n", ps->hyp, ps->confidence, ps->confidence_threshold); switch_mutex_unlock(ps->flag_mutex); *xmlstr = switch_mprintf("%s", ps->hyp); if (!switch_test_flag(ps, PSFLAG_INPUT_TIMERS) && switch_test_flag(ah, SWITCH_ASR_FLAG_AUTO_RESUME)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto Resuming\n"); switch_set_flag(ps, PSFLAG_READY); ps_start_utt(ps->ps, NULL); } status = SWITCH_STATUS_SUCCESS; } else if (switch_test_flag(ps, PSFLAG_NOINPUT)) { switch_clear_flag_locked(ps, PSFLAG_NOINPUT); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO INPUT\n"); *xmlstr = switch_mprintf(""); status = SWITCH_STATUS_SUCCESS; } else if (switch_test_flag(ps, PSFLAG_NOMATCH)) { switch_clear_flag_locked(ps, PSFLAG_NOMATCH); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO MATCH\n"); *xmlstr = switch_mprintf(""); status = SWITCH_STATUS_SUCCESS; } return status; }
SWITCH_DECLARE(switch_status_t) switch_core_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags) { switch_status_t status; switch_assert(ah != NULL); status = ah->asr_interface->asr_close(ah, flags); switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED); UNPROTECT_INTERFACE(ah->asr_interface); if (switch_test_flag(ah, SWITCH_ASR_FLAG_FREE_POOL)) { switch_core_destroy_memory_pool(&ah->memory_pool); } return status; }
/** * open next file for reading * @param handle the file handle */ static switch_status_t next_file(switch_file_handle_t *handle) { struct ssml_context *context = handle->private_info; const char *file; top: context->index++; if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&context->fh); } if (context->index >= context->num_files) { return SWITCH_STATUS_FALSE; } file = context->files[context->index].name; context->fh.prefix = context->files[context->index].prefix; if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { /* unsupported */ return SWITCH_STATUS_FALSE; } if (switch_core_file_open(&context->fh, file, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { goto top; } handle->samples = context->fh.samples; handle->format = context->fh.format; handle->sections = context->fh.sections; handle->seekable = context->fh.seekable; handle->speed = context->fh.speed; handle->interval = context->fh.interval; if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { switch_set_flag(handle, SWITCH_FILE_NATIVE); } else { switch_clear_flag(handle, SWITCH_FILE_NATIVE); } return SWITCH_STATUS_SUCCESS; }
/*! function to read results from the ASR*/ static switch_status_t pocketsphinx_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags) { pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; switch_status_t status = SWITCH_STATUS_SUCCESS; int32_t conf; if (switch_test_flag(ps, PSFLAG_BARGE)) { switch_clear_flag_locked(ps, PSFLAG_BARGE); status = SWITCH_STATUS_BREAK; } if (switch_test_flag(ps, PSFLAG_HAS_TEXT)) { switch_mutex_lock(ps->flag_mutex); switch_clear_flag(ps, PSFLAG_HAS_TEXT); conf = ps_get_prob(ps->ps, &ps->uttid); ps->confidence = (conf + 20000) / 200; if (ps->confidence < 0) { ps->confidence = 0; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Recognized: %s, Confidence: %d\n", ps->hyp, ps->confidence); switch_mutex_unlock(ps->flag_mutex); *xmlstr = switch_mprintf("<?xml version=\"1.0\"?>\n" "<result grammar=\"%s\">\n" " <interpretation grammar=\"%s\" confidence=\"%d\">\n" " <input mode=\"speech\">%s</input>\n" " </interpretation>\n" "</result>\n", ps->grammar, ps->grammar, ps->confidence, ps->hyp); if (switch_test_flag(ps, SWITCH_ASR_FLAG_AUTO_RESUME)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto Resuming\n"); switch_set_flag(ps, PSFLAG_READY); ps_start_utt(ps->ps, NULL); } status = SWITCH_STATUS_SUCCESS; } return status; }
/*! function to resume recognizer */ static switch_status_t pocketsphinx_asr_resume(switch_asr_handle_t *ah) { pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; switch_status_t status = SWITCH_STATUS_FALSE; switch_mutex_lock(ps->flag_mutex); switch_clear_flag(ps, PSFLAG_HAS_TEXT); if (!switch_test_flag(ps, PSFLAG_READY)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Manually Resuming\n"); if (ps_start_utt(ps->ps, NULL)) { status = SWITCH_STATUS_GENERR; } else { switch_set_flag(ps, PSFLAG_READY); } } switch_mutex_unlock(ps->flag_mutex); return status; }
static switch_status_t channel_on_routing(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; const char *app, *arg; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); do_reset(tech_pvt); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel)); if (switch_test_flag(tech_pvt, TFLAG_RUNNING_APP)) { switch_clear_flag(tech_pvt, TFLAG_RUNNING_APP); } if (switch_test_flag(tech_pvt, TFLAG_APP) && !switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && (app = switch_channel_get_variable(channel, "loopback_app"))) { switch_caller_extension_t *extension = NULL; switch_clear_flag(tech_pvt, TFLAG_APP); switch_set_flag(tech_pvt, TFLAG_RUNNING_APP); arg = switch_channel_get_variable(channel, "loopback_app_arg"); extension = switch_caller_extension_new(session, app, app); switch_caller_extension_add_application(session, extension, "pre_answer", NULL); switch_caller_extension_add_application(session, extension, app, arg); switch_channel_set_caller_extension(channel, extension); switch_channel_set_state(channel, CS_EXECUTE); return SWITCH_STATUS_FALSE; } return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(switch_status_t) switch_core_directory_open(switch_directory_handle_t *dh, char *module_name, char *source, char *dsn, char *passwd, switch_memory_pool_t *pool) { switch_status_t status; if ((dh->directory_interface = switch_loadable_module_get_directory_interface(module_name)) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid directory module [%s]!\n", module_name); return SWITCH_STATUS_GENERR; } if (pool) { dh->memory_pool = pool; } else { if ((status = switch_core_new_memory_pool(&dh->memory_pool)) != SWITCH_STATUS_SUCCESS) { UNPROTECT_INTERFACE(dh->directory_interface); return status; } switch_set_flag(dh, SWITCH_DIRECTORY_FLAG_FREE_POOL); } return dh->directory_interface->directory_open(dh, source, dsn, passwd); }
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_pop(switch_core_session_t *orig_session, const char *function, switch_media_bug_t **pop) { switch_media_bug_t *bp; if (orig_session->bugs) { switch_thread_rwlock_wrlock(orig_session->bug_rwlock); for (bp = orig_session->bugs; bp; bp = bp->next) { if (!strcmp(bp->function, function)) { switch_set_flag(bp, SMBF_LOCK); break; } } switch_thread_rwlock_unlock(orig_session->bug_rwlock); if (bp) { *pop = bp; return SWITCH_STATUS_SUCCESS; } else { *pop = NULL; } } return SWITCH_STATUS_FALSE; }
/** * Wraps file with interface that can be controlled by fileman flags * @param handle * @param path the file to play * @return SWITCH_STATUS_SUCCESS if opened */ static switch_status_t fileman_file_open(switch_file_handle_t *handle, const char *path) { int start_offset_ms = 0; switch_status_t status = SWITCH_STATUS_FALSE; struct fileman_file_context *context = switch_core_alloc(handle->memory_pool, sizeof(*context)); handle->private_info = context; if (handle->params) { const char *id = switch_event_get_header(handle->params, "id"); const char *uuid = switch_event_get_header(handle->params, "session"); const char *start_offset_ms_str = switch_event_get_header(handle->params, "start_offset_ms"); if (!zstr(id)) { context->id = switch_core_strdup(handle->memory_pool, id); } if (!zstr(uuid)) { context->uuid = switch_core_strdup(handle->memory_pool, uuid); } if (!zstr(start_offset_ms_str) && switch_is_number(start_offset_ms_str)) { start_offset_ms = atoi(start_offset_ms_str); if (start_offset_ms < 0) { start_offset_ms = 0; } } } switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Got path %s\n", path); if ((status = switch_core_file_open(&context->fh, path, handle->channels, handle->samplerate, handle->flags, NULL)) != SWITCH_STATUS_SUCCESS) { return status; } /* set up handle for external control */ if (!context->id) { /* use filename as ID */ context->id = switch_core_strdup(handle->memory_pool, path); } switch_mutex_lock(fileman_globals.mutex); if (!switch_core_hash_find(fileman_globals.hash, context->id)) { switch_core_hash_insert(fileman_globals.hash, context->id, handle); } else { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_WARNING, "Duplicate fileman ID: %s\n", context->id); return SWITCH_STATUS_FALSE; } switch_mutex_unlock(fileman_globals.mutex); context->max_frame_len = (handle->samplerate / 1000 * SWITCH_MAX_INTERVAL); switch_zmalloc(context->abuf, FILE_STARTBYTES * sizeof(*context->abuf)); if (!context->fh.audio_buffer) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Create audio buffer\n"); switch_buffer_create_dynamic(&context->fh.audio_buffer, FILE_BLOCKSIZE, FILE_BUFSIZE, 0); switch_assert(context->fh.audio_buffer); } handle->samples = context->fh.samples; handle->format = context->fh.format; handle->sections = context->fh.sections; handle->seekable = context->fh.seekable; handle->speed = context->fh.speed; handle->vol = context->fh.vol; handle->offset_pos = context->fh.offset_pos; handle->interval = context->fh.interval; if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { switch_set_flag(handle, SWITCH_FILE_NATIVE); } else { switch_clear_flag(handle, SWITCH_FILE_NATIVE); } if (handle->params && switch_true(switch_event_get_header(handle->params, "pause"))) { switch_set_flag(handle, SWITCH_FILE_PAUSE); } if (handle->seekable && start_offset_ms) { unsigned int pos = 0; int32_t target = start_offset_ms * (handle->samplerate / 1000); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", target); switch_core_file_seek(&context->fh, &pos, target, SEEK_SET); } return status; }
/** * open next file for reading * @param handle the file handle */ static switch_status_t next_file(switch_file_handle_t *handle) { int loops = 0; struct rayo_file_context *context = handle->private_info; struct output_component *output = context->component ? OUTPUT_COMPONENT(context->component) : NULL; top: if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&context->fh); } if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { /* unsupported */ return SWITCH_STATUS_FALSE; } if (!context->cur_doc) { context->cur_doc = iks_find(output->document, "document"); if (!context->cur_doc) { iks_delete(output->document); output->document = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document>\n"); return SWITCH_STATUS_FALSE; } } else { context->cur_doc = iks_next_tag(context->cur_doc); } /* done? */ if (!context->cur_doc) { if (context->could_open && ++loops < 2 && (output->repeat_times == 0 || ++context->play_count < output->repeat_times)) { /* repeat all document(s) */ if (!output->repeat_interval_ms) { goto top; } } else { /* no more files to play */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Done playing\n"); return SWITCH_STATUS_FALSE; } } if (!context->cur_doc) { /* play silence between repeats */ switch_safe_free(context->ssml); context->ssml = switch_mprintf("silence_stream://%i", output->repeat_interval_ms); } else { /* play next document */ iks *speak = NULL; switch_safe_free(context->ssml); context->ssml = NULL; speak = iks_find(context->cur_doc, "speak"); if (speak) { /* <speak> is child node */ char *ssml_str = iks_string(NULL, speak); if (zstr(output->renderer)) { /* FS must parse the SSML */ context->ssml = switch_mprintf("ssml://%s", ssml_str); } else { /* renderer will parse the SSML */ if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) { /* pass MRCP headers */ context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str); } else { context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); } } iks_free(ssml_str); } else if (iks_has_children(context->cur_doc)) { /* check if <speak> is in CDATA */ const char *ssml_str = NULL; iks *ssml = iks_child(context->cur_doc); if (ssml && iks_type(ssml) == IKS_CDATA) { ssml_str = iks_cdata(ssml); } if (zstr(ssml_str)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document> CDATA\n"); return SWITCH_STATUS_FALSE; } if (zstr(output->renderer)) { /* FS must parse the SSML */ context->ssml = switch_mprintf("ssml://%s", ssml_str); } else { /* renderer will parse the SSML */ if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) { /* pass MRCP headers */ context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str); } else { context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); } } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <speak>\n"); return SWITCH_STATUS_FALSE; } } if (switch_core_file_open(&context->fh, context->ssml, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to open %s\n", context->ssml); goto top; } else { context->could_open = 1; } handle->samples = context->fh.samples; handle->format = context->fh.format; handle->sections = context->fh.sections; handle->seekable = context->fh.seekable; handle->speed = context->fh.speed; handle->vol = context->fh.vol; handle->offset_pos = context->fh.offset_pos; handle->interval = context->fh.interval; if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) { switch_set_flag(handle, SWITCH_FILE_NATIVE); } else { switch_clear_flag(handle, SWITCH_FILE_NATIVE); } return SWITCH_STATUS_SUCCESS; }
/** * Process fileman command */ static switch_status_t fileman_process_cmd(const char *cmd, switch_file_handle_t *fhp) { if (zstr(cmd)) { return SWITCH_STATUS_SUCCESS; } if (fhp) { struct fileman_file_context *context = (struct fileman_file_context *)fhp->private_info; if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) { return SWITCH_STATUS_FALSE; } if (!strncasecmp(cmd, "speed", 5)) { char *p; if ((p = strchr(cmd, ':'))) { p++; if (*p == '+' || *p == '-') { int step; if (!(step = atoi(p))) { if (*p == '+') { step = 1; } else { step = -1; } } fhp->speed += step; } else { int speed = atoi(p); fhp->speed = speed; } return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_FALSE; } else if (!strncasecmp(cmd, "volume", 6)) { char *p; if ((p = strchr(cmd, ':'))) { p++; if (*p == '+' || *p == '-') { int step; if (!(step = atoi(p))) { if (*p == '+') { step = 1; } else { step = -1; } } fhp->vol += step; } else { int vol = atoi(p); fhp->vol = vol; } return SWITCH_STATUS_SUCCESS; } if (fhp->vol) { switch_normalize_volume(fhp->vol); } return SWITCH_STATUS_FALSE; } else if (!strcasecmp(cmd, "pause")) { switch_set_flag(fhp, SWITCH_FILE_PAUSE); return SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(cmd, "resume")) { switch_clear_flag(fhp, SWITCH_FILE_PAUSE); return SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(cmd, "stop")) { switch_set_flag(fhp, SWITCH_FILE_DONE); return SWITCH_STATUS_FALSE; } else if (!strcasecmp(cmd, "truncate")) { switch_core_file_truncate(fhp, 0); } else if (!strcasecmp(cmd, "restart")) { unsigned int pos = 0; fhp->speed = 0; switch_core_file_seek(fhp, &pos, 0, SEEK_SET); return SWITCH_STATUS_SUCCESS; } else if (!strncasecmp(cmd, "seek", 4)) { unsigned int samps = 0; unsigned int pos = 0; char *p; if ((p = strchr(cmd, ':'))) { p++; if (*p == '+' || *p == '-') { int step; int32_t target; if (!(step = atoi(p))) { if (*p == '+') { step = 1000; } else { step = -1000; } } samps = step * (fhp->samplerate / 1000); target = (int32_t)fhp->pos + samps; if (target < 0) { target = 0; } switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", target); switch_core_file_seek(fhp, &pos, target, SEEK_SET); } else { samps = switch_atoui(p) * (fhp->samplerate / 1000); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "seek to position %d\n", samps); switch_core_file_seek(fhp, &pos, samps, SEEK_SET); } } return SWITCH_STATUS_SUCCESS; } } if (!strcmp(cmd, "true") || !strcmp(cmd, "undefined")) { return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_FALSE; }
static switch_status_t switch_amr_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) { if (codec_fmtp) { amr_codec_settings_t *codec_settings = NULL; if (codec_fmtp->private_info) { codec_settings = codec_fmtp->private_info; memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); } if (fmtp) { int x, argc; char *argv[10]; char *fmtp_dup = strdup(fmtp); switch_assert(fmtp_dup); argc = switch_separate_string((char *) fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); for (x = 0; x < argc; x++) { char *data = argv[x]; char *arg; switch_assert(data); while (*data == ' ') { data++; } if ((arg = strchr(data, '='))) { *arg++ = '\0'; /* if (!strcasecmp(data, "bitrate")) { bit_rate = atoi(arg); } */ if (codec_settings) { if (!strcasecmp(data, "octet-align")) { if (atoi(arg)) { switch_set_flag(codec_settings, AMR_OPT_OCTET_ALIGN); } } else if (!strcasecmp(data, "mode-change-neighbor")) { if (atoi(arg)) { switch_set_flag(codec_settings, AMR_OPT_MODE_CHANGE_NEIGHBOR); } } else if (!strcasecmp(data, "crc")) { if (atoi(arg)) { switch_set_flag(codec_settings, AMR_OPT_CRC); } } else if (!strcasecmp(data, "robust-sorting")) { if (atoi(arg)) { switch_set_flag(codec_settings, AMR_OPT_ROBUST_SORTING); } } else if (!strcasecmp(data, "interveaving")) { if (atoi(arg)) { switch_set_flag(codec_settings, AMR_OPT_INTERLEAVING); } } else if (!strcasecmp(data, "mode-change-period")) { codec_settings->change_period = atoi(arg); } else if (!strcasecmp(data, "ptime")) { codec_settings->ptime = (switch_byte_t) atoi(arg); } else if (!strcasecmp(data, "channels")) { codec_settings->channels = (switch_byte_t) atoi(arg); } else if (!strcasecmp(data, "maxptime")) { codec_settings->max_ptime = (switch_byte_t) atoi(arg); } else if (!strcasecmp(data, "mode-set")) { int y, m_argc; char *m_argv[7]; m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); for (y = 0; y < m_argc; y++) { codec_settings->enc_modes |= (1 << atoi(m_argv[y])); } } else if (!strcasecmp(data, "dtx")) { codec_settings->dtx_mode = (atoi(arg)) ? AMR_DTX_ENABLED : AMR_DTX_DISABLED; } } } } free(fmtp_dup); } //codec_fmtp->bits_per_second = bit_rate; return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_FALSE; }
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t *session, const char *function, const char *target, switch_media_bug_callback_t callback, void *user_data, time_t stop_time, switch_media_bug_flag_t flags, switch_media_bug_t **new_bug) { switch_media_bug_t *bug, *bp; switch_size_t bytes; switch_event_t *event; int tap_only = 1, punt = 0; const char *p; if (!zstr(function)) { if ((flags & SMBF_ONE_ONLY)) { switch_thread_rwlock_wrlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (!zstr(bp->function) && !strcasecmp(function, bp->function)) { punt = 1; break; } } switch_thread_rwlock_unlock(session->bug_rwlock); } } if (punt) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n"); } if (!switch_channel_media_ready(session->channel)) { if (switch_channel_pre_answer(session->channel) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FALSE; } } *new_bug = NULL; if ((p = switch_channel_get_variable(session->channel, "media_bug_answer_req")) && switch_true(p)) { flags |= SMBF_ANSWER_REQ; } #if 0 if (flags & SMBF_WRITE_REPLACE) { switch_thread_rwlock_wrlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n"); switch_thread_rwlock_unlock(session->bug_rwlock); return SWITCH_STATUS_GENERR; } } switch_thread_rwlock_unlock(session->bug_rwlock); } if (flags & SMBF_READ_REPLACE) { switch_thread_rwlock_wrlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (switch_test_flag(bp, SMBF_READ_REPLACE)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n"); switch_thread_rwlock_unlock(session->bug_rwlock); return SWITCH_STATUS_GENERR; } } switch_thread_rwlock_unlock(session->bug_rwlock); } #endif if (!(bug = switch_core_session_alloc(session, sizeof(*bug)))) { return SWITCH_STATUS_MEMERR; } bug->callback = callback; bug->user_data = user_data; bug->session = session; bug->flags = flags; bug->function = "N/A"; bug->target = "N/A"; switch_core_session_get_read_impl(session, &bug->read_impl); switch_core_session_get_write_impl(session, &bug->write_impl); if (function) { bug->function = switch_core_session_strdup(session, function); } if (target) { bug->target = switch_core_session_strdup(session, target); } bug->stop_time = stop_time; bytes = bug->read_impl.decoded_bytes_per_packet; if (!bug->flags) { bug->flags = (SMBF_READ_STREAM | SMBF_WRITE_STREAM); } if (switch_test_flag(bug, SMBF_READ_STREAM) || switch_test_flag(bug, SMBF_READ_PING)) { switch_buffer_create_dynamic(&bug->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER); switch_mutex_init(&bug->read_mutex, SWITCH_MUTEX_NESTED, session->pool); } bytes = bug->write_impl.decoded_bytes_per_packet; if (switch_test_flag(bug, SMBF_WRITE_STREAM)) { switch_buffer_create_dynamic(&bug->raw_write_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, MAX_BUG_BUFFER); switch_mutex_init(&bug->write_mutex, SWITCH_MUTEX_NESTED, session->pool); } if ((bug->flags & SMBF_THREAD_LOCK)) { bug->thread_id = switch_thread_self(); } if (bug->callback) { switch_bool_t result = bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT); if (result == SWITCH_FALSE) { switch_core_media_bug_destroy(bug); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error attaching BUG to %s\n", switch_channel_get_name(session->channel)); return SWITCH_STATUS_GENERR; } } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attaching BUG to %s\n", switch_channel_get_name(session->channel)); bug->ready = 1; switch_thread_rwlock_wrlock(session->bug_rwlock); bug->next = session->bugs; session->bugs = bug; for(bp = session->bugs; bp; bp = bp->next) { if (bp->ready && !switch_test_flag(bp, SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp, SMBF_TAP_NATIVE_WRITE)) { tap_only = 0; } } switch_thread_rwlock_unlock(session->bug_rwlock); *new_bug = bug; if (tap_only) { switch_set_flag(session, SSF_MEDIA_BUG_TAP_ONLY); } else { switch_clear_flag(session, SSF_MEDIA_BUG_TAP_ONLY); } if (switch_event_create(&event, SWITCH_EVENT_MEDIA_BUG_START) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target); switch_channel_event_set_data(session->channel, event); switch_event_fire(&event); } return SWITCH_STATUS_SUCCESS; }