[asterisk-commits] russell: branch group/xcon_bfcp r51682 - in /team/group/xcon_bfcp/apps: ./ xc...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Jan 23 09:44:24 MST 2007


Author: russell
Date: Tue Jan 23 10:44:23 2007
New Revision: 51682

URL: http://svn.digium.com/view/asterisk?view=rev&rev=51682
Log:
merge the latest patch from issue #7838

Modified:
    team/group/xcon_bfcp/apps/Makefile
    team/group/xcon_bfcp/apps/app_meetme.c
    team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_messages.h
    team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_messages_parse.c
    team/group/xcon_bfcp/apps/xcon_bfcp/xcon_blueprints.h

Modified: team/group/xcon_bfcp/apps/Makefile
URL: http://svn.digium.com/view/asterisk/team/group/xcon_bfcp/apps/Makefile?view=diff&rev=51682&r1=51681&r2=51682
==============================================================================
--- team/group/xcon_bfcp/apps/Makefile (original)
+++ team/group/xcon_bfcp/apps/Makefile Tue Jan 23 10:44:23 2007
@@ -37,4 +37,4 @@
 
 include $(ASTTOPDIR)/Makefile.moddir_rules
 
-app_meetme.so : app_meetme.o xcon_bfcp/bfcp_server.o xcon_bfcp/bfcp_link_list.o xcon_bfcp/bfcp_user_list.o xcon_bfcp/bfcp_floor_list.o xcon_bfcp/bfcp_messages.o xcon_bfcp/bfcp_messages_build.o xcon_bfcp/bfcp_messages_parse.o xcon_bfcp/bfcp_sdp.o
+app_meetme.so : app_meetme.o xcon_bfcp/xcon_scheduler.o xcon_bfcp/bfcp_server.o xcon_bfcp/bfcp_link_list.o xcon_bfcp/bfcp_user_list.o xcon_bfcp/bfcp_floor_list.o xcon_bfcp/bfcp_messages.o xcon_bfcp/bfcp_messages_build.o xcon_bfcp/bfcp_messages_parse.o xcon_bfcp/bfcp_sdp.o xcon_bfcp/bfcp_gw.o xcon_bfcp/bfcp_base64.o

Modified: team/group/xcon_bfcp/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/group/xcon_bfcp/apps/app_meetme.c?view=diff&rev=51682&r1=51681&r2=51682
==============================================================================
--- team/group/xcon_bfcp/apps/app_meetme.c (original)
+++ team/group/xcon_bfcp/apps/app_meetme.c Tue Jan 23 10:44:23 2007
@@ -62,16 +62,14 @@
 #include "asterisk/devicestate.h"
 
 #include "asterisk/term.h"	/* Needed for some "coloured" console notifications */
-#include "asterisk/sched.h"	/* Will be needed for the external VideoMixer (currently UNUSED!) */
-#include "asterisk/io.h"	/* Will be needed for the external VideoMixer (currently UNUSED!) */
-#include "asterisk/rtp.h"	/* Will be needed for the external VideoMixer (currently UNUSED!) */
-
-/*! The library managing the Floor Contrl Server behaviour */
-#include "xcon_bfcp/bfcp_server.h"
-/*! Useful user-friendly strings for BFCP definitions */
-#include "xcon_bfcp/bfcp_strings.h"
-/*! Definition of the structure to pass to chan_sip for BFCP+SDP reinvites */
-#include "xcon_bfcp/bfcp_sdp.h"
+#include "asterisk/rtp.h"	/* Needed for the cascaded conferences trunking and for the external VideoMixer */
+
+/*! The Floor Control Server Gateway, to handle all that's related to BFCP:
+	1. centralized floor control for XCON Conferences;
+	2. SDP manipulation to add exchange of BFCP information;
+	3. user-friendly strings to access BFCP values;
+	4. DCON-compliant management of distributed floor control */
+#include "xcon_bfcp/bfcp_gw.h"
 /*! Static, embedded, definitions of some common conference blueprints
 	\todo: make it dynamic */
 #include "xcon_bfcp/xcon_blueprints.h"
@@ -79,22 +77,21 @@
 #include "enter.h"
 #include "leave.h"
 
-#define CONFIG_FILE_NAME "meetme.conf"
-
-#define DEFAULT_XCON_PREFIX	 867	/*!< Prefix wildcard for XCON conferences */
-#define DEFAULT_SCHEDULER_PORT 	2346	/*!< Default XconScheduler listening port */
-#define DEFAULT_BFCP_PORT 	2345	/*!< Default BFCP Server listening port */
-#define DEFAULT_BFCP_MAXCONF 	  10	/*!< Default BFCP Server max number of allowed concurrent conferences */
+#define DEFAULT_XCON_PREFIX	 	867	/*!< Prefix wildcard for XCON conferences */
+#define DEFAULT_SCHEDULER_PORT 		2346	/*!< Default XconScheduler listening port */
+#define DEFAULT_BFCP_PORT 		2345	/*!< Default BFCP Server listening port */
+#define DEFAULT_GW_BFCP_PORT 		2354	/*!< Default Gatewayed BFCP Server listening port (if used) */
+#define DEFAULT_GW_BFCP_DISPATCHER 	3000	/*!< Default DCON Dispatcher listening port (if used) */
+#define DEFAULT_BFCP_MAXCONF 	  	10	/*!< Default BFCP Server max number of allowed concurrent conferences */
 
 /*! Static variable to store the prefix wildcard for XCON conferences as read from the configuration file */
 static int xcon_prefix;
 
-/*! New VideoMixer stuff: RTPs, scheduler's and IO's context
-	\note currently UNUSED! */
-static struct sockaddr_in bindaddr = { 0, };	/*!< The address we bind the Mixer's RTPs to */
-static struct sched_context *mixer_sched;	/*!< The VideoMixer's scheduling context */
-static struct io_context *mixer_io;		/*!< The VideoMixer's IO context */
-static void *mixer_listener(void *args);	/*!< The VideoMixer(s) listening thread(s) */
+/*! Static variable that tells us if we have to be DCON-compliant or not */
+static int dcon_enabled;
+
+/*! The address we bind the local Mixers' RTPs to */
+static struct sockaddr_in bindaddr = { 0, };
 
 /*! each buffer is 20ms, so this is 640ms total */
 #define DEFAULT_AUDIO_BUFFERS  32
