/* send a message to every member of the conference */
void conference_event_chat_message_broadcast(conference_obj_t *conference, switch_event_t *event)
{
	conference_member_t *member = NULL;
	switch_event_t *processed;

	switch_assert(conference != NULL);
	switch_event_create(&processed, SWITCH_EVENT_CHANNEL_DATA);

	switch_mutex_lock(conference->member_mutex);
	for (member = conference->members; member; member = member->next) {
		if (member->session && !conference_utils_member_test_flag(member, MFLAG_NOCHANNEL)) {
			const char *presence_id = switch_channel_get_variable(member->channel, "presence_id");
			const char *chat_proto = switch_channel_get_variable(member->channel, "chat_proto");
			switch_event_t *reply = NULL;

			if (presence_id && chat_proto) {
				if (switch_event_get_header(processed, presence_id)) {
					continue;
				}
				switch_event_dup(&reply, event);
				switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "to", presence_id);
				switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "conference_name", conference->name);
				switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "conference_domain", conference->domain);

				switch_event_set_body(reply, switch_event_get_body(event));

				switch_core_chat_deliver(chat_proto, &reply);
				switch_event_add_header_string(processed, SWITCH_STACK_BOTTOM, presence_id, "true");
			}
		}
	}
	switch_event_destroy(&processed);
	switch_mutex_unlock(conference->member_mutex);
}
示例#2
0
SWITCH_DECLARE(bool) Event::fire(void)
{

	this_check(false);

	if (!mine) {
		switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Not My event!\n");
		return false;
	}

	if (event) {
		switch_event_t *new_event;
		if (switch_event_dup(&new_event, event) == SWITCH_STATUS_SUCCESS) {
			if (switch_event_fire(&new_event) != SWITCH_STATUS_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Failed to fire the event!\n");
				switch_event_destroy(&new_event);
				return false;
			}
			return true;
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Failed to dup the event!\n");
		}
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR, "Trying to fire an event that does not exist!\n");
	}
	return false;
}
static void put_text_msg(void *user_data, const uint8_t *msg, int len)
{
	switch_tdd_t *pvt = (switch_tdd_t *) user_data;
	switch_event_t *event, *clone;
	switch_channel_t *channel = switch_core_session_get_channel(pvt->session);
	switch_core_session_t *other_session;


	switch_channel_add_variable_var_check(channel, "tdd_messages", (char *)msg, SWITCH_FALSE, SWITCH_STACK_PUSH);


	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TDD_RECV_MESSAGE) == SWITCH_STATUS_SUCCESS) {

		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", "mod_spandsp");
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "tdd");
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "TDD MESSAGE");
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "TDD-Data", (char *)msg);
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(pvt->session));
		switch_event_add_body(event, "%s\n\n", (char *)msg);

		if (switch_core_session_get_partner(pvt->session, &other_session) == SWITCH_STATUS_SUCCESS) {

			if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
				switch_core_session_receive_event(other_session, &clone);
			}

			if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
				switch_core_session_queue_event(other_session, &clone);
			}

			switch_core_session_rwunlock(other_session);
		}

		switch_event_fire(&event);


	}

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s got TDD Message [%s]\n", switch_channel_get_name(channel), (char *)msg);

}
示例#4
0
SWITCH_DECLARE(void) CoreSession::sendEvent(Event *sendME)
{
	this_check_void();
	sanity_check_noreturn;

	if (sendME->event) {
		switch_event_t *new_event;
		if (switch_event_dup(&new_event, sendME->event) == SWITCH_STATUS_SUCCESS) {
			switch_core_session_receive_event(session, &new_event);
		}
	}
}
示例#5
0
static void event_handler(switch_event_t *event)
{
	EventConsumer *E = (EventConsumer *) event->bind_user_data;
	switch_event_t *dup;
	
	switch_event_dup(&dup, event);

	if (switch_queue_trypush(E->events, dup) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot queue any more events.....\n");
	}

}
void conference_data_event_handler(switch_event_t *event)
{
	switch_event_t *revent;
	char *name = switch_event_get_header(event, "conference-name");
	char *domain = switch_event_get_header(event, "conference-domain");
	conference_obj_t *conference = NULL;
	char *body = NULL;

	if (!zstr(name) && (conference = conference_find(name, domain))) {
		if (conference_utils_test_flag(conference, CFLAG_RFC4579)) {
			switch_event_dup(&revent, event);
			revent->event_id = SWITCH_EVENT_CONFERENCE_DATA;
			revent->flags |= EF_UNIQ_HEADERS;
			switch_event_add_header(revent, SWITCH_STACK_TOP, "Event-Name", "CONFERENCE_DATA");

			body = conference_cdr_rfc4579_render(conference, event, revent);
			switch_event_add_body(revent, "%s", body);
			switch_event_fire(&revent);
			switch_safe_free(body);
		}
		switch_thread_rwlock_unlock(conference->rwlock);
	}
}
示例#7
0
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
													switch_caller_profile_t *outbound_profile,
													switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
													switch_call_cause_t *cancel_cause)
{
	char name[128];
	switch_channel_t *ochannel = NULL;

	if (session) {
		ochannel = switch_core_session_get_channel(session);
		switch_channel_clear_flag(ochannel, CF_PROXY_MEDIA);
		switch_channel_clear_flag(ochannel, CF_PROXY_MODE);
		switch_channel_pre_answer(ochannel);
	}

	if ((*new_session = switch_core_session_request(loopback_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) {
		private_t *tech_pvt;
		switch_channel_t *channel;
		switch_caller_profile_t *caller_profile;
		switch_event_t *clone = NULL;

		switch_core_session_add_stream(*new_session, NULL);

		if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
			channel = switch_core_session_get_channel(*new_session);
			switch_snprintf(name, sizeof(name), "loopback/%s-a", outbound_profile->destination_number);
			switch_channel_set_name(channel, name);
			if (tech_init(tech_pvt, *new_session, session ? switch_core_session_get_read_codec(session) : NULL) != SWITCH_STATUS_SUCCESS) {
				switch_core_session_destroy(new_session);
				return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
			switch_core_session_destroy(new_session);
			return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
		}

		if (switch_event_dup(&clone, var_event) == SWITCH_STATUS_SUCCESS) {
			switch_channel_set_private(channel, "__loopback_vars__", clone);
		}

		if (outbound_profile) {
			char *dialplan = NULL, *context = NULL;

			caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
			caller_profile->source = switch_core_strdup(caller_profile->pool, modname);
			if (!strncasecmp(caller_profile->destination_number, "app=", 4)) {
				char *dest = switch_core_session_strdup(*new_session, caller_profile->destination_number);
				char *app = dest + 4;
				char *arg = NULL;

				if ((arg = strchr(app, ':'))) {
					*arg++ = '\0';
				}

				switch_channel_set_variable(channel, "loopback_app", app);

				if (clone) {
					switch_event_add_header_string(clone, SWITCH_STACK_BOTTOM, "loopback_app", app);
				}
				
				if (arg) {
					switch_channel_set_variable(channel, "loopback_app_arg", arg);
					if (clone) {
						switch_event_add_header_string(clone, SWITCH_STACK_BOTTOM, "loopback_app_arg", arg);
					}
				}

				switch_set_flag(tech_pvt, TFLAG_APP);

				caller_profile->destination_number = switch_core_strdup(caller_profile->pool, app);
			}

			if ((context = strchr(caller_profile->destination_number, '/'))) {
				*context++ = '\0';

				if ((dialplan = strchr(context, '/'))) {
					*dialplan++ = '\0';
				}

				if (!zstr(context)) {
					caller_profile->context = switch_core_strdup(caller_profile->pool, context);
				}

				if (!zstr(dialplan)) {
					caller_profile->dialplan = switch_core_strdup(caller_profile->pool, dialplan);
				}
			}

			if (zstr(caller_profile->context)) {
				caller_profile->context = switch_core_strdup(caller_profile->pool, "default");
			}

			if (zstr(caller_profile->dialplan)) {
				caller_profile->dialplan = switch_core_strdup(caller_profile->pool, "xml");
			}

			switch_snprintf(name, sizeof(name), "loopback/%s-a", caller_profile->destination_number);
			switch_channel_set_name(channel, name);
			switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
			switch_channel_set_caller_profile(channel, caller_profile);
			tech_pvt->caller_profile = caller_profile;
		} else {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_ERROR, "Doh! no caller profile\n");
			switch_core_session_destroy(new_session);
			return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
		}

		if (switch_true(switch_event_get_header(var_event, "loopback_bowout_on_execute"))) {
			switch_core_event_hook_add_state_change(*new_session, loopback_bowout_on_execute_state_handler);
		}

		switch_channel_set_state(channel, CS_INIT);

		return SWITCH_CAUSE_SUCCESS;
	}

	return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
示例#8
0
/*! \brief Process one frame of data with avmd algorithm
 * @author Eric des Courtis
 * @param session An avmd session
 * @param frame A audio frame
 */
static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
{
    switch_event_t *event;
    switch_status_t status;
    switch_event_t *event_copy;
    switch_channel_t *channel;

    circ_buffer_t *b;
    size_t pos;
    double f;
    double a;
    double error = 0.0;
    double success = 0.0;
    double amp = 0.0;
    double s_rate;
    double e_rate;
    double avg_a;
    double sine_len;
    uint32_t sine_len_i;
    int valid;
    
	b = &session->b;

	/*! If beep has already been detected skip the CPU heavy stuff */
    if(session->state.beep_state == BEEP_DETECTED){
        return;
    }

	/*! Precompute values used heavily in the inner loop */
    sine_len_i = SINE_LEN(session->rate);
    sine_len = (double)sine_len_i;


    channel = switch_core_session_get_channel(session->session);

	/*! Insert frame of 16 bit samples into buffer */
    INSERT_INT16_FRAME(b, (int16_t *)(frame->data), frame->samples);

    /*! INNER LOOP -- OPTIMIZATION TARGET */
    for(pos = GET_BACKLOG_POS(b); pos != (GET_CURRENT_POS(b) - P); pos++){

		/*! Get a desa2 frequency estimate in Hertz */
        f = TO_HZ(session->rate, desa2(b, pos));

        /*! Don't caculate amplitude if frequency is not within range */
        if(f < MIN_FREQUENCY || f > MAX_FREQUENCY) {
            a = 0.0;
            error += 1.0;
        } else {
            a = amplitude(b, pos, f);
            success += 1.0;
            if(!ISNAN(a)){
                amp += a;
            }
        }
		
		/*! Every once in a while we evaluate the desa2 and amplitude results */
        if(((pos + 1) % sine_len_i) == 0){
            s_rate = success / (error + success);
            e_rate = error   / (error + success);
            avg_a  = amp     / sine_len;

			/*! Results out of these ranges are considered invalid */
            valid = 0;
            if(     s_rate >  0.60 && avg_a > 0.50)	valid = 1;
            else if(s_rate >  0.65 && avg_a > 0.45)	valid = 1;
            else if(s_rate >  0.70 && avg_a > 0.40)	valid = 1;
            else if(s_rate >  0.80 && avg_a > 0.30)	valid = 1;
            else if(s_rate >  0.95 && avg_a > 0.05)	valid = 1;
            else if(s_rate >= 0.99 && avg_a > 0.04)	valid = 1;
            else if(s_rate == 1.00 && avg_a > 0.02)	valid = 1;

			if(valid) {
				APPEND_SMA_VAL(&session->sma_b, s_rate * avg_a);
			}
			else {
				APPEND_SMA_VAL(&session->sma_b, 0.0           );
			}

			/*! If sma is higher then 0 we have some kind of detection (increase this value to eliminate false positives ex: 0.01) */
            if(session->sma_b.sma > 0.00){
				/*! Throw an event to FreeSWITCH */
                status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, AVMD_EVENT_BEEP);
                if(status != SWITCH_STATUS_SUCCESS) {
                    return;
                }

                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session->session));
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd");

                if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
                    return;
                }

                switch_core_session_queue_event(session->session, &event);
                switch_event_fire(&event_copy);

                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected >>>\n");
                switch_channel_set_variable(channel, "avmd_detect", "TRUE");
                RESET_SMA_BUFFER(&session->sma_b);
                session->state.beep_state = BEEP_DETECTED;

                return;
            }

            amp = 0.0;
            success = 0.0;
            error = 0.0;
        }
    }
}
示例#9
0
/*! \brief Find voicemail beep in the audio stream 
 *
 * @author Eric des Courtis
 * @param vmd_info The session information associated with the call.
 * @param frame The audio data.
 * @return The success or failure of the function.
 */
