[asterisk-commits] rmudgett: branch group/bridge_construction r389370 - in /team/group/bridge_co...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue May 21 11:54:03 CDT 2013


Author: rmudgett
Date: Tue May 21 11:53:55 2013
New Revision: 389370

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389370
Log:
Make ConfBridge use its own unreal announcer channel driver and delete chan_bridge.

* Made the ConfBridge recorder channel driver type name and channel name
consistent.  Before the channel driver type was ConfBridgeRec and the
created channel name was ConfBridgeRecorder/conf-%s-uid-%d.  Now it is
CBRec and CBRec/conf-%s-uid-%d respectively.

* Replaced ConfBridge usage of chan_bridge with its own announcer channel.

* Deleted chan_bridge since it was created just for ConfBridge and it no
longer uses it.

* The CBRec and CBAnn drivers set the recorder and announcer bridge
channel roles respectively and are marked as IMMOVABLE to bridge merges
and channel moves.

* Extracted the CBRec and CBAnn ConfBridge special channel drivers into
their own files for ConfBridge.

(issue ASTERISK-21271)
Reporter: Matt Jordan

Review: https://reviewboard.asterisk.org/r/2551/

Added:
    team/group/bridge_construction/apps/confbridge/conf_chan_announce.c
      - copied unchanged from r389365, team/rmudgett/bridge_phase/apps/confbridge/conf_chan_announce.c
    team/group/bridge_construction/apps/confbridge/conf_chan_record.c
      - copied unchanged from r389365, team/rmudgett/bridge_phase/apps/confbridge/conf_chan_record.c
Removed:
    team/group/bridge_construction/channels/chan_bridge.c
Modified:
    team/group/bridge_construction/apps/app_confbridge.c
    team/group/bridge_construction/apps/confbridge/include/confbridge.h

Modified: team/group/bridge_construction/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/apps/app_confbridge.c?view=diff&rev=389370&r1=389369&r2=389370
==============================================================================
--- team/group/bridge_construction/apps/app_confbridge.c (original)
+++ team/group/bridge_construction/apps/app_confbridge.c Tue May 21 11:53:55 2013
@@ -306,7 +306,7 @@
 };
 
 /*! \brief Container to hold all conference bridges in progress */
-static struct ao2_container *conference_bridges;
+struct ao2_container *conference_bridges;
 
 static void leave_conference(struct confbridge_user *user);
 static int play_sound_number(struct confbridge_conference *conference, int say_number);
@@ -488,44 +488,6 @@
 	send_conf_stasis(conference, chan, "confbridge_unmute", NULL, 1);
 }
 
-
-static struct ast_frame *rec_read(struct ast_channel *ast)
-{
-	return &ast_null_frame;
-}
-static int rec_write(struct ast_channel *ast, struct ast_frame *f)
-{
-	return 0;
-}
-static struct ast_channel *rec_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
-static struct ast_channel_tech record_tech = {
-	.type = "ConfBridgeRec",
-	.description = "Conference Bridge Recording Channel",
-	.requester = rec_request,
-	.read = rec_read,
-	.write = rec_write,
-};
-static struct ast_channel *rec_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
-{
-	struct ast_channel *tmp;
-	struct ast_format fmt;
-	const char *conf_name = data;
-	if (!(tmp = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", NULL, 0,
-		"ConfBridgeRecorder/conf-%s-uid-%d",
-		conf_name,
-		(int) ast_random()))) {
-		return NULL;
-	}
-	ast_format_set(&fmt, AST_FORMAT_SLINEAR, 0);
-	ast_channel_tech_set(tmp, &record_tech);
-	ast_format_cap_add_all(ast_channel_nativeformats(tmp));
-	ast_format_copy(ast_channel_writeformat(tmp), &fmt);
-	ast_format_copy(ast_channel_rawwriteformat(tmp), &fmt);
-	ast_format_copy(ast_channel_readformat(tmp), &fmt);
-	ast_format_copy(ast_channel_rawreadformat(tmp), &fmt);
-	return tmp;
-}
-
 static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
 {
 	char *rec_file = conference->b_profile.rec_file;
@@ -596,6 +558,7 @@
 		ao2_ref(conference, -1);
 		return NULL;
 	}