@@ -186,8 +183,10 @@
 	CONFFLAG_HOLD = (1 << 27),
 	/*! If set, the user should continue in the dialplan if kicked out */
 	CONFFLAG_KICK_CONTINUE = (1 << 28),
-	/*! If set, the MeetMe room will be treated as an XCON conference */
-	CONFFLAG_XCON = (1 << 29)
+	/*! If set, the MeetMe room will be treated as a (primary) XCON conference */
+	CONFFLAG_XCON = (1 << 29),
+	/*! If set, the MeetMe room will be treated as a secondary XCON conference (Gateway to DCON) */
+	CONFFLAG_XCON_GW = (1 << 30)
 };
 
 enum {
@@ -223,6 +222,7 @@
 	AST_APP_OPTION('x', CONFFLAG_MARKEDEXIT ),
 	AST_APP_OPTION('1', CONFFLAG_NOONLYPERSON ),
 	AST_APP_OPTION('B', CONFFLAG_XCON ),
+	AST_APP_OPTION('G', CONFFLAG_XCON_GW ),
 });
 
 AST_APP_OPTIONS(sla_opts, {
@@ -337,7 +337,9 @@
 "other participants in the conference, all member stations are invited into\n"
 "the bridge.\n";
 
+#define CONFIG_FILE_NAME "meetme.conf"
 #define CONFIG_FILE_NAME_SLA "sla.conf"
+#define DCON_CONFIG_FILE_NAME "dcon.conf"
 #define XCON_CONFIG_FILE_NAME "xcon.conf"
 
 /*! \brief The MeetMe Conference object */
@@ -366,6 +368,7 @@
 	struct ast_frame *origframe;
 	struct ast_trans_pvt *transpath[32];
 
+	int xcondcontype;			/*!< XCON Local/Remote Conference */
 	unsigned long int xconconferenceID;	/*!< XCON specific Conference ID */
 	char *subject;				/*!< XCON specific Conference Subject (Topic) */
 	unsigned long int xconpin;		/*!< XCON pin, needed for conferences with private access */
@@ -373,13 +376,11 @@
 	unsigned short int audiofloorID;	/*!< BFCP Floor ID for Audio, if enabled */
 	unsigned short int videofloorID;	/*!< BFCP Floor ID for Video, if enabled */
 
-	struct ast_rtp *mixer_in;		/*!< The Mixer's RTP channel to get the mixed video from (currently UNUSED!) */
-	struct hostent *mixer_vhp;		/*!< RTP host IP we bind to (currently UNUSED!) */
-	struct ast_hostent *mixer_videohp;
-	pthread_t mixer_listening_thread;	/*!< Listening thread for incoming Mixer's RTP (currently UNUSED!) */
-	pthread_attr_t mixer_listening_attr;	/*!< Listening thread attribute (currently UNUSED!) */
+	struct xcon_videomixer_leg *videomixer;
 
 	AST_LIST_HEAD_NOLOCK(, ast_conf_user) userlist;
+	AST_LIST_HEAD_NOLOCK(, xcon_cascaded_conference) cascadedlist;
+	AST_LIST_HEAD_NOLOCK(, dcon_user) dconuserlist;		/* List of remote users */
 	AST_LIST_ENTRY(ast_conference) list;
 };
 
@@ -413,13 +414,65 @@
 	int notify_audio_change;		/*!< Flag to notify an user if he has been muted/unmuted */
 	int notify_video_change;		/*!< Flag to notify an user if he can/can't send video */
 
-	struct ast_rtp *mixer_out;		/*!< The Mixer's RTP channel to send this user's video to (currently UNUSED!) */
-	struct hostent *mixer_vhp;		/*!< RTP video Mixer's host IP (currently UNUSED!) */
-	struct ast_hostent *mixer_videohp;
-	struct ast_frame *mixer_frame;		/*!< The latest frame received from the VideoMixer (currently UNUSED!) */
+	struct xcon_videomixer_leg *videomixer;
+	unsigned short int queued_video_frames;
+	AST_LIST_HEAD_NOLOCK(, xcon_videoframe) videoframes;
+	ast_mutex_t videoframe_lock;		/*!< Lock to update/retrieve frames */
 
 	AST_LIST_ENTRY(ast_conf_user) list;
 };
+
+struct dcon_user {
+	unsigned short int xconuserID;		/*!< XCON specific User ID */
+	char *xconuserdisplay;			/*!< XCON User's Display Name */
+	char *xconuseruri;			/*!< XCON User's URI */
+	unsigned short int audiofloorstatus;	/*!< BFCP Status for the Floor Audio (if present) */
+	unsigned short int videofloorstatus;	/*!< BFCP Status for the Floor Video (if present) */
+
+	AST_LIST_ENTRY(dcon_user) list;
+};
+
+/*! \brief Mixer(s) and RTP related stuff */
+struct xcon_videoframe {
+	struct ast_frame *frame;		/*!< A received frame, to send to the user */
+	AST_LIST_ENTRY(xcon_videoframe) list;
+};
+
+struct xcon_videomixer_leg {
+	int is_focus;				/*! Is this leg related to a focus or to an user? */
+	struct ast_conference *conf;		/*!< The local Conference peer, if related to a conference */
+	struct ast_conf_user *user;		/*!< The local Conference peer, if related to an user */
+
+	int active;				/*!< A flag to check if the listener is active */
+	struct ast_rtp *rtp;			/*!< The Mixer's RTP channel to get the mixed video from (if focus) and send mixed video to (if user) */
+	unsigned short int own_port;		/*!< The Mixer's RTP channel local port */
+	pthread_t listening_thread;		/*!< Listening thread for incoming Mixer's RTP (only for focus) */
+	pthread_attr_t listening_attr;		/*!< Listening thread attribute (only for focus) */
+};
+
+struct xcon_cascaded_conference {
+	int xcondcontype;			/*!< This peer is an XCON Local/Remote Conference */
+	struct ast_conference *conf;		/*!< The local Conference peer */
+	int conf_fd;				/*!< Connected local channel */
+
+	int active;				/*!< A flag to check if the listener is active */
+	struct ast_rtp *rtp;			/*!< The Mixer's RTP channel to get the mixed frames from */
+	unsigned short int own_port;		/*!< The Mixer's RTP channel listening port */
+	char *peerIP;
+	unsigned short int peer_port;
+	pthread_t listening_thread;		/*!< Listening thread for incoming Mixer's RTP */
+	pthread_attr_t listening_attr;		/*!< Listening thread attribute */
+
+	AST_LIST_ENTRY(xcon_cascaded_conference) list;
+};
+
+/*! \brief Method to setup a new videomixer leg */
+int xcon_setup_new_videomixer(int is_focus, void *leg);
+static void *videomixer_listener(void *args);	/*!< The VideoMixer(s) listening thread(s) */
+
+/*! \brief Method to setup a new cascaded conference */
+struct xcon_cascaded_conference *xcon_setup_new_cascaded_conference(struct ast_conference *cnf);
+static void *cascaded_listener(void *args);	/*!< The Cascaded audio frames listening thread(s) */
 
 /*! SLA station - one device in an SLA configuration */
 struct ast_sla_station {
@@ -447,24 +500,24 @@
 	ASTOBJ_CONTAINER_COMPONENTS(struct ast_sla);
 } slas;
 
