You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3195 lines
92 KiB

This patch is derived from the difference between appconference-2.0.1
from http://appconference.sourceforge.net/ and the version included in
http://download.fedora.redhat.com/pub/fedora/linux/development/source/SRPMS/asterisk-1.6.0-0.4.beta5.fc9.src.rpm
Index: Flags.txt
--- Flags.txt.orig 2008-02-26 17:05:57 +0100
+++ Flags.txt 2008-03-19 09:18:57 +0100
@@ -21,6 +21,10 @@
Moderator/video switch options:
'M' : member is a "moderator". When a moderator quits, all members are kicked and the conference is disabled.
'S' : member accepts VAD controlled video switching. Do not use with 'X'.
+'z' : member can "linger". When the member is currently transmitting video and becomes silent and nobody else is speaking, we stay on it.
+'o' : enable special behavior when in 1 and 2 member situation (one on one video). The conference observes the 'o' status of the last
+ member to join it
+'F' : force switch mode: if the member is talking, force a switch to it even when there is no video
Miscellaneous:
't' : member accepts text based control messages. The messages are described in a separate document
Index: Makefile
--- Makefile.orig 2008-02-26 17:05:57 +0100
+++ Makefile 2008-03-19 09:18:57 +0100
@@ -18,11 +18,11 @@
#
INSTALL_PREFIX :=
-INSTALL_MODULES_DIR := $(INSTALL_PREFIX)/usr/lib/asterisk/modules
+INSTALL_MODULES_DIR := $(INSTALL_PREFIX)/lib/asterisk/modules
-ASTERISK_INCLUDE_DIR ?= ../asterisk/include
+ASTERISK_INCLUDE_DIR ?= $(INSTALL_PREFIX)/include
-REVISION = $(shell svnversion -n .)
+REVISION = 2.0.1
# turn app_conference debugging on or off ( 0 == OFF, 1 == ON )
APP_CONFERENCE_DEBUG ?= 0
Index: app_conference.c
--- app_conference.c.orig 2008-02-26 17:05:57 +0100
+++ app_conference.c 2008-03-19 09:18:57 +0100
@@ -27,14 +27,7 @@
#include "asterisk.h"
-// SVN revision number, provided by make
-#ifndef REVISION
-#define REVISION "unknown"
-#endif
-
-static char *revision = REVISION;
-
-ASTERISK_FILE_VERSION(__FILE__, REVISION)
+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.1 $")
#include "app_conference.h"
#include "common.h"
@@ -84,7 +77,7 @@
static int load_module( void )
{
- ast_log( LOG_NOTICE, "Loading app_conference module, revision=%s\n", revision) ;
+ ast_log( LOG_NOTICE, "Loading app_conference module\n") ;
init_conference() ;
Index: app_conference.h
--- app_conference.h.orig 2008-02-26 17:05:57 +0100
+++ app_conference.h 2008-03-19 09:18:57 +0100
@@ -31,6 +31,7 @@
#ifndef _ASTERISK_CONF_H
#define _ASTERISK_CONF_H
+#include "asterisk.h"
/* standard includes */
#include <stdlib.h>
@@ -40,27 +41,27 @@
#include <math.h>
#include <stdio.h>
-
#include <pthread.h>
/* asterisk includes */
-#include <asterisk/utils.h>
-#include <asterisk/pbx.h>
-#include <asterisk/module.h>
-#include <asterisk/logger.h>
-#include <asterisk/lock.h>
-#include <asterisk/frame.h>
-#include <asterisk/manager.h>
-#include <asterisk/dsp.h>
-#include <asterisk/translate.h>
-#include <asterisk/channel.h>
-#include <asterisk/file.h>
-//#include <asterisk/channel_pvt.h>
-#include <asterisk/cli.h>
+#include "asterisk/channel.h"
+#include "asterisk/utils.h"
+#include "asterisk/pbx.h"
+#include "asterisk/module.h"
+#include "asterisk/logger.h"
+#include "asterisk/lock.h"
+#include "asterisk/frame.h"
+#include "asterisk/manager.h"
+#include "asterisk/dsp.h"
+#include "asterisk/translate.h"
+#include "asterisk/channel.h"
+#include "asterisk/file.h"
+//#include "asterisk/channel_pvt.h"
+#include "asterisk/cli.h"
#if (SILDET == 2)
-#include "libspeex/speex_preprocess.h"
+#include "speex_preprocess.h"
#endif
//
@@ -226,6 +227,10 @@
// Amount of audio required before we decide somebody started talking
#define AST_CONF_VIDEO_START_TIMEOUT 2000
+// Amount of time we wait for a video frame until we decide that
+// the member has stopped broadcasting video
+#define AST_CONF_VIDEO_STOP_BROADCAST_TIMEOUT 200
+
//
// Text frame control protocol
//
Index: cli.c
--- cli.c.orig 2008-02-26 17:05:57 +0100
+++ cli.c 2008-03-19 09:27:50 +0100
@@ -28,125 +28,121 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "asterisk/autoconfig.h"
-#include "cli.h"
+#include "asterisk.h"
-static char conference_restart_usage[] =
- "usage: conference restart\n"
- " kick all users in all conferences\n"
-;
-
-static struct ast_cli_entry cli_restart = {
- { "conference", "restart", NULL },
- conference_restart,
- "restart a conference",
- conference_restart_usage
-} ;
+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.1 $")
+#include "asterisk/autoconfig.h"
+#include "cli.h"
-int conference_restart( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- if ( argc < 2 )
- return RESULT_SHOWUSAGE ;
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference restart";
+ e->usage = "usage: conference restart\n"
+ " restart a conference\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+ if ( a->argc < 2 )
+ return CLI_SHOWUSAGE;
+
kick_all();
- return RESULT_SUCCESS ;
+
+ return CLI_SUCCESS;
}
+static char *handle_cli_app_conference_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
-//
-// debug functions
-//
-
-static char conference_debug_usage[] =
- "usage: conference debug <conference_name> [ on | off ]\n"
- " enable debugging for a conference\n"
-;
-
-static struct ast_cli_entry cli_debug = {
- { "conference", "debug", NULL },
- conference_debug,
- "enable debugging for a conference",
- conference_debug_usage
-} ;
-
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference debug";
+ e->usage = "usage: conference debug <conference_name> [ on | off ]\n"
+ " enable debugging for a conference\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
-int conference_debug( int fd, int argc, char *argv[] )
-{
- if ( argc < 3 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 3)
+ return CLI_SHOWUSAGE;
// get the conference name
- const char* name = argv[2] ;
+ const char* name = a->argv[2] ;
// get the new state
int state = 0 ;
- if ( argc == 3 )
+ if ( a->argc == 3 )
{
// no state specified, so toggle it
state = -1 ;
}
else
{
- if ( strncasecmp( argv[3], "on", 4 ) == 0 )
+ if ( strncasecmp( a->argv[3], "on", 4 ) == 0 )
state = 1 ;
- else if ( strncasecmp( argv[3], "off", 3 ) == 0 )
+ else if ( strncasecmp( a->argv[3], "off", 3 ) == 0 )
state = 0 ;
else
- return RESULT_SHOWUSAGE ;
+ return CLI_SHOWUSAGE ;
}
int new_state = set_conference_debugging( name, state ) ;
if ( new_state == 1 )
{
- ast_cli( fd, "enabled conference debugging, name => %s, new_state => %d\n",
- name, new_state ) ;
+ ast_cli( a->fd, "enabled conference debugging, name => %s, new_state => %d\n",
+ name, new_state ) ;
}
else if ( new_state == 0 )
{
- ast_cli( fd, "disabled conference debugging, name => %s, new_state => %d\n",
+ ast_cli( a->fd, "disabled conference debugging, name => %s, new_state => %d\n",
name, new_state ) ;
}
else
{
// error setting state
- ast_cli( fd, "\nunable to set debugging state, name => %s\n\n", name ) ;
+ ast_cli( a->fd, "\nunable to set debugging state, name => %s\n\n", name ) ;
}
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-//
-// stats functions
-//
-
-static char conference_show_stats_usage[] =
- "usage: conference show stats\n"
- " display stats for active conferences.\n"
-;
-
-static struct ast_cli_entry cli_show_stats = {
- { "conference", "show", "stats", NULL },
- conference_show_stats,
- "show conference stats",
- conference_show_stats_usage
-} ;
+static char *conference_show_stats_name( int fd, const char* name )
+{
+ // not implemented yet
+ return CLI_SUCCESS ;
+}
-int conference_show_stats( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- if ( argc < 3 )
- return RESULT_SHOWUSAGE ;
+
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference show stats";
+ e->usage = "usage: conference show stats\n"
+ " display stats for active conferences.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if ( a->argc < 3 )
+ return CLI_SHOWUSAGE ;
// get count of active conferences
int count = get_conference_count() ;
- ast_cli( fd, "\n\nCONFERENCE STATS, ACTIVE( %d )\n\n", count ) ;
+ ast_cli( a->fd, "\n\nCONFERENCE STATS, ACTIVE( %d )\n\n", count ) ;
// if zero, go no further
if ( count <= 0 )
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
//
// get the conference stats
@@ -161,8 +157,8 @@
// make sure we were able to fetch some
if ( count <= 0 )
{
- ast_cli( fd, "!!! error fetching conference stats, available => %d !!!\n", count ) ;
- return RESULT_SUCCESS ;
+ ast_cli( a->fd, "!!! error fetching conference stats, available => %d !!!\n", count ) ;
+ return CLI_SUCCESS ;
}
//
@@ -170,8 +166,8 @@
//
// output header
- ast_cli( fd, "%-20.20s %-40.40s\n", "Name", "Stats") ;
- ast_cli( fd, "%-20.20s %-40.40s\n", "----", "-----") ;
+ ast_cli( a->fd, "%-20.20s %-40.40s\n", "Name", "Stats") ;
+ ast_cli( a->fd, "%-20.20s %-40.40s\n", "----", "-----") ;
ast_conference_stats* s = NULL ;
@@ -182,1008 +178,931 @@
s = &(stats[i]) ;
// output this conferences stats
- ast_cli( fd, "%-20.20s\n", (char*)( &(s->name) )) ;
+ ast_cli( a->fd, "%-20.20s\n", (char*)( &(s->name) )) ;
}
- ast_cli( fd, "\n" ) ;
+ ast_cli( a->fd, "\n" ) ;
//
// drill down to specific stats
//
- if ( argc == 4 )
+ if ( a->argc == 4 )
{
// show stats for a particular conference
- conference_show_stats_name( fd, argv[3] ) ;
+ conference_show_stats_name( a->fd, a->argv[3] ) ;
}
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-int conference_show_stats_name( int fd, const char* name )
+static char *handle_cli_app_conference_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- // not implemented yet
- return RESULT_SUCCESS ;
-}
-
-static char conference_list_usage[] =
- "usage: conference list {<conference_name>}\n"
- " list members of a conference\n"
-;
-
-static struct ast_cli_entry cli_list = {
- { "conference", "list", NULL },
- conference_list,
- "list members of a conference",
- conference_list_usage
-} ;
-
-
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference list";
+ e->usage = "usage: conference list {<conference_name>}\n"
+ " list members of a conference\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
-int conference_list( int fd, int argc, char *argv[] )
-{
int index;
- if ( argc < 2 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 2 )
+ return CLI_SHOWUSAGE ;
- if (argc >= 3)
+ if (a->argc >= 3)
{
- for (index = 2; index < argc; index++)
+ for (index = 2; index < a->argc; index++)
{
// get the conference name
- const char* name = argv[index] ;
- show_conference_list( fd, name );
+ const char* name = a->argv[index] ;
+ show_conference_list( a->fd, name );
}
}
else
{
- show_conference_stats(fd);
+ show_conference_stats(a->fd);
}
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-int conference_kick( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_kick(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- if ( argc < 4 )
- return RESULT_SHOWUSAGE ;
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference kick";
+ e->usage = "usage: conference kick <conference> <member id>\n"
+ " kick member <member id> from conference <conference>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE ;
// get the conference name
- const char* name = argv[2] ;
+ const char* name = a->argv[2] ;
int member_id;
- sscanf(argv[3], "%d", &member_id);
+ sscanf(a->argv[3], "%d", &member_id);
int res = kick_member( name, member_id );
- if (res) ast_cli( fd, "User #: %d kicked\n", member_id) ;
+ if (res) ast_cli( a->fd, "User #: %d kicked\n", member_id) ;
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-static char conference_kick_usage[] =
- "usage: conference kick <conference> <member id>\n"
- " kick member <member id> from conference <conference>\n"
-;
-
-static struct ast_cli_entry cli_kick = {
- { "conference", "kick", NULL },
- conference_kick,
- "kick member from a conference",
- conference_kick_usage
-} ;
-
-int conference_kickchannel( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_kickchannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- if ( argc < 4 )
- return RESULT_SHOWUSAGE ;
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference kickchannel";
+ e->usage = "usage: conference kickchannel <conference_name> <channel>\n"
+ " kick channel from conference\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE ;
- const char *name = argv[2] ;
- const char *channel = argv[3];
+ const char *name = a->argv[2] ;
+ const char *channel = a->argv[3];
int res = kick_channel( name, channel );
if ( !res )
{
- ast_cli( fd, "Cannot kick channel %s in conference %s\n", channel, name);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Cannot kick channel %s in conference %s\n", channel, name);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-static char conference_kickchannel_usage[] =
- "usage: conference kickchannel <conference_name> <channel>\n"
- " kick channel from conference\n"
-;
+static char *handle_cli_app_conference_exit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference exit";
+ e->usage = "usage: conference exit <channel>\n"
+ " exit channel from any conference where it in\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if ( a->argc < 3 )
+ return CLI_SHOWUSAGE ;
-static struct ast_cli_entry cli_kickchannel = {
- { "conference", "kickchannel", NULL },
- conference_kickchannel,
- "kick channel from conference",
- conference_kickchannel_usage
-} ;
+ const char *channel = a->argv[2];
+
+ struct ast_conf_member *member = find_member(channel, 1);
+ if(!member)
+ {
+ ast_cli( a->fd, "Member %s not found\n", channel);
+ return CLI_FAILURE;
+ }
+ const char * name = member->conf_name;
+ int res = kick_channel( name, channel );
+
+ if ( !res )
+ {
+ ast_cli( a->fd, "Cannot exit channel %s from conference %s\n", channel, name);
+ ast_mutex_unlock(&member->lock);
+ return CLI_FAILURE;
+ }
-int conference_mute( int fd, int argc, char *argv[] )
+ ast_mutex_unlock( &member->lock ) ;
+ return CLI_SUCCESS ;
+}
+
+static char *handle_cli_app_conference_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- if ( argc < 4 )
- return RESULT_SHOWUSAGE ;
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference mute";
+ e->usage = "usage: conference mute <conference_name> <member id>\n"
+ " mute member in a conference\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE ;
// get the conference name
- const char* name = argv[2] ;
+ const char* name = a->argv[2] ;
int member_id;
- sscanf(argv[3], "%d", &member_id);
+ sscanf(a->argv[3], "%d", &member_id);
int res = mute_member( name, member_id );
- if (res) ast_cli( fd, "User #: %d muted\n", member_id) ;
+ if (res) ast_cli( a->fd, "User #: %d muted\n", member_id) ;
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-static char conference_mute_usage[] =
- "usage: conference mute <conference_name> <member id>\n"
- " mute member in a conference\n"
-;
-
-static struct ast_cli_entry cli_mute = {
- { "conference", "mute", NULL },
- conference_mute,
- "mute member in a conference",
- conference_mute_usage
-} ;
-
-int conference_mutechannel( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_mutechannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference mutechannel";
+ e->usage = "usage: conference mutechannel <channel>\n"
+ " mute channel in a conference\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
struct ast_conf_member *member;
char *channel;
- if ( argc < 3 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 3 )
+ return CLI_SHOWUSAGE ;
- channel = argv[2];
+ channel = a->argv[2];
member = find_member(channel, 1);
if(!member) {
- ast_cli(fd, "Member %s not found\n", channel);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Member %s not found\n", channel);
+ return CLI_FAILURE;
}
member->mute_audio = 1;
ast_mutex_unlock( &member->lock ) ;
- ast_cli( fd, "Channel #: %s muted\n", argv[2]) ;
+ ast_cli( a->fd, "Channel #: %s muted\n", a->argv[2]) ;
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-static char conference_mutechannel_usage[] =
- "usage: conference mutechannel <channel>\n"
- " mute channel in a conference\n"
-;
-
-static struct ast_cli_entry cli_mutechannel = {
- { "conference", "mutechannel", NULL },
- conference_mutechannel,
- "mute channel in a conference",
- conference_mutechannel_usage
-} ;
-
-int conference_viewstream( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_viewstream(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference viewstream";
+ e->usage = "usage: conference viewstream <conference_name> <member id> <stream no>\n"
+ " member <member id> will receive video stream <stream no>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
int res;
- if ( argc < 5 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE ;
// get the conference name
- const char* switch_name = argv[2] ;
+ const char* switch_name = a->argv[2] ;
int member_id, viewstream_id;
- sscanf(argv[3], "%d", &member_id);
- sscanf(argv[4], "%d", &viewstream_id);
+ sscanf(a->argv[3], "%d", &member_id);
+ sscanf(a->argv[4], "%d", &viewstream_id);
res = viewstream_switch( switch_name, member_id, viewstream_id );
- if (res) ast_cli( fd, "User #: %d viewing %d\n", member_id, viewstream_id) ;
+ if (res) ast_cli( a->fd, "User #: %d viewing %d\n", member_id, viewstream_id) ;
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-static char conference_viewstream_usage[] =
- "usage: conference viewstream <conference_name> <member id> <stream no>\n"
- " member <member id> will receive video stream <stream no>\n"
-;
-
-static struct ast_cli_entry cli_viewstream = {
- { "conference", "viewstream", NULL },
- conference_viewstream,
- "switch view in a conference",
- conference_viewstream_usage
-} ;
-
-int conference_viewchannel( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_viewchannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference viewchannel";
+ e->usage = "usage: conference viewchannel <conference_name> <dest channel> <src channel>\n"
+ " channel <dest channel> will receive video stream <src channel>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
int res;
- if ( argc < 5 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE ;
// get the conference name
- const char* switch_name = argv[2] ;
+ const char* switch_name = a->argv[2] ;
- res = viewchannel_switch( switch_name, argv[3], argv[4] );
+ res = viewchannel_switch( switch_name, a->argv[3], a->argv[4] );
- if (res) ast_cli( fd, "Channel #: %s viewing %s\n", argv[3], argv[4]) ;
+ if (res) ast_cli( a->fd, "Channel #: %s viewing %s\n", a->argv[3], a->argv[4]) ;
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-static char conference_viewchannel_usage[] =
- "usage: conference viewchannel <conference_name> <dest channel> <src channel>\n"
- " channel <dest channel> will receive video stream <src channel>\n"
-;
-
-static struct ast_cli_entry cli_viewchannel = {
- { "conference", "viewchannel", NULL },
- conference_viewchannel,
- "switch channel in a conference",
- conference_viewchannel_usage
-} ;
-
-int conference_unmute( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_unmute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- if ( argc < 4 )
- return RESULT_SHOWUSAGE ;
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference unmute";
+ e->usage = "usage: conference unmute <conference_name> <member id>\n"
+ " unmute member in a conference\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE ;
// get the conference name
- const char* name = argv[2] ;
+ const char* name = a->argv[2] ;
int member_id;
- sscanf(argv[3], "%d", &member_id);
+ sscanf(a->argv[3], "%d", &member_id);
int res = unmute_member( name, member_id );
- if (res) ast_cli( fd, "User #: %d unmuted\n", member_id) ;
+ if (res) ast_cli( a->fd, "User #: %d unmuted\n", member_id) ;
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-static char conference_unmute_usage[] =
- "usage: conference unmute <conference_name> <member id>\n"
- " unmute member in a conference\n"
-;
-
-static struct ast_cli_entry cli_unmute = {
- { "conference", "unmute", NULL },
- conference_unmute,
- "unmute member in a conference",
- conference_unmute_usage
-} ;
-
-int conference_unmutechannel( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_unmutechannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference unmutechannel";
+ e->usage = "usage: conference unmutechannel <channel>\n"
+ " unmute channel in a conference\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
struct ast_conf_member *member;
char *channel;
- if ( argc < 3 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 3 )
+ return CLI_SHOWUSAGE ;
- channel = argv[2];
+ channel = a->argv[2];
member = find_member(channel, 1);
if(!member) {
- ast_cli(fd, "Member %s not found\n", channel);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Member %s not found\n", channel);
+ return CLI_FAILURE;
}
member->mute_audio = 0;
ast_mutex_unlock( &member->lock ) ;
- ast_cli( fd, "Channel #: %s unmuted\n", argv[2]) ;
+ ast_cli( a->fd, "Channel #: %s unmuted\n", a->argv[2]) ;
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-static char conference_unmutechannel_usage[] =
- "usage: conference unmutechannel <channel>\n"
- " unmute channel in a conference\n"
-;
-
-static struct ast_cli_entry cli_unmutechannel = {
- { "conference", "unmutechannel", NULL },
- conference_unmutechannel,
- "unmute channel in a conference",
- conference_unmutechannel_usage
-} ;
-
-//
-// play sound
-//
-static char conference_play_sound_usage[] =
- "usage: conference play sound <channel-id> <sound-file> [mute]\n"
- " play sound <sound-file> to conference member <channel-id>.\n"
- " If mute is specified, all other audio is muted while the sound is played back.\n"
-;
-
-static struct ast_cli_entry cli_play_sound = {
- { "conference", "play", "sound", NULL },
- conference_play_sound,
- "play a sound to a conference member",
- conference_play_sound_usage
-} ;
-
-int conference_play_sound( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_play_sound(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference play sound";
+ e->usage = "usage: conference play sound <channel-id> <sound-file> [mute]\n"
+ " play sound <sound-file> to conference member <channel-id>.\n"
+ " If mute is specified, all other audio is muted while the sound is played back.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
char *channel, *file;
int mute = 0;
- if ( argc < 5 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE ;
- channel = argv[3];
- file = argv[4];
+ channel = a->argv[3];
+ file = a->argv[4];
- if(argc > 5 && !strcmp(argv[5], "mute"))
+ if(a->argc > 5 && !strcmp(a->argv[5], "mute"))
mute = 1;
- int res = play_sound_channel(fd, channel, file, mute);
+ int res = play_sound_channel(a->fd, channel, file, mute);
if ( !res )
{
- ast_cli(fd, "Sound playback failed failed\n");
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Sound playback failed failed\n");
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-//
-// stop sounds
-//
-
-static char conference_stop_sounds_usage[] =
- "usage: conference stop sounds <channel-id>\n"
- " stop sounds for conference member <channel-id>.\n"
-;
-
-static struct ast_cli_entry cli_stop_sounds = {
- { "conference", "stop", "sounds", NULL },
- conference_stop_sounds,
- "stop sounds for a conference member",
- conference_stop_sounds_usage
-} ;
-
-int conference_stop_sounds( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_stop_sounds(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference play sound";
+ e->usage = "usage: conference stop sounds <channel-id>\n"
+ " stop sounds for conference member <channel-id>.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
char *channel;
- if ( argc < 4 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE ;
- channel = argv[3];
+ channel = a->argv[3];
- int res = stop_sound_channel(fd, channel);
+ int res = stop_sound_channel( a->fd, channel);
if ( !res )
{
- ast_cli(fd, "Sound stop failed failed\n");
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Sound stop failed failed\n");
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-//
-// end conference
-//
-
-static char conference_end_usage[] =
- "usage: conference end <conference name>\n"
- " ends a conference.\n"
-;
-
-static struct ast_cli_entry cli_end = {
- { "conference", "end", NULL },
- conference_end,
- "stops a conference",
- conference_end_usage
-} ;
-
-int conference_end( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_end(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference end";
+ e->usage = "usage: conference end <conference name>\n"
+ " ends a conference.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check the args length
- if ( argc < 3 )
- return RESULT_SHOWUSAGE ;
+ if ( a->argc < 3 )
+ return CLI_SHOWUSAGE ;
// conference name
- const char* name = argv[2] ;
+ const char* name = a->argv[2] ;
// get the conference
if ( end_conference( name, 1 ) != 0 )
{
- ast_cli( fd, "unable to end the conference, name => %s\n", name ) ;
- return RESULT_SHOWUSAGE ;
+ ast_cli( a->fd, "unable to end the conference, name => %s\n", name ) ;
+ return CLI_SHOWUSAGE ;
}
- return RESULT_SUCCESS ;
+ return CLI_SUCCESS ;
}
-//
-// E.BUU - Manager conference end. Additional option to just kick everybody out
-// without hangin up channels
-//
-int manager_conference_end(struct mansession *s, const struct message *m)
+static char *handle_cli_app_conference_lock(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- const char *confname = astman_get_header(m,"Conference");
- int hangup = 1;
-
- const char * h = astman_get_header(m, "Hangup");
- if (h)
- {
- hangup = atoi(h);
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference lock";
+ e->usage = "usage: conference lock <conference name> <member id>\n"
+ " locks incoming video stream for conference <conference name> to member <member id>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
}
- ast_log( LOG_NOTICE, "Terminating conference %s on manager's request. Hangup: %s.\n", confname, hangup?"YES":"NO" );
- if ( end_conference( confname, hangup ) != 0 )
- {
- ast_log( LOG_ERROR, "manager end conf: unable to terminate conference %s.\n", confname );
- astman_send_error(s, m, "Failed to terminate\r\n");
- return RESULT_FAILURE;
- }
-
- astman_send_ack(s, m, "Conference terminated");
- return RESULT_SUCCESS;
-}
-//
-// lock conference to a video source
-//
-static char conference_lock_usage[] =
- "usage: conference lock <conference name> <member id>\n"
- " locks incoming video stream for conference <conference name> to member <member id>\n"
-;
-
-static struct ast_cli_entry cli_lock = {
- { "conference", "lock", NULL },
- conference_lock,
- "locks incoming video to a member",
- conference_lock_usage
-} ;
-
-int conference_lock( int fd, int argc, char *argv[] )
-{
// check args
- if ( argc < 4 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[2];
+ const char *conference = a->argv[2];
int member;
- sscanf(argv[3], "%d", &member);
+ sscanf(a->argv[3], "%d", &member);
int res = lock_conference(conference, member);
if ( !res )
{
- ast_cli(fd, "Locking failed\n");
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Locking failed\n");
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// lock conference to a video source channel
-//
-static char conference_lockchannel_usage[] =
- "usage: conference lockchannel <conference name> <channel>\n"
- " locks incoming video stream for conference <conference name> to channel <channel>\n"
-;
-
-static struct ast_cli_entry cli_lockchannel = {
- { "conference", "lockchannel", NULL },
- conference_lockchannel,
- "locks incoming video to a channel",
- conference_lockchannel_usage
-} ;
-
-int conference_lockchannel( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_lockchannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference lockchannel";
+ e->usage = "usage: conference lockchannel <conference name> <channel>\n"
+ " locks incoming video stream for conference <conference name> to channel <channel>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 4 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[2];
- const char *channel = argv[3];
+ const char *conference = a->argv[2];
+ const char *channel = a->argv[3];
int res = lock_conference_channel(conference, channel);
if ( !res )
{
- ast_cli(fd, "Locking failed\n");
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Locking failed\n");
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// unlock conference
-//
-static char conference_unlock_usage[] =
- "usage: conference unlock <conference name>\n"
- " unlocks conference <conference name>\n"
-;
-
-static struct ast_cli_entry cli_unlock = {
- { "conference", "unlock", NULL },
- conference_unlock,
- "unlocks conference",
- conference_unlock_usage
-} ;
-
-int conference_unlock( int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_unlock(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference unlock";
+ e->usage = "usage: conference unlock <conference name>\n"
+ " unlocks conference <conference name>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 3 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 3 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[2];
+ const char *conference = a->argv[2];
int res = unlock_conference(conference);
if ( !res )
{
- ast_cli(fd, "Unlocking failed\n");
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Unlocking failed\n");
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Set conference default video source
-//
-static char conference_set_default_usage[] =
- "usage: conference set default <conference name> <member id>\n"
- " sets the default video source for conference <conference name> to member <member id>\n"
- " Use a negative value for member if you want to clear the default\n"
-;
-
-static struct ast_cli_entry cli_set_default = {
- { "conference", "set", "default", NULL },
- conference_set_default,
- "sets default video source",
- conference_set_default_usage
-} ;
-
-int conference_set_default(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_set_default(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference set default";
+ e->usage = "usage: conference set default <conference name> <member id>\n"
+ " sets the default video source for conference <conference name> to member <member id>\n"
+ " Use a negative value for member if you want to clear the default\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 5 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[3];
+ const char *conference = a->argv[3];
int member;
- sscanf(argv[4], "%d", &member);
+ sscanf(a->argv[4], "%d", &member);
int res = set_default_id(conference, member);
if ( !res )
{
- ast_cli(fd, "Setting default video id failed\n");
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Setting default video id failed\n");
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Set conference default video source channel
-//
-static char conference_set_defaultchannel_usage[] =
- "usage: conference set defaultchannel <conference name> <channel>\n"
- " sets the default video source channel for conference <conference name> to channel <channel>\n"
-;
-
-static struct ast_cli_entry cli_set_defaultchannel = {
- { "conference", "set", "defaultchannel", NULL },
- conference_set_defaultchannel,
- "sets default video source channel",
- conference_set_defaultchannel_usage
-} ;
-
-int conference_set_defaultchannel(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_set_defaultchannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference set defaultchannel";
+ e->usage = "usage: conference set defaultchannel <conference name> <channel>\n"
+ " sets the default video source channel for conference <conference name> to channel <channel>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 5 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[3];
- const char *channel = argv[4];
+ const char *conference = a->argv[3];
+ const char *channel = a->argv[4];
int res = set_default_channel(conference, channel);
if ( !res )
{
- ast_cli(fd, "Setting default video id failed\n");
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Setting default video id failed\n");
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Mute video from a member
-//
-static char conference_video_mute_usage[] =
- "usage: conference video mute <conference name> <member id>\n"
- " mutes video from member <member id> in conference <conference name>\n"
-;
-
-static struct ast_cli_entry cli_video_mute = {
- { "conference", "video", "mute", NULL },
- conference_video_mute,
- "mutes video from a member",
- conference_video_mute_usage
-} ;
-
-int conference_video_mute(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_video_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference video mute";
+ e->usage = "usage: conference video mute <conference name> <member id>\n"
+ " mutes video from member <member id> in conference <conference name>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 5 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[3];
+ const char *conference = a->argv[3];
int member;
- sscanf(argv[4], "%d", &member);
+ sscanf(a->argv[4], "%d", &member);
int res = video_mute_member(conference, member);
if ( !res )
{
- ast_cli(fd, "Muting video from member %d failed\n", member);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Muting video from member %d failed\n", member);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Unmute video from a member
-//
-static char conference_video_unmute_usage[] =
- "usage: conference video unmute <conference name> <member id>\n"
- " unmutes video from member <member id> in conference <conference name>\n"
-;
-
-static struct ast_cli_entry cli_video_unmute = {
- { "conference", "video", "unmute", NULL },
- conference_video_unmute,
- "unmutes video from a member",
- conference_video_unmute_usage
-} ;
-
-int conference_video_unmute(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_video_unmute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference video unmute";
+ e->usage = "usage: conference video unmute <conference name> <member id>\n"
+ " unmutes video from member <member id> in conference <conference name>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 5 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[3];
+ const char *conference = a->argv[3];
int member;
- sscanf(argv[4], "%d", &member);
+ sscanf(a->argv[4], "%d", &member);
int res = video_unmute_member(conference, member);
if ( !res )
{
- ast_cli(fd, "Unmuting video from member %d failed\n", member);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Unmuting video from member %d failed\n", member);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Mute video from a channel
-//
-static char conference_video_mutechannel_usage[] =
- "usage: conference video mutechannel <conference name> <channel>\n"
- " mutes video from channel <channel> in conference <conference name>\n"
-;
-
-static struct ast_cli_entry cli_video_mutechannel = {
- { "conference", "video", "mutechannel", NULL },
- conference_video_mutechannel,
- "mutes video from a channel",
- conference_video_mutechannel_usage
-} ;
-
-int conference_video_mutechannel(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_video_mutechannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference video mutechannel";
+ e->usage = "usage: conference video mutechannel <conference name> <channel>\n"
+ " mutes video from channel <channel> in conference <conference name>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 5 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[3];
- const char *channel = argv[4];
+ const char *conference = a->argv[3];
+ const char *channel = a->argv[4];
int res = video_mute_channel(conference, channel);
if ( !res )
{
- ast_cli(fd, "Muting video from channel %s failed\n", channel);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Muting video from channel %s failed\n", channel);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Unmute video from a channel
-//
-static char conference_video_unmutechannel_usage[] =
- "usage: conference video unmutechannel <conference name> <channel>\n"
- " unmutes video from channel <channel> in conference <conference name>\n"
-;
-
-static struct ast_cli_entry cli_video_unmutechannel = {
- { "conference", "video", "unmutechannel", NULL },
- conference_video_unmutechannel,
- "unmutes video from a channel",
- conference_video_unmutechannel_usage
-} ;
-
-int conference_video_unmutechannel(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_video_unmutechannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference video unmutechannel";
+ e->usage = "usage: conference video unmutechannel <conference name> <channel>\n"
+ " unmutes video from channel <channel> in conference <conference name>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 5 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[3];
- const char *channel = argv[4];
+ const char *conference = a->argv[3];
+ const char *channel = a->argv[4];
int res = video_unmute_channel(conference, channel);
if ( !res )
{
- ast_cli(fd, "Unmuting video from channel %s failed\n", channel);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Unmuting video from channel %s failed\n", channel);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-
-//
-// Text message functions
-// Send a text message to a member
-//
-static char conference_text_usage[] =
- "usage: conference text <conference name> <member id> <text>\n"
- " Sends text message <text> to member <member id> in conference <conference name>\n"
-;
-
-static struct ast_cli_entry cli_text = {
- { "conference", "text", NULL },
- conference_text,
- "sends a text message to a member",
- conference_text_usage
-} ;
-
-int conference_text(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_text(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference text";
+ e->usage = "usage: conference text <conference name> <member id> <text>\n"
+ " Sends text message <text> to member <member id> in conference <conference name>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 5 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[2];
+ const char *conference = a->argv[2];
int member;
- sscanf(argv[3], "%d", &member);
- const char *text = argv[4];
+ sscanf(a->argv[3], "%d", &member);
+ const char *text = a->argv[4];
int res = send_text(conference, member, text);
if ( !res )
{
- ast_cli(fd, "Sending a text message to member %d failed\n", member);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Sending a text message to member %d failed\n", member);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Send a text message to a channel
-//
-static char conference_textchannel_usage[] =
- "usage: conference textchannel <conference name> <channel> <text>\n"
- " Sends text message <text> to channel <channel> in conference <conference name>\n"
-;
-
-static struct ast_cli_entry cli_textchannel = {
- { "conference", "textchannel", NULL },
- conference_textchannel,
- "sends a text message to a channel",
- conference_textchannel_usage
-} ;
-
-int conference_textchannel(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_textchannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference textchannel";
+ e->usage = "usage: conference textchannel <conference name> <channel> <text>\n"
+ " Sends text message <text> to channel <channel> in conference <conference name>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 5 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 5 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[2];
- const char *channel = argv[3];
- const char *text = argv[4];
+ const char *conference = a->argv[2];
+ const char *channel = a->argv[3];
+ const char *text = a->argv[4];
int res = send_text_channel(conference, channel, text);
if ( !res )
{
- ast_cli(fd, "Sending a text message to channel %s failed\n", channel);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Sending a text message to channel %s failed\n", channel);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Send a text message to all members in a conference
-//
-static char conference_textbroadcast_usage[] =
- "usage: conference textbroadcast <conference name> <text>\n"
- " Sends text message <text> to all members in conference <conference name>\n"
-;
-
-static struct ast_cli_entry cli_textbroadcast = {
- { "conference", "textbroadcast", NULL },
- conference_textbroadcast,
- "sends a text message to all members in a conference",
- conference_textbroadcast_usage
-} ;
-
-int conference_textbroadcast(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_textbroadcast(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference textbroadcast";
+ e->usage = "usage: conference textbroadcast <conference name> <text>\n"
+ " Sends text message <text> to all members in conference <conference name>\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 4 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[2];
- const char *text = argv[3];
+ const char *conference = a->argv[2];
+ const char *text = a->argv[3];
int res = send_text_broadcast(conference, text);
if ( !res )
{
- ast_cli(fd, "Sending a text broadcast to conference %s failed\n", conference);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Sending a text broadcast to conference %s failed\n", conference);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Associate two members
-// Audio from the source member will drive VAD based video switching for the destination member
-// If the destination member is missing or negative, break any existing association
-//
-static char conference_drive_usage[] =
- "usage: conference drive <conference name> <source member> [destination member]\n"
- " Drives VAD video switching of <destination member> using audio from <source member> in conference <conference name>\n"
- " If destination is missing or negative, break existing association\n"
-;
-
-static struct ast_cli_entry cli_drive = {
- { "conference", "drive", NULL },
- conference_drive,
- "pairs two members to drive VAD-based video switching",
- conference_drive_usage
-} ;
-
-int conference_drive(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_drive(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference drive";
+ e->usage = "usage: conference drive <conference name> <source member> [destination member]\n"
+ " Drives VAD video switching of <destination member> using audio from <source member> in conference <conference name>\n"
+ " If destination is missing or negative, break existing association\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 4 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[2];
+ const char *conference = a->argv[2];
int src_member = -1;
int dst_member = -1;
- sscanf(argv[3], "%d", &src_member);
- if ( argc > 4 )
- sscanf(argv[4], "%d", &dst_member);
+ sscanf(a->argv[3], "%d", &src_member);
+ if ( a->argc > 4 )
+ sscanf(a->argv[4], "%d", &dst_member);
int res = drive(conference, src_member, dst_member);
if ( !res )
{
- ast_cli(fd, "Pairing members %d and %d failed\n", src_member, dst_member);
- return RESULT_FAILURE;
+ ast_cli( a->fd, "Pairing members %d and %d failed\n", src_member, dst_member);
+ return CLI_FAILURE;
}
- return RESULT_SUCCESS;
+ return CLI_SUCCESS;
}
-//
-// Associate two channels
-// Audio from the source channel will drive VAD based video switching for the destination channel
-// If the destination channel is missing, break any existing association
-//
-static char conference_drivechannel_usage[] =
- "usage: conference drive <conference name> <source channel> [destination channel]\n"
- " Drives VAD video switching of <destination member> using audio from <source channel> in conference <conference channel>\n"
- " If destination is missing, break existing association\n"
-;
-
-static struct ast_cli_entry cli_drivechannel = {
- { "conference", "drivechannel", NULL },
- conference_drivechannel,
- "pairs two channels to drive VAD-based video switching",
- conference_drivechannel_usage
-} ;
-
-int conference_drivechannel(int fd, int argc, char *argv[] )
+static char *handle_cli_app_conference_drivechannel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
+ switch ( cmd ) {
+ case CLI_INIT:
+ e->command = "conference drivechannel";
+ e->usage = "usage: conference drive <conference name> <source channel> [destination channel]\n"
+ " Drives VAD video switching of <destination member> using audio from <source channel> in conference <conference channel>\n"
+ " If destination is missing, break existing association\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
// check args
- if ( argc < 4 )
- return RESULT_SHOWUSAGE;
+ if ( a->argc < 4 )
+ return CLI_SHOWUSAGE;
- const char *conference = argv[2];
- const char *src_channel = argv[3];
+ const char *conference = a->argv[2];
+ const char *src_channel = a->argv[3];
const char *dst_channel = NULL;
- if ( argc > 4 )
- dst_channel = argv[4];
+ if ( a->argc > 4 )
+ dst_channel = a->argv[4];
int res = drive_channel(conference, src_channel, dst_channel);
if ( !res )
{
- ast_cli(fd, "Pairing channels %s and %s failed\n", src_channel, dst_channel);
+ ast_cli( a->fd, "Pairing channels %s and %s failed\n", src_channel, dst_channel);
+ return CLI_FAILURE;
+ }
+
+ return CLI_SUCCESS;
+}
+
+static struct ast_cli_entry app_conference_clis[] = {
+ AST_CLI_DEFINE(handle_cli_app_conference_restart, "Restart a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_debug, "Enable debugging for a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_show_stats, "Display stats for active conferences"),
+ AST_CLI_DEFINE(handle_cli_app_conference_list, "List members of a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_kick, "Kick member from a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_kickchannel, "Kick channel from conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_exit, "Exit channel from any conference where it in"),
+ AST_CLI_DEFINE(handle_cli_app_conference_mute, "Mute member in a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_mutechannel, "Mute channel in a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_viewstream, "Switch view in a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_viewchannel, "Switch channel in a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_unmute, "Unmute member in a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_unmutechannel, "Unmute channel in a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_play_sound, "Play a sound to a conference member"),
+ AST_CLI_DEFINE(handle_cli_app_conference_stop_sounds, "Stop sounds for a conference member"),
+ AST_CLI_DEFINE(handle_cli_app_conference_end, "Stops a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_lock, "Locks incoming video to a member"),
+ AST_CLI_DEFINE(handle_cli_app_conference_lockchannel, "Locks incoming video to a channel"),
+ AST_CLI_DEFINE(handle_cli_app_conference_unlock, "Unlocks conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_set_default, "Sets default video sourcee"),
+ AST_CLI_DEFINE(handle_cli_app_conference_set_defaultchannel, "Sets default video source channel"),
+ AST_CLI_DEFINE(handle_cli_app_conference_video_mute, "Mutes video from a member"),
+ AST_CLI_DEFINE(handle_cli_app_conference_video_unmute, "Unmutes video from a member"),
+ AST_CLI_DEFINE(handle_cli_app_conference_video_mutechannel, "Mutes video from a channel"),
+ AST_CLI_DEFINE(handle_cli_app_conference_video_unmutechannel, "Unmutes video from a channel"),
+ AST_CLI_DEFINE(handle_cli_app_conference_text, "Sends a text message to a member"),
+ AST_CLI_DEFINE(handle_cli_app_conference_textchannel, "Sends a text message to a channel"),
+ AST_CLI_DEFINE(handle_cli_app_conference_textbroadcast, "Sends a text message to all members in a conference"),
+ AST_CLI_DEFINE(handle_cli_app_conference_drive, "Pairs two members to drive VAD-based video switching"),
+ AST_CLI_DEFINE(handle_cli_app_conference_drivechannel, "Pairs two channels to drive VAD-based video switching"),
+};
+
+//
+// E.BUU - Manager conference end. Additional option to just kick everybody out
+// without hangin up channels
+//
+int manager_conference_end(struct mansession *s, const struct message *m)
+{
+ const char *confname = astman_get_header(m,"Conference");
+ int hangup = 1;
+
+ const char * h = astman_get_header(m, "Hangup");
+ if (h)
+ {
+ hangup = atoi(h);
+ }
+
+ ast_log( LOG_NOTICE, "Terminating conference %s on manager's request. Hangup: %s.\n", confname, hangup?"YES":"NO" );
+ if ( end_conference( confname, hangup ) != 0 )
+ {
+ ast_log( LOG_ERROR, "manager end conf: unable to terminate conference %s.\n", confname );
+ astman_send_error(s, m, "Failed to terminate\r\n");
return RESULT_FAILURE;
}
+ astman_send_ack(s, m, "Conference terminated");
return RESULT_SUCCESS;
}
-
//
// cli initialization function
//
void register_conference_cli( void )
{
- ast_cli_register( &cli_restart );
- ast_cli_register( &cli_debug ) ;
- ast_cli_register( &cli_show_stats ) ;
- ast_cli_register( &cli_list );
- ast_cli_register( &cli_kick );
- ast_cli_register( &cli_kickchannel );
- ast_cli_register( &cli_mute );
- ast_cli_register( &cli_mutechannel );
- ast_cli_register( &cli_viewstream );
- ast_cli_register( &cli_viewchannel );
- ast_cli_register( &cli_unmute );
- ast_cli_register( &cli_unmutechannel );
- ast_cli_register( &cli_play_sound ) ;
- ast_cli_register( &cli_stop_sounds ) ;
- ast_cli_register( &cli_end );
- ast_cli_register( &cli_lock );
- ast_cli_register( &cli_lockchannel );
- ast_cli_register( &cli_unlock );
- ast_cli_register( &cli_set_default );
- ast_cli_register( &cli_set_defaultchannel );
- ast_cli_register( &cli_video_mute ) ;
- ast_cli_register( &cli_video_unmute ) ;
- ast_cli_register( &cli_video_mutechannel ) ;
- ast_cli_register( &cli_video_unmutechannel ) ;
- ast_cli_register( &cli_text );
- ast_cli_register( &cli_textchannel );
- ast_cli_register( &cli_textbroadcast );
- ast_cli_register( &cli_drive );
- ast_cli_register( &cli_drivechannel );
+ ast_cli_register_multiple(app_conference_clis, sizeof(app_conference_clis) / sizeof(struct ast_cli_entry));
ast_manager_register( "ConferenceList", 0, manager_conference_list, "Conference List" );
ast_manager_register( "ConferenceEnd", EVENT_FLAG_CALL, manager_conference_end, "Terminate a conference" );
@@ -1191,35 +1110,7 @@
void unregister_conference_cli( void )
{
- ast_cli_unregister( &cli_restart );
- ast_cli_unregister( &cli_debug ) ;
- ast_cli_unregister( &cli_show_stats ) ;
- ast_cli_unregister( &cli_list );
- ast_cli_unregister( &cli_kick );
- ast_cli_unregister( &cli_kickchannel );
- ast_cli_unregister( &cli_mute );
- ast_cli_unregister( &cli_mutechannel );
- ast_cli_unregister( &cli_viewstream );
- ast_cli_unregister( &cli_viewchannel );
- ast_cli_unregister( &cli_unmute );
- ast_cli_unregister( &cli_unmutechannel );
- ast_cli_unregister( &cli_play_sound ) ;
- ast_cli_unregister( &cli_stop_sounds ) ;
- ast_cli_unregister( &cli_end );
- ast_cli_unregister( &cli_lock );
- ast_cli_unregister( &cli_lockchannel );
- ast_cli_unregister( &cli_unlock );
- ast_cli_unregister( &cli_set_default );
- ast_cli_unregister( &cli_set_defaultchannel );
- ast_cli_unregister( &cli_video_mute ) ;
- ast_cli_unregister( &cli_video_unmute ) ;
- ast_cli_unregister( &cli_video_mutechannel ) ;
- ast_cli_unregister( &cli_video_unmutechannel ) ;
- ast_cli_unregister( &cli_text );
- ast_cli_unregister( &cli_textchannel );
- ast_cli_unregister( &cli_textbroadcast );
- ast_cli_unregister( &cli_drive );
- ast_cli_unregister( &cli_drivechannel );
+ ast_cli_unregister_multiple(app_conference_clis, sizeof(app_conference_clis) / sizeof(struct ast_cli_entry));
ast_manager_unregister( "ConferenceList" );
ast_manager_unregister( "ConferenceEnd" );
}
Index: cli.h
--- cli.h.orig 2008-02-26 17:05:57 +0100
+++ cli.h 2008-03-19 09:18:57 +0100
@@ -42,52 +42,6 @@
// function declarations
//
-int conference_show_stats( int fd, int argc, char *argv[] ) ;
-int conference_show_stats_name( int fd, const char* name ) ;
-
-int conference_restart( int fd, int argc, char *argv[] );
-
-int conference_debug( int fd, int argc, char *argv[] ) ;
-int conference_no_debug( int fd, int argc, char *argv[] ) ;
-
-int conference_list( int fd, int argc, char *argv[] ) ;
-int conference_kick( int fd, int argc, char *argv[] ) ;
-int conference_kickchannel( int fd, int argc, char *argv[] ) ;
-
-int conference_mute( int fd, int argc, char *argv[] ) ;
-int conference_unmute( int fd, int argc, char *argv[] ) ;
-int conference_mutechannel( int fd, int argc, char *argv[] ) ;
-int conference_unmutechannel( int fd, int argc, char *argv[] ) ;
-int conference_viewstream( int fd, int argc, char *argv[] ) ;
-int conference_viewchannel( int fd, int argc, char *argv[] ) ;
-
-int conference_play_sound( int fd, int argc, char *argv[] ) ;
-int conference_stop_sounds( int fd, int argc, char *argv[] ) ;
-
-int conference_play_video( int fd, int argc, char *argv[] ) ;
-int conference_stop_videos( int fd, int argc, char *argv[] ) ;
-
-int conference_end( int fd, int argc, char *argv[] ) ;
-
-int conference_lock( int fd, int argc, char *argv[] ) ;
-int conference_lockchannel( int fd, int argc, char *argv[] ) ;
-int conference_unlock( int fd, int argc, char *argv[] ) ;
-
-int conference_set_default(int fd, int argc, char *argv[] ) ;
-int conference_set_defaultchannel(int fd, int argc, char *argv[] ) ;
-
-int conference_video_mute(int fd, int argc, char *argv[] ) ;
-int conference_video_mutechannel(int fd, int argc, char *argv[] ) ;
-int conference_video_unmute(int fd, int argc, char *argv[] ) ;
-int conference_video_unmutechannel(int fd, int argc, char *argv[] ) ;
-
-int conference_text( int fd, int argc, char *argv[] ) ;
-int conference_textchannel( int fd, int argc, char *argv[] ) ;
-int conference_textbroadcast( int fd, int argc, char *argv[] ) ;
-
-int conference_drive( int fd, int argc, char *argv[] ) ;
-int conference_drivechannel(int fd, int argc, char *argv[] );
-
int manager_conference_end(struct mansession *s, const struct message *m);
void register_conference_cli( void ) ;
Index: conference.c
--- conference.c.orig 2008-02-26 17:05:57 +0100
+++ conference.c 2008-03-19 09:18:57 +0100
@@ -28,6 +28,9 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "asterisk.h"
+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.1 $")
+
#include "asterisk/autoconfig.h"
#include "conference.h"
#include "asterisk/utils.h"
@@ -45,12 +48,21 @@
static int conference_count = 0 ;
+// Forward funtcion declarations
+static void do_VAD_switching(struct ast_conference *conf);
+static void do_video_switching(struct ast_conference *conf, int new_id, int lock);
+static struct ast_conference* find_conf(const char* name);
+static struct ast_conference* create_conf(char* name, struct ast_conf_member* member);
+static void remove_conf(struct ast_conference* conf);
+static void add_member(struct ast_conf_member* member, struct ast_conference* conf);
+static int get_new_id(struct ast_conference *conf);
+static int update_member_broadcasting(struct ast_conference *conf, struct ast_conf_member *member, struct conf_frame *cfr, struct timeval time);
//
// main conference function
//
-void conference_exec( struct ast_conference *conf )
+static void conference_exec( struct ast_conference *conf )
{
struct ast_conf_member *next_member;
@@ -302,54 +314,126 @@
// VIDEO //
//-------//
- // loop over the incoming frames and send to all outgoing
- // TODO: this is an O(n^2) algorithm. Can we speed it up without sacrificing per-member switching?
- for (video_source_member = conf->memberlist;
- video_source_member != NULL;
- video_source_member = video_source_member->next)
+ curr = ast_tvnow();
+
+ // Chat mode handling
+ // If there's only one member, then video gets reflected back to it
+ // If there are two members, then each sees the other's video
+ if ( conf->does_chat_mode &&
+ conf->membercount > 0 &&
+ conf->membercount <= 2
+ )
+ {
+ struct ast_conf_member *m1, *m2;
+
+ m1 = conf->memberlist;
+ m2 = conf->memberlist->next;
+
+ if ( !conf->chat_mode_on )
+ conf->chat_mode_on = 1;
+
+ start_video(m1);
+ if ( m2 != NULL )
+ start_video(m2);
+
+ if ( conf->membercount == 1 )
+ {
+ cfr = get_incoming_video_frame(m1);
+ update_member_broadcasting(conf, m1, cfr, curr);
+ while ( cfr )
+ {
+ queue_outgoing_video_frame(m1, cfr->fr, conf->delivery_time);
+ delete_conf_frame(cfr);
+ cfr = get_incoming_video_frame(m1);
+ }
+ } else if ( conf->membercount == 2 )
+ {
+ cfr = get_incoming_video_frame(m1);
+ update_member_broadcasting(conf, m1, cfr, curr);
+ while ( cfr )
+ {
+ queue_outgoing_video_frame(m2, cfr->fr, conf->delivery_time);
+ delete_conf_frame(cfr);
+ cfr = get_incoming_video_frame(m1);
+ }
+
+ cfr = get_incoming_video_frame(m2);
+ update_member_broadcasting(conf, m2, cfr, curr);
+ while ( cfr )
+ {
+ queue_outgoing_video_frame(m1, cfr->fr, conf->delivery_time);
+ delete_conf_frame(cfr);
+ cfr = get_incoming_video_frame(m2);
+ }
+ }
+ } else
{
- while ((cfr = get_incoming_video_frame( video_source_member )))
+ // Generic conference handling (chat mode disabled or more than 2 members)
+ // If we were previously in chat mode, turn it off and stop video from members
+ if ( conf->chat_mode_on )
{
+ // Send STOPVIDEO commands to everybody except the current source, if any
+ conf->chat_mode_on = 0;
for (member = conf->memberlist; member != NULL; member = member->next)
{
- // skip members that are not ready or are not supposed to receive video
- if ( !member->ready_for_outgoing || member->norecv_video )
- continue ;
-
- if ( conf->video_locked )
- {
- // Always send video from the locked source
- if ( conf->current_video_source_id == video_source_member->id )
- queue_outgoing_video_frame(member, cfr->fr, conf->delivery_time);
- } else
+ if ( member->id != conf->current_video_source_id )
+ stop_video(member);
+ }
+ }
+
+ // loop over the incoming frames and send to all outgoing
+ // TODO: this is an O(n^2) algorithm. Can we speed it up without sacrificing per-member switching?
+ for (video_source_member = conf->memberlist;
+ video_source_member != NULL;
+ video_source_member = video_source_member->next
+ )
+ {
+ cfr = get_incoming_video_frame(video_source_member);
+ update_member_broadcasting(conf, video_source_member, cfr, curr);
+ while ( cfr )
+ {
+ for (member = conf->memberlist; member != NULL; member = member->next)
{
- // If the member has vad switching disabled and dtmf switching enabled, use that
- if ( member->dtmf_switch &&
- !member->vad_switch &&
- member->req_id == video_source_member->id
- )
+ // skip members that are not ready or are not supposed to receive video
+ if ( !member->ready_for_outgoing || member->norecv_video )
+ continue ;
+
+ if ( conf->video_locked )
{
- queue_outgoing_video_frame(member, cfr->fr, conf->delivery_time);
+ // Always send video from the locked source
+ if ( conf->current_video_source_id == video_source_member->id )
+ queue_outgoing_video_frame(member, cfr->fr, conf->delivery_time);
} else
{
- // If no dtmf switching, then do VAD switching
- // The VAD switching decision code should make sure that our video source
- // is legit
- if ( (conf->current_video_source_id == video_source_member->id) ||
- (conf->current_video_source_id < 0 &&
- conf->default_video_source_id == video_source_member->id
- )
+ // If the member has vad switching disabled and dtmf switching enabled, use that
+ if ( member->dtmf_switch &&
+ !member->vad_switch &&
+ member->req_id == video_source_member->id
)
{
queue_outgoing_video_frame(member, cfr->fr, conf->delivery_time);
+ } else
+ {
+ // If no dtmf switching, then do VAD switching
+ // The VAD switching decision code should make sure that our video source
+ // is legit
+ if ( (conf->current_video_source_id == video_source_member->id) ||
+ (conf->current_video_source_id < 0 &&
+ conf->default_video_source_id == video_source_member->id
+ )
+ )
+ {
+ queue_outgoing_video_frame(member, cfr->fr, conf->delivery_time);
+ }
}
- }
+ }
}
+ // Garbage collection
+ delete_conf_frame(cfr);
+ cfr = get_incoming_video_frame(video_source_member);
}
- // Garbage collection
- delete_conf_frame(cfr);
}
}
@@ -448,7 +532,7 @@
ast_mutex_init( &conflist_lock ) ;
}
-struct ast_conference* start_conference( struct ast_conf_member* member )
+struct ast_conference* join_conference( struct ast_conf_member* member )
{
// check input
if ( member == NULL )
@@ -499,7 +583,7 @@
}
// This function should be called with conflist_lock mutex being held
-struct ast_conference* find_conf( const char* name )
+static struct ast_conference* find_conf( const char* name )
{
// no conferences exist
if ( conflist == NULL )
@@ -527,7 +611,7 @@
}
// This function should be called with conflist_lock held
-struct ast_conference* create_conf( char* name, struct ast_conf_member* member )
+static struct ast_conference* create_conf( char* name, struct ast_conf_member* member )
{
ast_log( AST_CONF_DEBUG, "entered create_conf, name => %s\n", name ) ;
@@ -551,7 +635,7 @@
conf->memberlist = NULL ;
conf->membercount = 0 ;
- conf->conference_thread = -1 ;
+ conf->conference_thread = 0 ;
conf->debug_flag = 0 ;
@@ -562,6 +646,9 @@
//conf->current_video_source_timestamp = ast_tvnow();
conf->video_locked = 0;
+ conf->chat_mode_on = 0;
+ conf->does_chat_mode = 0;
+
// zero stats
memset( &conf->stats, 0x0, sizeof( ast_conference_stats ) ) ;
@@ -614,7 +701,7 @@
{
ast_log( LOG_ERROR, "unable to start conference thread for conference %s\n", conf->name ) ;
- conf->conference_thread = -1 ;
+ conf->conference_thread = 0 ;
// release conference mutexes
ast_mutex_unlock( &conf->lock ) ;
@@ -632,7 +719,7 @@
}
//This function should be called with conflist_lock and conf->lock held
-void remove_conf( struct ast_conference *conf )
+static void remove_conf( struct ast_conference *conf )
{
int c;
@@ -709,7 +796,7 @@
return ;
}
-int get_new_id( struct ast_conference *conf )
+static int get_new_id( struct ast_conference *conf )
{
// must have the conf lock when calling this
int newid;
@@ -788,11 +875,10 @@
//
// This function should be called with conflist_lock held
-void add_member( struct ast_conf_member *member, struct ast_conference *conf )
+static void add_member( struct ast_conf_member *member, struct ast_conference *conf )
{
int newid, last_id;
struct ast_conf_member *othermember;
- int count;
if ( conf == NULL )
{
@@ -820,11 +906,22 @@
}
}
- if ( member->mute_video )
+ // update conference stats
+ conf->membercount++;
+
+ // The conference sets chat mode according to the latest member chat flag
+ conf->does_chat_mode = member->does_chat_mode;
+
+ // check if we're supposed to do chat_mode, and if so, start video on the client
+ if ( conf->does_chat_mode && conf->membercount <= 2 )
{
- send_text_message_to_member(member, AST_CONF_CONTROL_STOP_VIDEO);
+ start_video(member);
+ conf->chat_mode_on = 1;
}
+ if ( member->mute_video )
+ stop_video(member);
+
// set a long term id
int new_initial_id = 0;
othermember = conf->memberlist;
@@ -853,9 +950,6 @@
member->next = conf->memberlist ; // next is now list
conf->memberlist = member ; // member is now at head of list
- // update conference stats
- count = count_member( member, conf, 1 ) ;
-
ast_log( AST_CONF_DEBUG, "member added to conference, name => %s\n", conf->name ) ;
// release the conference lock
@@ -957,7 +1051,7 @@
member_temp->next = member->next ;
// update conference stats
- count = count_member( member, conf, 0 ) ;
+ count = --conf->membercount;
// Check if member is the default or current video source
if ( conf->current_video_source_id == member->id )
@@ -970,6 +1064,17 @@
conf->default_video_source_id = -1;
}
+ // If the member is broadcasting, we notify that it is no longer the case
+ if ( member->video_broadcast_active )
+ {
+ manager_event(EVENT_FLAG_CALL,
+ "ConferenceVideoBroadcastOff",
+ "ConferenceName: %s\r\nChannel: %s\r\n",
+ conf->name,
+ member->channel_name
+ );
+ }
+
// output to manager...
manager_event(
EVENT_FLAG_CALL,
@@ -997,6 +1102,32 @@
// it already points to the previous (or NULL).
// it will still be the previous after member is deleted
+ // notify others about leave
+ char * leave_snd = member->leave_snd;
+ if (conf->membercount && strcmp(leave_snd, "-")>1)
+ {
+ struct ast_conf_member *membertest = conf->memberlist;
+ while (membertest != NULL)
+ {
+ if (membertest != member)
+ {
+ // lock member for basic_play_sound
+ ast_mutex_lock(&membertest->lock);
+
+ // basic_play_sound unlock member automatically. do not mute on enter message
+ if (!basic_play_sound (membertest, leave_snd, 0))
+ {
+ ast_log(LOG_ERROR, "playing conference[%d] leave message <%s> FAILED on <%s>\n", conf->membercount, leave_snd, membertest->channel_name) ;
+ }
+ else
+ {
+ ast_log(LOG_NOTICE, "playing conference[%d] leave message <%s> on <%s>\n", conf->membercount, leave_snd, membertest->channel_name);
+ }
+ membertest = membertest->next;
+ }
+ }
+ }
+
// delete the member
delete_member( member ) ;
@@ -1028,33 +1159,6 @@
return count ;
}
-int count_member( struct ast_conf_member* member, struct ast_conference* conf, short add_member )
-{
- if ( member == NULL || conf == NULL )
- {
- ast_log( LOG_WARNING, "unable to count member\n" ) ;
- return -1 ;
- }
-
- short delta = ( add_member == 1 ) ? 1 : -1 ;
-
- // increment member count
- conf->membercount += delta ;
-
- return conf->membercount ;
-}
-
-//
-// queue incoming frame functions
-//
-
-
-
-
-//
-// get conference stats
-//
-
//
// returns: -1 => error, 0 => debugging off, 1 => debugging on
// state: on => 1, off => 0, toggle => -1
@@ -1160,6 +1264,8 @@
// acquire conference mutex
ast_mutex_lock(&conf->lock);
+ ast_cli(fd, "Chat mode is %s\n", conf->chat_mode_on ? "ON" : "OFF");
+
// do the biz
member = conf->memberlist ;
while ( member != NULL )
@@ -1182,6 +1288,9 @@
if ( member->no_camera ) ast_cli( fd, "N");
if ( member->does_text ) ast_cli( fd, "t");
if ( member->via_telephone ) ast_cli( fd, "T");
+ if ( member->vad_linger ) ast_cli( fd, "z");
+ if ( member->does_chat_mode ) ast_cli( fd, "o" );
+ if ( member->force_vad_switch ) ast_cli( fd, "F" );
ast_cli( fd, " " );
if ( member->id == conf->default_video_source_id )
@@ -1871,16 +1980,18 @@
// All the VAD-based video switching magic happens here
// This function should be called inside conference_exec
// The conference mutex should be locked, we don't have to do it here
-void do_VAD_switching(struct ast_conference *conf)
+static void do_VAD_switching(struct ast_conference *conf)
{
struct ast_conf_member *member;
- struct timeval current_time;
- long longest_speaking;
- struct ast_conf_member *longest_speaking_member;
- int current_silent, current_no_camera, current_video_mute;
- int default_no_camera, default_video_mute;
-
- current_time = ast_tvnow();
+ struct timeval current_time = ast_tvnow();
+ long longest_speaking = 0;
+ struct ast_conf_member *longest_speaking_member = NULL;
+ int current_silent = 0;
+ int current_linger = 0;
+ int current_no_video = 0;
+ int current_force_switch = 0;
+ int default_no_video = 0;
+ int default_force_switch = 0;
// Scan the member list looking for the longest speaking member
// We also check if the currently speaking member has been silent for a while
@@ -1889,27 +2000,10 @@
// at least AST_CONF_VIDEO_START_TIMEOUT ms
// We say that a member is silent after his speaking state has been off for
// at least AST_CONF_VIDEO_STOP_TIMEOUT ms
- longest_speaking = 0;
- longest_speaking_member = NULL;
- current_silent = 0;
- current_no_camera = 0;
- current_video_mute = 0;
- default_no_camera = 0;
- default_video_mute = 0;
for ( member = conf->memberlist ;
member != NULL ;
member = member->next )
{
- // Has the state changed since last time through this loop? Notify!
- if ( member->speaking_state_notify )
- {
-/* fprintf(stderr, "Mihai: member %d, channel %s has changed state to %s\n",
- member->id,
- member->channel_name,
- ((member->speaking_state == 1 ) ? "speaking" : "silent")
- ); */
- }
-
// If a member connects via telephone, they don't have video
if ( member->via_telephone )
continue;
@@ -1920,29 +2014,30 @@
if ( !member->vad_switch )
continue;
- if ( member->mute_video )
+ // Extract the linger and force switch flags of the current video source
+ if ( member->id == conf->current_video_source_id )
{
- if ( member->id == conf->default_video_source_id )
- default_video_mute = 1;
- if ( member->id == conf->current_video_source_id )
- current_video_mute = 1;
- else
- continue;
+ current_linger = member->vad_linger;
+ current_force_switch = member->force_vad_switch;
}
+
+ if ( member->id == conf->default_video_source_id )
+ default_force_switch = member->force_vad_switch;
- if ( member->no_camera )
+ if ( member->no_camera || member->mute_video )
{
if ( member->id == conf->default_video_source_id )
- default_no_camera = 1;
+ default_no_video = 1;
+
if ( member->id == conf->current_video_source_id )
- current_no_camera = 1;
- else
+ current_no_video = 1;
+ else if ( !member->force_vad_switch )
continue;
}
// Check if current speaker has been silent for a while
if ( member->id == conf->current_video_source_id &&
- member->speaking_state == 0 &&
+ !member->speaking_state &&
ast_tvdiff_ms(current_time, member->last_state_change) > AST_CONF_VIDEO_STOP_TIMEOUT )
{
current_silent = 1;
@@ -1963,27 +2058,33 @@
// We got our results, now let's make a decision
// If the currently speaking member has been marked as silent, then we take the longest
- // speaking member. If no member is speaking, we go to default
+ // speaking member. If no member is speaking, but the current member has the vad_linger
+ // flag set, we stay put, otherwise we go to default. If there's no default, we blank.
// As a policy we don't want to switch away from a member that is speaking
// however, we might need to refine this to avoid a situation when a member has a
// low noise threshold or its VAD is simply stuck
- if ( current_silent || current_no_camera || current_video_mute || conf->current_video_source_id < 0 )
- {
- if ( longest_speaking_member != NULL )
- {
- do_video_switching(conf, longest_speaking_member->id, 0);
- } else
- {
- // If there's nobody speaking and we have a default that can send video, switch to it
- // If not, then switch to empty (-1)
- if ( conf->default_video_source_id >= 0 &&
- !default_no_camera &&
- !default_video_mute
- )
- do_video_switching(conf, conf->default_video_source_id, 0);
- else
- do_video_switching(conf, -1, 0);
- }
+ if (
+ (conf->current_video_source_id < 0) ||
+ (current_silent && !current_linger) ||
+ (current_silent && longest_speaking_member != NULL ) ||
+ (current_no_video && !current_force_switch)
+ )
+ {
+ int new_id;
+
+ if ( longest_speaking_member )
+ // Somebody is talking, switch to that member
+ new_id = longest_speaking_member->id;
+ else if ( conf->default_video_source_id &&
+ (!default_no_video || default_force_switch)
+ )
+ // No talking, but we have a default that can send video
+ new_id = conf->default_video_source_id;
+ else
+ // No default, switch to empty (-1)
+ new_id = -1;
+
+ do_video_switching(conf, new_id, 0);
}
}
@@ -2752,80 +2853,62 @@
// a text message notifying members of a video switch
// The notification is sent to the current member and to the new member
// The function locks the conference mutex as required
-void do_video_switching(struct ast_conference *conf, int new_id, int lock)
+static void do_video_switching(struct ast_conference *conf, int new_id, int lock)
{
- struct ast_conf_member *member;
- struct ast_conf_member *new_member = NULL;
-
if ( conf == NULL ) return;
if ( lock )
- {
- // acquire conference mutex
ast_mutex_lock( &conf->lock );
- }
-
- //fprintf(stderr, "Mihai: video switch from %d to %d\n", conf->current_video_source_id, new_id);
// No need to do anything if the current member is the same as the new member
if ( new_id != conf->current_video_source_id )
{
+ // During chat mode, we don't actually switch members
+ // however, we keep track of who's supposed to be current speaker
+ // so we can switch to it once we get out of chat mode.
+ // We also send VideoSwitch events so anybody monitoring the AMI
+ // can keep track of this
+ struct ast_conf_member *member;
+ struct ast_conf_member *new_member = NULL;
+
for ( member = conf->memberlist ; member != NULL ; member = member->next )
{
if ( member->id == conf->current_video_source_id )
{
- send_text_message_to_member(member, AST_CONF_CONTROL_STOP_VIDEO);
+ if ( !conf->chat_mode_on )
+ stop_video(member);
}
if ( member->id == new_id )
{
- send_text_message_to_member(member, AST_CONF_CONTROL_START_VIDEO);
+ if ( !conf->chat_mode_on )
+ start_video(member);
new_member = member;
}
}
- conf->current_video_source_id = new_id;
+ manager_event(EVENT_FLAG_CALL,
+ "ConferenceVideoSwitch",
+ "ConferenceName: %s\r\nChannel: %s\r\n",
+ conf->name,
+ new_member == NULL ? "empty" : new_member->channel_name
+ );
- if ( new_member != NULL )
- {
- manager_event(EVENT_FLAG_CALL,
- "ConferenceVideoSwitch",
- "ConferenceName: %s\r\nChannel: %s\r\n",
- conf->name,
- new_member->channel_name);
- } else
- {
- manager_event(EVENT_FLAG_CALL,
- "ConferenceVideoSwitch",
- "ConferenceName: %s\r\nChannel: empty\r\n",
- conf->name);
- }
+ conf->current_video_source_id = new_id;
}
if ( lock )
- {
- // release conference mutex
ast_mutex_unlock( &conf->lock );
- }
}
-int play_sound_channel(int fd, const char *channel, const char *file, int mute)
+int basic_play_sound(struct ast_conf_member *member, const char *file, int mute)
{
- struct ast_conf_member *member;
struct ast_conf_soundq *newsound;
struct ast_conf_soundq **q;
- member = find_member(channel, 1);
- if( !member )
- {
- ast_cli(fd, "Member %s not found\n", channel);
- return 0;
- }
-
newsound = calloc(1, sizeof(struct ast_conf_soundq));
newsound->stream = ast_openstream(member->chan, file, NULL);
- if( !newsound->stream )
+ if( !newsound->stream )
{
- ast_cli(fd, "Sound %s not found\n", file);
free(newsound);
ast_mutex_unlock(&member->lock);
return 0;
@@ -2841,6 +2924,26 @@
ast_mutex_unlock(&member->lock);
+ return 1 ;
+}
+
+int play_sound_channel(int fd, const char *channel, const char *file, int mute)
+{
+ struct ast_conf_member *member;
+
+ member = find_member(channel, 1);
+ if( !member )
+ {
+ ast_cli(fd, "Member %s not found\n", channel);
+ return 0;
+ }
+
+ if (! basic_play_sound(member, file, mute))
+ {
+ ast_cli(fd, "Sound %s not found\n", file);
+ return 0;
+ }
+
ast_cli(fd, "Playing sound %s to member %s %s\n",
file, channel, mute ? "with mute" : "");
@@ -2884,3 +2987,38 @@
ast_cli( fd, "Stopped sounds to member %s\n", channel);
return 1;
}
+
+static int update_member_broadcasting(struct ast_conference *conf, struct ast_conf_member *member, struct conf_frame *cfr, struct timeval now)
+{
+ if ( conf == NULL || member == NULL )
+ return 0;
+
+ if ( cfr == NULL &&
+ member->video_broadcast_active &&
+ (ast_tvdiff_ms(now, member->last_video_frame_time)) > AST_CONF_VIDEO_STOP_BROADCAST_TIMEOUT
+ )
+ {
+ member->video_broadcast_active = 0;
+ manager_event(EVENT_FLAG_CALL,
+ "ConferenceVideoBroadcastOff",
+ "ConferenceName: %s\r\nChannel: %s\r\n",
+ conf->name,
+ member->channel_name
+ );
+ } else if ( cfr != NULL )
+ {
+ member->last_video_frame_time = now;
+ if ( !member->video_broadcast_active )
+ {
+ member->video_broadcast_active = 1;
+ manager_event(EVENT_FLAG_CALL,
+ "ConferenceVideoBroadcastOn",
+ "ConferenceName: %s\r\nChannel: %s\r\n",
+ conf->name,
+ member->channel_name
+ );
+ }
+ }
+
+ return member->video_broadcast_active;
+}
Index: conference.h
--- conference.h.orig 2008-02-26 17:05:57 +0100
+++ conference.h 2008-03-19 09:18:57 +0100
@@ -109,6 +109,12 @@
// keep track of current delivery time
struct timeval delivery_time ;
+ // the conference does chat mode: special treatment for situations with 1 and 2 members
+ short does_chat_mode;
+
+ // chat mode is on;
+ short chat_mode_on;
+
// 1 => on, 0 => off
short debug_flag ;
} ;
@@ -120,13 +126,8 @@
// function declarations
//
-struct ast_conference* start_conference( struct ast_conf_member* member ) ;
-
-void conference_exec( struct ast_conference* conf ) ;
+struct ast_conference* join_conference( struct ast_conf_member* member ) ;
-struct ast_conference* find_conf( const char* name ) ;
-struct ast_conference* create_conf( char* name, struct ast_conf_member* member ) ;
-void remove_conf( struct ast_conference* conf ) ;
int end_conference( const char *name, int hangup ) ;
// find a particular member, locking if requested.
@@ -136,14 +137,9 @@
int queue_frame_for_speaker( struct ast_conference* conf, struct ast_conf_member* member, conf_frame* frame ) ;
int queue_silent_frame( struct ast_conference* conf, struct ast_conf_member* member ) ;
-int get_new_id( struct ast_conference *conf );
-void add_member( struct ast_conf_member* member, struct ast_conference* conf ) ;
int remove_member( struct ast_conf_member* member, struct ast_conference* conf ) ;
-int count_member( struct ast_conf_member* member, struct ast_conference* conf, short add_member ) ;
-void do_VAD_switching(struct ast_conference *conf);
int send_text_message_to_member(struct ast_conf_member *member, const char *text);
-void do_video_switching(struct ast_conference *conf, int new_id, int lock);
// called by app_confernce.c:load_module()
void init_conference( void ) ;
@@ -185,6 +181,7 @@
int drive(const char *conference, int src_member_id, int dst_member_id);
int drive_channel(const char *conference, const char *src_channel, const char *dst_channel);
+int basic_play_sound(struct ast_conf_member *member, const char *file, int mute);
int play_sound_channel(int fd, const char *channel, const char *file, int mute);
int stop_sound_channel(int fd, const char *channel);
Index: frame.c
--- frame.c.orig 2008-02-26 17:05:57 +0100
+++ frame.c 2008-03-19 09:18:57 +0100
@@ -28,6 +28,10 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.1 $")
+
#include "asterisk/autoconfig.h"
#include "frame.h"
Index: member.c
--- member.c.orig 2008-02-26 17:05:57 +0100
+++ member.c 2008-03-19 09:18:57 +0100
@@ -28,7 +28,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.1 $")
+
#include <stdio.h>
+#include "asterisk/channel.h"
+#include "asterisk/app.h"
#include "asterisk/autoconfig.h"
#include "member.h"
@@ -635,7 +641,7 @@
// setup a conference for the new member
//
- conf = start_conference( member ) ;
+ conf = join_conference( member ) ;
if ( conf == NULL )
{
@@ -690,6 +696,42 @@
// tell conference_exec we're ready for frames
member->ready_for_outgoing = 1 ;
+
+ // notify others about enter
+ char * enter_snd = member->enter_snd;
+ if (strcmp(enter_snd, "-")!=0)
+ {
+ // lock conference
+ ast_mutex_lock( &conf->lock );
+
+ /*if (conf->membercount < 2)
+ {
+ enter_snd = "conf-onlyperson";
+ }*/
+
+ struct ast_conf_member *membertest = conf->memberlist;
+ while (membertest != NULL)
+ {
+ // lock member for basic_play_sound
+ ast_mutex_lock(&membertest->lock);
+
+ // basic_play_sound unlock member automatically. do not mute on enter message
+ if (!basic_play_sound ( membertest, enter_snd, 0 ))
+ {
+ ast_log(LOG_ERROR, "playing conference[%d] entry message <%s> FAILED on <%s>\n", conf->membercount, enter_snd, membertest->channel_name);
+ }
+ else
+ {
+ ast_log(LOG_NOTICE, "playing conference[%d] entry message <%s> on <%s>\n", conf->membercount, enter_snd, membertest->channel_name);
+ }
+
+ membertest = membertest->next;
+ }
+
+ // unlock conference
+ ast_mutex_unlock( &conf->lock );
+ }
+
while ( 42 == 42 )
{
// make sure we have a channel to process
@@ -812,6 +854,17 @@
struct ast_conf_member* create_member( struct ast_channel *chan, const char* data )
{
+ char *parse;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(conf_name);
+ AST_APP_ARG(flags);
+ AST_APP_ARG(enter_snd);
+ AST_APP_ARG(leave_snd);
+ AST_APP_ARG(priority);
+ AST_APP_ARG(vad_prob_start);
+ AST_APP_ARG(vad_prob_continue);
+ );
+
//
// check input
//
@@ -828,6 +881,11 @@
return NULL ;
}
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_ERROR, "Conference requires an argument (conf_name[|flags[|enter_snd[|leave_snd[|priority[vad_prob_start[|vad_prob_continue]]]]]]))\n");
+ return NULL;
+ }
+
//
// allocate memory for new conference member
//
@@ -846,61 +904,54 @@
//
// initialize member with passed data values
//
+
+ parse = ast_strdupa(data);
- char argstr[80] ;
- char *stringp, *token ;
-
- // copy the passed data
- strncpy( argstr, data, sizeof(argstr) - 1 ) ;
-
- // point to the copied data
- stringp = argstr ;
-
- ast_log( AST_CONF_DEBUG, "attempting to parse passed params, stringp => %s\n", stringp ) ;
+ AST_STANDARD_APP_ARGS(args, parse);
// parse the id
- if ( ( token = strsep( &stringp, "/" ) ) != NULL )
- {
- member->conf_name = malloc( strlen( token ) + 1 ) ;
- strcpy( member->conf_name, token ) ;
- }
- else
+ if (ast_strlen_zero(args.conf_name))
{
ast_log( LOG_ERROR, "unable to parse member id\n" ) ;
free( member ) ;
return NULL ;
}
+ else
+ member->conf_name = ast_strdup(args.conf_name);
// parse the flags
- if ( ( token = strsep( &stringp, "/" ) ) != NULL )
- {
- member->flags = malloc( strlen( token ) + 1 ) ;
- strcpy( member->flags, token ) ;
- }
+ if (!ast_strlen_zero(args.flags))
+ member->flags = ast_strdup(args.flags);
else
- {
- // make member->flags something
- member->flags = malloc( sizeof( char ) ) ;
- memset( member->flags, 0x0, sizeof( char ) ) ;
- }
+ member->flags = ast_strdup("");
+
+ // parse enter sound
+ if (!ast_strlen_zero(args.enter_snd))
+ member->enter_snd = ast_strdup(args.enter_snd);
+ else
+ member->enter_snd = ast_strdup("enter");
+ // parse leave sound
+ if (!ast_strlen_zero(args.leave_snd))
+ member->leave_snd = ast_strdup(args.leave_snd);
+ else
+ member->leave_snd = ast_strdup("leave");
+
+ if (!ast_strlen_zero(args.priority))
// parse the priority
- member->priority = ( token = strsep( &stringp, "/" ) ) != NULL
- ? atoi( token )
- : 0
- ;
-
- // parse the vad_prob_start
- member->vad_prob_start = ( token = strsep( &stringp, "/" ) ) != NULL
- ? atof( token )
- : AST_CONF_PROB_START
- ;
-
- // parse the vad_prob_continue
- member->vad_prob_continue = ( token = strsep( &stringp, "/" ) ) != NULL
- ? atof( token )
- : AST_CONF_PROB_CONTINUE
- ;
+ member->priority = atoi(args.priority);
+ else
+ member->priority = 0;
+
+ if (!ast_strlen_zero(args.vad_prob_start))
+ member->vad_prob_start = atof(args.vad_prob_start);
+ else
+ member->vad_prob_start = AST_CONF_PROB_START;
+
+ if (!ast_strlen_zero(args.vad_prob_continue))
+ member->vad_prob_continue = atof(args.vad_prob_continue);
+ else
+ member->vad_prob_continue = AST_CONF_PROB_CONTINUE;
// debugging
ast_log(
@@ -991,9 +1042,15 @@
member->speaking_state_notify = 0 ;
member->speaking_state = 0 ;
member->local_speaking_state = 0;
+ member->last_state_change = (struct timeval){0, 0};
member->speaker_count = 0;
member->driven_member = NULL;
+ member->video_broadcast_active = 0;
+ member->last_video_frame_time = (struct timeval){0, 0};
+
+ member->video_started = 0;
+
// linked-list pointer
member->next = NULL ;
@@ -1067,7 +1124,7 @@
}
else
{
- // allowed flags are C, c, L, l, V, D, A, C, X, R, T, t, M, S
+ // allowed flags are C, c, L, l, V, D, A, C, X, R, T, t, M, S, z, o, F
// mute/no_recv options
switch ( flags[i] )
{
@@ -1105,6 +1162,9 @@
case 'S':
member->vad_switch = 1;
break;
+ case 'F':
+ member->force_vad_switch = 1;
+ break;
case 'M':
member->ismoderator = 1;
break;
@@ -1114,6 +1174,12 @@
case 't':
member->does_text = 1;
break;
+ case 'z':
+ member->vad_linger = 1;
+ break;
+ case 'o':
+ member->does_chat_mode = 1;
+ break;
//Telephone connection
case 'T':
@@ -1162,8 +1228,11 @@
speex_preprocess_ctl( member->dsp, SPEEX_PREPROCESS_SET_PROB_START, &member->vad_prob_start ) ;
speex_preprocess_ctl( member->dsp, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &member->vad_prob_continue ) ;
+ speex_preprocess_ctl( member->dsp, SPEEX_PREPROCESS_GET_PROB_START, &member->vad_prob_start ) ;
+ speex_preprocess_ctl( member->dsp, SPEEX_PREPROCESS_GET_PROB_CONTINUE, &member->vad_prob_continue ) ;
+
ast_log( AST_CONF_DEBUG, "speech_prob_start => %f, speech_prob_continue => %f\n",
- member->dsp->speech_prob_start, member->dsp->speech_prob_continue ) ;
+ member->vad_prob_start, member->vad_prob_continue ) ;
}
}
#endif
@@ -1446,6 +1515,10 @@
free(member->callerid);
free(member->callername);
+ // free enter/leave sounds
+ free(member->enter_snd);
+ free(member->leave_snd);
+
free( member ) ;
member = NULL ;
@@ -3276,3 +3349,31 @@
return;
}
+
+int is_video_eligible(struct ast_conf_member *member)
+{
+ if ( member == NULL )
+ return 0;
+
+ return !member->no_camera && !member->mute_video && !member->via_telephone;
+}
+
+// Member start and stop video methods
+void start_video(struct ast_conf_member *member)
+{
+ if ( member == NULL || member->video_started || !is_video_eligible(member))
+ return;
+
+ send_text_message_to_member(member, AST_CONF_CONTROL_START_VIDEO);
+ member->video_started = 1;
+}
+
+void stop_video(struct ast_conf_member *member)
+{
+ if ( member == NULL || !member->video_started )
+ return;
+
+ send_text_message_to_member(member, AST_CONF_CONTROL_STOP_VIDEO);
+ member->video_started = 0;
+
+}
Index: member.h
--- member.h.orig 2008-02-26 17:05:57 +0100
+++ member.h 2008-03-19 09:18:57 +0100
@@ -151,6 +151,10 @@
// switch video by VAD?
short vad_switch;
+ // do a VAD switch even if video is not enabled?
+ short force_vad_switch;
+ // if member is current speaker, video will stay on it when it becomes silent
+ short vad_linger;
// switch by dtmf?
short dtmf_switch;
// relay dtmf to manager?
@@ -159,6 +163,8 @@
short first_frame_received;
// does text messages?
short does_text;
+ // conference does chat mode (1 on 1 video when two members in conference)
+ short does_chat_mode;
// time we last dropped a frame
@@ -177,6 +183,15 @@
struct timeval last_state_change;
int speaker_count; // Number of drivers (including this member) that are speaking
+ // Stuff used to determine video broadcast state
+ // This member's video is sent out to at least one member of the conference
+ short video_broadcast_active;
+ // Time when we last sent out a video frame from this member
+ struct timeval last_video_frame_time;
+
+ // Is the member supposed to be transmitting video?
+ short video_started;
+
// pointer to next member in single-linked list
struct ast_conf_member* next ;
@@ -237,6 +252,10 @@
// For playing sounds
struct ast_conf_soundq *soundq;
struct ast_conf_soundq *videoq;
+
+ // Enter/leave sounds
+ char * enter_snd;
+ char * leave_snd;
// Pointer to another member that will be driven from this member's audio
struct ast_conf_member *driven_member;
@@ -295,6 +314,12 @@
struct ast_conf_member *member,
struct conf_frame *send_frames);
+int is_video_eligible(struct ast_conf_member *member);
+
+// Member start and stop video methods
+void start_video(struct ast_conf_member *member);
+void stop_video(struct ast_conf_member *member);
+
//
// packer functions
//