static int process_incoming(struct cw_conf_member *member, struct cw_frame *f) { int res; // Play our sound queue, if not empty. if (member->soundq) { // Free the frame. if ( f != NULL ) { cw_fr_free( f ) ; } res = conf_play_soundqueue( member ); if (res != 0) { queue_incoming_silent_frame(member,2); // send the DTMF event to the MGR interface.. manager_event( EVENT_FLAG_CALL, APP_CONFERENCE_MANID"DTMF", "Channel: %s\r\n" "Key: %c\r\n", member->channel_name, res ) ; parse_dtmf_option( member, res); } return res; } // // Moderator forces MOH management // if ( member->force_on_hold == 1 ) { cw_moh_start(member->chan,""); member->force_on_hold = 0 ; } else if ( member->force_on_hold == -1 ) { cw_moh_stop(member->chan); cw_generator_activate(member->chan,&membergen,member); member->force_on_hold = 0 ; } // // MOH When the user is alone in the conference // if ( member->conf->membercount == 1 && member->is_on_hold == 0 && member->skip_moh_when_alone == 0 ) { cw_moh_start(member->chan,""); member->is_on_hold = 1 ; return 0; } if ( member->conf->membercount > 1 && member->is_on_hold == 1 && member->skip_moh_when_alone == 0 ) { cw_moh_stop(member->chan); cw_generator_activate(member->chan,&membergen,member); member->is_on_hold = 0 ; return 0; } if ( member->force_remove_flag == 1 ) { return 0; } // If we don't have any frame to parse, then return if ( f == NULL ) { return 0; } // Actions based on the content of the frame if ( f->frametype == CW_FRAME_DTMF && member->manage_dtmf ) { queue_incoming_silent_frame(member,2); // send the DTMF event to the MGR interface.. manager_event( EVENT_FLAG_CALL, APP_CONFERENCE_MANID"DTMF", "Channel: %s\r\n" "Key: %c\r\n", member->channel_name, f->subclass ) ; parse_dtmf_option( member, f->subclass); cw_fr_free(f); } else if ( (member->type == MEMBERTYPE_LISTENER) || (member->talk_mute) ) { // this is a listen-only user, or it's muted. // Ignore the frame cw_fr_free( f ) ; } else if ( f->frametype == CW_FRAME_VOICE ) { // ********************************************************************************** VOICE int old_speaking_state = member->is_speaking; #if ENABLE_VAD if ( member->talk_mute == 1 ) member->is_speaking = 0; if ( member->enable_vad && f->subclass == CW_FORMAT_SLINEAR && f->samples > 0 ) { // and if it's time to check what the member is doing if ( member->skip_voice_detection <= 0 || member->is_speaking ) { int rees; rees = vad_is_talk( f->data, f->datalen, &member->silence_nr, 20); // send the frame to the preprocessor if ( rees != 0 ) { // voice detected, reset skip count if ( member->framelen != 0 ) member->skip_voice_detection = (CW_CONF_SKIP_MS_AFTER_VOICE_DETECTION / member->framelen); else // Let's suppose that 20ms as a framelen is not too different from the real situation member->skip_voice_detection = 20; member->is_speaking=1; } else { // member is silent member->is_speaking=0; if ( member->framelen != 0 ) member->skip_voice_detection = ( CW_CONF_SKIP_MS_WHEN_SILENT / member->framelen ); else member->skip_voice_detection = 5; } } --member->skip_voice_detection ; } if (old_speaking_state != member ->is_speaking) send_state_change_notifications(member); #endif // volume of the frame is modified after the VAD has been done if (member->talk_volume != 0) set_talk_volume(member, f, 1); if ( member->is_speaking && queue_incoming_frame( member, f ) != 0 ) cw_log( CW_CONF_DEBUG, "dropped incoming frame, channel => %s\n", member->channel_name ) ; // free the original frame cw_fr_free( f ) ; } else if ( f->frametype == CW_FRAME_CONTROL && f->subclass == CW_CONTROL_HANGUP ) { // hangup received, queue silence && free the frame queue_incoming_silent_frame(member,2); cw_fr_free( f ) ; } else { // Unmanaged frame #if ( APP_NCONFERENCE_DEBUG == 1 ) cw_log(LOG_WARNING,"Freeing unknown frame: type %d member %s \n", f->frametype, member->chan->name ); #endif cw_fr_free( f ) ; } return 0; }
static int changrab_cli(int fd, int argc, char *argv[]) { char *chan_name_1, *chan_name_2 = NULL, *context,*exten,*flags=NULL; char *pria = NULL; struct cw_channel *xferchan_1, *xferchan_2; int pri=0,x=1; if(argc < 3) { cw_cli(fd,CGUSAGE); return -1; } chan_name_1 = argv[x++]; if(chan_name_1[0] == '-') { flags = cw_strdupa(chan_name_1); if (strchr(flags,'h')) { chan_name_1 = argv[x++]; if((xferchan_1 = my_cw_get_channel_by_name_locked(chan_name_1))) { cw_mutex_unlock(&xferchan_1->lock); cw_hangup(xferchan_1); cw_verbose("OK, good luck!\n"); return 0; } else return -1; } else if (strchr(flags,'m') || strchr(flags,'M')) { chan_name_1 = argv[x++]; if((xferchan_1 = my_cw_get_channel_by_name_locked(chan_name_1))) { cw_mutex_unlock(&xferchan_1->lock); strchr(flags,'m') ? cw_moh_start(xferchan_1,NULL) : cw_moh_stop(xferchan_1); } else return 1; return 0; } if(argc < 4) { cw_cli(fd,CGUSAGE); return -1; } chan_name_1 = argv[x++]; } exten = cw_strdupa(argv[x++]); if((context = strchr(exten,'@'))) { *context = 0; context++; if(!(context && exten)) { cw_cli(fd,CGUSAGE); return -1; } if((pria = strchr(context,':'))) { *pria = '\0'; pria++; pri = atoi(pria); } else { pri = argv[x] ? atoi(argv[x++]) : 1; } if(!pri) pri = 1; } else if (strchr(exten,'/')) { chan_name_2 = exten; } xferchan_1 = my_cw_get_channel_by_name_locked(chan_name_1); if(!xferchan_1) { cw_log(LOG_WARNING, "No Such Channel: %s\n",chan_name_1); return -1; } cw_mutex_unlock(&xferchan_1->lock); if(flags && strchr(flags,'b')) { if(cw_bridged_channel(xferchan_1)) { xferchan_1 = cw_bridged_channel(xferchan_1); } } if(chan_name_2) { struct cw_frame *f; struct cw_channel *newchan_1, *newchan_2; if (!(newchan_1 = cw_channel_alloc(0))) { cw_log(LOG_WARNING, "Memory Error!\n"); cw_hangup(newchan_1); return -1; } else { snprintf(newchan_1->name, sizeof (newchan_1->name), "ChanGrab/%s", xferchan_1->name); newchan_1->readformat = xferchan_1->readformat; newchan_1->writeformat = xferchan_1->writeformat; cw_channel_masquerade(newchan_1, xferchan_1); if ((f = cw_read(newchan_1))) { cw_fr_free(f); } else { cw_hangup(newchan_1); return -1; } } if(!(xferchan_2 = my_cw_get_channel_by_name_locked(chan_name_2))) { cw_log(LOG_WARNING, "No Such Channel: %s\n",chan_name_2); cw_hangup(newchan_1); return -1; } cw_mutex_unlock(&xferchan_2->lock); if(flags && strchr(flags, 'B')) { if(cw_bridged_channel(xferchan_2)) { xferchan_2 = cw_bridged_channel(xferchan_2); } } if(!(newchan_2 = cw_channel_alloc(0))) { cw_log(LOG_WARNING, "Memory Error!\n"); cw_hangup(newchan_1); return -1; } else { snprintf(newchan_2->name, sizeof (newchan_2->name), "ChanGrab/%s", xferchan_2->name); newchan_2->readformat = xferchan_2->readformat; newchan_2->writeformat = xferchan_2->writeformat; cw_channel_masquerade(newchan_2, xferchan_2); if ((f = cw_read(newchan_2))) { cw_fr_free(f); } else { cw_hangup(newchan_1); cw_hangup(newchan_2); return -1; } } cw_bridge_call_thread_launch(newchan_1, newchan_2); } else { cw_verbose("Transferring_to context %s, extension %s, priority %d\n", context, exten, pri); cw_async_goto(xferchan_1, context, exten, pri); if(xferchan_1) cw_mutex_unlock(&xferchan_1->lock); } return 0; }