+/*! XCON Scheduler protocol management */
+static int scheduler_exists;			/*! A static variable to check whether the Scheduler is up or not */
+static unsigned short int scheduler_port;	/*! The port the Scheduler server will listen on */
+/*! Callback function called by the Scheduler to notify the application about incoming/outgoing messages */
+int scheduler_notifications(int type, ...);
+
 /*! XCON Binary Floor Control Protocol (BFCP) management */
-static bfcp bfcp_server_list;		/*! The object managing the BFCP server behaviour */
+static int bfcp_exists;			/*! A static variable to check whether the FCS is up or not */
 static unsigned short int bfcp_port;	/*! The port the BFCP server will listen on (TCP only, TLS not supported yet) */
-static int bfcp_user_id;		/*! Static user counter to assign new BFCP User IDs */
-/*! Callback function called by the BFCP library to notify the application about incoming/outgoing messages */
+static unsigned short int gw_bfcp_port;	/*! The port the BFCP server will listen on, if gatewayed (TCP only, TLS not supported yet) */
+static char gw_ip[15];			/*! The IP the BFCP server will listen on, if gatewayed (TCP only, TLS not supported yet) */
+static unsigned short int gw_bfcp_dispatcher;
+/*! Callback function called by the BFCP library to notify the application about incoming/outgoing BFCP messages */
 int bfcp_notifications(bfcp_arguments *arguments, int outgoing);
-
-/*! XCON Scheduler server management */
-static struct xcon_scheduler {
-	int socket;			/*! The file descriptor */
-	unsigned short int port;	/*! The listening port */
-	struct sockaddr_in *address;	/*! The listening address */
-	int fdmax;			/*! The highest file descriptor (needed for select) */
-	fd_set *readfds, *writefds;	/*! The file descriptor sets for select */
-	pthread_t thread;		/*! The XconScheduler listening thread */
-	char admin[15];			/*! The manager's username... (must be a valid user from manager.conf)  */
-	char password[15];		/*! 	... and password 						*/
-} xcon_scheduler;
+/*! Management of FloorRequestStatus messages, to opportunely act upon floor status changes (e.g. mute/unmute) */
+void bfcp_manage_floor_request_status(bfcp_arguments *arguments);
+/*! Callback function called by the Gateway to notify the application about DCON updates */
+int gw_notifications(int update, ...);
 
 /*! XCON Registered Conferences management, to avoid always checking the configuration file */
 struct xcon_registered_conference {
@@ -494,11 +547,18 @@
 /*! Wrapper functions to get pointers to a conference and/or an user */
 struct ast_conference *xcon_get_conference(unsigned long int conferenceID);
 struct ast_conf_user *xcon_get_user(struct ast_conference *cnf, unsigned short int userID);
+struct ast_conf_user *xcon_get_user_from_info(struct ast_conference *cnf, char *uri, char *display);
 
 /*! Muting/Unmuting XCON wrappers */
 int xcon_mute_user(struct ast_conference *cnf, struct ast_conf_user *user);
 int xcon_unmute_user(struct ast_conference *cnf, struct ast_conf_user *user);
 
+/*! Methods to manage the Remote Users list */
+int dcon_add_remote_user(struct ast_conference *cnf, unsigned short int ID, char *uri, char *display);
+struct dcon_user *dcon_get_remote_user(struct ast_conference *cnf, unsigned short int userID);
+int dcon_remove_remote_user(struct ast_conference *cnf, unsigned short int userID);
+int dcon_free_remote_users(struct ast_conference *cnf);
+ 
 /*! The number of audio buffers to be allocated on pseudo channels
  *  when in a conference */
 static int audio_buffers;
@@ -522,7 +582,6 @@
 	13,
 	15,
 };
-
 
 static int admin_exec(struct ast_channel *chan, void *data);
 static void *recordthread(void *args);