+	ast_set_flag(&features.feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE);
 
 	/* XXX If we get an EXIT right here, START will essentially be a no-op */
 	while (conference->record_state != CONF_RECORD_EXIT) {
@@ -689,8 +652,7 @@
 static int conf_start_record(struct confbridge_conference *conference)
 {
 	struct ast_format_cap *cap;
-	struct ast_format tmpfmt;
-	int cause;
+	struct ast_format format;
 
 	if (conference->record_state != CONF_RECORD_STOP) {
 		return -1;
@@ -701,18 +663,19 @@
 		return -1;
 	}
 
-	if (!(cap = ast_format_cap_alloc_nolock())) {
+	cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
 		return -1;
 	}
 
-	ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
-
-	if (!(conference->record_chan = ast_request("ConfBridgeRec", cap, NULL, conference->name, &cause))) {
-		cap = ast_format_cap_destroy(cap);
+	ast_format_cap_add(cap, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
+
+	conference->record_chan = ast_request("CBRec", cap, NULL,
+		conference->name, NULL);
+	cap = ast_format_cap_destroy(cap);
+	if (!conference->record_chan) {
 		return -1;
 	}
-
-	cap = ast_format_cap_destroy(cap);
 
 	conference->record_state = CONF_RECORD_START;
 	ast_mutex_lock(&conference->record_lock);
@@ -923,10 +886,7 @@
 	ast_debug(1, "Destroying conference bridge '%s'\n", conference->name);
 
 	if (conference->playback_chan) {
-		struct ast_channel *underlying_channel = ast_channel_tech(conference->playback_chan)->bridged_channel(conference->playback_chan, NULL);
-		if (underlying_channel) {
-			ast_hangup(underlying_channel);
-		}
+		conf_announce_channel_depart(conference->playback_chan);
 		ast_hangup(conference->playback_chan);
 		conference->playback_chan = NULL;
 	}
@@ -1360,74 +1320,59 @@
 
 /*!
  * \internal
- * \brief allocates playback chan on a channel
+ * \brief Allocate playback channel for a conference.
  * \pre expects conference to be locked before calling this function
  */
 static int alloc_playback_chan(struct confbridge_conference *conference)
 {
-	int cause;
 	struct ast_format_cap *cap;
-	struct ast_format tmpfmt;
-
-	if (conference->playback_chan) {
-		return 0;
-	}
-	if (!(cap = ast_format_cap_alloc_nolock())) {
+	struct ast_format format;
+
+	cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
 		return -1;
 	}
-	ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
-	if (!(conference->playback_chan = ast_request("Bridge", cap, NULL, "", &cause))) {
-		cap = ast_format_cap_destroy(cap);
+	ast_format_cap_add(cap, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
+	conference->playback_chan = ast_request("CBAnn", cap, NULL,
+		conference->name, NULL);
+	cap = ast_format_cap_destroy(cap);
+	if (!conference->playback_chan) {
 		return -1;
 	}
-	cap = ast_format_cap_destroy(cap);
-
-	ast_channel_internal_bridge_set(conference->playback_chan, conference->bridge);
-
-	if (ast_call(conference->playback_chan, "", 0)) {
-		ast_hangup(conference->playback_chan);
-		conference->playback_chan = NULL;
-		return -1;
-	}
-
-	ast_debug(1, "Created a playback channel to conference bridge '%s'\n", conference->name);
+
+	ast_debug(1, "Created announcer channel '%s' to conference bridge '%s'\n",
+		ast_channel_name(conference->playback_chan), conference->name);
 	return 0;
 }
 
 static int play_sound_helper(struct confbridge_conference *conference, const char *filename, int say_number)
 {
-	struct ast_channel *underlying_channel;
-
 	/* Do not waste resources trying to play files that do not exist */
 	if (!ast_strlen_zero(filename) && !sound_file_exists(filename)) {
 		return 0;
 	}
 
 	ast_mutex_lock(&conference->playback_lock);
-	if (!(conference->playback_chan)) {
-		if (alloc_playback_chan(conference)) {
-			ast_mutex_unlock(&conference->playback_lock);
-			return -1;
-		}
-		underlying_channel = ast_channel_tech(conference->playback_chan)->bridged_channel(conference->playback_chan, NULL);
-	} else {
-		/* Channel was already available so we just need to add it back into the bridge */
-		underlying_channel = ast_channel_tech(conference->playback_chan)->bridged_channel(conference->playback_chan, NULL);
-		if (ast_bridge_impart(conference->bridge, underlying_channel, NULL, NULL, 0)) {
-			ast_mutex_unlock(&conference->playback_lock);
-			return -1;
-		}
+	if (!conference->playback_chan && alloc_playback_chan(conference)) {
+		ast_mutex_unlock(&conference->playback_lock);
+		return -1;
+	}
+	if (conf_announce_channel_push(conference->playback_chan)) {
+		ast_mutex_unlock(&conference->playback_lock);
+		return -1;
 	}
 
 	/* The channel is all under our control, in goes the prompt */
 	if (!ast_strlen_zero(filename)) {
 		ast_stream_and_wait(conference->playback_chan, filename, "");
 	} else if (say_number >= 0) {
-		ast_say_number(conference->playback_chan, say_number, "", ast_channel_language(conference->playback_chan), NULL);
-	}
-
-	ast_debug(1, "Departing underlying channel '%s' from bridge '%p'\n", ast_channel_name(underlying_channel), conference->bridge);
-	ast_bridge_depart(underlying_channel);
+		ast_say_number(conference->playback_chan, say_number, "",
+			ast_channel_language(conference->playback_chan), NULL);
+	}
+
+	ast_debug(1, "Departing announcer channel '%s' from conference bridge '%s'\n",
+		ast_channel_name(conference->playback_chan), conference->name);
+	conf_announce_channel_depart(conference->playback_chan);
 
 	ast_mutex_unlock(&conference->playback_lock);
 
@@ -3102,6 +3047,46 @@
 	conference->waitingusers--;
 }
 
+/*!
+ * \internal
+ * \brief Unregister a ConfBridge channel technology.
+ * \since 12.0.0
+ *
+ * \param tech What to unregister.
+ *
+ * \return Nothing
+ */
+static void unregister_channel_tech(struct ast_channel_tech *tech)
+{
+	ast_channel_unregister(tech);
+	tech->capabilities = ast_format_cap_destroy(tech->capabilities);
+}
+
+/*!
+ * \internal
+ * \brief Register a ConfBridge channel technology.
+ * \since 12.0.0
+ *
+ * \param tech What to register.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int register_channel_tech(struct ast_channel_tech *tech)
+{
+	tech->capabilities = ast_format_cap_alloc();
+	if (!tech->capabilities) {
+		return -1;
+	}
+	ast_format_cap_add_all(tech->capabilities);
+	if (ast_channel_register(tech)) {
+		ast_log(LOG_ERROR, "Unable to register channel technology %s(%s).\n",
+			tech->type, tech->description);
+		return -1;
+	}
+	return 0;
+}
+
 /*! \brief Called when module is being unloaded */
 static int unload_module(void)
 {
@@ -3132,8 +3117,8 @@
 
 	conf_destroy_config();
 
-	ast_channel_unregister(&record_tech);
-	record_tech.capabilities = ast_format_cap_destroy(record_tech.capabilities);
+	unregister_channel_tech(conf_announce_get_tech());
+	unregister_channel_tech(conf_record_get_tech());
 
 	return 0;
 }
@@ -3157,13 +3142,8 @@
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
-	if (!(record_tech.capabilities = ast_format_cap_alloc())) {
-		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
-	}
-	ast_format_cap_add_all(record_tech.capabilities);
-	if (ast_channel_register(&record_tech)) {
-		ast_log(LOG_ERROR, "Unable to register ConfBridge recorder.\n");
+	if (register_channel_tech(conf_record_get_tech())
+		|| register_channel_tech(conf_announce_get_tech())) {
 		unload_module();
 		return AST_MODULE_LOAD_FAILURE;
 	}

Modified: team/group/bridge_construction/apps/confbridge/include/confbridge.h
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/apps/confbridge/include/confbridge.h?view=diff&rev=389370&r1=389369&r2=389370
==============================================================================
--- team/group/bridge_construction/apps/confbridge/include/confbridge.h (original)
+++ team/group/bridge_construction/apps/confbridge/include/confbridge.h Tue May 21 11:53:55 2013
@@ -222,6 +222,8 @@
 	AST_LIST_HEAD_NOLOCK(, confbridge_user) waiting_list;             /*!< List of users waiting to join the conference bridge */
 };
 
+extern struct ao2_container *conference_bridges;
+
 struct post_join_action {
 	int (*func)(struct confbridge_user *user);
 	AST_LIST_ENTRY(post_join_action) list;
@@ -484,4 +486,41 @@
  * \brief unregister stasis message routers to handle manager events for confbridge messages
  */
 void manager_confbridge_shutdown(void);
+
+/*!
+ * \brief Get ConfBridge record channel technology struct.
+ * \since 12.0.0
+ *
+ * \return ConfBridge record channel technology.
+ */
+struct ast_channel_tech *conf_record_get_tech(void);
+
+/*!
+ * \brief Get ConfBridge announce channel technology struct.
+ * \since 12.0.0
+ *
+ * \return ConfBridge announce channel technology.
+ */
+struct ast_channel_tech *conf_announce_get_tech(void);
+
+/*!
+ * \brief Remove the announcer channel from the conference.
+ * \since 12.0.0
+ *
+ * \param chan Either channel in the announcer channel pair.
+ *
+ * \return Nothing
+ */
+void conf_announce_channel_depart(struct ast_channel *chan);
+
+/*!
+ * \brief Push the announcer channel into the conference.
+ * \since 12.0.0
+ *
+ * \param ast Either channel in the announcer channel pair.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int conf_announce_channel_push(struct ast_channel *ast);
 #endif




More information about the asterisk-commits mailing list