SWITCH_DECLARE(void) switch_cond_yield(switch_interval_time_t t) { switch_time_t want; if (!t) return; if (globals.RUNNING != 1 || !runtime.timestamp || globals.use_cond_yield != 1) { do_sleep(t); return; } want = runtime.timestamp + t; while (globals.RUNNING == 1 && globals.use_cond_yield == 1 && runtime.timestamp < want) { switch_mutex_lock(TIMER_MATRIX[1].mutex); if (runtime.timestamp < want) { switch_thread_cond_wait(TIMER_MATRIX[1].cond, TIMER_MATRIX[1].mutex); } switch_mutex_unlock(TIMER_MATRIX[1].mutex); } }
static void event_handler(switch_event_t *event) { const char *sig = switch_event_get_header(event, "Trapped-Signal"); switch_hash_index_t *hi; void *val; cdr_fd_t *fd; if (globals.shutdown) { return; } if (sig && !strcmp(sig, "HUP")) { for (hi = switch_hash_first(NULL, globals.fd_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, NULL, NULL, &val); fd = (cdr_fd_t *) val; switch_mutex_lock(fd->mutex); do_rotate(fd); switch_mutex_unlock(fd->mutex); } } }
static void write_cdr(const char *path, const char *log_line) { cdr_fd_t *fd = NULL; unsigned int bytes_in, bytes_out; 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); } switch_mutex_lock(fd->mutex); bytes_out = (unsigned) strlen(log_line); 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); } if ((bytes_in = write(fd->fd, log_line, bytes_out)) != bytes_out) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write error to file %s %d/%d\n", path, (int) bytes_in, (int) bytes_out); } fd->bytes += bytes_in; end: switch_mutex_unlock(fd->mutex); }
SWITCH_DECLARE(switch_status_t) switch_core_codec_decode(switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, uint32_t encoded_data_len, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag) { switch_status_t status; switch_assert(codec != NULL); switch_assert(encoded_data != NULL); switch_assert(decoded_data != NULL); if (!codec->implementation || !switch_core_codec_ready(codec)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec is not initialized!\n"); abort(); return SWITCH_STATUS_NOT_INITALIZED; } if (!switch_test_flag(codec, SWITCH_CODEC_FLAG_DECODE)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec decoder is not initialized!\n"); return SWITCH_STATUS_NOT_INITALIZED; } if (codec->implementation->encoded_bytes_per_packet) { uint32_t frames = encoded_data_len / codec->implementation->encoded_bytes_per_packet; if (frames && codec->implementation->decoded_bytes_per_packet * frames > *decoded_data_len) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Buffer size sanity check failed!\n"); return SWITCH_STATUS_GENERR; } } if (codec->mutex) switch_mutex_lock(codec->mutex); status = codec->implementation->decode(codec, other_codec, encoded_data, encoded_data_len, encoded_rate, decoded_data, decoded_data_len, decoded_rate, flag); if (codec->mutex) switch_mutex_unlock(codec->mutex); return status; }
static int next_id(valet_lot_t *lot, int min, int max, int in) { int i, r = 0, m; char buf[128] = ""; if (!min) min = 1; switch_mutex_lock(globals.mutex); for (i = min; (i < max || max == 0); i++) { switch_snprintf(buf, sizeof(buf), "%d", i); m = !!switch_core_hash_find(lot->hash, buf); if ((in && !m) || (!in && m)) { r = i; break; } } switch_mutex_unlock(globals.mutex); return r; }
static void *SWITCH_THREAD_FUNC log_thread(switch_thread_t *t, void *obj) { if (!obj) { obj = NULL; } THREAD_RUNNING = 1; while (THREAD_RUNNING == 1) { void *pop = NULL; switch_log_node_t *node = NULL; switch_log_binding_t *binding; if (switch_queue_pop(LOG_QUEUE, &pop) != SWITCH_STATUS_SUCCESS) { break; } if (!pop) { break; } node = (switch_log_node_t *) pop; switch_mutex_lock(BINDLOCK); for (binding = BINDINGS; binding; binding = binding->next) { if (binding->level >= node->level) { binding->function(node, node->level); } } switch_mutex_unlock(BINDLOCK); switch_log_node_free(&node); } THREAD_RUNNING = 0; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Logger Ended.\n"); return NULL; }
void eventpipe_events_untrack_call(switch_core_session_t *session) { struct eventpipe_call *current, *next, *last; next = NULL; last = NULL; current = NULL; switch_assert(session != NULL); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Untracking call events\n"); switch_mutex_lock(globals.eventpipe_call_list_mutex); if (head) { if (head->session == session) { head = NULL; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "No more call to track\n"); goto eventpipe_remove_call_end; } } else { goto eventpipe_remove_call_end; } current = head; last = head; while (current) { if (current->session == session) { next = current->next; last->next = next; goto eventpipe_remove_call_end; } else { current = current->next; } last = current; } eventpipe_remove_call_end: switch_mutex_unlock(globals.eventpipe_call_list_mutex); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Untracking call events done\n"); }
SWITCH_DECLARE(char *) switch_core_perform_strdup(switch_memory_pool_t *pool, const char *todup, const char *file, const char *func, int line) { char *duped = NULL; switch_size_t len; switch_assert(pool != NULL); if (!todup) { return NULL; } if (zstr(todup)) { return SWITCH_BLANK_STRING; } #ifdef LOCK_MORE #ifdef USE_MEM_LOCK switch_mutex_lock(memory_manager.mem_lock); #endif #endif len = strlen(todup) + 1; #ifdef DEBUG_ALLOC if (len > 500) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Core Strdup Allocate %s %d\n", (void *) pool, apr_pool_tag(pool, NULL), (int)len); #endif duped = apr_pstrmemdup(pool, todup, len); switch_assert(duped != NULL); #ifdef LOCK_MORE #ifdef USE_MEM_LOCK switch_mutex_unlock(memory_manager.mem_lock); #endif #endif return duped; }
SWITCH_DECLARE(char *) switch_core_vsprintf(switch_memory_pool_t *pool, const char *fmt, va_list ap) { char *result = NULL; switch_assert(pool != NULL); #ifdef LOCK_MORE #ifdef USE_MEM_LOCK switch_mutex_lock(memory_manager.mem_lock); #endif #endif result = apr_pvsprintf(pool, fmt, ap); switch_assert(result != NULL); #ifdef LOCK_MORE #ifdef USE_MEM_LOCK switch_mutex_unlock(memory_manager.mem_lock); #endif #endif return result; }
static switch_status_t local_stream_file_close(switch_file_handle_t *handle) { local_stream_context_t *cp, *last = NULL, *context = handle->private_info; switch_mutex_lock(context->source->mutex); for (cp = context->source->context_list; cp; cp = cp->next) { if (cp == context) { if (last) { last->next = cp->next; } else { context->source->context_list = cp->next; } break; } last = cp; } context->source->total--; switch_mutex_unlock(context->source->mutex); switch_buffer_destroy(&context->audio_buffer); switch_thread_rwlock_unlock(context->source->rwlock); return SWITCH_STATUS_SUCCESS; }
void AsyncIOServer::RecvHandle(Client* client) { switch_mutex_lock(client->clientMutex); // if( client->recvHandleCount == 0 ) { // 增加计数器 client->recvHandleCount++; // 增加到处理队列 switch_queue_push(mpHandleQueue, client); // // } else { // // 已经有包在处理则返回 // } switch_mutex_unlock(client->clientMutex); // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AsyncIOServer::RecvHandle( " // "client : %p, " // "recvHandleCount : %d " // ") \n", // client, // client->recvHandleCount // ); }
/* State methods they get called when the state changes to the specific state returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. */ static switch_status_t channel_on_init(switch_core_session_t *session) { switch_channel_t *channel; private_t *tech_pvt = NULL; tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); channel = switch_core_session_get_channel(session); assert(channel != NULL); switch_set_flag_locked(tech_pvt, TFLAG_IO); /* Move channel's state machine to ROUTING. This means the call is trying to get from the initial start where the call because, to the point where a destination has been identified. If the channel is simply left in the initial state, nothing will happen. */ switch_channel_set_state(channel, CS_ROUTING); switch_mutex_lock(globals.mutex); globals.calls++; switch_mutex_unlock(globals.mutex); return SWITCH_STATUS_SUCCESS; }
static switch_status_t switch_sangoma_destroy(switch_codec_t *codec) { struct sangoma_transcoding_session *sess = codec->private_info; /* things that you may do here is closing files, sockets or other resources used during the codec session * no need to free memory allocated from the pool though, the owner of the pool takes care of that */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sangoma destroy called.\n"); switch_mutex_lock(g_sessions_lock); if (sess->encoder.txrtp) { sngtc_free_transcoding_session(&sess->encoder.reply); memset(&sess->encoder, 0, sizeof(sess->encoder)); } if (sess->decoder.txrtp) { sngtc_free_transcoding_session(&sess->decoder.reply); memset(&sess->decoder, 0, sizeof(sess->decoder)); } switch_core_hash_delete(g_sessions_hash, sess->hashkey); switch_mutex_unlock(g_sessions_lock); return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(switch_status_t) switch_core_codec_destroy(switch_codec_t *codec) { switch_mutex_t *mutex; switch_memory_pool_t *pool; int free_pool = 0; switch_assert(codec != NULL); if (!codec->implementation || !switch_core_codec_ready(codec)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Codec is not initialized!\n"); return SWITCH_STATUS_NOT_INITALIZED; } if (switch_test_flag(codec, SWITCH_CODEC_FLAG_FREE_POOL)) { free_pool = 1; } pool = codec->memory_pool; mutex = codec->mutex; if (mutex) switch_mutex_lock(mutex); codec->implementation->destroy(codec); switch_clear_flag(codec, SWITCH_CODEC_FLAG_READY); UNPROTECT_INTERFACE(codec->codec_interface); if (mutex) switch_mutex_unlock(mutex); if (free_pool) { switch_core_destroy_memory_pool(&pool); } return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_id(uint32_t task_id) { switch_scheduler_task_container_t *tp; switch_event_t *event; uint32_t delcnt = 0; switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp; tp = tp->next) { if (tp->task.task_id == task_id) { if (switch_test_flag(tp, SSHF_NO_DEL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Attempt made to delete undeletable task #%u (group %s)\n", tp->task.task_id, tp->task.group); break; } if (tp->running) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Attempt made to delete running task #%u (group %s)\n", tp->task.task_id, tp->task.group); break; } tp->destroyed++; if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Desc", tp->desc); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Group", switch_str_nil(tp->task.group)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" SWITCH_INT64_T_FMT, tp->task.runtime); switch_event_fire(&event); } delcnt++; break; } } switch_mutex_unlock(globals.task_mutex); return delcnt; }
static void decode_fd(shout_context_t *context, void *data, size_t bytes) { int decode_status = 0; size_t usedlen; while (!context->err && !context->eof && switch_buffer_inuse(context->audio_buffer) < bytes) { 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) { ; } else if (decode_status == MPG123_DONE || decode_status == MPG123_NEED_MORE) { 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!\n"); context->eof++; goto error; } continue; } context->mp3err = 0; switch_buffer_write(context->audio_buffer, context->decode_buf, usedlen); } return; error: switch_mutex_lock(context->audio_mutex); context->err++; switch_mutex_unlock(context->audio_mutex); }
static int valet_lot_count(valet_lot_t *lot) { switch_hash_index_t *i_hi; const void *i_var; void *i_val; valet_token_t *token; int count = 0; time_t now; now = switch_epoch_time_now(NULL); switch_mutex_lock(lot->mutex); for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) { switch_hash_this(i_hi, &i_var, NULL, &i_val); token = (valet_token_t *) i_val; if (token->timeout > 0 && (token->timeout < now || token->timeout == 1)) { continue; } count++; } switch_mutex_unlock(lot->mutex); return count; }
/*! function to resume recognizer */ static switch_status_t pocketsphinx_asr_resume(switch_asr_handle_t *ah) { pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; switch_status_t status = SWITCH_STATUS_FALSE; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, ">>>>>>>>pocketsphinx_asr_resume<<<<<<<<<\n"); switch_mutex_lock(ps->flag_mutex); switch_clear_flag(ps, PSFLAG_HAS_TEXT); ps->silence_time = switch_micro_time_now(); if (!switch_test_flag(ps, PSFLAG_READY)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Manually Resuming\n"); if (ps_start_utt(ps->ps, NULL)) { status = SWITCH_STATUS_GENERR; } else { switch_set_flag(ps, PSFLAG_READY); } } switch_mutex_unlock(ps->flag_mutex); return status; }
static switch_status_t directory_execute_sql(char *sql, switch_mutex_t *mutex) { switch_core_db_t *db; switch_status_t status = SWITCH_STATUS_SUCCESS; if (mutex) { switch_mutex_lock(mutex); } if (!(db = switch_core_db_open_file(globals.dbname))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", globals.dbname); status = SWITCH_STATUS_FALSE; goto end; } status = switch_core_db_persistant_execute(db, sql, 1); switch_core_db_close(db); end: if (mutex) { switch_mutex_unlock(mutex); } return status; }
static modem_t *acquire_modem(int index) { modem_t *modem = NULL; switch_time_t now = switch_time_now(); int64_t idle_debounce = 2000000; switch_mutex_lock(globals.mutex); if (index > -1 && index < globals.SOFT_MAX_MODEMS) { modem = &globals.MODEM_POOL[index]; } else { int x; for(x = 0; x < globals.SOFT_MAX_MODEMS; x++) { if (globals.MODEM_POOL[x].state == MODEM_STATE_ONHOOK && (now - globals.MODEM_POOL[x].last_event) > idle_debounce) { modem = &globals.MODEM_POOL[x]; break; } } } if (modem && (modem->state != MODEM_STATE_ONHOOK || (now - modem->last_event) < idle_debounce)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Modem %s In Use!\n", modem->devlink); modem = NULL; } if (modem) { modem_set_state(modem, MODEM_STATE_ACQUIRED); modem->last_event = switch_time_now(); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Modems Available!\n"); } switch_mutex_unlock(globals.mutex); return modem; }
/* function to fill in an erlang reference struct */ void ei_init_ref(ei_cnode * ec, erlang_ref * ref) { memset(ref, 0, sizeof(*ref)); /* zero out the struct */ snprintf(ref->node, MAXATOMLEN, "%s", ec->thisnodename); switch_mutex_lock(globals.ref_mutex); globals.reference0++; if (globals.reference0 >= MAX_REFERENCE) { globals.reference0 = 0; globals.reference1++; if (globals.reference1 == 0) { globals.reference2++; } } ref->n[0] = globals.reference0; ref->n[1] = globals.reference1; ref->n[2] = globals.reference2; switch_mutex_unlock(globals.ref_mutex); ref->creation = 1; /* why is this 1 */ ref->len = 3; /* why is this 3 */ }
static switch_status_t channel_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = NULL; loopback_private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); switch_channel_set_variable(channel, "is_loopback", "1"); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel)); switch_clear_flag_locked(tech_pvt, TFLAG_LINKED); switch_mutex_lock(tech_pvt->mutex); if (tech_pvt->other_tech_pvt) { switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_LINKED); if (tech_pvt->other_tech_pvt->session && tech_pvt->other_tech_pvt->session != tech_pvt->other_session) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "OTHER SESSION MISMATCH????\n"); tech_pvt->other_session = tech_pvt->other_tech_pvt->session; } tech_pvt->other_tech_pvt = NULL; } if (tech_pvt->other_session) { switch_channel_hangup(tech_pvt->other_channel, switch_channel_get_cause(channel)); switch_core_session_rwunlock(tech_pvt->other_session); tech_pvt->other_channel = NULL; tech_pvt->other_session = NULL; } switch_mutex_unlock(tech_pvt->mutex); return SWITCH_STATUS_SUCCESS; }
SWITCH_DECLARE(void) switch_core_memory_reclaim(void) { #if !defined(PER_POOL_LOCK) && !defined(INSTANTLY_DESTROY_POOLS) switch_memory_pool_t *pool; void *pop = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled memory pool(s)\n", switch_queue_size(memory_manager.pool_recycle_queue) + switch_queue_size(memory_manager.pool_queue)); while (switch_queue_trypop(memory_manager.pool_recycle_queue, &pop) == SWITCH_STATUS_SUCCESS) { pool = (switch_memory_pool_t *) pop; if (!pool) { break; } #ifdef USE_MEM_LOCK switch_mutex_lock(memory_manager.mem_lock); #endif apr_pool_destroy(pool); #ifdef USE_MEM_LOCK switch_mutex_unlock(memory_manager.mem_lock); #endif } #endif return; }
static switch_status_t shout_file_write(switch_file_handle_t *handle, void *data, size_t *len) { shout_context_t *context; int rlen = 0; int16_t *audio = data; size_t nsamples = *len; if (!handle) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error no handle\n"); return SWITCH_STATUS_FALSE; } if (!(context = handle->private_info)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error no context\n"); return SWITCH_STATUS_FALSE; } if (context->err) { return SWITCH_STATUS_FALSE; } if (context->shout && !context->shout_init) { if (!context->gfp) { return SWITCH_STATUS_FALSE; } context->shout_init++; if (shout_open(context->shout) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening stream: %s\n", shout_get_error(context->shout)); context->err++; return SWITCH_STATUS_FALSE; } launch_write_stream_thread(context); } if (handle->handler && context->audio_mutex) { switch_mutex_lock(context->audio_mutex); if (context->audio_buffer) { if (!switch_buffer_write(context->audio_buffer, data, (nsamples * sizeof(int16_t) * handle->channels))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Buffer error\n"); context->err++; } } else { context->err++; } switch_mutex_unlock(context->audio_mutex); if (context->err) { return SWITCH_STATUS_FALSE; } handle->sample_count += *len; return SWITCH_STATUS_SUCCESS; } if (!context->lame_ready) { lame_init_params(context->gfp); lame_print_config(context->gfp); context->lame_ready = 1; } if (context->mp3buflen < nsamples * 4) { context->mp3buflen = nsamples * 4; context->mp3buf = switch_core_alloc(context->memory_pool, context->mp3buflen); } if (handle->channels == 2) { switch_size_t i, j = 0; if (context->llen < nsamples) { context->l = switch_core_alloc(context->memory_pool, nsamples * 2); context->r = switch_core_alloc(context->memory_pool, nsamples * 2); context->llen = context->rlen = nsamples; } for (i = 0; i < nsamples; i++) { context->l[i] = audio[j++]; context->r[i] = audio[j++]; } if ((rlen = lame_encode_buffer(context->gfp, context->l, context->r, nsamples, context->mp3buf, context->mp3buflen)) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); return SWITCH_STATUS_FALSE; } } else if (handle->channels == 1) { if ((rlen = lame_encode_buffer(context->gfp, audio, NULL, nsamples, context->mp3buf, context->mp3buflen)) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); return SWITCH_STATUS_FALSE; } } else { rlen = 0; } if (rlen) { int ret = fwrite(context->mp3buf, 1, rlen, context->fp); if (ret < 0) { return SWITCH_STATUS_FALSE; } } handle->sample_count += *len; return SWITCH_STATUS_SUCCESS; }
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 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; }
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 void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t **results) { char *str = ldns_rr2str(naptr); char *argv[11] = { 0 }; int i, argc; char *pack[4] = { 0 }; int packc; char *p; int order = 10; int preference = 100; char *service = NULL; char *packstr; char *regex, *replace; if (zstr(str)) { if (str != NULL) { /* In this case ldns_rr2str returned a malloc'd null terminated string */ switch_safe_free(str); } return; } for (p = str; p && *p; p++) { if (*p == '\t') *p = ' '; if (*p == ' ' && *(p+1) == '.') *p = '\0'; } argc = switch_split(str, ' ', argv); for (i = 0; i < argc; i++) { if (i > 0) { strip_quotes(argv[i]); } } service = argv[7]; packstr = argv[8]; if (zstr(service) || zstr(packstr)) { goto end; } if (!zstr(argv[4])) { order = atoi(argv[4]); } if (!zstr(argv[5])) { preference = atoi(argv[5]); } if ((packc = switch_split(packstr, '!', pack))) { regex = pack[1]; replace = pack[2]; } else { goto end; } for (p = replace; p && *p; p++) { if (*p == '\\') { *p = '$'; } } if (service && regex && replace) { switch_regex_t *re = NULL, *re2 = NULL; int proceed = 0, ovector[30]; char *substituted = NULL; char *substituted_2 = NULL; char *orig_uri; char *uri_expanded = NULL; enum_route_t *route; int supported = 0; uint32_t len = 0; if ((proceed = switch_regex_perform(number, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) { if (strchr(regex, '(')) { len = (uint32_t) (strlen(number) + strlen(replace) + 10) * proceed; if (!(substituted = malloc(len))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); switch_regex_safe_free(re); goto end; } memset(substituted, 0, len); switch_perform_substitution(re, proceed, replace, number, substituted, len, ovector); orig_uri = substituted; } else { orig_uri = replace; } switch_mutex_lock(MUTEX); for (route = globals.route_order; route; route = route->next) { char *uri = orig_uri; if (strcasecmp(service, route->service)) { continue; } if ((proceed = switch_regex_perform(uri, route->regex, &re2, ovector, sizeof(ovector) / sizeof(ovector[0])))) { switch_event_t *event = NULL; if (strchr(route->regex, '(')) { len = (uint32_t) (strlen(uri) + strlen(route->replace) + 10) * proceed; if (!(substituted_2 = malloc(len))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); switch_safe_free(substituted); switch_regex_safe_free(re); switch_regex_safe_free(re2); switch_mutex_unlock(MUTEX); goto end; } memset(substituted_2, 0, len); switch_perform_substitution(re2, proceed, route->replace, uri, substituted_2, len, ovector); uri = substituted_2; } else { uri = route->replace; } switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS); uri_expanded = switch_event_expand_headers(event, uri); switch_event_destroy(&event); if (uri_expanded == uri) { uri_expanded = NULL; } else { uri = uri_expanded; } supported++; add_result(results, order, preference, service, uri, supported); } switch_safe_free(uri_expanded); switch_safe_free(substituted_2); switch_regex_safe_free(re2); } switch_mutex_unlock(MUTEX); if (!supported) { add_result(results, order, preference, service, orig_uri, 0); } switch_safe_free(substituted); switch_regex_safe_free(re); } } end: switch_safe_free(str); return; }
/** * 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 int task_thread_loop(int done) { switch_scheduler_task_container_t *tofree, *tp, *last = NULL; switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp; tp = tp->next) { if (done) { tp->destroyed = 1; } else if (!tp->destroyed) { int64_t now = switch_epoch_time_now(NULL); if (now >= tp->task.runtime && !tp->in_thread) { int32_t diff = (int32_t) (now - tp->task.runtime); if (diff > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Task was executed late by %d seconds %u %s (%s)\n", diff, tp->task.task_id, tp->desc, switch_str_nil(tp->task.group)); } tp->executed = now; if (switch_test_flag(tp, SSHF_OWN_THREAD)) { switch_thread_t *thread; switch_threadattr_t *thd_attr; switch_core_new_memory_pool(&tp->pool); switch_threadattr_create(&thd_attr, tp->pool); switch_threadattr_detach_set(thd_attr, 1); tp->in_thread = 1; switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool); } else { tp->running = 1; switch_mutex_unlock(globals.task_mutex); switch_scheduler_execute(tp); switch_mutex_lock(globals.task_mutex); tp->running = 0; } } } } switch_mutex_unlock(globals.task_mutex); switch_mutex_lock(globals.task_mutex); for (tp = globals.task_list; tp;) { if (tp->destroyed && !tp->in_thread) { switch_event_t *event; tofree = tp; tp = tp->next; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting task %u %s (%s)\n", tofree->task.task_id, tofree->desc, switch_str_nil(tofree->task.group)); if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tofree->task.task_id); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Desc", tofree->desc); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Task-Group", switch_str_nil(tofree->task.group)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-Runtime", "%" SWITCH_INT64_T_FMT, tofree->task.runtime); switch_queue_push(globals.event_queue, event); event = NULL; } if (last) { last->next = tofree->next; } else { globals.task_list = tofree->next; } switch_safe_free(tofree->task.group); if (tofree->task.cmd_arg && switch_test_flag(tofree, SSHF_FREE_ARG)) { free(tofree->task.cmd_arg); } switch_safe_free(tofree->desc); free(tofree); } else { last = tp; tp = tp->next; } } switch_mutex_unlock(globals.task_mutex); return done; }