@@ -781,95 +840,92 @@
 					if (option_verbose > 2)
 						ast_verbose(VERBOSE_PREFIX_3 "The XCON ConferenceID is invalid...\n");
 				} else {
-					/* We don't read the file for that: we use the locally registered conferences */
-					AST_LIST_LOCK(&regxconfs);
-					struct xcon_registered_conference *conferences;
-					if(AST_LIST_EMPTY(&regxconfs)) {
-						fatal++;
-						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "  There are no registered conferences?? That should NEVER happen here!\n");
+					if(xcon == XCON_REMOTE_CONFERENCE) {
+						cnf->xcondcontype = XCON_REMOTE_CONFERENCE;
+						if(bfcp_gw_initialize_conference_server(XCON_REMOTE_CONFERENCE, cnf->xconconferenceID, 0, 0, 0, 0 < 0)) {
+							fatal++;
+							if (option_verbose > 2)
+								ast_verbose(VERBOSE_PREFIX_3 "The new remote conference could not be added to the BFCP Server...\n");
+						}
+						/* NOTE: we create an RTP channel to send/receive audio to/from the main XCON focus */
+						if(!xcon_setup_new_cascaded_conference(cnf)) {
+							fatal++;
+							if (option_verbose > 2)
+								ast_verbose(VERBOSE_PREFIX_3 "Could not create the Cascaded Conference RTP channel...\n");
+						}
+						if (!fatal && (option_verbose > 2))
+							ast_verbose(VERBOSE_PREFIX_3 "The new remote conference (ConferenceID: %lu) has been added to the BFCP Server:\n", cnf->xconconferenceID);
 					} else {
-						AST_LIST_TRAVERSE(&regxconfs, conferences, list) {	/* We look for the right conference */
-							if(conferences->conferenceID == cnf->xconconferenceID) {	/* Found, read it*/
-								/* First of all we get the Administrator's numeric password... */
-								cnf->xconpassword = conferences->password;
-								/* ...and the numeric PIN to enter the conference, if private... */
-								cnf->xconpin = conferences->pin;
-								/* ...then we add the conference to the BFCP server... */
-								if(bfcp_initialize_conference_server(bfcp_server_list,
-												conferences->conferenceID,
-												conferences->maxfloors,
-												conferences->maxrequests,
-												conferences->autopolicy,
-												conferences->waitrequest) <0) {
-									fatal++;
-									if (option_verbose > 2)
-										ast_verbose(VERBOSE_PREFIX_3 "The new conference could not be added to the BFCP Server...\n");
-									break;
-								}
-								if (option_verbose > 2)
-									ast_verbose(VERBOSE_PREFIX_3 "The new conference (ConferenceID: %lu) has been added to the BFCP Server:\n",cnf->xconconferenceID);
-								/* ...and finally we add the required floors to the BFCP conference */
-								if(conferences->audiofloorID) { /* Add a Floor for Audio */
-									cnf->audiofloorID = conferences->audiofloorID;
-									if(bfcp_add_floor_server(bfcp_server_list, conferences->conferenceID, conferences->audiofloorID, 0, conferences->audiousers) <0 ) {
+						/* We don't read the file for that: we use the locally registered conferences */
+						AST_LIST_LOCK(&regxconfs);
+						struct xcon_registered_conference *conferences;
+						if(AST_LIST_EMPTY(&regxconfs)) {
+							fatal++;
+							if (option_verbose > 2)
+								ast_verbose(VERBOSE_PREFIX_3 "  There are no registered conferences?? That should NEVER happen here!\n");
+						} else {
+							AST_LIST_TRAVERSE(&regxconfs, conferences, list) {	/* We look for the right conference */
+								if(conferences->conferenceID == cnf->xconconferenceID) {	/* Found, read it*/
+									/* Set up the conference type (remote or local) */
+									cnf->xcondcontype = XCON_LOCAL_CONFERENCE;
+									/* First of all we get the Administrator's numeric password... */
+									cnf->xconpassword = conferences->password;
+									/* ...and the numeric PIN to enter the conference, if private... */
+									cnf->xconpin = conferences->pin;
+									/* ...then we add the conference to the BFCP server... */
+									if(bfcp_gw_initialize_conference_server(XCON_LOCAL_CONFERENCE,
+													conferences->conferenceID,
+													conferences->maxfloors,
+													conferences->maxrequests,
+													conferences->autopolicy,
+													conferences->waitrequest) < 0) {
 										fatal++;
 										if (option_verbose > 2)
-											ast_verbose(VERBOSE_PREFIX_3 "Couldn't add the new Audio Floor to the Conference...\n");
+											ast_verbose(VERBOSE_PREFIX_3 "The new local conference could not be added to the BFCP Server...\n");
 										break;
 									}
 									if (option_verbose > 2)
-										ast_verbose(VERBOSE_PREFIX_3 "    Floor: Audio, ID %d (%s)\n", cnf->audiofloorID, conferences->audiousers ? "limited users" : "unlimited users");
-								}
-								if(conferences->videofloorID) { /* Add a Floor for Video */
-									cnf->videofloorID = conferences->videofloorID;
-									/* Only add to the list if Audio and Video floors are different (they could be managed together in the same floor) */
-									if(cnf->videofloorID != cnf->audiofloorID) {
-										if(bfcp_add_floor_server(bfcp_server_list, conferences->conferenceID, conferences->videofloorID, 0, conferences->videousers) <0 ) {
+										ast_verbose(VERBOSE_PREFIX_3 "The new local conference (ConferenceID: %lu) has been added to the BFCP Server:\n", cnf->xconconferenceID);
+									/* ...and finally we add the required floors to the BFCP conference */
+									if(conferences->audiofloorID) { /* Add a Floor for Audio */
+										cnf->audiofloorID = conferences->audiofloorID;
+										if(bfcp_gw_add_floor_server(conferences->conferenceID, AUDIO_FLOOR, conferences->audiofloorID, 0, conferences->audiousers) <0 ) {
 											fatal++;
 											if (option_verbose > 2)
-												ast_verbose(VERBOSE_PREFIX_3 "Couldn't add the new Video Floor to the Conference...\n");
+												ast_verbose(VERBOSE_PREFIX_3 "Couldn't add the new Audio Floor to the Conference...\n");
 											break;
 										}
+										if (option_verbose > 2)
+											ast_verbose(VERBOSE_PREFIX_3 "    Floor: Audio, ID %d (%s)\n", cnf->audiofloorID, conferences->audiousers ? "limited users" : "unlimited users");
 									}
-									if (option_verbose > 2)
-										ast_verbose(VERBOSE_PREFIX_3 "    Floor: Video, ID %d (%s)\n", cnf->videofloorID, conferences->videousers ? "limited users" : "unlimited users");
-								/* NOTE: we create an RTP channel to receive media from the video mixer too (currently UNUSED!) */
-									if(!cnf->mixer_in) {
-										struct sockaddr_in vsin;	/* Video socket address */
-										cnf->mixer_in = ast_rtp_new_with_bindaddr(NULL, NULL, 0, 0, bindaddr.sin_addr);
-/*										ast_rtp_set_callback(cnf->mixer_in, mixer_callback);*/
-										ast_rtp_settos(cnf->mixer_in, 0);
-										ast_rtp_setdtmf(cnf->mixer_in, 0);
-										ast_rtp_setdtmfcompensate(cnf->mixer_in, 0);
-/*										ast_rtp_set_m_type(cnf->mixer_in, 31);
-										ast_rtp_set_rtpmap_type(cnf->mixer_in, 31, "video", "H.261", 0);*/
-										ast_rtp_get_us(cnf->mixer_in, &vsin);
+									if(conferences->videofloorID) { /* Add a Floor for Video */
+										cnf->videofloorID = conferences->videofloorID;
+										/* Only add to the list if Audio and Video floors are different (they could be managed together in the same floor) */
+/*										if(cnf->videofloorID != cnf->audiofloorID) {*/
+											if(bfcp_gw_add_floor_server(conferences->conferenceID, VIDEO_FLOOR, conferences->videofloorID, 0, conferences->videousers) <0 ) {
+												fatal++;
+												if (option_verbose > 2)
+													ast_verbose(VERBOSE_PREFIX_3 "Couldn't add the new Video Floor to the Conference...\n");
+												break;
+											}
+/*										}*/
 										if (option_verbose > 2)
-											ast_verbose(VERBOSE_PREFIX_3 "\tIncoming VideoMixer RTP Channel waiting on port %d\n", ntohs(vsin.sin_port));
-										struct hostent *mixer_vhp;
-										struct ast_hostent *mixer_videohp;
-										mixer_videohp = calloc(sizeof(struct ast_hostent), sizeof(char));
-										mixer_vhp = ast_gethostbyname("127.0.0.1", mixer_videohp);
-										vsin.sin_family = AF_INET;
-										if (mixer_vhp)
-											memcpy(&vsin.sin_addr, mixer_vhp->h_addr, sizeof(vsin.sin_addr));
-										/* Setup video port number */
-										vsin.sin_port = htons(6668);
-										ast_rtp_set_peer(cnf->mixer_in, &vsin);
-										pthread_attr_init(&cnf->mixer_listening_attr);
-										pthread_attr_setdetachstate(&cnf->mixer_listening_attr, PTHREAD_CREATE_DETACHED);
-										ast_pthread_create(&cnf->mixer_listening_thread, &cnf->mixer_listening_attr, mixer_listener, cnf);
+											ast_verbose(VERBOSE_PREFIX_3 "    Floor: Video, ID %d (%s)\n", cnf->videofloorID, conferences->videousers ? "limited users" : "unlimited users");
+										/* NOTE: we create an RTP channel to latterly receive mixed frames from the video mixer as well
+										if(xcon_setup_new_videomixer(1, cnf) < 0) {
+											fatal++;
+											if (option_verbose > 2)
+												ast_verbose(VERBOSE_PREFIX_3 "Could not create the VideoMixer RTP channel...\n");
+										}	*/
 									}
+									cnf->subject = conferences->subject;
+									conferences->is_active = 1;
+									break;
 								}
-								cnf->subject = conferences->subject;
-								conferences->is_active = 1;
-								break;
 							}
 						}
+						AST_LIST_UNLOCK(&regxconfs);
 					}
-					AST_LIST_UNLOCK(&regxconfs);
-	
 					/* Show the results */
 					if (option_verbose > 2)
 						ast_verbose(VERBOSE_PREFIX_3 "    Adding conference to the BFCP Server: %s\n", fatal ? "FAILED" : "DONE");
@@ -936,6 +992,8 @@
 static int xcon_show_user(int fd, int argc, char *argv[]);
 static int xcon_remove_conference(int fd, int argc, char *argv[]);
 static int xcon_remove_user(int fd, int argc, char *argv[]);
+static int xcon_add_mixer(int fd, int argc, char *argv[]);
+static int xcon_play(int fd, int argc, char *argv[]);
 
 static char xcon_info_usage[] = 
 "Usage: xcon info\n"
@@ -968,6 +1026,14 @@
 static char xcon_remove_user_usage[] = 
 "Usage: xcon remove user <conferenceID> <userID>\n"
 "       Removes the user <userID> from the conference <confID> in the XCON Server.\n";
+
+static char xcon_add_mixer_usage[] = 
+"Usage: xcon add mixer <conferenceID> <IP> <port>\n"
+"       Add a Video Mixer (<IP>:<port>) to the conference <confID>.\n";
+
+static char xcon_play_usage[] = 
+"Usage: xcon play <conferenceID>\n"
+"       Play an announcement in conference <confID>.\n";
 
 static struct ast_cli_entry xcon_cli[] = {
 	{ { "xcon", "info", NULL }, xcon_info, "Shows information on the XCON Server", xcon_info_usage },
@@ -978,19 +1044,27 @@
 	{ { "xcon", "show", "user", NULL }, xcon_show_user, "Shows info about an user in a conference in the XCON Server", xcon_show_user_usage },
 	{ { "xcon", "remove", "conference", NULL }, xcon_remove_conference, "Removes a conference from the XCON Server", xcon_remove_conference_usage },
 	{ { "xcon", "remove", "user", NULL }, xcon_remove_user, "Removes an user from a conference in the XCON Server", xcon_remove_user_usage },
+	{ { "xcon", "add", "mixer", NULL }, xcon_add_mixer, "Add a Video Mixer to a conference", xcon_add_mixer_usage },
+	{ { "xcon", "play", NULL }, xcon_play, "Play an announcement in a conference", xcon_play_usage },
 };
 
 /*! \brief Shows XCON Servers (XconScheduler and BFCP) Information */
 static int xcon_info(int fd, int argc, char *argv[])
 {
-	if (bfcp_server_list) {
-		ast_cli(fd,"  BFCP Server listening on port %d.\n",bfcp_port);
-		ast_cli(fd,"  BFCP Server List active with max %d conferences allowed (%d active).\n",bfcp_server_list->Max_number_conference + 1,bfcp_server_list->Actual_number_conference);
+	if (bfcp_exists) {
+		if(dcon_enabled) {
+			ast_cli(fd,"  Real BFCP Server listening on port %d.\n", gw_bfcp_port);
+			ast_cli(fd,"  Gateway/Proxy BFCP Server listening on port %d.\n", bfcp_port);
+		} else
+			ast_cli(fd,"  BFCP Server listening on port %d.\n", bfcp_port);
+		bfcp list = bfcp_gw_get_list();
+		if(list)
+			ast_cli(fd,"  BFCP Server List active with max %d conferences allowed (%d active).\n", list->Max_number_conference + 1, list->Actual_number_conference);
 	}
 	else
 		ast_cli(fd,"BFCP Server not up.\n");
-	if (xcon_scheduler.socket > -1)
-		ast_cli(fd,"  XconScheduler Server listening on port %d.\n",xcon_scheduler.port);
+	if (scheduler_exists)
+		ast_cli(fd,"  XconScheduler Server listening on port %d.\n", scheduler_port);
 	else
 		ast_cli(fd,"XconScheduler Server not up.\n");
 	return RESULT_SUCCESS;
@@ -1018,22 +1092,27 @@
 /*! \brief Shows all currently active (running) XCON conferences */
 static int xcon_show_conferences(int fd, int argc, char *argv[])
 {
-	if (bfcp_server_list == NULL)
+	if (!bfcp_exists)
 		ast_cli(fd,"  BFCP Server List has not been created yet.\n");
 	else {
-		bfcp_conference *lconferences = bfcp_server_list->list_conferences;
+		bfcp list = bfcp_gw_get_list();
+		if(!list) {
+			ast_cli(fd,"  BFCP Server List doesn't exist?\n");
+			return RESULT_FAILURE;
+		}
+		bfcp_conference *lconferences = list->list_conferences;
 		int i = 0;
 		if (lconferences == NULL) {
 			ast_cli(fd,"  The BFCP Server List is NULL.\n");
 			return RESULT_SUCCESS;
 		}
-		if (bfcp_server_list->Actual_number_conference == 0) {
+		if (list->Actual_number_conference == 0) {
 			ast_cli(fd,"  There are no active conferences in the BFCP Server.\n");
 			return RESULT_SUCCESS;
 		}		
 		ast_cli(fd,"  Conferences:\n");
-		for(i=0; i < bfcp_server_list->Actual_number_conference; i++)
-			ast_cli(fd,"    %d: %li\n",i+1,bfcp_server_list->list_conferences[i].conferenceID);
+		for(i=0; i < list->Actual_number_conference; i++)
+			ast_cli(fd,"    %d: %li\n",i+1,list->list_conferences[i].conferenceID);
 	}
 	return RESULT_SUCCESS;
 }
@@ -1053,25 +1132,30 @@
 
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
-	if (bfcp_server_list == NULL)
+	if (!bfcp_exists)
 		ast_cli(fd,"  BFCP Server List has not been created yet.\n");
 	else {
 		unsigned long int ID = atoi(argv[3]);
 		if(!ID)
 			return RESULT_SHOWUSAGE;
 		int i = 0;
-		if (bfcp_server_list->list_conferences == NULL) {
+		bfcp list = bfcp_gw_get_list();
+		if(!list) {
+			ast_cli(fd,"  BFCP Server List doesn't exist?\n");
+			return RESULT_FAILURE;
+		}
+		if (list->list_conferences == NULL) {
 			ast_cli(fd,"  The BFCP Server List is NULL.\n");
 			return RESULT_FAILURE;
 		}
-		if (bfcp_server_list->Actual_number_conference == 0) {
+		if (list->Actual_number_conference == 0) {
 			ast_cli(fd,"  There are no active conferences in the BFCP Server.\n");
 			return RESULT_FAILURE;
 		}		
-		for(i=0; i < bfcp_server_list->Actual_number_conference; i++) {
-			if (bfcp_server_list->list_conferences[i].conferenceID == ID) {
-				ast_cli(fd,"ConferenceID: %li\n\n", bfcp_server_list->list_conferences[i].conferenceID);
-				list_floor = bfcp_server_list->list_conferences[i].floor;
+		for(i=0; i < list->Actual_number_conference; i++) {
+			if (list->list_conferences[i].conferenceID == ID) {
+				ast_cli(fd,"ConferenceID: %li\n\n", list->list_conferences[i].conferenceID);
+				list_floor = list->list_conferences[i].floor;
 				if (list_floor !=NULL) {
 					ast_cli(fd,"Maximum number of floors in the conference: %d\n", list_floor->number_floors + 1);
 					ast_cli(fd,"FLOORS\n");
@@ -1096,7 +1180,7 @@
 						}
 					}
 				}
-				list_user = bfcp_server_list->list_conferences[i].user;
+				list_user = list->list_conferences[i].user;
 				if (list_user !=NULL) {
 					user=list_user->users;
 					ast_cli(fd,"Maximum number of request per floors in the conference: %d\n", list_user->max_number_floor_request);
@@ -1110,7 +1194,7 @@
 						user= user->next;
 					}
 				}
-				list_link = bfcp_server_list->list_conferences[i].pending;
+				list_link = list->list_conferences[i].pending;
 				if (list_link !=NULL) {
 					node=list_link->head;
 					if (node) ast_cli(fd,"PENDING LIST\n");
@@ -1143,7 +1227,7 @@
 						ast_cli(fd,"-----------------\n");
 					}
 				}
-				list_link = bfcp_server_list->list_conferences[i].accepted;
+				list_link = list->list_conferences[i].accepted;
 				if (list_link !=NULL) {
 					node=list_link->head;
 					if (node)
@@ -1177,7 +1261,7 @@
 						ast_cli(fd,"-----------------\n");
 					}
 				}
-				list_link = bfcp_server_list->list_conferences[i].granted;
+				list_link = list->list_conferences[i].granted;
 				if (list_link !=NULL) {
 					node=list_link->head;
 					if (node)
@@ -1211,7 +1295,7 @@
 					}
 				}			
 			} else {
-				ast_cli(fd,"  There is no active conference with ID %ld in the BFCP Server.\n",ID);
+				ast_cli(fd,"  There is no active conference with ID %lu in the BFCP Server.\n",ID);
 				return RESULT_FAILURE;
 			}		
 		}
@@ -1224,48 +1308,62 @@
 {
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
-	if (bfcp_server_list == NULL)
-		ast_cli(fd,"  BFCP Server List has not been created yet.\n");
-	else {
-		unsigned long int ID = atoi(argv[3]);
-		if(!ID)
-			return RESULT_SHOWUSAGE;
-		if (bfcp_server_list->list_conferences == NULL) {
-			ast_cli(fd,"  The BFCP Server List is NULL.\n");
-			return RESULT_FAILURE;
-		}
-		if (bfcp_server_list->Actual_number_conference == 0) {
-			ast_cli(fd,"  There are no active conferences in the BFCP Server.\n");
-			return RESULT_FAILURE;
-		}	
-
-		struct ast_conference *cnf = xcon_get_conference(ID);
-		int user_count = 0;
-		if(cnf) {
-			AST_LIST_LOCK(&confs);
-			struct ast_conf_user *user;
-			ast_cli(fd,"  Users in Conference %lu:\n",ID);
-			AST_LIST_TRAVERSE(&cnf->userlist, user, list) {
-				if(!user)
+
+	unsigned long int ID = atoi(argv[3]);
+	if(!ID)
+		return RESULT_SHOWUSAGE;
+
+	if(AST_LIST_EMPTY(&confs)) {
+		ast_cli(fd,"  There are no active conferences in the BFCP Server.\n");
+		return RESULT_FAILURE;
+	}	
+
+	struct ast_conference *cnf = xcon_get_conference(ID);
+	int user_count = 0;
+	if(cnf) {
+		AST_LIST_LOCK(&confs);
+		struct ast_conf_user *user;
+		ast_cli(fd,"  Users in Conference %lu:\n",ID);
+		AST_LIST_TRAVERSE(&cnf->userlist, user, list) {
+			if(!user)
+				break;
+			user_count++;
+			ast_cli(fd,"    %d: UserID %u (Display Name: %s, URI: %s)",
+				user_count,
+				user->xconuserID,
+				user->xconuserdisplay ? user->xconuserdisplay : "none",
+				user->xconuseruri ? user->xconuseruri : "none");
+			if(cnf->audiofloorID)
+				ast_cli(fd,", Audio %s", user->audiofloorstatus ? bfcp_status[user->audiofloorstatus-1].description : "NOT GRANTED");
+			if(cnf->videofloorID)
+				ast_cli(fd,", Video %s", user->videofloorstatus ? bfcp_status[user->videofloorstatus-1].description : "NOT GRANTED");
+			ast_cli(fd,"\n");
+		}
+		if(!AST_LIST_EMPTY(&cnf->dconuserlist)) {	/* There are remote users too */
+			struct dcon_user *dconuser;
+			ast_cli(fd,"  Remote Users in Conference %lu:\n",ID);
+			AST_LIST_TRAVERSE(&cnf->dconuserlist, dconuser, list) {
+				if(!dconuser)
 					break;
 				user_count++;
 				ast_cli(fd,"    %d: UserID %u (Display Name: %s, URI: %s)",
 					user_count,
-					user->xconuserID,
-					user->xconuserdisplay ? user->xconuserdisplay : "none",
-					user->xconuseruri ? user->xconuseruri : "none");
+					dconuser->xconuserID,
+					dconuser->xconuserdisplay ? dconuser->xconuserdisplay : "none",
+					dconuser->xconuseruri ? dconuser->xconuseruri : "none");
 				if(cnf->audiofloorID)
-					ast_cli(fd,", Audio %s", user->audiofloorstatus ? bfcp_status[user->audiofloorstatus-1].description : "NOT GRANTED");
+					ast_cli(fd,", Audio %s", dconuser->audiofloorstatus ? bfcp_status[dconuser->audiofloorstatus-1].description : "NOT GRANTED");
 				if(cnf->videofloorID)
-					ast_cli(fd,", Video %s", user->videofloorstatus ? bfcp_status[user->videofloorstatus-1].description : "NOT GRANTED");
-				ast_cli(fd,"\n");
-			}
-			AST_LIST_UNLOCK(&confs);
-		} else {
-			ast_cli(fd,"  There is no active conference with ID %ld in the BFCP Server.\n",ID);
-			return RESULT_FAILURE;
-		}	
-	}
+					ast_cli(fd,", Video %s", dconuser->videofloorstatus ? bfcp_status[dconuser->videofloorstatus-1].description : "NOT GRANTED");
+				ast_cli(fd," (REMOTE USER)\n");
+			}
+		}
+		AST_LIST_UNLOCK(&confs);
+	} else {
+		ast_cli(fd,"  There is no active conference with ID %lu in the BFCP Server.\n",ID);
+		return RESULT_FAILURE;
+	}	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1274,49 +1372,57 @@
 {
 	if (argc != 5)
 		return RESULT_SHOWUSAGE;
-	if (bfcp_server_list == NULL)
-		ast_cli(fd,"  BFCP Server List has not been created yet.\n");
-	else {
-		unsigned long int confID = atoi(argv[3]);
-		if(!confID)
-			return RESULT_SHOWUSAGE;
-		unsigned short int userID = atoi(argv[4]);
-		if(!userID)
-			return RESULT_SHOWUSAGE;
-		if (bfcp_server_list->list_conferences == NULL) {
-			ast_cli(fd,"  The BFCP Server List is NULL.\n");
-			return RESULT_FAILURE;
-		}
-		if (bfcp_server_list->Actual_number_conference == 0) {
-			ast_cli(fd,"  There are no active conferences in the BFCP Server.\n");
-			return RESULT_FAILURE;
-		}	
-
-		struct ast_conference *cnf = xcon_get_conference(confID);
-		if(cnf) {
-			AST_LIST_LOCK(&confs);
-			struct ast_conf_user *user = xcon_get_user(cnf, userID);
-			if(user) {
+
+	unsigned long int confID = atoi(argv[3]);
+	if(!confID)
+		return RESULT_SHOWUSAGE;
+	unsigned short int userID = atoi(argv[4]);
+	if(!userID)
+		return RESULT_SHOWUSAGE;
+
+	if(AST_LIST_EMPTY(&confs)) {
+		ast_cli(fd,"  There are no active conferences in the BFCP Server.\n");
+		return RESULT_FAILURE;
+	}	
+
+	struct ast_conference *cnf = xcon_get_conference(confID);
+	if(cnf) {
+		AST_LIST_LOCK(&confs);
+		struct ast_conf_user *user = xcon_get_user(cnf, userID);
+		if(user) {
+			ast_cli(fd,"  UserID %u (Display Name: %s, URI: %s)",
+				user->xconuserID,
+				user->xconuserdisplay ? user->xconuserdisplay : "none",
+				user->xconuseruri ? user->xconuseruri : "none");
+			if(cnf->audiofloorID)
+				ast_cli(fd,", Audio %s", user->audiofloorstatus ? bfcp_status[user->audiofloorstatus-1].description : "NOT GRANTED");
+			if(cnf->videofloorID)
+				ast_cli(fd,", Video %s", user->videofloorstatus ? bfcp_status[user->videofloorstatus-1].description : "NOT GRANTED");
+			ast_cli(fd,"\n");
+		} else {	/* Try remote users */
+			struct dcon_user *dconuser = dcon_get_remote_user(cnf, userID);
+			if(dconuser) {
 				ast_cli(fd,"  UserID %u (Display Name: %s, URI: %s)",
-					user->xconuserID,
-					user->xconuserdisplay ? user->xconuserdisplay : "none",
-					user->xconuseruri ? user->xconuseruri : "none");
+					dconuser->xconuserID,
+					dconuser->xconuserdisplay ? dconuser->xconuserdisplay : "none",
+					dconuser->xconuseruri ? dconuser->xconuseruri : "none");
 				if(cnf->audiofloorID)
-					ast_cli(fd,", Audio %s", user->audiofloorstatus ? bfcp_status[user->audiofloorstatus-1].description : "NOT GRANTED");
+					ast_cli(fd,", Audio %s", dconuser->audiofloorstatus ? bfcp_status[dconuser->audiofloorstatus-1].description : "NOT GRANTED");
 				if(cnf->videofloorID)
-					ast_cli(fd,", Video %s", user->videofloorstatus ? bfcp_status[user->videofloorstatus-1].description : "NOT GRANTED");
-				ast_cli(fd,"\n");
+					ast_cli(fd,", Video %s", dconuser->videofloorstatus ? bfcp_status[dconuser->videofloorstatus-1].description : "NOT GRANTED");
+				ast_cli(fd," (REMOTE USER)\n");
 			} else {
-				ast_cli(fd,"  There is no user %u in conference with ID %ld in the BFCP Server.\n",userID,confID);
+				ast_cli(fd,"  There is no user %u in conference with ID %lu in the BFCP Server.\n",userID,confID);
 				AST_LIST_UNLOCK(&confs);
 				return RESULT_FAILURE;
 			}
-			AST_LIST_UNLOCK(&confs);
-		} else {
-			ast_cli(fd,"  There is no active conference with ID %ld in the BFCP Server.\n",confID);
-			return RESULT_FAILURE;
-		}	
-	}
+		}
+		AST_LIST_UNLOCK(&confs);
+	} else {
+		ast_cli(fd,"  There is no active conference with ID %lu in the BFCP Server.\n",confID);
+		return RESULT_FAILURE;
+	}	
+
 	return RESULT_SUCCESS;
 }
 
@@ -1325,34 +1431,32 @@
 {
 	if (argc != 4)
 		return RESULT_SHOWUSAGE;
-	if (bfcp_server_list == NULL)
-		ast_cli(fd,"  BFCP Server List has not been created yet.\n");
-	else {
-		unsigned long int ID = atoi(argv[3]);
-		if(!ID)
-			return RESULT_SHOWUSAGE;
-		if (bfcp_server_list->list_conferences == NULL) {
-			ast_cli(fd,"  The BFCP Server List is NULL.\n");
-			return RESULT_FAILURE;
-		}
-		if (bfcp_server_list->Actual_number_conference == 0) {
-			ast_cli(fd,"  There are no active conferences in the BFCP Server.\n");
-			return RESULT_FAILURE;
-		}	
-
-		struct ast_conference *cnf = xcon_get_conference(ID);
-		if(cnf) {
-			AST_LIST_LOCK(&confs);
-			struct ast_conf_user *user;
-			AST_LIST_TRAVERSE(&cnf->userlist, user, list) {
-				user->adminflags |= ADMINFLAG_KICKME;
-			}
-			AST_LIST_UNLOCK(&confs);
-		} else {
-			ast_cli(fd,"  There is no active conference with ID %ld in the BFCP Server.\n",ID);
-			return RESULT_FAILURE;
-		}	
-	}
+
+	unsigned long int ID = atoi(argv[3]);
+	if(!ID)
+		return RESULT_SHOWUSAGE;
+
+	if(AST_LIST_EMPTY(&confs)) {
+		ast_cli(fd,"  There are no active conferences in the BFCP Server.\n");
+		return RESULT_FAILURE;
+	}	
+
+	struct ast_conference *cnf = xcon_get_conference(ID);
+	if(cnf) {
+		AST_LIST_LOCK(&confs);
+		struct ast_conf_user *user;
+		AST_LIST_TRAVERSE(&cnf->userlist, user, list)
+			user->adminflags |= ADMINFLAG_KICKME;
+		if(cnf->xcondcontype == XCON_LOCAL_CONFERENCE) {
+			dcon_free_remote_users(cnf);
+			ast_cli(fd,"  Removing all Remote Users from Local Conference %lu\n", ID);
+		}
+		AST_LIST_UNLOCK(&confs);
+	} else {

[... 3038 lines stripped ...]


More information about the asterisk-commits mailing list