static void event_handler(switch_event_t *event) { const char *dest_proto = switch_event_get_header(event, "dest_proto"); const char *check_failure = switch_event_get_header(event, "Delivery-Failure"); const char *check_nonblocking = switch_event_get_header(event, "Nonblocking-Delivery"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "skip_global_process", "true"); if (switch_true(check_failure)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Delivery Failure\n"); DUMP_EVENT(event); send_report(event, "Failure"); return; } else if ( check_failure && switch_false(check_failure) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SMS Delivery Success\n"); send_report(event, "Success"); return; } else if ( check_nonblocking && switch_true(check_nonblocking) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SMS Delivery assumed successful due to being sent in non-blocking manner\n"); send_report(event, "Accepted"); return; } switch_core_chat_send(dest_proto, event); }
static switch_status_t config_logger(void) { char *cf = "console.conf"; switch_xml_t cfg, xml, settings, param; 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 (log_hash) { switch_core_hash_destroy(&log_hash); } switch_core_hash_init(&log_hash, module_pool); if ((settings = switch_xml_child(cfg, "mappings"))) { 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"); add_mapping(var, val, 1); } for (param = switch_xml_child(settings, "map"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); add_mapping(var, val, 0); } } 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 (!strcasecmp(var, "colorize") && switch_true(val)) { #ifdef WIN32 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (switch_core_get_console() == stdout && hStdout != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) { wOldColorAttrs = csbiInfo.wAttributes; COLORIZE = 1; } #else COLORIZE = 1; #endif } else if (!strcasecmp(var, "loglevel") && !zstr(val)) { hard_log_level = switch_log_str2level(val); } else if (!strcasecmp(var, "uuid") && switch_true(val)) { log_uuid = SWITCH_TRUE; } } } switch_xml_free(xml); return SWITCH_STATUS_SUCCESS; }
static switch_status_t do_config(void) { char *cf = "xml_rpc.conf"; switch_xml_t cfg, xml, settings, param; char *realm, *user, *pass, *default_domain; default_domain = realm = user = pass = NULL; 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; } globals.virtual_host = SWITCH_TRUE; 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 (!zstr(var) && !zstr(val)) { if (!strcasecmp(var, "auth-realm")) { realm = val; } else if (!strcasecmp(var, "auth-user")) { user = val; } else if (!strcasecmp(var, "auth-pass")) { pass = val; } else if (!strcasecmp(var, "http-port")) { globals.port = (uint16_t) atoi(val); } else if (!strcasecmp(var, "default-domain")) { default_domain = val; } else if (!strcasecmp(var, "virtual-host")) { globals.virtual_host = switch_true(val); } else if (!strcasecmp(var, "enable-websocket")) { globals.enable_websocket = switch_true(val); } } } } if (!globals.port) { globals.port = 8080; } if (realm) { set_global_realm(realm); if (user && pass) { set_global_user(user); set_global_pass(pass); } } if (default_domain) { set_global_default_domain(default_domain); } switch_xml_free(xml); return SWITCH_STATUS_SUCCESS; }
void print_result(char const *addr, char const *port, char const *tport, double weight, unsigned preference, switch_stream_handle_t *stream) { int xml = switch_true(switch_event_get_header(stream->param_event, "xml")); if (!port || !port[0]) port = transport_is_secure(tport) ? "5061" : "5060"; if (xml) { stream->write_function(stream, " <route>\n" " <preference>%u</preference>\n" " <weight>%.3f</weight>\n" " <transport>%s</transport>\n" " <port>%s</port>\n" " <address>%s</address>\n" " </route>\n", preference, weight, tport, port, addr); } else { stream->write_function(stream, "%10u\t%10.3f\t%10s\t%10s\t%10s\n", preference, weight, tport, port, addr); } }
static switch_status_t limit_state_handler(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_state_t state = switch_channel_get_state(channel); const char *vval = switch_channel_get_variable(channel, LIMIT_IGNORE_TRANSFER_VARIABLE); const char *backendlist = switch_channel_get_variable(channel, LIMIT_BACKEND_VARIABLE); if (zstr(backendlist)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unset limit backendlist!\n"); return SWITCH_STATUS_SUCCESS; } if (state >= CS_HANGUP || (state == CS_ROUTING && !switch_true(vval))) { int argc = 0; char *argv[6] = { 0 }; char *mydata = strdup(backendlist); int x; argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0]))); for (x = 0; x < argc; x++) { switch_limit_release(argv[x], session, NULL, NULL); } switch_core_event_hook_remove_state_change(session, limit_state_handler); /* Remove limit_backend variable so we register another hook if limit is called again */ switch_channel_set_variable(channel, LIMIT_BACKEND_VARIABLE, NULL); free(mydata); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t load_profile(switch_xml_t xml) { switch_xml_t param, settings; char *name = (char *) switch_xml_attr_soft(xml, "name"); logfile_profile_t *new_profile; new_profile = switch_core_alloc(module_pool, sizeof(*new_profile)); memset(new_profile, 0, sizeof(*new_profile)); switch_core_hash_init(&(new_profile->log_hash)); new_profile->name = switch_core_strdup(module_pool, switch_str_nil(name)); new_profile->suffix = 1; new_profile->log_uuid = SWITCH_TRUE; if ((settings = switch_xml_child(xml, "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, "logfile")) { new_profile->logfile = strdup(val); } else if (!strcmp(var, "rollover")) { new_profile->roll_size = switch_atoui(val); } else if (!strcmp(var, "maximum-rotate")) { new_profile->max_rot = switch_atoui(val); if (new_profile->max_rot == 0) { new_profile->max_rot = MAX_ROT; } } else if (!strcmp(var, "uuid")) { new_profile->log_uuid = switch_true(val); } } } if ((settings = switch_xml_child(xml, "mappings"))) { for (param = switch_xml_child(settings, "map"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); add_mapping(new_profile, var, val); } } if (zstr(new_profile->logfile)) { char logfile[512]; switch_snprintf(logfile, sizeof(logfile), "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, "freeswitch.log"); new_profile->logfile = strdup(logfile); } if (mod_logfile_openlogfile(new_profile, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_GENERR; } switch_core_hash_insert_destructor(profile_hash, new_profile->name, (void *) new_profile, cleanup_profile); return SWITCH_STATUS_SUCCESS; }
static switch_status_t load_config(void) { char *cf = "syslog.conf"; switch_xml_t cfg, xml, settings, param; /* default log level */ log_level = SWITCH_LOG_WARNING; /* default facility */ globals.facility = DEFAULT_FACILITY; globals.log_uuid = SWITCH_TRUE; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); } else { 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, "ident")) { set_global_ident(val); } else if (!strcmp(var, "format")) { set_global_format(val); } else if (!strcmp(var, "facility")) { set_global_facility(val); } else if (!strcasecmp(var, "loglevel") && !zstr(val)) { log_level = switch_log_str2level(val); if (log_level == SWITCH_LOG_INVALID) { log_level = SWITCH_LOG_WARNING; } } else if (!strcasecmp(var, "uuid")) { globals.log_uuid = switch_true(val); } } } switch_xml_free(xml); } if (zstr(globals.ident)) { set_global_ident(DEFAULT_IDENT); } if (zstr(globals.format)) { set_global_format(DEFAULT_FORMAT); } return 0; }
void vmivr_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile) { vmivr_menu_t menu = { "std_menu_purge" }; /* Initialize Menu Configs */ menu_init(profile, &menu); if (profile->id && profile->authorized) { const char *exit_purge = switch_event_get_header(menu.event_settings, "Exit-Purge"); if (switch_true(exit_purge)) { const char *cmd = switch_core_session_sprintf(session, "%s %s %s", profile->api_profile, profile->domain, profile->id); vmivr_api_execute(session, profile->api_msg_purge, cmd); } } menu_free(&menu); }
/*! set text parameter */ static void pocketsphinx_asr_text_param(switch_asr_handle_t *ah, char *param, const char *val) { pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; if (!zstr(param) && !zstr(val)) { if (!strcasecmp("no-input-timeout", param) && switch_is_number(val)) { ps->no_input_timeout = atoi(val); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no-input-timeout = %d\n", ps->no_input_timeout); } else if (!strcasecmp("speech-timeout", param) && switch_is_number(val)) { ps->speech_timeout = atoi(val); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "speech-timeout = %d\n", ps->speech_timeout); } else if (!strcasecmp("start-input-timers", param)) { ps->start_input_timers = switch_true(val); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "start-input-timers = %d\n", ps->start_input_timers); } else if (!strcasecmp("confidence-threshold", param) && switch_is_number(val)) { ps->confidence_threshold = atoi(val); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "confidence-threshold = %d\n", ps->confidence_threshold); } } }
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event) { const char *command = switch_event_get_header(event, "command"); ctdm_private_t *tech_pvt = switch_core_session_get_private(session); if (!zstr(command)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received %s command \n",command); if (!strcasecmp(command, kPREBUFFER_LEN)) { const char *szval = switch_event_get_header(event, kPREBUFFER_LEN); int val = !zstr(szval) ? atoi(szval) : 0; if (tech_pvt->prebuffer_len == val) { tech_pvt->prebuffer_len = val; if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n"); return SWITCH_STATUS_GENERR; } } } else if (!strcasecmp(command, kECHOCANCEL)) { const char *szval = switch_event_get_header(event, kECHOCANCEL); int enabled = !!switch_true(szval); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM sending echo cancel [%s] command \n",enabled ? "enable" : "disable"); if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, enabled ? FTDM_COMMAND_ENABLE_ECHOCANCEL : FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to %s echo cancellation.\n", enabled ? "enable" : "disable"); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received unknown command [%s] \n",command); } } return SWITCH_STATUS_SUCCESS; }
void vmivr_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile) { vmivr_menu_t menu = { "std_select_greeting_slot" }; const char *result; int gnum = -1; /* Initialize Menu Configs */ menu_init(profile, &menu); result = vmivr_menu_get_input_set(session, profile, &menu, "X"); if (result) gnum = atoi(result); if (gnum != -1) { char * cmd = switch_core_session_sprintf(session, "%s %s %s %d", profile->api_profile, profile->domain, profile->id, gnum); if (vmivr_api_execute(session, profile->api_pref_greeting_set, cmd) == SWITCH_STATUS_SUCCESS) { char *str_num = switch_core_session_sprintf(session, "%d", gnum); char *cmd = switch_core_session_sprintf(session, "json %s %s %s %d %s", profile->api_profile, profile->domain, profile->id); switch_event_t *phrases = jsonapi2event(session, profile->api_pref_greeting_get, cmd); ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, phrases, NULL, 0); if (switch_true(switch_event_get_header(phrases, "VM-Message-Private-Local-Copy"))) { const char *file_path = switch_event_get_header(phrases, "VM-Preference-Greeting-File-Path"); if (file_path && unlink(file_path) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete temp file [%s]\n", file_path); } } switch_event_destroy(&phrases); } else { ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid_slot"), NULL, NULL, NULL, 0); } } menu_free(&menu); }
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; }
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) { crtp_private_t *tech_pvt = NULL; tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_DEBUG_MEDIA: { if (switch_rtp_ready(tech_pvt->rtp_session) && !zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0}; int x = 0; if (!strcasecmp(msg->string_array_arg[0], "read")) { flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]++;x++; } else if (!strcasecmp(msg->string_array_arg[0], "write")) { flags[SWITCH_RTP_FLAG_DEBUG_RTP_WRITE]++;x++; } else if (!strcasecmp(msg->string_array_arg[0], "both")) { flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]++;x++; flags[SWITCH_RTP_FLAG_DEBUG_RTP_WRITE]++; } if (x) { if (switch_true(msg->string_array_arg[1])) { switch_rtp_set_flags(tech_pvt->rtp_session, flags); } else { switch_rtp_clear_flags(tech_pvt->rtp_session, flags); } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Options\n"); } } break; } case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC: if (switch_rtp_ready(tech_pvt->rtp_session)) { rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_ONCE); } break; case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER: { if (switch_rtp_ready(tech_pvt->rtp_session)) { int len = 0, maxlen = 0, qlen = 0, maxqlen = 50, max_drift = 0; if (msg->string_arg) { char *p, *q; const char *s; if (!strcasecmp(msg->string_arg, "pause")) { switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_TRUE); goto end; } else if (!strcasecmp(msg->string_arg, "resume")) { switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_FALSE); goto end; } else if (!strncasecmp(msg->string_arg, "debug:", 6)) { s = msg->string_arg + 6; if (s && !strcmp(s, "off")) { s = NULL; } switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s); goto end; } if ((len = atoi(msg->string_arg))) { qlen = len / (tech_pvt->read_codec.implementation->microseconds_per_packet / 1000); if (qlen < 1) { qlen = 3; } } if (qlen) { if ((p = strchr(msg->string_arg, ':'))) { p++; maxlen = atol(p); if ((q = strchr(p, ':'))) { q++; max_drift = abs(atol(q)); } } } if (maxlen) { maxqlen = maxlen / (tech_pvt->read_codec.implementation->microseconds_per_packet / 1000); } } if (qlen) { if (maxqlen < qlen) { maxqlen = qlen * 5; } if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen, tech_pvt->read_codec.implementation->samples_per_packet, tech_pvt->read_codec.implementation->samples_per_second, max_drift) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames) (%d max drift)\n", len, qlen, maxqlen, max_drift); switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER); if (!switch_false(switch_channel_get_variable(tech_pvt->channel, "rtp_jitter_buffer_plc"))) { switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER_PLC); } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); } } else { switch_rtp_deactivate_jitter_buffer(tech_pvt->rtp_session); } } } break; default: break; } end: return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session) { switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state; const switch_endpoint_interface_t *endpoint_interface; const switch_state_handler_table_t *driver_state_handler = NULL; const switch_state_handler_table_t *application_state_handler = NULL; int proceed = 1; int global_proceed = 1; int do_extra_handlers = 1; int silly = 0; int index = 0; const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE); const char *skip_var = switch_channel_get_variable(session->channel, SWITCH_SKIP_CDR_CAUSES_VARIABLE); const char *hook_var; int use_session = 0; switch_event_t *event; switch_call_cause_t cause = switch_channel_get_cause(session->channel); if (switch_channel_test_flag(session->channel, CF_REPORTING)) { return; } switch_channel_set_flag(session->channel, CF_REPORTING); switch_assert(session != NULL); endpoint_interface = session->endpoint_interface; switch_assert(endpoint_interface != NULL); driver_state_handler = endpoint_interface->state_handler; switch_assert(driver_state_handler != NULL); if (!zstr(var)) { if (!strcasecmp(var, "a_only")) { if (switch_channel_get_originator_caller_profile(session->channel)) { do_extra_handlers = 0; } } else if (!strcasecmp(var, "b_only")) { if (switch_channel_get_originatee_caller_profile(session->channel)) { do_extra_handlers = 0; } } else if (!switch_true(var)) { do_extra_handlers = 0; } } if (!zstr(skip_var)) { int x, ttl = 0; char *list[128] = { 0 }; char *dup = switch_core_session_strdup(session, skip_var); ttl = switch_split(dup, '|', list); for(x = 0; x < ttl; x++) { if (switch_channel_str2cause(list[x]) == cause) { do_extra_handlers = 0; break; } } } if (switch_channel_test_flag(session->channel, CF_NO_CDR)) { do_extra_handlers = 0; } STATE_MACRO(reporting, "REPORTING"); if ((hook_var = switch_channel_get_variable(session->channel, SWITCH_API_REPORTING_HOOK_VARIABLE))) { if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE))) { use_session = 1; } api_hook(session, hook_var, use_session); } if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(cause)); switch_channel_event_set_data(session->channel, event); if (switch_true(switch_channel_get_variable(session->channel, "hangup_complete_with_xml"))) { switch_xml_t cdr = NULL; char *xml_cdr_text; if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { xml_cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Attached", "xml"); switch_event_add_body(event, "%s", xml_cdr_text); switch_xml_free(cdr); switch_safe_free(xml_cdr_text); } } switch_event_fire(&event); } return; }
static switch_status_t my_on_reporting(switch_core_session_t *session) { cJSON *json_cdr = NULL; char *json_text = NULL; char *path = NULL; char *curl_json_text = NULL; const char *logdir = NULL; char *json_text_escaped = NULL; int fd = -1, err_dir_index; uint32_t cur_try; long httpRes; CURL *curl_handle = NULL; switch_curl_slist_t *headers = NULL; switch_curl_slist_t *slist = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_FALSE; int is_b; const char *a_prefix = ""; if (globals.shutdown) { return SWITCH_STATUS_SUCCESS; } is_b = channel && switch_channel_get_originator_caller_profile(channel); if (!globals.log_b && is_b) { const char *force_cdr = switch_channel_get_variable(channel, SWITCH_FORCE_PROCESS_CDR_VARIABLE); if (!switch_true(force_cdr)) { return SWITCH_STATUS_SUCCESS; } } if (!is_b && globals.prefix_a) a_prefix = "a_"; if (switch_ivr_generate_json_cdr(session, &json_cdr, globals.encode_values == ENCODING_DEFAULT) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Generating Data!\n"); return SWITCH_STATUS_FALSE; } json_text = cJSON_PrintUnformatted(json_cdr); if (!json_text) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); goto error; } switch_thread_rwlock_rdlock(globals.log_path_lock); if (!(logdir = switch_channel_get_variable(channel, "json_cdr_base"))) { logdir = globals.log_dir; } if (!zstr(logdir) && (globals.log_http_and_disk || !globals.url_count)) { path = switch_mprintf("%s%s%s%s.cdr.json", logdir, SWITCH_PATH_SEPARATOR, a_prefix, switch_core_session_get_uuid(session)); switch_thread_rwlock_unlock(globals.log_path_lock); if (path) { #ifdef _MSC_VER if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) { #else if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) { #endif int wrote; wrote = write(fd, json_text, (unsigned) strlen(json_text)); close(fd); fd = -1; if(wrote < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s]\n",path); } } else { char ebuf[512] = { 0 }; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n", path, switch_strerror_r(errno, ebuf, sizeof(ebuf))); } switch_safe_free(path); } } else { switch_thread_rwlock_unlock(globals.log_path_lock); } /* try to post it to the web server */ if (globals.url_count) { char *destUrl = NULL; curl_handle = switch_curl_easy_init(); if (globals.encode) { switch_size_t need_bytes = strlen(json_text) * 3; json_text_escaped = malloc(need_bytes); switch_assert(json_text_escaped); memset(json_text_escaped, 0, need_bytes); if (globals.encode == ENCODING_DEFAULT) { headers = switch_curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded"); switch_url_encode(json_text, json_text_escaped, need_bytes); } else { headers = switch_curl_slist_append(headers, "Content-Type: application/x-www-form-base64-encoded"); switch_b64_encode((unsigned char *) json_text, need_bytes / 3, (unsigned char *) json_text_escaped, need_bytes); } switch_safe_free(json_text); json_text = json_text_escaped; if (!(curl_json_text = switch_mprintf("cdr=%s", json_text))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); goto error; } } else { headers = switch_curl_slist_append(headers, "Content-Type: application/json"); curl_json_text = (char *)json_text; } if (!zstr(globals.cred)) { switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, globals.auth_scheme); switch_curl_easy_setopt(curl_handle, CURLOPT_USERPWD, globals.cred); } switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); switch_curl_easy_setopt(curl_handle, CURLOPT_POST, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, curl_json_text); switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-json/1.0"); switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, httpCallBack); if (globals.disable100continue) { slist = switch_curl_slist_append(slist, "Expect:"); switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, slist); } if (globals.ssl_cert_file) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLCERT, globals.ssl_cert_file); } if (globals.ssl_key_file) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEY, globals.ssl_key_file); } if (globals.ssl_key_password) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEYPASSWD, globals.ssl_key_password); } if (globals.ssl_version) { if (!strcasecmp(globals.ssl_version, "SSLv3")) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3); } else if (!strcasecmp(globals.ssl_version, "TLSv1")) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); } } if (globals.ssl_cacert_file) { switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, globals.ssl_cacert_file); } /* these were used for testing, optionally they may be enabled if someone desires switch_curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 120); // tcp timeout switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); // 302 recursion level */ for (cur_try = 0; cur_try < globals.retries; cur_try++) { if (cur_try > 0) { switch_yield(globals.delay * 1000000); } destUrl = switch_mprintf("%s?uuid=%s", globals.urls[globals.url_index], switch_core_session_get_uuid(session)); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, destUrl); if (!strncasecmp(destUrl, "https", 5)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0); } if (globals.enable_cacert_check) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, TRUE); } if (globals.enable_ssl_verifyhost) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2); } switch_curl_easy_perform(curl_handle); switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes); switch_safe_free(destUrl); if (httpRes >= 200 && httpRes < 300) { goto success; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Got error [%ld] posting to web server [%s]\n", httpRes, globals.urls[globals.url_index]); globals.url_index++; switch_assert(globals.url_count <= MAX_URLS); if (globals.url_index >= globals.url_count) { globals.url_index = 0; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retry will be with url [%s]\n", globals.urls[globals.url_index]); } } switch_curl_easy_cleanup(curl_handle); switch_curl_slist_free_all(headers); switch_curl_slist_free_all(slist); slist = NULL; headers = NULL; curl_handle = NULL; /* if we are here the web post failed for some reason */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n"); for (err_dir_index = 0; err_dir_index < globals.err_dir_count; err_dir_index++) { switch_thread_rwlock_rdlock(globals.log_path_lock); path = switch_mprintf("%s%s%s%s.cdr.json", globals.err_log_dir[err_dir_index], SWITCH_PATH_SEPARATOR, a_prefix, switch_core_session_get_uuid(session)); switch_thread_rwlock_unlock(globals.log_path_lock); if (path) { #ifdef _MSC_VER if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) { #else if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) { #endif int wrote; wrote = write(fd, json_text, (unsigned) strlen(json_text)); close(fd); fd = -1; if(wrote < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s]\n",path); } break; } else { char ebuf[512] = { 0 }; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s! [%s]\n", path, switch_strerror_r(errno, ebuf, sizeof(ebuf))); } switch_safe_free(path); } } } success: status = SWITCH_STATUS_SUCCESS; error: if (curl_handle) { switch_curl_easy_cleanup(curl_handle); } if (headers) { switch_curl_slist_free_all(headers); } if (slist) { switch_curl_slist_free_all(slist); } if (curl_json_text != json_text) { switch_safe_free(curl_json_text); } cJSON_Delete(json_cdr); switch_safe_free(json_text); return status; } static void event_handler(switch_event_t *event) { const char *sig = switch_event_get_header(event, "Trapped-Signal"); if (sig && !strcmp(sig, "HUP")) { if (globals.rotate) { set_json_cdr_log_dirs(); } } } static switch_state_handler_table_t state_handlers = { /*.on_init */ NULL, /*.on_routing */ NULL, /*.on_execute */ NULL, /*.on_hangup */ NULL, /*.on_exchange_media */ NULL, /*.on_soft_execute */ NULL, /*.on_consume_media */ NULL, /*.on_hibernate */ NULL, /*.on_reset */ NULL, /*.on_park */ NULL, /*.on_reporting */ my_on_reporting }; SWITCH_MODULE_LOAD_FUNCTION(mod_json_cdr_load) { char *cf = "json_cdr.conf"; switch_xml_t cfg, xml, settings, param; switch_status_t status = SWITCH_STATUS_SUCCESS; /* test global state handlers */ switch_core_add_state_handler(&state_handlers); *module_interface = switch_loadable_module_create_module_interface(pool, modname); memset(&globals, 0, sizeof(globals)); if (switch_event_bind_removable(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); return SWITCH_STATUS_GENERR; } globals.log_http_and_disk = 0; globals.log_b = 1; globals.disable100continue = 0; globals.pool = pool; globals.auth_scheme = CURLAUTH_BASIC; globals.encode_values = ENCODING_DEFAULT; switch_thread_rwlock_create(&globals.log_path_lock, pool); /* parse the config */ 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 (!strcasecmp(var, "cred") && !zstr(val)) { globals.cred = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "url") && !zstr(val)) { if (globals.url_count >= MAX_URLS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "maximum urls configured!\n"); } else { globals.urls[globals.url_count++] = switch_core_strdup(globals.pool, val); } } else if (!strcasecmp(var, "log-http-and-disk")) { globals.log_http_and_disk = switch_true(val); } else if (!strcasecmp(var, "delay") && !zstr(val)) { globals.delay = (uint32_t) atoi(val); } else if (!strcasecmp(var, "log-b-leg")) { globals.log_b = switch_true(val); } else if (!strcasecmp(var, "prefix-a-leg")) { globals.prefix_a = switch_true(val); } else if (!strcasecmp(var, "disable-100-continue") && switch_true(val)) { globals.disable100continue = 1; } else if (!strcasecmp(var, "encode") && !zstr(val)) { if (!strcasecmp(val, "base64")) { globals.encode = ENCODING_BASE64; } else { globals.encode = switch_true(val) ? ENCODING_DEFAULT : ENCODING_NONE; } } else if (!strcasecmp(var, "retries") && !zstr(val)) { globals.retries = (uint32_t) atoi(val); } else if (!strcasecmp(var, "rotate") && !zstr(val)) { globals.rotate = switch_true(val); } else if (!strcasecmp(var, "log-dir")) { if (zstr(val)) { globals.base_log_dir = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); } else { if (switch_is_file_path(val)) { globals.base_log_dir = switch_core_strdup(globals.pool, val); } else { globals.base_log_dir = switch_core_sprintf(globals.pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, val); } } } else if (!strcasecmp(var, "err-log-dir")) { if (globals.err_dir_count >= MAX_ERR_DIRS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "maximum error directories configured!\n"); } else { if (zstr(val)) { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); } else { if (switch_is_file_path(val)) { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_strdup(globals.pool, val); } else { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, val); } } } } else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) { globals.enable_cacert_check = 1; } else if (!strcasecmp(var, "ssl-cert-path")) { globals.ssl_cert_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-key-path")) { globals.ssl_key_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-key-password")) { globals.ssl_key_password = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-version")) { globals.ssl_version = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-cacert-file")) { globals.ssl_cacert_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) { globals.enable_ssl_verifyhost = 1; } else if (!strcasecmp(var, "auth-scheme")) { if (*val == '=') { globals.auth_scheme = 0; val++; } if (!strcasecmp(val, "basic")) { globals.auth_scheme |= CURLAUTH_BASIC; } else if (!strcasecmp(val, "digest")) { globals.auth_scheme |= CURLAUTH_DIGEST; } else if (!strcasecmp(val, "NTLM")) { globals.auth_scheme |= CURLAUTH_NTLM; } else if (!strcasecmp(val, "GSS-NEGOTIATE")) { globals.auth_scheme |= CURLAUTH_GSSNEGOTIATE; } else if (!strcasecmp(val, "any")) { globals.auth_scheme = CURLAUTH_ANY; } } else if (!strcasecmp(var, "encode-values") && !zstr(val)) { globals.encode_values = switch_true(val) ? ENCODING_DEFAULT : ENCODING_NONE; } } if (!globals.err_dir_count) { if (!zstr(globals.base_log_dir)) { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_strdup(globals.pool, globals.base_log_dir); } else { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); } } } if (globals.retries && !globals.delay) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retries set but delay 0 setting to 5 seconds\n"); globals.delay = 5; } globals.retries++; set_json_cdr_log_dirs(); switch_xml_free(xml); return status; } SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_json_cdr_shutdown) { int err_dir_index = 0; globals.shutdown = 1; switch_safe_free(globals.log_dir); for (;err_dir_index < globals.err_dir_count; err_dir_index++) { switch_safe_free(globals.err_log_dir[err_dir_index]); } switch_event_unbind(&globals.node); switch_core_remove_state_handler(&state_handlers); switch_thread_rwlock_destroy(globals.log_path_lock); return SWITCH_STATUS_SUCCESS; }
static int sangoma_parse_config(void) { switch_xml_t cfg, settings, param, vocallos, xml, vocallo; struct in_addr vocallo_base_ip; char ipbuff[50]; char netbuff[50]; int host_ipaddr = 0; int host_netmaskaddr = 0; int vidx = 0; int baseudp = 0; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reading sangoma codec configuration\n"); if (!(xml = switch_xml_open_cfg(SANGOMA_TRANSCODE_CONFIG, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to open sangoma codec configuration %s\n", SANGOMA_TRANSCODE_CONFIG); return -1; } memset(&g_init_cfg, 0, sizeof(g_init_cfg)); if ((settings = switch_xml_child(cfg, "settings"))) { /* nothing here yet */ 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"); /* this parameter overrides the default list of codecs to load */ if (!strcasecmp(var, "register")) { strncpy(g_codec_register_list, val, sizeof(g_codec_register_list)-1); g_codec_register_list[sizeof(g_codec_register_list)-1] = 0; } else if (!strcasecmp(var, "noregister")) { strncpy(g_codec_noregister_list, val, sizeof(g_codec_noregister_list)-1); g_codec_noregister_list[sizeof(g_codec_noregister_list)-1] = 0; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored unknown Sangoma codec setting %s\n", var); } } } if ((vocallos = switch_xml_child(cfg, "vocallos"))) { for (vocallo = switch_xml_child(vocallos, "vocallo"); vocallo; vocallo = vocallo->next) { const char *name = switch_xml_attr(vocallo, "name"); if (!name) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Sangoma vocallo found with no name= attribute, ignoring!\n"); continue; } if (load_nic_network_information(name, &g_init_cfg.host_nic_vocallo_cfg[vidx])) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring vocallo %s, failed to retrieve its network configuration\n", name); continue; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Configuring vocallo %s\n", name); g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_base_udp_port = SANGOMA_DEFAULT_UDP_PORT; g_init_cfg.host_nic_vocallo_cfg[vidx].silence_suppression = 0; for (param = switch_xml_child(vocallo, "param"); param; param = param->next) { char *var = (char *)switch_xml_attr_soft(param, "name"); char *val = (char *)switch_xml_attr_soft(param, "value"); /* starting UDP port to be used by the vocallo modules */ if (!strcasecmp(var, "baseudp")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec base udp port %s\n", val); baseudp = atoi(val); if (baseudp < SANGOMA_MIN_UDP_PORT || baseudp > SANGOMA_MAX_UDP_PORT) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Sangoma codec base udp port %s, using default %d\n", val, SANGOMA_DEFAULT_UDP_PORT); break; } g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_base_udp_port = baseudp; } else if (!strcasecmp(var, "vocalloaddr")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec vocallo addr %s\n", val); if (switch_inet_pton(AF_INET, val, &vocallo_base_ip) <= 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Sangoma codec vocallo addr %s\n", val); break; } g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_ip = ntohl(vocallo_base_ip.s_addr); } else if (!strcasecmp(var, "silence")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found Sangoma codec silence setting %s\n", val); g_init_cfg.host_nic_vocallo_cfg[vidx].silence_suppression = switch_true(val) ? 1 : 0; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored unknown Sangoma vocallo setting %s\n", var); } } if (!g_init_cfg.host_nic_vocallo_cfg[vidx].vocallo_ip) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring vocallo %s, no valid address was configured\n", name); continue; } host_ipaddr = htonl(g_init_cfg.host_nic_vocallo_cfg[vidx].host_ip); host_netmaskaddr = htonl(g_init_cfg.host_nic_vocallo_cfg[vidx].host_ip_netmask); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Configured Sangoma transcoding interface %s, IP address %s, netmask %s\n", name, switch_inet_ntop(AF_INET, &host_ipaddr, ipbuff, sizeof(ipbuff)), switch_inet_ntop(AF_INET, &host_netmaskaddr, netbuff, sizeof(netbuff))); strncpy(g_vocallo_names[vidx], name, sizeof(g_vocallo_names[vidx])-1); g_vocallo_names[vidx][sizeof(g_vocallo_names[vidx])-1] = 0; vidx++; } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No <vocallos> section found in configuration file %s\n", SANGOMA_TRANSCODE_CONFIG); } switch_xml_free(xml); if (!vidx) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No vocallos were configured, make sure there is at least one <vocallo> in %s.\n", SANGOMA_TRANSCODE_CONFIG); } g_init_cfg.host_nic_vocallo_sz = vidx; return 0; }
SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force) { switch_call_cause_t cause = switch_channel_get_cause(session->channel); switch_call_cause_t cause_q850 = switch_channel_get_cause_q850(session->channel); int proceed = 1; int global_proceed = 1; int do_extra_handlers = 1; int silly = 0; int index = 0; switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state; const switch_endpoint_interface_t *endpoint_interface; const switch_state_handler_table_t *driver_state_handler = NULL; const switch_state_handler_table_t *application_state_handler = NULL; const char *hook_var; int use_session = 0; if (!force) { if (!switch_channel_test_flag(session->channel, CF_EARLY_HANGUP) && !switch_test_flag((&runtime), SCF_EARLY_HANGUP)) { return; } if (switch_thread_self() != session->thread_id) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s thread mismatch skipping state handler.\n", switch_channel_get_name(session->channel)); return; } } if (switch_test_flag(session, SSF_HANGUP)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s handler already called, skipping state handler.\n", switch_channel_get_name(session->channel)); return; } endpoint_interface = session->endpoint_interface; switch_assert(endpoint_interface != NULL); driver_state_handler = endpoint_interface->state_handler; switch_assert(driver_state_handler != NULL); switch_channel_set_hangup_time(session->channel); switch_core_media_bug_remove_all(session); switch_channel_stop_broadcast(session->channel); switch_channel_set_variable(session->channel, "hangup_cause", switch_channel_cause2str(cause)); switch_channel_set_variable_printf(session->channel, "hangup_cause_q850", "%d", cause_q850); //switch_channel_presence(session->channel, "unknown", switch_channel_cause2str(cause), NULL); switch_channel_set_timestamps(session->channel); STATE_MACRO(hangup, "HANGUP"); switch_core_media_set_stats(session); if ((hook_var = switch_channel_get_variable(session->channel, SWITCH_API_HANGUP_HOOK_VARIABLE))) { if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE))) { use_session = 1; } api_hook(session, hook_var, use_session); } switch_channel_set_callstate(session->channel, CCS_HANGUP); switch_set_flag(session, SSF_HANGUP); }
static void launch_thread(const char *name, const char *path, switch_xml_t directory) { local_stream_source_t *source = NULL; switch_memory_pool_t *pool; switch_xml_t param; switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n"); abort(); } source = switch_core_alloc(pool, sizeof(*source)); assert(source != NULL); source->pool = pool; source->name = switch_core_strdup(source->pool, name); source->location = switch_core_strdup(source->pool, path); source->rate = 8000; source->interval = 20; source->channels = 1; source->timer_name = "soft"; source->prebuf = DEFAULT_PREBUFFER_SIZE; source->stopped = 0; source->hup = 0; source->chime_freq = 30; for (param = switch_xml_child(directory, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "rate")) { int tmp = atoi(val); if (tmp == 8000 || tmp == 12000 || tmp == 16000 || tmp == 24000 || tmp == 32000 || tmp == 48000) { source->rate = tmp; } } else if (!strcasecmp(var, "shuffle")) { source->shuffle = switch_true(val); } else if (!strcasecmp(var, "prebuf")) { int tmp = atoi(val); if (tmp > 0) { source->prebuf = (uint32_t) tmp; } } else if (!strcasecmp(var, "channels")) { int tmp = atoi(val); if (tmp == 1 || tmp == 2) { source->channels = (uint8_t) tmp; } } else if (!strcasecmp(var, "chime-freq")) { int tmp = atoi(val); if (tmp > 1) { source->chime_freq = tmp; } } else if (!strcasecmp(var, "chime-max")) { int tmp = atoi(val); if (tmp > 1) { source->chime_max = tmp; } } else if (!strcasecmp(var, "chime-list")) { char *list_dup = switch_core_strdup(source->pool, val); source->chime_total = switch_separate_string(list_dup, ',', source->chime_list, (sizeof(source->chime_list) / sizeof(source->chime_list[0]))); } else if (!strcasecmp(var, "interval")) { int tmp = atoi(val); if (SWITCH_ACCEPTABLE_INTERVAL(tmp)) { source->interval = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Interval must be multiple of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL); } } else if (!strcasecmp(var, "timer-name")) { source->timer_name = switch_core_strdup(source->pool, val); } } if (source->chime_max) { source->chime_max *= source->rate; } if (source->chime_total) { source->chime_counter = source->rate * source->chime_freq; } source->samples = switch_samples_per_packet(source->rate, source->interval); switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool); switch_threadattr_create(&thd_attr, source->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, read_stream_thread, source, source->pool); }
static switch_status_t load_config(void) { char *cf = "enum.conf"; int inameserver = 0; switch_xml_t cfg, xml = NULL, param, settings, route, routes; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); status = SWITCH_STATUS_FALSE; goto done; } globals.timeout = 5000; globals.retries = 3; globals.random = 0; if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { const char *var = switch_xml_attr_soft(param, "name"); const char *val = switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "default-root")) { set_global_root(val); } else if (!strcasecmp(var, "auto-reload")) { globals.auto_reload = switch_true(val); } else if (!strcasecmp(var, "query-timeout")) { globals.timeout = atoi(val) * 1000; } else if (!strcasecmp(var, "query-timeout-ms")) { globals.timeout = atoi(val); } else if (!strcasecmp(var, "query-timeout-retry")) { globals.retries = atoi(val); } else if (!strcasecmp(var, "random-nameserver")) { globals.random = switch_true(val); } else if (!strcasecmp(var, "default-isn-root")) { set_global_isn_root(val); } else if (!strcasecmp(var, "nameserver") || !strcasecmp(var, "use-server")) { if ( inameserver < ENUM_MAXNAMESERVERS ) { globals.nameserver[inameserver] = (char *) val; inameserver++; } } else if (!strcasecmp(var, "log-level-trace")) { } } } if ((routes = switch_xml_child(cfg, "routes"))) { for (route = switch_xml_child(routes, "route"); route; route = route->next) { char *service = (char *) switch_xml_attr_soft(route, "service"); char *regex = (char *) switch_xml_attr_soft(route, "regex"); char *replace = (char *) switch_xml_attr_soft(route, "replace"); if (service && regex && replace) { add_route(service, regex, replace); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Route!\n"); } } } done: #ifdef _MSC_VER if (!globals.nameserver[0]) { HKEY hKey; DWORD data_sz; char* buf; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_QUERY_VALUE, &hKey); if (hKey) { RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, NULL, &data_sz); if (data_sz) { buf = (char*)malloc(data_sz + 1); RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, (LPBYTE)buf, &data_sz); RegCloseKey(hKey); if(buf[data_sz - 1] != 0) { buf[data_sz] = 0; } switch_replace_char(buf, ' ', 0, SWITCH_FALSE); /* only use the first entry ex "192.168.1.1 192.168.1.2" */ globals.nameserver[0] = buf; } } } #endif if (xml) { switch_xml_free(xml); } if (!globals.root) { set_global_root("e164.org"); } if (!globals.isn_root) { set_global_isn_root("freenum.org"); } return status; }
void vmivr_menu_navigator(switch_core_session_t *session, vmivr_profile_t *profile) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_event_t *msg_list_params = NULL; size_t msg_count = 0; size_t current_msg = 1; size_t next_msg = current_msg; size_t previous_msg = current_msg; char *cmd = NULL; int retry; /* Different switch to control playback of phrases */ switch_bool_t initial_count_played = SWITCH_FALSE; switch_bool_t skip_header = SWITCH_FALSE; switch_bool_t skip_playback = SWITCH_FALSE; switch_bool_t msg_deleted = SWITCH_FALSE; switch_bool_t msg_undeleted = SWITCH_FALSE; switch_bool_t msg_saved = SWITCH_FALSE; vmivr_menu_t menu = { "std_navigator" }; /* Initialize Menu Configs */ menu_init(profile, &menu); if (!menu.event_keys_dtmf || !menu.event_phrases) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases or Keys in menu '%s'\n", menu.name); goto done; } /* Get VoiceMail List And update msg count */ cmd = switch_core_session_sprintf(session, "json %s %s %s %s %s", profile->api_profile, profile->domain, profile->id, profile->folder_name, profile->folder_filter); msg_list_params = jsonapi2event(session, profile->api_msg_list, cmd); if (msg_list_params) { msg_count = atol(switch_event_get_header(msg_list_params,"VM-List-Count")); if (msg_count == 0) { goto done; } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "API message list return invalid result : %s(%s)\n", profile->api_msg_list, cmd); goto done; } /* TODO Add Detection of new message and notify the user */ for (retry = menu.ivr_maximum_attempts; switch_channel_ready(channel) && retry > 0; retry--) { switch_core_session_message_t msg = { 0 }; char cid_buf[1024] = ""; menu_instance_init(&menu); switch_event_add_header(menu.phrase_params, SWITCH_STACK_BOTTOM, "IVR-Retry-Left", "%d", retry); previous_msg = current_msg; ivre_init(&menu.ivre_d, menu.dtmfa); /* Prompt related to previous Message here */ append_event_message(session, profile, menu.phrase_params, msg_list_params, previous_msg); if (msg_deleted) { msg_deleted = SWITCH_FALSE; ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "ack"), "deleted", menu.phrase_params, NULL, 0); } if (msg_undeleted) { msg_undeleted = SWITCH_FALSE; ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "ack"), "undeleted", menu.phrase_params, NULL, 0); } if (msg_saved) { msg_saved = SWITCH_FALSE; ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "ack"), "saved", menu.phrase_params, NULL, 0); } switch_event_del_header(menu.phrase_params, "VM-Message-Flags"); /* Simple Protection to not go out of msg list scope */ if (next_msg == 0) { next_msg = 1; } else if (next_msg > msg_count) { next_msg = msg_count; ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "no_more_messages"), NULL, NULL, NULL, 0); } current_msg = next_msg; /* Prompt related the current message */ append_event_message(session, profile, menu.phrase_params, msg_list_params, current_msg); /* Used for extra control in phrases */ switch_event_add_header(menu.phrase_params, SWITCH_STACK_BOTTOM, "VM-List-Count", "%"SWITCH_SIZE_T_FMT, msg_count); /* Display MSG CID/Name to caller */ switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", switch_str_nil(switch_event_get_header(menu.phrase_params, "VM-Message-Caller-Number")), switch_str_nil(switch_event_get_header(menu.phrase_params, "VM-Message-Caller-Name"))); msg.from = __FILE__; msg.string_arg = cid_buf; msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY; switch_core_session_receive_message(session, &msg); /* Save in profile the current msg info for other menu processing AND restoration of our current position */ profile->current_msg = current_msg; profile->current_msg_uuid = switch_core_session_strdup(session, switch_event_get_header(menu.phrase_params, "VM-Message-UUID")); /* TODO check if msg is gone (purged by another session, notify user and auto jump to next message or something) */ if (!skip_header) { if (!initial_count_played) { cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id); jsonapi_populate_event(session, menu.phrase_params, profile->api_msg_count, cmd); initial_count_played = SWITCH_TRUE; // TODO ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, menu.phrase_params, NULL, 0); } if (msg_count > 0) { ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "say_msg_number"), NULL, menu.phrase_params, NULL, 0); ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "say_date"), NULL, menu.phrase_params, NULL, 0); } } if (msg_count > 0 && !skip_playback) { /* TODO Update the Read date of a message (When msg start, or when it listen compleatly ??? To be determined */ ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "play_message"), NULL, menu.phrase_params, NULL, 0); } skip_header = SWITCH_FALSE; skip_playback = SWITCH_FALSE; ivre_playback(session, &menu.ivre_d, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, menu.phrase_params, NULL, menu.ivr_entry_timeout); if (menu.ivre_d.result == RES_TIMEOUT) { ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "timeout"), NULL, NULL, NULL, 0); } else if (menu.ivre_d.result == RES_INVALID) { ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "invalid"), NULL, NULL, NULL, 0); } else if (menu.ivre_d.result == RES_FOUND) { /* Matching DTMF Key Pressed */ const char *action = switch_event_get_header(menu.event_keys_dtmf, menu.ivre_d.dtmf_stored); /* Reset the try count */ retry = menu.ivr_maximum_attempts; action: if (action) { if (!strcasecmp(action, "skip_intro")) { /* Skip Header / Play the recording again */ skip_header = SWITCH_TRUE; } else if (!strcasecmp(action, "next_msg")) { /* Next Message */ next_msg++; } else if (!strcasecmp(action, "prev_msg")) { /* Previous Message */ next_msg--; } else if (!strcasecmp(action, "delete_msg")) { /* Delete / Undelete Message */ const char *msg_flags = switch_event_get_header(menu.phrase_params, "VM-Message-Flags"); if (!msg_flags || strncasecmp(msg_flags, "delete", 6)) { const char *action_on_delete = switch_event_get_header(menu.event_settings, "Nav-Action-On-Delete"); cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(menu.phrase_params, "VM-Message-UUID")); vmivr_api_execute(session, profile->api_msg_delete, cmd); msg_deleted = SWITCH_TRUE; if (action_on_delete) { action = action_on_delete; goto action; } else { skip_header = skip_playback = SWITCH_TRUE; } } else { cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(menu.phrase_params, "VM-Message-UUID")); vmivr_api_execute(session, profile->api_msg_undelete, cmd); msg_undeleted = SWITCH_TRUE; } } else if (!strcasecmp(action, "save_msg")) { /* Save Message */ cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(menu.phrase_params, "VM-Message-UUID")); vmivr_api_execute(session, profile->api_msg_save, cmd); msg_saved = SWITCH_TRUE; } else if (!strcasecmp(action, "callback")) { /* CallBack caller */ const char *cid_num = switch_event_get_header(menu.phrase_params, "VM-Message-Caller-Number"); if (cid_num) { /* TODO add detection for private number */ switch_core_session_execute_exten(session, cid_num, "XML", profile->domain); } else { /* TODO Some error msg that the msg doesn't contain a caller number */ } } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */ void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = vmivr_get_menu_function(action+5); if (fPtr) { fPtr(session, profile); } } else if (!strcasecmp(action, "return")) { /* Return */ retry = -1; } } } /* IF the API to get the message returned us a COPY of the file menu.ivre_dally (temp file create from a DB or from a web server), delete it */ if (switch_true(switch_event_get_header(menu.phrase_params, "VM-Message-Private-Local-Copy"))) { const char *file_path = switch_event_get_header(menu.phrase_params, "VM-Message-File-Path"); if (file_path && unlink(file_path) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete temp file [%s]\n", file_path); } } menu_instance_free(&menu); } done: switch_event_destroy(&msg_list_params); menu_free(&menu); return; }
void vmivr_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile) { switch_channel_t *channel = switch_core_session_get_channel(session); vmivr_menu_t menu = { "std_authenticate" }; int retry; const char *auth_var = NULL; /* Initialize Menu Configs */ menu_init(profile, &menu); if (profile->id && (auth_var = switch_channel_get_variable(channel, "voicemail_authorized")) && switch_true(auth_var)) { profile->authorized = SWITCH_TRUE; } for (retry = menu.ivr_maximum_attempts; switch_channel_ready(channel) && retry > 0 && profile->authorized == SWITCH_FALSE; retry--) { const char *id = profile->id, *password = NULL; char *cmd = NULL; const char *password_mask = switch_event_get_header(menu.event_settings, "Password-Mask"); const char *user_mask = switch_event_get_header(menu.event_settings, "User-Mask"); if (!id) { vmivr_menu_t sub_menu = { "std_authenticate_ask_user" }; /* Initialize Menu Configs */ menu_init(profile, &sub_menu); switch_event_add_header(sub_menu.phrase_params, SWITCH_STACK_BOTTOM, "IVR-Retry-Left", "%d", retry); id = vmivr_menu_get_input_set(session, profile, &sub_menu, user_mask); menu_free(&sub_menu); } if (!password) { vmivr_menu_t sub_menu = { "std_authenticate_ask_password" }; /* Initialize Menu Configs */ menu_init(profile, &sub_menu); switch_event_add_header(sub_menu.phrase_params, SWITCH_STACK_BOTTOM, "IVR-Retry-Left", "%d", retry); password = vmivr_menu_get_input_set(session, profile, &sub_menu, password_mask); menu_free(&sub_menu); } cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, id, password); if (vmivr_api_execute(session, profile->api_auth_login, cmd) == SWITCH_STATUS_SUCCESS) { profile->id = id; profile->authorized = SWITCH_TRUE; } else { ivre_playback_dtmf_buffered(session, switch_event_get_header(menu.event_phrases, "fail_auth"), NULL, NULL, NULL, 0); } } menu_free(&menu); }
static switch_status_t my_on_reporting(switch_core_session_t *session) { switch_status_t status = SWITCH_STATUS_SUCCESS; switch_channel_t *channel = switch_core_session_get_channel(session); switch_event_header_t *hi; switch_caller_profile_t *caller_profile; switch_app_log_t *app_log; bson cdr; int is_b; char *tmp; if (globals.shutdown) { return SWITCH_STATUS_SUCCESS; } is_b = channel && switch_channel_get_originator_caller_profile(channel); if (!globals.log_b && is_b) { const char *force_cdr = switch_channel_get_variable(channel, SWITCH_FORCE_PROCESS_CDR_VARIABLE); if (!switch_true(force_cdr)) { return SWITCH_STATUS_SUCCESS; } } bson_init(&cdr); /* Channel data */ bson_append_start_object(&cdr, "channel_data"); bson_append_string(&cdr, "state", switch_channel_state_name(switch_channel_get_state(channel))); bson_append_string(&cdr, "direction", switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"); bson_append_int(&cdr, "state_number", switch_channel_get_state(channel)); if ((tmp = switch_channel_get_flag_string(channel))) { bson_append_string(&cdr, "flags", tmp); free(tmp); } if ((tmp = switch_channel_get_cap_string(channel))) { bson_append_string(&cdr, "caps", tmp); free(tmp); } bson_append_finish_object(&cdr); /* channel_data */ /* Channel variables */ bson_append_start_object(&cdr, "variables"); if ((hi = switch_channel_variable_first(channel))) { for (; hi; hi = hi->next) { if (!zstr(hi->name) && !zstr(hi->value)) { bson_append_string(&cdr, hi->name, hi->value); } } switch_channel_variable_last(channel); } bson_append_finish_object(&cdr); /* variables */ /* App log */ if ((app_log = switch_core_session_get_app_log(session))) { switch_app_log_t *ap; bson_append_start_object(&cdr, "app_log"); for (ap = app_log; ap; ap = ap->next) { bson_append_start_object(&cdr, "application"); bson_append_string(&cdr, "app_name", ap->app); bson_append_string(&cdr, "app_data", ap->arg); bson_append_long(&cdr, "app_stamp", ap->stamp); bson_append_finish_object(&cdr); /* application */ } bson_append_finish_object(&cdr); /* app_log */ } /* Callflow */ caller_profile = switch_channel_get_caller_profile(channel); while (caller_profile) { bson_append_start_object(&cdr, "callflow"); if (!zstr(caller_profile->dialplan)) { bson_append_string(&cdr, "dialplan", caller_profile->dialplan); } if (!zstr(caller_profile->profile_index)) { bson_append_string(&cdr, "profile_index", caller_profile->profile_index); } if (caller_profile->caller_extension) { switch_caller_application_t *ap; bson_append_start_object(&cdr, "extension"); bson_append_string(&cdr, "name", caller_profile->caller_extension->extension_name); bson_append_string(&cdr, "number", caller_profile->caller_extension->extension_number); if (caller_profile->caller_extension->current_application) { bson_append_string(&cdr, "current_app", caller_profile->caller_extension->current_application->application_name); } for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) { bson_append_start_object(&cdr, "application"); if (ap == caller_profile->caller_extension->current_application) { bson_append_bool(&cdr, "last_executed", 1); } bson_append_string(&cdr, "app_name", ap->application_name); bson_append_string(&cdr, "app_data", ap->application_data); bson_append_finish_object(&cdr); } if (caller_profile->caller_extension->children) { switch_caller_profile_t *cp = NULL; for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) { if (!cp->caller_extension) { continue; } bson_append_start_object(&cdr, "sub_extensions"); bson_append_start_object(&cdr, "extension"); bson_append_string(&cdr, "name", cp->caller_extension->extension_name); bson_append_string(&cdr, "number", cp->caller_extension->extension_number); bson_append_string(&cdr, "dialplan", cp->dialplan); if (cp->caller_extension->current_application) { bson_append_string(&cdr, "current_app", cp->caller_extension->current_application->application_name); } for (ap = cp->caller_extension->applications; ap; ap = ap->next) { bson_append_start_object(&cdr, "application"); if (ap == cp->caller_extension->current_application) { bson_append_bool(&cdr, "last_executed", 1); } bson_append_string(&cdr, "app_name", ap->application_name); bson_append_string(&cdr, "app_data", ap->application_data); bson_append_finish_object(&cdr); } bson_append_finish_object(&cdr); /* extension */ bson_append_finish_object(&cdr); /* sub_extensions */ } } bson_append_finish_object(&cdr); /* extension */ } bson_append_start_object(&cdr, "caller_profile"); set_bson_profile_data(&cdr, caller_profile); if (caller_profile->origination_caller_profile) { switch_caller_profile_t *cp = NULL; bson_append_start_object(&cdr, "origination"); for (cp = caller_profile->origination_caller_profile; cp; cp = cp->next) { bson_append_start_object(&cdr, "origination_caller_profile"); set_bson_profile_data(&cdr, cp); bson_append_finish_object(&cdr); } bson_append_finish_object(&cdr); /* origination */ } if (caller_profile->originator_caller_profile) { switch_caller_profile_t *cp = NULL; bson_append_start_object(&cdr, "originator"); for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) { bson_append_start_object(&cdr, "originator_caller_profile"); set_bson_profile_data(&cdr, cp); bson_append_finish_object(&cdr); } bson_append_finish_object(&cdr); /* originator */ } if (caller_profile->originatee_caller_profile) { switch_caller_profile_t *cp = NULL; bson_append_start_object(&cdr, "originatee"); for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) { bson_append_start_object(&cdr, "originatee_caller_profile"); set_bson_profile_data(&cdr, cp); bson_append_finish_object(&cdr); } bson_append_finish_object(&cdr); /* originatee */ } bson_append_finish_object(&cdr); /* caller_profile */ /* Timestamps */ if (caller_profile->times) { bson_append_start_object(&cdr, "times"); /* Insert timestamps as long ints (microseconds) to preserve accuracy */ bson_append_long(&cdr, "created_time", caller_profile->times->created); bson_append_long(&cdr, "profile_created_time", caller_profile->times->profile_created); bson_append_long(&cdr, "progress_time", caller_profile->times->progress); bson_append_long(&cdr, "progress_media_time", caller_profile->times->progress_media); bson_append_long(&cdr, "answered_time", caller_profile->times->answered); bson_append_long(&cdr, "bridged_time", caller_profile->times->bridged); bson_append_long(&cdr, "last_hold_time", caller_profile->times->last_hold); bson_append_long(&cdr, "hold_accum_time", caller_profile->times->hold_accum); bson_append_long(&cdr, "hangup_time", caller_profile->times->hungup); bson_append_long(&cdr, "resurrect_time", caller_profile->times->resurrected); bson_append_long(&cdr, "transfer_time", caller_profile->times->transferred); bson_append_finish_object(&cdr); /* times */ } bson_append_finish_object(&cdr); /* callflow */ caller_profile = caller_profile->next; } bson_finish(&cdr); switch_mutex_lock(globals.mongo_mutex); if (mongo_insert(globals.mongo_conn, globals.mongo_namespace, &cdr) != MONGO_OK) { if (globals.mongo_conn->err == MONGO_IO_ERROR) { mongo_error_t db_status; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MongoDB connection failed; attempting reconnect...\n"); db_status = mongo_reconnect(globals.mongo_conn); if (db_status != MONGO_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MongoDB reconnect failed with error code %d\n", db_status); status = SWITCH_STATUS_FALSE; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "MongoDB connection re-established.\n"); if (mongo_insert(globals.mongo_conn, globals.mongo_namespace, &cdr) != MONGO_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: error code %d\n", globals.mongo_conn->err); status = SWITCH_STATUS_FALSE; } } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: error code %d\n", globals.mongo_conn->err); status = SWITCH_STATUS_FALSE; } } switch_mutex_unlock(globals.mongo_mutex); bson_destroy(&cdr); return status; }
static switch_status_t switch_silk_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) { if (codec_fmtp) { silk_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(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 (codec_settings) { if (!strcasecmp(data, "useinbandfec")) { if (switch_true(arg)) { codec_settings->useinbandfec = 1; } } if (!strcasecmp(data, "usedtx")) { if (switch_true(arg)) { codec_settings->usedtx = 1; } } if (!strcasecmp(data, "maxaveragebitrate")) { codec_settings->maxaveragebitrate = atoi(arg); switch(codec_fmtp->actual_samples_per_second) { case 8000: { if(codec_settings->maxaveragebitrate < 6000 || codec_settings->maxaveragebitrate > 20000) { codec_settings->maxaveragebitrate = 20000; } break; } case 12000: { if(codec_settings->maxaveragebitrate < 7000 || codec_settings->maxaveragebitrate > 25000) { codec_settings->maxaveragebitrate = 25000; } break; } case 16000: { if(codec_settings->maxaveragebitrate < 8000 || codec_settings->maxaveragebitrate > 30000) { codec_settings->maxaveragebitrate = 30000; } break; } case 24000: { if(codec_settings->maxaveragebitrate < 12000 || codec_settings->maxaveragebitrate > 40000) { codec_settings->maxaveragebitrate = 40000; } break; } default: /* this should never happen but 20000 is common among all rates */ codec_settings->maxaveragebitrate = 20000; break; } } } } } free(fmtp_dup); } //codec_fmtp->bits_per_second = bit_rate; return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_FALSE; }
static switch_status_t populate_database(switch_core_session_t *session, dir_profile_t *profile, const char *domain_name) { switch_status_t status = SWITCH_STATUS_SUCCESS; char *sql = NULL; char *sqlvalues = NULL; char *sqltmp = NULL; int count = 0; switch_xml_t xml_root = NULL, x_domain; switch_xml_t ut; switch_event_t *xml_params = NULL; switch_xml_t group = NULL, groups = NULL, users = NULL, x_params = NULL, x_param = NULL, x_vars = NULL, x_var = NULL; switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS); switch_assert(xml_params); if (switch_xml_locate_domain(domain_name, xml_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain_name); status = SWITCH_STATUS_FALSE; goto end; } if ((groups = switch_xml_child(x_domain, "groups"))) { for (group = switch_xml_child(groups, "group"); group; group = group->next) { if ((users = switch_xml_child(group, "users"))) { for (ut = switch_xml_child(users, "user"); ut; ut = ut->next) { int name_visible = 1; int exten_visible = 1; const char *type = switch_xml_attr_soft(ut, "type"); const char *id = switch_xml_attr_soft(ut, "id"); char *fullName = NULL; char *caller_name = NULL; char *caller_name_override = NULL; char *firstName = NULL; char *lastName = NULL; char *fullNameDigit = NULL; char *firstNameDigit = NULL; char *lastNameDigit = NULL; if (!strcasecmp(type, "pointer")) { continue; } /* Check all the user params */ if ((x_params = switch_xml_child(ut, "params"))) { for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { const char *var = switch_xml_attr_soft(x_param, "name"); const char *val = switch_xml_attr_soft(x_param, "value"); if (!strcasecmp(var, "directory-visible")) { name_visible = switch_true(val); } if (!strcasecmp(var, "directory-exten-visible")) { exten_visible = switch_true(val); } } } /* Check all the user variables */ if ((x_vars = switch_xml_child(ut, "variables"))) { for (x_var = switch_xml_child(x_vars, "variable"); x_var; x_var = x_var->next) { const char *var = switch_xml_attr_soft(x_var, "name"); const char *val = switch_xml_attr_soft(x_var, "value"); if (!strcasecmp(var, "effective_caller_id_name")) { caller_name = switch_core_session_strdup(session, val); } if (!strcasecmp(var, "directory_full_name")) { caller_name_override = switch_core_session_strdup(session, val); } } } if (caller_name_override) { fullName = caller_name_override; } else { fullName = caller_name; } if (zstr(fullName)) { continue; } firstName = switch_core_session_strdup(session, fullName); if ((lastName = strrchr(firstName, ' '))) { *lastName++ = '\0'; } else { lastName = switch_core_session_strdup(session, firstName); } /* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "FullName %s firstName [%s] lastName [%s]\n", fullName, firstName, lastName); */ /* Generate Digits key mapping */ fullNameDigit = string_to_keypad_digit(fullName); lastNameDigit = string_to_keypad_digit(lastName); firstNameDigit = string_to_keypad_digit(firstName); /* add user into DB */ sql = switch_mprintf("insert into directory_search values('%q','%q','%q','%q','%q','%q','%q','%q','%q','%d','%d')", globals.hostname, switch_core_session_get_uuid(session), id, fullName, fullNameDigit, firstName, firstNameDigit, lastName, lastNameDigit, name_visible, exten_visible); if (sqlvalues) { sqltmp = sqlvalues; sqlvalues = switch_mprintf("%s;%s", sqlvalues, sql); switch_safe_free(sqltmp); } else { sqlvalues = sql; sql = NULL; } switch_safe_free(sql); switch_safe_free(fullNameDigit); switch_safe_free(lastNameDigit); switch_safe_free(firstNameDigit); if (++count >= 100) { count = 0; sql = switch_mprintf("BEGIN;%s;COMMIT;", sqlvalues); directory_execute_sql(sql, globals.mutex); switch_safe_free(sql); switch_safe_free(sqlvalues); } } } } } if (sqlvalues) { sql = switch_mprintf("BEGIN;%s;COMMIT;", sqlvalues); directory_execute_sql(sql, globals.mutex); } end: switch_safe_free(sql); switch_safe_free(sqlvalues); switch_event_destroy(&xml_params); switch_xml_free(xml_root); return status; }
static switch_status_t load_config(switch_memory_pool_t *pool) { char *cf = "cdr_csv.conf"; switch_xml_t cfg, xml, settings, param; switch_status_t status = SWITCH_STATUS_SUCCESS; memset(&globals, 0, sizeof(globals)); switch_core_hash_init(&globals.fd_hash, pool); switch_core_hash_init(&globals.template_hash, pool); globals.pool = pool; switch_core_hash_insert(globals.template_hash, "default", default_template); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n"); globals.legs = CDR_LEG_A; if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { 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 (!strcasecmp(var, "debug")) { globals.debug = switch_true(val); } else if (!strcasecmp(var, "legs")) { globals.legs = 0; if (strchr(val, 'a')) { globals.legs |= CDR_LEG_A; } if (strchr(val, 'b')) { globals.legs |= CDR_LEG_B; } } else if (!strcasecmp(var, "log-base")) { globals.log_dir = switch_core_sprintf(pool, "%s%scdr-csv", val, SWITCH_PATH_SEPARATOR); } else if (!strcasecmp(var, "rotate-on-hup")) { globals.rotate = switch_true(val); } else if (!strcasecmp(var, "default-template")) { globals.default_template = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "master-file-only")) { globals.masterfileonly = switch_true(val); } } } if ((settings = switch_xml_child(cfg, "templates"))) { for (param = switch_xml_child(settings, "template"); param; param = param->next) { char *var = (char *) switch_xml_attr(param, "name"); if (var) { char *tpl; size_t len = strlen(param->txt) + 2; if (end_of(param->txt) != '\n') { tpl = switch_core_alloc(pool, len); switch_snprintf(tpl, len, "%s\n", param->txt); } else { tpl = switch_core_strdup(pool, param->txt); } switch_core_hash_insert(globals.template_hash, var, tpl); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding template %s.\n", var); } } } switch_xml_free(xml); } if (zstr(globals.default_template)) { globals.default_template = switch_core_strdup(pool, "default"); } if (!globals.log_dir) { globals.log_dir = switch_core_sprintf(pool, "%s%scdr-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); } return status; }
static switch_status_t do_config(void) { char *cf = "xml_curl.conf"; switch_xml_t cfg, xml, bindings_tag, binding_tag, param; xml_binding_t *binding = NULL; int x = 0; int need_vars_map = 0; switch_hash_t *vars_map = NULL; 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 (!(bindings_tag = switch_xml_child(cfg, "bindings"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <bindings> tag!\n"); goto done; } for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) { char *bname = (char *) switch_xml_attr_soft(binding_tag, "name"); char *url = NULL; char *bind_cred = NULL; char *bind_mask = NULL; char *method = NULL; int disable100continue = 1; int use_dynamic_url = 0, timeout = 0; uint32_t enable_cacert_check = 0; char *ssl_cert_file = NULL; char *ssl_key_file = NULL; char *ssl_key_password = NULL; char *ssl_version = NULL; char *ssl_cacert_file = NULL; uint32_t enable_ssl_verifyhost = 0; char *cookie_file = NULL; hash_node_t *hash_node; int auth_scheme = CURLAUTH_BASIC; need_vars_map = 0; vars_map = NULL; for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "gateway-url")) { bind_mask = (char *) switch_xml_attr_soft(param, "bindings"); if (val) { url = val; } } else if (!strcasecmp(var, "gateway-credentials")) { bind_cred = val; } else if (!strcasecmp(var, "auth-scheme")) { if (*val == '=') { auth_scheme = 0; val++; } if (!strcasecmp(val, "basic")) { auth_scheme |= CURLAUTH_BASIC; } else if (!strcasecmp(val, "digest")) { auth_scheme |= CURLAUTH_DIGEST; } else if (!strcasecmp(val, "NTLM")) { auth_scheme |= CURLAUTH_NTLM; } else if (!strcasecmp(val, "GSS-NEGOTIATE")) { auth_scheme |= CURLAUTH_GSSNEGOTIATE; } else if (!strcasecmp(val, "any")) { auth_scheme = CURLAUTH_ANY; } } else if (!strcasecmp(var, "disable-100-continue") && !switch_true(val)) { disable100continue = 0; } else if (!strcasecmp(var, "method")) { method = val; } else if (!strcasecmp(var, "timeout")) { int tmp = atoi(val); if (tmp >= 0) { timeout = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set a negative timeout!\n"); } } else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) { enable_cacert_check = 1; } else if (!strcasecmp(var, "ssl-cert-path")) { ssl_cert_file = val; } else if (!strcasecmp(var, "ssl-key-path")) { ssl_key_file = val; } else if (!strcasecmp(var, "ssl-key-password")) { ssl_key_password = val; } else if (!strcasecmp(var, "ssl-version")) { ssl_version = val; } else if (!strcasecmp(var, "ssl-cacert-file")) { ssl_cacert_file = val; } else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) { enable_ssl_verifyhost = 1; } else if (!strcasecmp(var, "cookie-file")) { cookie_file = val; } else if (!strcasecmp(var, "use-dynamic-url") && switch_true(val)) { use_dynamic_url = 1; } else if (!strcasecmp(var, "enable-post-var")) { if (!vars_map && need_vars_map == 0) { if (switch_core_hash_init(&vars_map, globals.pool) != SWITCH_STATUS_SUCCESS) { need_vars_map = -1; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't init params hash!\n"); continue; } need_vars_map = 1; } if (vars_map && val) if (switch_core_hash_insert(vars_map, val, ENABLE_PARAM_VALUE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't add %s to params hash!\n", val); } } } if (!url) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Binding has no url!\n"); if (vars_map) switch_core_hash_destroy(&vars_map); continue; } if (!(binding = malloc(sizeof(*binding)))) { if (vars_map) switch_core_hash_destroy(&vars_map); goto done; } memset(binding, 0, sizeof(*binding)); binding->auth_scheme = auth_scheme; binding->timeout = timeout; binding->url = strdup(url); switch_assert(binding->url); if (method != NULL) { binding->method = strdup(method); } else { binding->method = NULL; } if (bind_mask) { binding->bindings = strdup(bind_mask); } if (bind_cred) { binding->cred = strdup(bind_cred); } binding->disable100continue = disable100continue; binding->use_get_style = method != NULL && strcasecmp(method, "post") != 0; binding->use_dynamic_url = use_dynamic_url; binding->enable_cacert_check = enable_cacert_check; if (ssl_cert_file) { binding->ssl_cert_file = strdup(ssl_cert_file); } if (ssl_key_file) { binding->ssl_key_file = strdup(ssl_key_file); } if (ssl_key_password) { binding->ssl_key_password = strdup(ssl_key_password); } if (ssl_version) { binding->ssl_version = strdup(ssl_version); } if (ssl_cacert_file) { binding->ssl_cacert_file = strdup(ssl_cacert_file); } binding->enable_ssl_verifyhost = enable_ssl_verifyhost; if (cookie_file) { binding->cookie_file = strdup(cookie_file); } binding->vars_map = vars_map; if (vars_map) { switch_zmalloc(hash_node, sizeof(hash_node_t)); hash_node->hash = vars_map; hash_node->next = NULL; if (!globals.hash_root) { globals.hash_root = hash_node; globals.hash_tail = globals.hash_root; } else { globals.hash_tail->next = hash_node; globals.hash_tail = globals.hash_tail->next; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n", zstr(bname) ? "N/A" : bname, binding->url, binding->bindings ? binding->bindings : "all"); switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(binding->bindings), binding); x++; binding = NULL; } done: switch_xml_free(xml); return x ? SWITCH_STATUS_SUCCESS : 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; }
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_status_t status = SWITCH_STATUS_FALSE; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || switch_test_flag(tech_pvt, TFLAG_BOWOUT)) { return SWITCH_STATUS_SUCCESS; } switch_mutex_lock(tech_pvt->mutex); if (!switch_test_flag(tech_pvt, TFLAG_BOWOUT) && tech_pvt->other_tech_pvt && switch_test_flag(tech_pvt, TFLAG_BRIDGE) && switch_test_flag(tech_pvt->other_tech_pvt, TFLAG_BRIDGE) && switch_channel_test_flag(tech_pvt->channel, CF_BRIDGED) && switch_channel_test_flag(tech_pvt->other_channel, CF_BRIDGED) && switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED) && switch_channel_test_flag(tech_pvt->other_channel, CF_ANSWERED) && !--tech_pvt->bowout_frame_count <= 0) { const char *a_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE); const char *b_uuid = switch_channel_get_variable(tech_pvt->other_channel, SWITCH_SIGNAL_BOND_VARIABLE); const char *vetoa, *vetob; switch_set_flag_locked(tech_pvt, TFLAG_BOWOUT); switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_BOWOUT); vetoa = switch_channel_get_variable(tech_pvt->channel, "loopback_bowout"); vetob = switch_channel_get_variable(tech_pvt->other_tech_pvt->channel, "loopback_bowout"); if ((!vetoa || switch_true(vetoa)) && (!vetob || switch_true(vetob))) { switch_clear_flag_locked(tech_pvt, TFLAG_WRITE); switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE); if (a_uuid && b_uuid) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s detected bridge on both ends, attempting direct connection.\n", switch_channel_get_name(channel)); /* channel_masquerade eat your heart out....... */ switch_ivr_uuid_bridge(a_uuid, b_uuid); switch_mutex_unlock(tech_pvt->mutex); return SWITCH_STATUS_SUCCESS; } } } if (switch_test_flag(tech_pvt, TFLAG_LINKED) && tech_pvt->other_tech_pvt) { switch_frame_t *clone; if (frame->codec->implementation != tech_pvt->write_codec.implementation) { /* change codecs to match */ tech_init(tech_pvt, session, frame->codec); tech_init(tech_pvt->other_tech_pvt, tech_pvt->other_session, frame->codec); } if (switch_queue_size(tech_pvt->other_tech_pvt->frame_queue) < FRAME_QUEUE_LEN) { if (switch_frame_dup(frame, &clone) != SWITCH_STATUS_SUCCESS) { abort(); } if (switch_queue_trypush(tech_pvt->other_tech_pvt->frame_queue, clone) != SWITCH_STATUS_SUCCESS) { switch_frame_free(&clone); } switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE); } status = SWITCH_STATUS_SUCCESS; } switch_mutex_unlock(tech_pvt->mutex); return status; }
static switch_status_t load_config(switch_memory_pool_t *pool) { char *cf = "cdr_sqlite.conf"; switch_xml_t cfg, xml, settings, param; switch_cache_db_handle_t *dbh = NULL; char *select_sql = NULL, *create_sql = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; memset(&globals, 0, sizeof(globals)); switch_core_hash_init(&globals.template_hash, pool); globals.pool = pool; switch_core_hash_insert(globals.template_hash, "default", default_template); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n"); globals.legs = CDR_LEG_A; if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) { 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 (!strcasecmp(var, "debug")) { globals.debug = switch_true(val); } else if (!strcasecmp(var, "db-name")) { globals.db_name = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "db-table")) { globals.db_table = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "legs")) { globals.legs = 0; if (strchr(val, 'a')) { globals.legs |= CDR_LEG_A; } if (strchr(val, 'b')) { globals.legs |= CDR_LEG_B; } } else if (!strcasecmp(var, "default-template")) { globals.default_template = switch_core_strdup(pool, val); } } } if ((settings = switch_xml_child(cfg, "templates"))) { for (param = switch_xml_child(settings, "template"); param; param = param->next) { char *var = (char *) switch_xml_attr(param, "name"); if (var) { char *tpl; tpl = switch_core_strdup(pool, param->txt); switch_core_hash_insert(globals.template_hash, var, tpl); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding template %s.\n", var); } } } switch_xml_free(xml); } if (zstr(globals.db_name)) { globals.db_name = switch_core_strdup(pool, "cdr"); } if (zstr(globals.db_table)) { globals.db_table = switch_core_strdup(pool, "cdr"); } if (zstr(globals.default_template)) { globals.default_template = switch_core_strdup(pool, "default"); } dbh = cdr_get_db_handle(); if (dbh) { select_sql = switch_mprintf("SELECT * FROM %s LIMIT 1", globals.db_table); assert(select_sql); create_sql = switch_mprintf(default_create_sql, globals.db_table); assert(create_sql); /* Check if table exists (try SELECT FROM ...) and create table if query fails */ switch_cache_db_test_reactive(dbh, select_sql, NULL, create_sql); switch_safe_free(select_sql); switch_safe_free(create_sql); switch_cache_db_release_db_handle(&dbh); } return status; }
/** * Handle fax completion event from FreeSWITCH core * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. */ static void on_execute_complete_event(switch_event_t *event) { const char *application = switch_event_get_header(event, "Application"); if (!zstr(application) && (!strcmp(application, "rxfax") || !strcmp(application, "txfax"))) { int is_rxfax = !strcmp(application, "rxfax"); const char *uuid = switch_event_get_header(event, "Unique-ID"); const char *fax_jid = switch_event_get_header(event, "variable_rayo_fax_jid"); struct rayo_actor *component; if (!zstr(fax_jid) && (component = RAYO_LOCATE(fax_jid))) { iks *result; iks *complete; iks *fax; int have_fax_document = 1; switch_core_session_t *session; switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got result for %s\n", fax_jid); /* clean up channel */ session = switch_core_session_locate(uuid); if (session) { switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); switch_core_session_rwunlock(session); } /* RX only: transfer HTTP document and delete local copy */ if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename); switch_api_execute("http_put", RECEIVEFAX_COMPONENT(component)->filename, NULL, &stream); /* check if successful */ if (!zstr(stream.data) && strncmp(stream.data, "+OK", 3)) { /* PUT failed */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s failed: %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename, (char *)stream.data); have_fax_document = 0; } switch_safe_free(stream.data) switch_file_remove(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)); } /* successful fax? */ if (have_fax_document && switch_true(switch_event_get_header(event, "variable_fax_success"))) { result = rayo_component_create_complete_event(RAYO_COMPONENT(component), FAX_FINISH); } else if (have_fax_document && FAX_COMPONENT(component)->stop) { result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); } else { result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR); } complete = iks_find(result, "complete"); /* RX only: add fax document information */ if (is_rxfax && have_fax_document) { const char *pages = switch_event_get_header(event, "variable_fax_document_transferred_pages"); if (!zstr(pages) && switch_is_number(pages) && atoi(pages) > 0) { const char *resolution = switch_event_get_header(event, "variable_fax_file_image_resolution"); const char *size = switch_event_get_header(event, "variable_fax_image_size"); fax = iks_insert(complete, "fax"); iks_insert_attrib(fax, "xmlns", RAYO_FAX_COMPLETE_NS); if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive) { iks_insert_attrib(fax, "url", RECEIVEFAX_COMPONENT(component)->filename); } else { /* convert absolute path to file:// URI */ iks_insert_attrib_printf(fax, "url", "file://%s", RECEIVEFAX_COMPONENT(component)->filename); } if (!zstr(resolution)) { iks_insert_attrib(fax, "resolution", resolution); } if (!zstr(size)) { iks_insert_attrib(fax, "size", size); } iks_insert_attrib(fax, "pages", pages); } } /* add metadata from event */ insert_fax_metadata(event, "fax_success", complete); insert_fax_metadata(event, "fax_result_code", complete); insert_fax_metadata(event, "fax_result_text", complete); insert_fax_metadata(event, "fax_document_transferred_pages", complete); insert_fax_metadata(event, "fax_document_total_pages", complete); insert_fax_metadata(event, "fax_image_resolution", complete); insert_fax_metadata(event, "fax_image_size", complete); insert_fax_metadata(event, "fax_bad_rows", complete); insert_fax_metadata(event, "fax_transfer_rate", complete); insert_fax_metadata(event, "fax_ecm_used", complete); insert_fax_metadata(event, "fax_local_station_id", complete); insert_fax_metadata(event, "fax_remote_station_id", complete); /* flag faxing as done */ rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0); rayo_component_send_complete_event(RAYO_COMPONENT(component), result); RAYO_UNLOCK(component); } } }