/* 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); }
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); }
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); } } }
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); } }
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; }
/*! \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; } } }
/*! \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; } }