static void *torture_thread(switch_thread_t *thread, void *obj) { int y = 0; int z = 0; switch_core_thread_session_t *ts = obj; switch_event_t *event; z = THREADS++; while (THREADS > 0) { int x; for (x = 0; x < 1; x++) { if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_COOL) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, "event_info", "hello world %d %d", z, y++); switch_event_fire(&event); } } switch_yield(100000); } if (ts->pool) { switch_memory_pool_t *pool = ts->pool; switch_core_destroy_memory_pool(&pool); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Thread Ended\n"); }
SWITCH_DECLARE(int) switch_core_db_exec(switch_core_db_t *db, const char *sql, switch_core_db_callback_func_t callback, void *data, char **errmsg) { int ret = 0; int sane = 300; char *err = NULL; while (--sane > 0) { ret = sqlite3_exec(db, sql, callback, data, &err); if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) { if (sane > 1) { switch_core_db_free(err); switch_yield(100000); continue; } } else { break; } } if (errmsg) { *errmsg = err; } else if (err) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", err); switch_core_db_free(err); err = NULL; } return ret; }
static void launch_read_stream_thread(shout_context_t *context) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; int sanity = 10; size_t used; context->thread_running = 1; switch_threadattr_create(&thd_attr, context->memory_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, context, context->memory_pool); while (context->thread_running && --sanity) { /* at least 1s of audio and up to 5s initialize */ switch_mutex_lock(context->audio_mutex); used = switch_buffer_inuse(context->audio_buffer); switch_mutex_unlock(context->audio_mutex); if (used >= (2 * context->samplerate)) { break; } switch_yield(500000); } }
SWITCH_DECLARE(void) switch_nat_thread_stop(void) { /* don't do anything if no thread ptr */ if (!nat_thread_p) { return; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping NAT Task Thread\n"); if (nat_globals_perm.running == 1) { int sanity = 0; switch_status_t st; nat_globals_perm.running = -1; switch_thread_join(&st, nat_thread_p); while (nat_globals_perm.running) { switch_yield(1000000); /* can take up to 5s for the thread to terminate, so wait for 10 */ if (++sanity > 10) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Timed out waiting for NAT Task Thread to stop\n"); break; } } } nat_thread_p = NULL; }
SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute(switch_core_db_t *db, char *sql, uint32_t retries) { char *errmsg; switch_status_t status = SWITCH_STATUS_FALSE; uint8_t forever = 0; if (!retries) { forever = 1; retries = 1000; } while (retries > 0) { switch_core_db_exec(db, sql, NULL, NULL, &errmsg); if (errmsg) { //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg); switch_core_db_free(errmsg); switch_yield(100000); retries--; if (retries == 0 && forever) { retries = 1000; continue; } } else { status = SWITCH_STATUS_SUCCESS; break; } } return status; }
SWITCH_DECLARE(switch_status_t) switch_core_session_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) { switch_io_event_hook_send_dtmf_t *ptr; switch_status_t status = SWITCH_STATUS_FALSE; switch_dtmf_t new_dtmf; if (switch_channel_down(session->channel)) { return SWITCH_STATUS_FALSE; } switch_assert(dtmf); new_dtmf = *dtmf; if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration); new_dtmf.duration = switch_core_max_dtmf_duration(0); } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration); new_dtmf.duration = switch_core_min_dtmf_duration(0); } else if (!new_dtmf.duration) { new_dtmf.duration = switch_core_default_dtmf_duration(0); } for (ptr = session->event_hooks.send_dtmf; ptr; ptr = ptr->next) { if ((status = ptr->send_dtmf(session, dtmf, SWITCH_DTMF_SEND)) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_SUCCESS; } } if (session->endpoint_interface->io_routines->send_dtmf) { if (dtmf->digit == 'w') { switch_yield(500000); } else if (dtmf->digit == 'W') { switch_yield(1000000); } else { status = session->endpoint_interface->io_routines->send_dtmf(session, &new_dtmf); } } return status; }
static void spool_cdr(const char *path, const char *log_line) { cdr_fd_t *fd = NULL; char *log_line_lf = NULL; unsigned int bytes_in, bytes_out; int loops = 0; if (!(fd = switch_core_hash_find(globals.fd_hash, path))) { fd = switch_core_alloc(globals.pool, sizeof(*fd)); switch_assert(fd); memset(fd, 0, sizeof(*fd)); fd->fd = -1; switch_mutex_init(&fd->mutex, SWITCH_MUTEX_NESTED, globals.pool); fd->path = switch_core_strdup(globals.pool, path); switch_core_hash_insert(globals.fd_hash, path, fd); } if (end_of(log_line) != '\n') { log_line_lf = switch_mprintf("%s\n", log_line); } else { switch_strdup(log_line_lf, log_line); } assert(log_line_lf); switch_mutex_lock(fd->mutex); bytes_out = (unsigned) strlen(log_line_lf); if (fd->fd < 0) { do_reopen(fd); if (fd->fd < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", path); goto end; } } if (fd->bytes + bytes_out > UINT_MAX) { do_rotate(fd); } while ((bytes_in = write(fd->fd, log_line_lf, bytes_out)) != bytes_out && ++loops < 10) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write error to file %s %d/%d\n", path, (int) bytes_in, (int) bytes_out); do_rotate(fd); switch_yield(250000); } if (bytes_in > 0) { fd->bytes += bytes_in; } end: switch_mutex_unlock(fd->mutex); switch_safe_free(log_line_lf); }
static switch_status_t vlc_file_close(switch_file_handle_t *handle) { vlc_file_context_t *context = handle->private_info; int sanity = 0; context->playing = 0; /* The clients need to empty the last of the audio buffer */ while ( switch_buffer_inuse(context->audio_buffer) > 0 ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VLC waiting to close the files: %d \n", (int) switch_buffer_inuse(context->audio_buffer)); switch_yield(500000); if (++sanity > 10) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Giving up waiting for client to empty the audio buffer\n"); break; } } /* Let the clients get the last of the audio stream */ sanity = 0; while ( 3 == libvlc_media_get_state(context->m) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VLC waiting for clients: %d \n", libvlc_media_get_state(context->m)); switch_yield(500000); if (++sanity > 10) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Giving up waiting for client to get the last of the audio stream\n"); break; } } if( context->mp ) libvlc_media_player_stop(context->mp); if( context->m ) libvlc_media_release(context->m); if ( context->inst_out != NULL ) libvlc_release(context->inst_out); return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_trywrlock_timeout(switch_thread_rwlock_t *rwlock, int timeout) { int sanity = timeout * 2; while (sanity) { if (switch_thread_rwlock_trywrlock(rwlock) == SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_SUCCESS; } sanity--; switch_yield(500000); } return SWITCH_STATUS_FALSE; }
static void do_reopen(cdr_fd_t *fd) { int x = 0; if (fd->fd > -1) { close(fd->fd); fd->fd = -1; } for (x = 0; x < 10; x++) { if ((fd->fd = open(fd->path, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)) > -1) { fd->bytes = fd_size(fd->fd); break; } switch_yield(100000); } }
static void switch_core_standard_on_reset(switch_core_session_t *session) { switch_channel_set_variable(session->channel, "call_uuid", switch_core_session_get_uuid(session)); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard RESET\n", switch_channel_get_name(session->channel)); if (switch_channel_test_flag(session->channel, CF_RECOVERING_BRIDGE)) { switch_core_session_t *other_session = NULL; const char *uuid = switch_core_session_get_uuid(session); if (switch_channel_test_flag(session->channel, CF_BRIDGE_ORIGINATOR)) { const char *other_uuid = switch_channel_get_partner_uuid(session->channel); int x = 0; if (other_uuid) { for (x = 0; other_session == NULL && x < 20; x++) { if (!switch_channel_up(session->channel)) { break; } other_session = switch_core_session_locate(other_uuid); switch_yield(100000); } } if (other_session) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); switch_channel_clear_flag(session->channel, CF_BRIDGE_ORIGINATOR); switch_channel_wait_for_state_timeout(other_channel, CS_RESET, 5000); switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 2000, NULL); if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && switch_channel_test_flag(other_channel, CF_PROXY_MODE)) { switch_ivr_signal_bridge(session, other_session); } else { switch_ivr_uuid_bridge(uuid, other_uuid); } switch_core_session_rwunlock(other_session); } } switch_channel_clear_flag(session->channel, CF_RECOVERING_BRIDGE); } }
SWITCH_DECLARE(void) switch_scheduler_task_thread_stop(void) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping Task Thread\n"); if (globals.task_thread_running == 1) { int sanity = 0; switch_status_t st; globals.task_thread_running = -1; switch_thread_join(&st, task_thread_p); while (globals.task_thread_running) { switch_yield(100000); if (++sanity > 10) { break; } } } }
/* This callback caches the audio in the buffer */ static swift_result_t write_audio(swift_event * event, swift_event_t type, void *udata) { cepstral_t *cepstral; swift_event_t rv = SWIFT_SUCCESS; void *buf = NULL; int len = 0, i = 0; cepstral = udata; assert(cepstral != NULL); if (!cepstral->port || cepstral->done || cepstral->done_gen) { return SWIFT_UNKNOWN_ERROR; } /* Only proceed when we have success */ if (!SWIFT_FAILED((rv = swift_event_get_audio(event, &buf, &len)))) { while (!cepstral->done) { switch_mutex_lock(cepstral->audio_lock); if (switch_buffer_write(cepstral->audio_buffer, buf, len) > 0) { switch_mutex_unlock(cepstral->audio_lock); break; } switch_mutex_unlock(cepstral->audio_lock); if (!cepstral->done) { for (i = 0; i < 10; i++) { switch_yield(10000); if (cepstral->done) { break; } } } } } else { cepstral->done = 1; } if (cepstral->done) { rv = SWIFT_UNKNOWN_ERROR; } return rv; }
static void deactivate_modems(void) { int max = globals.SOFT_MAX_MODEMS; int x; switch_mutex_lock(globals.mutex); for(x = 0; x < max; x++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Stopping Modem SLOT %d\n", x); modem_close(&globals.MODEM_POOL[x]); } switch_mutex_unlock(globals.mutex); /* Wait for Threads to die */ while (globals.THREADCOUNT) { switch_yield(100000); } }
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { crtp_private_t *tech_pvt; switch_channel_t *channel; switch_status_t status; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); if (!tech_pvt->rtp_session || tech_pvt->mode == RTP_SENDONLY) { switch_yield(20000); /* replace by local timer XXX */ goto cng; } if (switch_rtp_has_dtmf(tech_pvt->rtp_session)) { switch_dtmf_t dtmf = { 0 }; switch_rtp_dequeue_dtmf(tech_pvt->rtp_session, &dtmf); switch_channel_queue_dtmf(channel, &dtmf); } tech_pvt->read_frame.flags = SFF_NONE; tech_pvt->read_frame.codec = &tech_pvt->read_codec; status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags); if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { goto cng; } *frame = &tech_pvt->read_frame; return SWITCH_STATUS_SUCCESS; cng: *frame = &tech_pvt->read_frame; tech_pvt->read_frame.codec = &tech_pvt->read_codec; tech_pvt->read_frame.flags |= SFF_CNG; tech_pvt->read_frame.datalen = 0; return SWITCH_STATUS_SUCCESS; }
static void *SWITCH_THREAD_FUNC switch_scheduler_task_thread(switch_thread_t *thread, void *obj) { globals.task_thread_running = 1; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Starting task thread\n"); while (globals.task_thread_running == 1) { if (task_thread_loop(0)) { break; } switch_yield(500000); } task_thread_loop(1); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Task thread ending\n"); globals.task_thread_running = 0; return NULL; }
void *SWITCH_THREAD_FUNC monitor_thread_run(switch_thread_t *thread, void *obj) { xml_binding_t *binding = (xml_binding_t *) obj; time_t st; int diff; while(globals.running) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Running server command: %s\n", binding->server); st = switch_epoch_time_now(NULL); switch_system(binding->server, SWITCH_TRUE); diff = (int) switch_epoch_time_now(NULL) - st; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Server command complete: %s\n", binding->server); if (globals.running && diff < 5) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Server command had short run duration, sleeping: %s\n", binding->server); switch_yield(10000000); } } return NULL; }
static void launch_write_stream_thread(shout_context_t *context) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; int sanity = 10; if (context->err) { return; } context->thread_running = 1; switch_threadattr_create(&thd_attr, context->memory_pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, write_stream_thread, context, context->memory_pool); while (context->thread_running && context->thread_running != 2) { switch_yield(100000); if (!--sanity) break; } }
SWITCH_DECLARE(switch_status_t) switch_socket_send(switch_socket_t *sock, const char *buf, switch_size_t *len) { switch_status_t status = SWITCH_STATUS_SUCCESS; switch_size_t req = *len, wrote = 0, need = *len; int to_count = 0; while ((wrote < req && status == SWITCH_STATUS_SUCCESS) || (need == 0 && status == SWITCH_STATUS_BREAK) || status == 730035) { need = req - wrote; status = apr_socket_send(sock, buf + wrote, &need); if (status == SWITCH_STATUS_BREAK || status == 730035) { if (++to_count > 10000000) { status = SWITCH_STATUS_FALSE; break; } switch_yield(10000); } else { to_count = 0; } wrote += need; } *len = wrote; return status; }
static switch_status_t do_reopen(cdr_fd_t *fd) { int x = 0; switch_status_t status = SWITCH_STATUS_FALSE; if(fd == NULL || fd->path == NULL){ return SWITCH_STATUS_FALSE; } //if (fd->fd > -1) { do_close(fd); fd->fd = NULL; for (x = 0; x < 10; x++) { //if ((fd->fd = open(fd->path, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)) > -1) { if(do_open(fd) == SWITCH_STATUS_SUCCESS && fd->fd != NULL){ fd->bytes = switch_file_get_size(fd->fd);//fd_size(fd->fd); status = SWITCH_STATUS_SUCCESS; break; } switch_yield(100000); } return status; }
SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { switch_io_event_hook_read_frame_t *ptr; switch_status_t status = SWITCH_STATUS_FALSE; int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0; switch_codec_implementation_t codec_impl; unsigned int flag = 0; switch_assert(session != NULL); if (switch_mutex_trylock(session->codec_read_mutex) == SWITCH_STATUS_SUCCESS) { switch_mutex_unlock(session->codec_read_mutex); } else { switch_cond_next(); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_SUCCESS; } if (!(session->read_codec && session->read_codec->implementation && switch_core_codec_ready(session->read_codec))) { if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_get_state(session->channel) == CS_HIBERNATE) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s reading on a session with no media!\n", switch_channel_get_name(session->channel)); switch_cond_next(); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_SUCCESS; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->codec_read_mutex); if (!switch_core_codec_ready(session->read_codec)) { switch_mutex_unlock(session->codec_read_mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->read_codec->mutex); top: if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { switch_ivr_dmachine_ping(session->dmachine, NULL); } if (switch_channel_down(session->channel) || !switch_core_codec_ready(session->read_codec)) { *frame = NULL; status = SWITCH_STATUS_FALSE; goto even_more_done; } status = SWITCH_STATUS_FALSE; need_codec = perfect = 0; *frame = NULL; if (session->read_codec && !session->track_id && session->track_duration) { if (session->read_frame_count == 0) { switch_event_t *event; session->read_frame_count = (session->read_impl.actual_samples_per_second / session->read_impl.samples_per_packet) * session->track_duration; switch_event_create(&event, SWITCH_EVENT_SESSION_HEARTBEAT); switch_channel_event_set_data(session->channel, event); switch_event_fire(&event); } else { session->read_frame_count--; } } if (switch_channel_test_flag(session->channel, CF_HOLD)) { switch_yield(session->read_impl.microseconds_per_packet); status = SWITCH_STATUS_BREAK; goto even_more_done; } if (session->endpoint_interface->io_routines->read_frame) { switch_mutex_unlock(session->read_codec->mutex); switch_mutex_unlock(session->codec_read_mutex); if ((status = session->endpoint_interface->io_routines->read_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { for (ptr = session->event_hooks.read_frame; ptr; ptr = ptr->next) { if ((status = ptr->read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) { break; } } } if (!SWITCH_READ_ACCEPTABLE(status) || !session->read_codec || !switch_core_codec_ready(session->read_codec)) { *frame = NULL; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->codec_read_mutex); if (!switch_core_codec_ready(session->read_codec)) { switch_mutex_unlock(session->codec_read_mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_FALSE; } switch_mutex_lock(session->read_codec->mutex); if (!switch_core_codec_ready(session->read_codec)) { *frame = NULL; status = SWITCH_STATUS_FALSE; goto even_more_done; } } if (status != SWITCH_STATUS_SUCCESS) { goto done; } if (!(*frame)) { goto done; } switch_assert(*frame != NULL); if (switch_test_flag(*frame, SFF_PROXY_PACKET)) { /* Fast PASS! */ status = SWITCH_STATUS_SUCCESS; goto done; } if (switch_test_flag(*frame, SFF_CNG)) { status = SWITCH_STATUS_SUCCESS; if (!session->bugs && !session->plc) { goto done; } is_cng = 1; } switch_assert((*frame)->codec != NULL); if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) { status = SWITCH_STATUS_FALSE; goto done; } codec_impl = *(*frame)->codec->implementation; if (session->read_codec->implementation->impl_id != codec_impl.impl_id) { need_codec = TRUE; } if (codec_impl.actual_samples_per_second != session->read_impl.actual_samples_per_second) { do_resample = 1; } if (session->bugs && !need_codec) { do_bugs = 1; need_codec = 1; } if (switch_test_flag(session, SSF_READ_TRANSCODE) && !need_codec && switch_core_codec_ready(session->read_codec)) { switch_core_session_t *other_session; const char *uuid = switch_channel_get_variable(switch_core_session_get_channel(session), SWITCH_SIGNAL_BOND_VARIABLE); switch_clear_flag(session, SSF_READ_TRANSCODE); if (uuid && (other_session = switch_core_session_locate(uuid))) { switch_set_flag(other_session, SSF_READ_CODEC_RESET); switch_set_flag(other_session, SSF_READ_CODEC_RESET); switch_set_flag(other_session, SSF_WRITE_CODEC_RESET); switch_core_session_rwunlock(other_session); } } if (switch_test_flag(session, SSF_READ_CODEC_RESET)) { switch_core_codec_reset(session->read_codec); switch_clear_flag(session, SSF_READ_CODEC_RESET); } if (status == SWITCH_STATUS_SUCCESS && need_codec) { switch_frame_t *enc_frame, *read_frame = *frame; switch_set_flag(session, SSF_READ_TRANSCODE); if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) { switch_core_session_message_t msg = { 0 }; msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY; switch_core_session_receive_message(session, &msg); switch_set_flag(session, SSF_WARN_TRANSCODE); } if (read_frame->codec || is_cng) { session->raw_read_frame.datalen = session->raw_read_frame.buflen; if (is_cng) { if (session->plc) { plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2); is_cng = 0; flag &= !SFF_CNG; } else { memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); } session->raw_read_frame.timestamp = 0; session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; } else { switch_codec_t *use_codec = read_frame->codec; if (do_bugs) { switch_thread_rwlock_wrlock(session->bug_rwlock); if (!session->bugs) { do_bugs = 0; switch_thread_rwlock_unlock(session->bug_rwlock); goto done; } if (!switch_core_codec_ready(&session->bug_codec)) { switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL); } use_codec = &session->bug_codec; switch_thread_rwlock_unlock(session->bug_rwlock); switch_thread_rwlock_wrlock(session->bug_rwlock); if (!session->bugs) { do_bugs = 0; } switch_thread_rwlock_unlock(session->bug_rwlock); if (!do_bugs) goto done; } if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen); status = SWITCH_STATUS_SUCCESS; } else { status = switch_core_codec_decode(use_codec, session->read_codec, read_frame->data, read_frame->datalen, session->read_impl.actual_samples_per_second, session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, &read_frame->flags); } if (status == SWITCH_STATUS_SUCCESS) { if ((switch_channel_test_flag(session->channel, CF_JITTERBUFFER) || switch_channel_test_flag(session->channel, CF_CNG_PLC)) && !session->plc) { session->plc = plc_init(NULL); } if (session->plc) { if (switch_test_flag(read_frame, SFF_PLC)) { plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); switch_clear_flag(read_frame, SFF_PLC); } else { plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); } } } } if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) { status = SWITCH_STATUS_RESAMPLE; } switch (status) { case SWITCH_STATUS_RESAMPLE: if (!session->read_resampler) { switch_mutex_lock(session->resample_mutex); status = switch_resample_create(&session->read_resampler, read_frame->codec->implementation->actual_samples_per_second, session->read_impl.actual_samples_per_second, session->read_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, 1); switch_mutex_unlock(session->resample_mutex); if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n"); status = SWITCH_STATUS_FALSE; goto done; } } case SWITCH_STATUS_SUCCESS: session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); session->raw_read_frame.rate = read_frame->rate; if (read_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) { session->raw_read_frame.timestamp = 0; } else { session->raw_read_frame.timestamp = read_frame->timestamp; } session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; session->raw_read_frame.flags = 0; if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.flags |= SFF_PLC; } read_frame = &session->raw_read_frame; break; case SWITCH_STATUS_NOOP: if (session->read_resampler) { switch_mutex_lock(session->resample_mutex); switch_resample_destroy(&session->read_resampler); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n"); switch_mutex_unlock(session->resample_mutex); } status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_BREAK: memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); session->raw_read_frame.timestamp = read_frame->timestamp; session->raw_read_frame.rate = read_frame->rate; session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; session->raw_read_frame.flags = 0; if (switch_test_flag(read_frame, SFF_PLC)) { session->raw_read_frame.flags |= SFF_PLC; } read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); goto done; default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n", session->read_codec->codec_interface->interface_name); goto done; } } if (session->bugs) { switch_media_bug_t *bp; switch_bool_t ok = SWITCH_TRUE; int prune = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { continue; } if (switch_test_flag(bp, SMBF_PRUNE)) { prune++; continue; } if (bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) { switch_mutex_lock(bp->read_mutex); switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen); if (bp->callback) { ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ); } switch_mutex_unlock(bp->read_mutex); } if (ok && switch_test_flag(bp, SMBF_READ_REPLACE)) { do_bugs = 0; if (bp->callback) { bp->read_replace_frame_in = read_frame; bp->read_replace_frame_out = read_frame; if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) { read_frame = bp->read_replace_frame_out; } } } if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) { switch_set_flag(bp, SMBF_PRUNE); prune++; } } switch_thread_rwlock_unlock(session->bug_rwlock); if (prune) { switch_core_media_bug_prune(session); } } if (do_bugs) { goto done; } if (session->read_codec) { if (session->read_resampler) { short *data = read_frame->data; switch_mutex_lock(session->resample_mutex); switch_resample_process(session->read_resampler, data, (int) read_frame->datalen / 2); memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2); read_frame->samples = session->read_resampler->to_len; read_frame->datalen = session->read_resampler->to_len * 2; read_frame->rate = session->read_resampler->to_rate; switch_mutex_unlock(session->resample_mutex); } if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) { perfect = TRUE; } else { if (!session->raw_read_buffer) { switch_size_t bytes = session->read_impl.decoded_bytes_per_packet; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes vs %u\n", (uint32_t) bytes, (uint32_t) (*frame)->datalen); switch_buffer_create_dynamic(&session->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, 0); } if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) { status = SWITCH_STATUS_MEMERR; goto done; } } if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) { if (perfect) { enc_frame = read_frame; session->raw_read_frame.rate = read_frame->rate; } else { session->raw_read_frame.datalen = (uint32_t) switch_buffer_read(session->raw_read_buffer, session->raw_read_frame.data, session->read_impl.decoded_bytes_per_packet); session->raw_read_frame.rate = session->read_impl.actual_samples_per_second; enc_frame = &session->raw_read_frame; } session->enc_read_frame.datalen = session->enc_read_frame.buflen; switch_assert(session->read_codec != NULL); switch_assert(enc_frame != NULL); switch_assert(enc_frame->data != NULL); status = switch_core_codec_encode(session->read_codec, enc_frame->codec, enc_frame->data, enc_frame->datalen, session->read_impl.actual_samples_per_second, session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag); switch (status) { case SWITCH_STATUS_RESAMPLE: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 1\n"); case SWITCH_STATUS_SUCCESS: session->enc_read_frame.samples = session->read_impl.decoded_bytes_per_packet / sizeof(int16_t); if (perfect) { if (enc_frame->codec->implementation->samples_per_packet != session->read_impl.samples_per_packet) { session->enc_read_frame.timestamp = 0; } else { session->enc_read_frame.timestamp = read_frame->timestamp; } session->enc_read_frame.rate = read_frame->rate; session->enc_read_frame.ssrc = read_frame->ssrc; session->enc_read_frame.seq = read_frame->seq; session->enc_read_frame.m = read_frame->m; session->enc_read_frame.payload = session->read_impl.ianacode; } *frame = &session->enc_read_frame; break; case SWITCH_STATUS_NOOP: session->raw_read_frame.samples = enc_frame->codec->implementation->samples_per_packet; session->raw_read_frame.timestamp = read_frame->timestamp; session->raw_read_frame.payload = enc_frame->codec->implementation->ianacode; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.ssrc = read_frame->ssrc; session->raw_read_frame.seq = read_frame->seq; *frame = enc_frame; status = SWITCH_STATUS_SUCCESS; break; case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n"); *frame = NULL; status = SWITCH_STATUS_GENERR; break; default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n", session->read_codec->codec_interface->interface_name); *frame = NULL; status = SWITCH_STATUS_GENERR; break; } } else { goto top; } } } done: if (!(*frame)) { status = SWITCH_STATUS_FALSE; } else { if (flag & SFF_CNG) { switch_set_flag((*frame), SFF_CNG); } if (session->bugs) { switch_media_bug_t *bp; switch_bool_t ok = SWITCH_TRUE; int prune = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) { continue; } if (switch_test_flag(bp, SMBF_PRUNE)) { prune++; continue; } if (bp->ready && switch_test_flag(bp, SMBF_READ_PING)) { switch_mutex_lock(bp->read_mutex); if (bp->callback) { if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_PING) == SWITCH_FALSE || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) { ok = SWITCH_FALSE; } } switch_mutex_unlock(bp->read_mutex); } if (ok == SWITCH_FALSE) { switch_set_flag(bp, SMBF_PRUNE); prune++; } } switch_thread_rwlock_unlock(session->bug_rwlock); if (prune) { switch_core_media_bug_prune(session); } } } even_more_done: if (!*frame || !(*frame)->codec || !(*frame)->codec->implementation || !switch_core_codec_ready((*frame)->codec)) { *frame = &runtime.dummy_cng_frame; } switch_mutex_unlock(session->read_codec->mutex); switch_mutex_unlock(session->codec_read_mutex); return status; }
static int db_is_up(switch_pgsql_handle_t *handle) { int ret = 0; switch_event_t *event; char *err_str = NULL; int max_tries = DEFAULT_PGSQL_RETRIES; int code = 0, recon = 0; if (handle) { max_tries = handle->num_retries; if (max_tries < 1) max_tries = DEFAULT_PGSQL_RETRIES; } top: if (!handle) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n"); goto done; } if (!handle->con) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Connection\n"); goto done; } /* Try a non-blocking read on the connection to gobble up any EOF from a closed connection and mark the connection BAD if it is closed. */ PQconsumeInput(handle->con); if (PQstatus(handle->con) == CONNECTION_BAD) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PQstatus returned bad connection; reconnecting...\n"); handle->state = SWITCH_PGSQL_STATE_ERROR; PQreset(handle->con); if (PQstatus(handle->con) == CONNECTION_BAD) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PQstatus returned bad connection -- reconnection failed!\n"); goto error; } handle->state = SWITCH_PGSQL_STATE_CONNECTED; handle->sock = PQsocket(handle->con); } /* if (!PQsendQuery(handle->con, "SELECT 1")) { code = __LINE__; goto error; } if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { code = __LINE__; goto error; } if (!result || result->status != PGRES_COMMAND_OK) { code = __LINE__; goto error; } switch_pgsql_free_result(&result); switch_pgsql_finish_results(handle); */ ret = 1; goto done; error: err_str = switch_pgsql_handle_get_error(handle); if (PQstatus(handle->con) == CONNECTION_BAD) { handle->state = SWITCH_PGSQL_STATE_ERROR; PQreset(handle->con); if (PQstatus(handle->con) == CONNECTION_OK) { handle->state = SWITCH_PGSQL_STATE_CONNECTED; recon = SWITCH_PGSQL_SUCCESS; handle->sock = PQsocket(handle->con); } } max_tries--; if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Failure-Message", "The sql server is not responding for DSN %s [%s][%d]", switch_str_nil(handle->dsn), switch_str_nil(err_str), code); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The sql server is not responding for DSN %s [%s][%d]\n", switch_str_nil(handle->dsn), switch_str_nil(err_str), code); if (recon == SWITCH_PGSQL_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection has been re-established"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "The connection has been re-established\n"); } else { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection could not be re-established"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The connection could not be re-established\n"); } if (!max_tries) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "Giving up!"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up!\n"); } switch_event_fire(&event); } if (!max_tries) { goto done; } switch_safe_free(err_str); switch_yield(1000000); goto top; done: switch_safe_free(err_str); return ret; }
static void *SWITCH_THREAD_FUNC write_stream_thread(switch_thread_t *thread, void *obj) { shout_context_t *context = (shout_context_t *) obj; switch_thread_rwlock_rdlock(context->rwlock); if (context->thread_running) { context->thread_running++; } else { switch_thread_rwlock_unlock(context->rwlock); return NULL; } if (!context->lame_ready) { lame_init_params(context->gfp); lame_print_config(context->gfp); context->lame_ready = 1; } while (!context->err && context->thread_running) { unsigned char mp3buf[8192] = ""; int16_t audio[9600] = { 0 }; switch_size_t audio_read = 0; int rlen = 0; long ret = 0; switch_mutex_lock(context->audio_mutex); if (context->audio_buffer) { audio_read = switch_buffer_read(context->audio_buffer, audio, sizeof(audio)); } else { context->err++; } switch_mutex_unlock(context->audio_mutex); error_check(); if (!audio_read) { audio_read = sizeof(audio); memset(audio, 255, sizeof(audio)); } if (context->channels == 2) { int16_t l[4800] = { 0 }; int16_t r[4800] = { 0 }; int j = 0; switch_size_t i; for (i = 0; i < audio_read / 4; i++) { l[i] = audio[j++]; r[i] = audio[j++]; } if ((rlen = lame_encode_buffer(context->gfp, l, r, audio_read / 4, mp3buf, sizeof(mp3buf))) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); goto error; } } else if (context->channels == 1) { if ((rlen = lame_encode_buffer(context->gfp, (void *) audio, NULL, audio_read / sizeof(int16_t), mp3buf, sizeof(mp3buf))) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); goto error; } } if (rlen) { ret = shout_send(context->shout, mp3buf, rlen); if (ret != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Send error: %s\n", shout_get_error(context->shout)); goto error; } } else { memset(mp3buf, 0, 128); ret = shout_send(context->shout, mp3buf, 128); } shout_sync(context->shout); switch_yield(100000); } error: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write Thread Done\n"); switch_thread_rwlock_unlock(context->rwlock); context->thread_running = 0; return NULL; }
static inline void free_context(shout_context_t *context) { int ret; if (context) { switch_mutex_lock(context->audio_mutex); context->err++; switch_mutex_unlock(context->audio_mutex); if (context->stream_url) { int sanity = 0; while (context->thread_running) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for stream to terminate: %s\n", context->stream_url); switch_yield(500000); if (++sanity > 10) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up waiting for stream to terminate: %s\n", context->stream_url); break; } } } switch_thread_rwlock_wrlock(context->rwlock); if (context->mh) { mpg123_close(context->mh); mpg123_delete(context->mh); } if (context->fp) { unsigned char mp3buffer[8192]; int len; int16_t blank[2048] = { 0 }, *r = NULL; if (context->channels == 2) { r = blank; } len = lame_encode_buffer(context->gfp, blank, r, sizeof(blank) / 2, mp3buffer, sizeof(mp3buffer)); if (len) { ret = fwrite(mp3buffer, 1, len, context->fp); } while ((len = lame_encode_flush(context->gfp, mp3buffer, sizeof(mp3buffer))) > 0) { ret = fwrite(mp3buffer, 1, len, context->fp); if (ret < 0) { break; } } lame_mp3_tags_fid(context->gfp, context->fp); fclose(context->fp); context->fp = NULL; } if (context->shout) { shout_close(context->shout); context->shout = NULL; } if (context->gfp) { lame_close(context->gfp); context->gfp = NULL; } if (context->audio_buffer) { switch_buffer_destroy(&context->audio_buffer); } switch_mutex_destroy(context->audio_mutex); switch_thread_rwlock_unlock(context->rwlock); switch_thread_rwlock_destroy(context->rwlock); } }
static size_t stream_callback(void *ptr, size_t size, size_t nmemb, void *data) { register unsigned int realsize = (unsigned int) (size * nmemb); shout_context_t *context = data; int decode_status = 0; size_t usedlen; uint32_t used, buf_size = 1024 * 128; /* do not make this 64 or less, stutter will ensue after first 64k buffer is dry */ if (context->prebuf) { buf_size = context->prebuf; } /* make sure we aren't over zealous by slowing down the stream when the buffer is too full */ while (!context->err) { switch_mutex_lock(context->audio_mutex); used = switch_buffer_inuse(context->audio_buffer); switch_mutex_unlock(context->audio_mutex); if (used < buf_size) { /* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Buffered %u/%u!\n", used, buf_size); */ break; } switch_yield(500000); } if (mpg123_feed(context->mh, ptr, realsize) != MPG123_OK) { goto error; } do { usedlen = 0; decode_status = mpg123_read(context->mh, context->decode_buf, sizeof(context->decode_buf), &usedlen); if (decode_status == MPG123_NEW_FORMAT) { continue; } else if (decode_status == MPG123_OK || decode_status == MPG123_NEED_MORE) { ; } else if (decode_status == MPG123_DONE) { context->eof++; } else if (decode_status == MPG123_ERR || decode_status > 0) { if (++context->mp3err >= 5) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error! %s\n", context->stream_url); context->eof++; goto error; } continue; } context->mp3err = 0; switch_mutex_lock(context->audio_mutex); switch_buffer_write(context->audio_buffer, context->decode_buf, usedlen); switch_mutex_unlock(context->audio_mutex); } while (!context->err && !context->eof && decode_status != MPG123_NEED_MORE); if (context->err) { goto error; } return realsize; error: switch_mutex_lock(context->audio_mutex); context->err++; switch_mutex_unlock(context->audio_mutex); return 0; }
void do_broadcast(switch_stream_handle_t *stream) { char *path_info = switch_event_get_header(stream->param_event, "http-path-info"); char *file; lame_global_flags *gfp = NULL; switch_file_handle_t fh = { 0 }; unsigned char mp3buf[TC_BUFFER_SIZE] = ""; uint8_t buf[1024]; int rlen; int is_local = 0; uint32_t interval = 20000; if (strstr(path_info + 7, "://")) { file = strdup(path_info + 7); is_local++; } else { file = switch_mprintf("%s/streamfiles/%s", SWITCH_GLOBAL_dirs.base_dir, path_info + 7); } assert(file); if (switch_core_file_open(&fh, file, 0, 0, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { memset(&fh, 0, sizeof(fh)); stream->write_function(stream, "Content-type: text/html\r\n\r\n<h2>File not found</h2>\n"); goto end; } if (switch_test_flag((&fh), SWITCH_FILE_NATIVE)) { stream->write_function(stream, "Content-type: text/html\r\n\r\n<h2>File format not supported</h2>\n"); goto end; } if (!(gfp = lame_init())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate lame\n"); goto end; } lame_set_num_channels(gfp, fh.channels); lame_set_in_samplerate(gfp, fh.samplerate); lame_set_brate(gfp, 16 * (fh.samplerate / 8000) * fh.channels); lame_set_mode(gfp, 3); lame_set_quality(gfp, 2); lame_set_errorf(gfp, log_error); lame_set_debugf(gfp, log_debug); lame_set_msgf(gfp, log_msg); lame_set_bWriteVbrTag(gfp, 0); lame_mp3_tags_fid(gfp, NULL); lame_init_params(gfp); lame_print_config(gfp); stream->write_function(stream, "Content-type: audio/mpeg\r\n" "Content-Disposition: inline; filename=\"%s.mp3\"\r\n\r\n", path_info + 7); if (fh.interval) { interval = fh.interval * 1000; } for (;;) { switch_size_t samples = sizeof(buf) / 2; switch_core_file_read(&fh, buf, &samples); if (is_local) { switch_yield(interval); } if (!samples) { break; } if ((rlen = lame_encode_buffer(gfp, (void *) buf, NULL, samples, mp3buf, sizeof(mp3buf))) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); goto end; } if (rlen) { if (stream->raw_write_function(stream, mp3buf, rlen)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Disconnected\n"); goto end; } } } while ((rlen = lame_encode_flush(gfp, mp3buf, sizeof(mp3buf))) > 0) { if (stream->raw_write_function(stream, mp3buf, rlen)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Disconnected\n"); goto end; } } end: if (fh.channels) { switch_core_file_close(&fh); } switch_safe_free(file); if (gfp) { lame_close(gfp); gfp = NULL; } }
SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute_trans(switch_core_db_t *db, char *sql, uint32_t retries) { char *errmsg; switch_status_t status = SWITCH_STATUS_FALSE; uint8_t forever = 0; unsigned begin_retries = 100; uint8_t again = 0; if (!retries) { forever = 1; retries = 1000; } again: while (begin_retries > 0) { again = 0; switch_core_db_exec(db, "BEGIN", NULL, NULL, &errmsg); if (errmsg) { begin_retries--; if (strstr(errmsg, "cannot start a transaction within a transaction")) { again = 1; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL Retry [%s]\n", errmsg); } switch_core_db_free(errmsg); errmsg = NULL; if (again) { switch_core_db_exec(db, "COMMIT", NULL, NULL, NULL); goto again; } switch_yield(100000); if (begin_retries == 0) { goto done; } } else { break; } } while (retries > 0) { switch_core_db_exec(db, sql, NULL, NULL, &errmsg); if (errmsg) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg); switch_core_db_free(errmsg); errmsg = NULL; switch_yield(100000); retries--; if (retries == 0 && forever) { retries = 1000; continue; } } else { status = SWITCH_STATUS_SUCCESS; break; } } done: switch_core_db_exec(db, "COMMIT", NULL, NULL, NULL); return status; }
SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) { switch_channel_state_t state = CS_NEW, midstate = CS_DESTROY, endstate; 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 silly = 0; uint32_t new_loops = 500; /* Life of the channel. you have channel and pool in your session everywhere you go you use the session to malloc with switch_core_session_alloc(session, <size>) The endpoint module gets the first crack at implementing the state if it wants to, it can cancel the default behavior by returning SWITCH_STATUS_FALSE Next comes the channel's event handler table that can be set by an application which also can veto the next behavior in line by returning SWITCH_STATUS_FALSE Finally the default state behavior is called. */ switch_assert(session != NULL); switch_set_flag(session, SSF_THREAD_RUNNING); endpoint_interface = session->endpoint_interface; switch_assert(endpoint_interface != NULL); driver_state_handler = endpoint_interface->state_handler; switch_assert(driver_state_handler != NULL); switch_mutex_lock(session->mutex); while ((state = switch_channel_get_state(session->channel)) != CS_DESTROY) { if (switch_channel_test_flag(session->channel, CF_BLOCK_STATE)) { switch_channel_wait_for_flag(session->channel, CF_BLOCK_STATE, SWITCH_FALSE, 0, NULL); if ((state = switch_channel_get_state(session->channel)) == CS_DESTROY) { break; } } midstate = state; if (state != switch_channel_get_running_state(session->channel) || state >= CS_HANGUP) { int index = 0; int proceed = 1; int global_proceed = 1; int do_extra_handlers = 1; switch_io_event_hook_state_run_t *ptr; switch_status_t rstatus = SWITCH_STATUS_SUCCESS; switch_channel_set_running_state(session->channel, state); switch_channel_clear_flag(session->channel, CF_TRANSFER); switch_channel_clear_flag(session->channel, CF_REDIRECT); if (session->endpoint_interface->io_routines->state_run) { rstatus = session->endpoint_interface->io_routines->state_run(session); } if (rstatus == SWITCH_STATUS_SUCCESS) { for (ptr = session->event_hooks.state_run; ptr; ptr = ptr->next) { if ((rstatus = ptr->state_run(session)) != SWITCH_STATUS_SUCCESS) { break; } } } switch (state) { case CS_NEW: /* Just created, Waiting for first instructions */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel)); break; case CS_DESTROY: goto done; case CS_REPORTING: /* Call Detail */ { switch_core_session_reporting_state(session); switch_channel_set_state(session->channel, CS_DESTROY); } goto done; case CS_HANGUP: /* Deactivate and end the thread */ { switch_core_session_hangup_state(session, SWITCH_TRUE); switch_channel_set_state(session->channel, CS_REPORTING); } break; case CS_INIT: /* Basic setup tasks */ { switch_event_t *event; STATE_MACRO(init, "INIT"); if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_CREATE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(session->channel, event); switch_event_fire(&event); } if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_ORIGINATE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(session->channel, event); switch_event_fire(&event); } } } break; case CS_ROUTING: /* Look for a dialplan and find something to do */ STATE_MACRO(routing, "ROUTING"); break; case CS_RESET: /* Reset */ STATE_MACRO(reset, "RESET"); break; /* These other states are intended for prolonged durations so we do not signal lock for them */ case CS_EXECUTE: /* Execute an Operation */ STATE_MACRO(execute, "EXECUTE"); break; case CS_EXCHANGE_MEDIA: /* loop all data back to source */ STATE_MACRO(exchange_media, "EXCHANGE_MEDIA"); break; case CS_SOFT_EXECUTE: /* send/recieve data to/from another channel */ STATE_MACRO(soft_execute, "SOFT_EXECUTE"); break; case CS_PARK: /* wait in limbo */ STATE_MACRO(park, "PARK"); break; case CS_CONSUME_MEDIA: /* wait in limbo */ STATE_MACRO(consume_media, "CONSUME_MEDIA"); break; case CS_HIBERNATE: /* sleep */ STATE_MACRO(hibernate, "HIBERNATE"); break; case CS_NONE: abort(); break; } check_presence(session); if (midstate == CS_DESTROY) { break; } } endstate = switch_channel_get_state(session->channel); if (endstate == switch_channel_get_running_state(session->channel)) { if (endstate == CS_NEW) { switch_yield(20000); switch_ivr_parse_all_events(session); if (!--new_loops) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s %s Abandoned\n", session->uuid_str, switch_core_session_get_name(session)); switch_channel_set_flag(session->channel, CF_NO_CDR); switch_channel_hangup(session->channel, SWITCH_CAUSE_WRONG_CALL_STATE); } } else { switch_ivr_parse_all_events(session); switch_ivr_parse_all_events(session); if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { switch_channel_state_thread_lock(session->channel); switch_channel_set_flag(session->channel, CF_THREAD_SLEEPING); if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { switch_ivr_parse_all_events(session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s session thread sleep state: %s!\n", switch_channel_get_name(session->channel), switch_channel_state_name(switch_channel_get_running_state(session->channel))); switch_thread_cond_wait(session->cond, session->mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s session thread wake state: %s!\n", switch_channel_get_name(session->channel), switch_channel_state_name(switch_channel_get_running_state(session->channel))); } switch_channel_clear_flag(session->channel, CF_THREAD_SLEEPING); switch_channel_state_thread_unlock(session->channel); } switch_ivr_parse_all_events(session); switch_ivr_parse_all_events(session); } } } done: switch_mutex_unlock(session->mutex); switch_clear_flag(session, SSF_THREAD_RUNNING); }
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; }
SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void) { THREADS = -1; switch_yield(100000); return SWITCH_STATUS_SUCCESS; }