static void find_beep(vmd_session_info_t *vmd_info, switch_frame_t *frame)
{
	int i;
	int c;
	double m[POINTS];
	double med;
	unsigned int j = (vmd_info->pos + 1) % POINTS;
	unsigned int k = j;
	switch_event_t *event;
	switch_status_t status;
	switch_event_t *event_copy;
	switch_channel_t *channel = switch_core_session_get_channel(vmd_info->session);

	switch (vmd_info->state) {
	case BEEP_DETECTED:
		for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
			vmd_info->timestamp++;
			if (vmd_info->points[j].freq < TOLERANCE_T(vmd_info->beep_freq) && vmd_info->points[j].freq > TOLERANCE_B(vmd_info->beep_freq)) {
				c++;
				vmd_info->beep_freq = (vmd_info->beep_freq * 0.95) + (vmd_info->points[j].freq * 0.05);
			}
		}

		if (c < (POINTS - MAX_CHIRP)) {
			vmd_info->state = BEEP_NOT_DETECTED;
			if (vmd_info->timestamp < (switch_size_t) vmd_info->minTime) {
				break;
			}

			status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VMD_EVENT_BEEP);
			if (status != SWITCH_STATUS_SUCCESS) {
				return;
			}

			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop");
			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Beep-Time", "%d", (int) vmd_info->timestamp / POINTS);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(vmd_info->session));
			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Frequency", "%6.4lf", vmd_info->beep_freq);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "vmd");

			if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) {
				return;
			}

			switch_core_session_queue_event(vmd_info->session, &event);
			switch_event_fire(&event_copy);

			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vmd_info->session), SWITCH_LOG_INFO, "<<< VMD - Beep Detected >>>\n");
			switch_channel_set_variable(channel, "vmd_detect", "TRUE");

			vmd_info->timestamp = 0;
		}

		break;

	case BEEP_NOT_DETECTED:

		for (i = 0; i < POINTS; k++, k %= POINTS, i++) {
			m[i] = vmd_info->points[k].freq;
			if (ISNAN(m[i])) {
				m[i] = 0.0;
			}
		}

		med = median(m, POINTS);
		if (ISNAN(med)) {
			for (i = 0; i < POINTS; i++) {
				if (!ISNAN(m[i])) {
					med = m[i];
					break;
				}
			}
		}

		for (c = 0, i = 0; i < POINTS; j++, j %= POINTS, i++) {
			if (vmd_info->points[j].freq < TOLERANCE_T(med) && vmd_info->points[j].freq > TOLERANCE_B(med)) {
				if (vmd_info->points[j].ampl > MIN_AMPL && vmd_info->points[j].freq > MIN_FREQ && vmd_info->points[j].freq < MAX_FREQ) {
					c++;
				}
			}
		}

		if (c >= VALID) {
			vmd_info->state = BEEP_DETECTED;
			vmd_info->beep_freq = med;
			vmd_info->timestamp = 0;
		}

		break;
	}
}