Exemple #1
0
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);
	}


}
Exemple #2
0
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);
		}
	}
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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);
}
Exemple #17
0
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;
}
Exemple #18
0
/*! 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 */
}
Exemple #22
0
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;
}
Exemple #30
0
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;
}