[asterisk-commits] kmoore: trunk r391643 - in /trunk: include/asterisk/ main/ res/parking/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 13 08:46:47 CDT 2013


Author: kmoore
Date: Thu Jun 13 08:46:40 2013
New Revision: 391643

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=391643
Log:
Refactor CEL bridge events on top of Stasis-Core

This pulls bridge-related CEL event triggers out of the code in which
they were residing and pulls them into cel.c where they are now
triggered by changes in bridge snapshots. To get access to the
Stasis-Core parking topic in cel.c, the Stasis-Core portions of parking
init have been pulled into core Asterisk init.

This also adds a new CEL event (AST_CEL_BRIDGE_TO_CONF) that indicates
a two-party bridge has transitioned to a multi-party conference. The
reverse cannot occur in CEL terms even though it may occur in actuality
and two party bridges which receive a AST_CEL_BRIDGE_TO_CONF will be
treated as multi-party conferences for the duration of the bridge.

Review: https://reviewboard.asterisk.org/r/2563/
(closes issue ASTERISK-21564)

Modified:
    trunk/include/asterisk/_private.h
    trunk/include/asterisk/cel.h
    trunk/include/asterisk/parking.h
    trunk/main/asterisk.c
    trunk/main/cel.c
    trunk/main/features.c
    trunk/main/parking.c
    trunk/res/parking/parking_manager.c

Modified: trunk/include/asterisk/_private.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/_private.h?view=diff&rev=391643&r1=391642&r2=391643
==============================================================================
--- trunk/include/asterisk/_private.h (original)
+++ trunk/include/asterisk/_private.h Thu Jun 13 08:46:40 2013
@@ -134,4 +134,10 @@
 
 /*! \brief initializes the rtp engine arrays */
 int ast_rtp_engine_init(void);
+
+/*!
+ * \brief initializes the rtp engine arrays
+ * \since 12.0.0
+ */
+int ast_parking_stasis_init(void);
 #endif /* _ASTERISK__PRIVATE_H */

Modified: trunk/include/asterisk/cel.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/cel.h?view=diff&rev=391643&r1=391642&r2=391643
==============================================================================
--- trunk/include/asterisk/cel.h (original)
+++ trunk/include/asterisk/cel.h Thu Jun 13 08:46:40 2013
@@ -103,6 +103,8 @@
 	AST_CEL_PICKUP = 24,
 	/*! \brief this call was forwarded somewhere else  */
 	AST_CEL_FORWARD = 25,
+	/*! \brief a bridge turned into a conference and will be treated as such until it is torn down */
+	AST_CEL_BRIDGE_TO_CONF = 26,
 };
 
 /*! 

Modified: trunk/include/asterisk/parking.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/parking.h?view=diff&rev=391643&r1=391642&r2=391643
==============================================================================
--- trunk/include/asterisk/parking.h (original)
+++ trunk/include/asterisk/parking.h Thu Jun 13 08:46:40 2013
@@ -76,18 +76,6 @@
 		struct ast_channel_snapshot *parkee_snapshot, struct ast_channel_snapshot *parker_snapshot,
 		struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot,
 		unsigned int parkingspace, unsigned long int timeout, unsigned long int duration);
-
-/*!
- * \brief initialize parking stasis types
- * \since 12
- */
-void ast_parking_stasis_init(void);
-
-/*!
- * \brief disable parking stasis types
- * \since 12
- */
-void ast_parking_stasis_disable(void);
 
 /*!
  * \brief accessor for the parking stasis topic

Modified: trunk/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/asterisk.c?view=diff&rev=391643&r1=391642&r2=391643
==============================================================================
--- trunk/main/asterisk.c (original)
+++ trunk/main/asterisk.c Thu Jun 13 08:46:40 2013
@@ -4366,6 +4366,11 @@
 		exit(1);
 	}
 
+	if (ast_parking_stasis_init()) {
+		printf("%s", term_quit());
+		exit(1);
+	}
+
 	if (ast_cel_engine_init()) {
 		printf("%s", term_quit());
 		exit(1);

Modified: trunk/main/cel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/cel.c?view=diff&rev=391643&r1=391642&r2=391643
==============================================================================
--- trunk/main/cel.c (original)
+++ trunk/main/cel.c Thu Jun 13 08:46:40 2013
@@ -60,6 +60,7 @@
 #include "asterisk/stasis_channels.h"
 #include "asterisk/stasis_bridging.h"
 #include "asterisk/bridging.h"
+#include "asterisk/parking.h"
 
 /*** DOCUMENTATION
 	<configInfo name="cel" language="en_US">
@@ -96,6 +97,7 @@
 						<enum name="BRIDGE_START"/>
 						<enum name="BRIDGE_END"/>
 						<enum name="BRIDGE_UPDATE"/>
+						<enum name="BRIDGE_TO_CONF"/>
 						<enum name="CONF_START"/>
 						<enum name="CONF_END"/>
 						<enum name="PARK_START"/>
@@ -133,6 +135,9 @@
 /*! Subscription for forwarding the channel caching topic */
 static struct stasis_subscription *cel_bridge_forwarder;
 
+/*! Subscription for forwarding the parking topic */
+static struct stasis_subscription *cel_parking_forwarder;
+
 /*! Container for primary channel/bridge ID listing for 2 party bridges */
 static struct ao2_container *bridge_primaries;
 
@@ -301,6 +306,7 @@
 	[AST_CEL_BRIDGE_START]     = "BRIDGE_START",
 	[AST_CEL_BRIDGE_END]       = "BRIDGE_END",
 	[AST_CEL_BRIDGE_UPDATE]    = "BRIDGE_UPDATE",
+	[AST_CEL_BRIDGE_TO_CONF]   = "BRIDGE_TO_CONF",
 	[AST_CEL_CONF_START]       = "CONF_START",
 	[AST_CEL_CONF_END]         = "CONF_END",
 	[AST_CEL_PARK_START]       = "PARK_START",
@@ -321,36 +327,41 @@
 
 struct bridge_assoc {
 	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(channel_id);	/*!< UniqueID of the primary/dialing channel */
-		AST_STRING_FIELD(bridge_id);	/*!< UniqueID of the bridge */
-		AST_STRING_FIELD(secondary_id);	/*!< UniqueID of the secondary/dialed channel */
+		AST_STRING_FIELD(bridge_id);           /*!< UniqueID of the bridge */
+		AST_STRING_FIELD(secondary_name);      /*!< UniqueID of the secondary/dialed channel */
 	);
+	struct ast_channel_snapshot *primary_snapshot; /*!< The snapshot for the initiating channel in the bridge */
+	int track_as_conf;                             /*!< Whether this bridge will be treated like a conference in CEL terms */
 };
 
 static void bridge_assoc_dtor(void *obj)
 {
 	struct bridge_assoc *assoc = obj;
 	ast_string_field_free_memory(assoc);
-}
-
-static struct bridge_assoc *bridge_assoc_alloc(const char *channel_id, const char *bridge_id, const char *secondary_id)
+	ao2_cleanup(assoc->primary_snapshot);
+	assoc->primary_snapshot = NULL;
+}
+
+static struct bridge_assoc *bridge_assoc_alloc(struct ast_channel_snapshot *primary, const char *bridge_id, const char *secondary_name)
 {
 	RAII_VAR(struct bridge_assoc *, assoc, ao2_alloc(sizeof(*assoc), bridge_assoc_dtor), ao2_cleanup);
-	if (!assoc || ast_string_field_init(assoc, 64)) {
+	if (!primary || !assoc || ast_string_field_init(assoc, 64)) {
 		return NULL;
 	}
 
-	ast_string_field_set(assoc, channel_id, channel_id);
 	ast_string_field_set(assoc, bridge_id, bridge_id);
-	ast_string_field_set(assoc, secondary_id, secondary_id);
+	ast_string_field_set(assoc, secondary_name, secondary_name);
+
+	assoc->primary_snapshot = primary;
+	ao2_ref(primary, +1);
 
 	ao2_ref(assoc, +1);
 	return assoc;
 }
 
-static int add_bridge_primary(const char *channel_id, const char *bridge_id, const char *secondary_id)
-{
-	RAII_VAR(struct bridge_assoc *, assoc, bridge_assoc_alloc(channel_id, bridge_id, secondary_id), ao2_cleanup);
+static int add_bridge_primary(struct ast_channel_snapshot *primary, const char *bridge_id, const char *secondary_name)
+{
+	RAII_VAR(struct bridge_assoc *, assoc, bridge_assoc_alloc(primary, bridge_id, secondary_name), ao2_cleanup);
 	if (!assoc) {
 		return -1;
 	}
@@ -370,7 +381,7 @@
 	const struct bridge_assoc *assoc = obj;
 	const char *uniqueid = obj;
 	if (!(flags & OBJ_KEY)) {
-		uniqueid = assoc->channel_id;
+		uniqueid = assoc->primary_snapshot->uniqueid;
 	}
 
 	return ast_str_hash(uniqueid);
@@ -380,9 +391,9 @@
 static int bridge_assoc_cmp(void *obj, void *arg, int flags)
 {
 	struct bridge_assoc *assoc1 = obj, *assoc2 = arg;
-	const char *assoc2_id = arg, *assoc1_id = assoc1->channel_id;
+	const char *assoc2_id = arg, *assoc1_id = assoc1->primary_snapshot->uniqueid;
 	if (!(flags & OBJ_KEY)) {
-		assoc2_id = assoc2->channel_id;
+		assoc2_id = assoc2->primary_snapshot->uniqueid;
 	}
 
 	return !strcmp(assoc1_id, assoc2_id) ? CMP_MATCH | CMP_STOP : 0;
@@ -645,12 +656,12 @@
 
 static int report_event_snapshot(struct ast_channel_snapshot *snapshot,
 		enum ast_cel_event_type event_type, const char *userdefevname,
-		const char *extra)
+		const char *extra, const char *peer2_name)
 {
 	struct timeval eventtime;
 	struct ast_event *ev;
 	char *linkedid = ast_strdupa(snapshot->linkedid);
-	char *peer_name = "";
+	const char *peer_name = peer2_name;
 	RAII_VAR(struct bridge_assoc *, assoc, NULL, ao2_cleanup);
 	RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
 
@@ -662,12 +673,10 @@
 		return 0;
 	}
 
-	assoc = ao2_find(bridge_primaries, snapshot->uniqueid, OBJ_KEY);
-	if (assoc) {
-		RAII_VAR(struct ast_channel_snapshot *, bridged_snapshot, NULL, ao2_cleanup);
-		bridged_snapshot = ast_channel_snapshot_get_latest(assoc->secondary_id);
-		if (bridged_snapshot) {
-			peer_name = ast_strdupa(bridged_snapshot->name);
+	if (ast_strlen_zero(peer_name)) {
+		assoc = ao2_find(bridge_primaries, snapshot->uniqueid, OBJ_KEY);
+		if (assoc) {
+			peer_name = assoc->secondary_name;
 		}
 	}
 
@@ -712,7 +721,7 @@
 		AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, snapshot->linkedid,
 		AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, snapshot->userfield,
 		AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, S_OR(extra, ""),
-		AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peer_name,
+		AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, S_OR(peer_name, ""),
 		AST_EVENT_IE_END);
 
 	if (ev && ast_event_queue(ev)) {
@@ -744,7 +753,7 @@
 	 * before unreffing the channel we have a refcount of 3, we're done. Unlink and report. */
 	if (ao2_ref(lid, -1) == 3) {
 		ast_str_container_remove(linkedids, lid);
-		report_event_snapshot(snapshot, AST_CEL_LINKEDID_END, NULL, NULL);
+		report_event_snapshot(snapshot, AST_CEL_LINKEDID_END, NULL, NULL, NULL);
 	}
 	ao2_ref(lid, -1);
 }
@@ -1083,13 +1092,13 @@
 	int is_hungup, was_hungup;
 
 	if (!new_snapshot) {
-		report_event_snapshot(old_snapshot, AST_CEL_CHANNEL_END, NULL, NULL);
+		report_event_snapshot(old_snapshot, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
 		check_retire_linkedid(old_snapshot);
 		return;
 	}
 
 	if (!old_snapshot) {
-		report_event_snapshot(new_snapshot, AST_CEL_CHANNEL_START, NULL, NULL);
+		report_event_snapshot(new_snapshot, AST_CEL_CHANNEL_START, NULL, NULL, NULL);
 		return;
 	}
 
@@ -1107,12 +1116,12 @@
 			new_snapshot->hangupcause,
 			new_snapshot->hangupsource,
 			dialstatus);
-		report_event_snapshot(new_snapshot, AST_CEL_HANGUP, NULL, ast_str_buffer(extra_str));
+		report_event_snapshot(new_snapshot, AST_CEL_HANGUP, NULL, ast_str_buffer(extra_str), NULL);
 		return;
 	}
 
 	if (old_snapshot->state != new_snapshot->state && new_snapshot->state == AST_STATE_UP) {
-		report_event_snapshot(new_snapshot, AST_CEL_ANSWER, NULL, NULL);
+		report_event_snapshot(new_snapshot, AST_CEL_ANSWER, NULL, NULL, NULL);
 		return;
 	}
 }
@@ -1141,12 +1150,12 @@
 
 	/* old snapshot has an application, end it */
 	if (old_snapshot && !ast_strlen_zero(old_snapshot->appl)) {
-		report_event_snapshot(old_snapshot, AST_CEL_APP_END, NULL, NULL);
+		report_event_snapshot(old_snapshot, AST_CEL_APP_END, NULL, NULL, NULL);
 	}
 
 	/* new snapshot has an application, start it */
 	if (new_snapshot && !ast_strlen_zero(new_snapshot->appl)) {
-		report_event_snapshot(new_snapshot, AST_CEL_APP_START, NULL, NULL);
+		report_event_snapshot(new_snapshot, AST_CEL_APP_START, NULL, NULL, NULL);
 	}
 }
 
@@ -1156,6 +1165,47 @@
 	cel_channel_linkedid_change,
 };
 
+static void update_bridge_primary(struct ast_channel_snapshot *snapshot)
+{
+	RAII_VAR(struct bridge_assoc *, assoc, NULL, ao2_cleanup);
+
+	if (!snapshot) {
+		return;
+	}
+
+	assoc = ao2_find(bridge_primaries, snapshot->uniqueid, OBJ_KEY);
+	if (!assoc) {
+		return;
+	}
+
+	ao2_cleanup(assoc->primary_snapshot);
+	ao2_ref(snapshot, +1);
+	assoc->primary_snapshot = snapshot;
+}
+
+static int bridge_match_cb(void *obj, void *arg, int flags)
+{
+	struct bridge_assoc *assoc = obj;
+	char *bridge_id = arg;
+	ast_assert(flags & OBJ_KEY);
+	if (!strcmp(bridge_id, assoc->bridge_id)) {
+		return CMP_MATCH;
+	}
+	return 0;
+}
+
+static struct bridge_assoc *find_bridge_primary_by_bridge_id(const char *bridge_id)
+{
+	char *dup_id = ast_strdupa(bridge_id);
+	return ao2_callback(bridge_primaries, OBJ_KEY, bridge_match_cb, dup_id);
+}
+
+static void clear_bridge_primary(const char *bridge_id)
+{
+	char *dup_id = ast_strdupa(bridge_id);
+	ao2_callback(bridge_primaries, OBJ_KEY | OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, bridge_match_cb, dup_id);
+}
+
 static void cel_snapshot_update_cb(void *data, struct stasis_subscription *sub,
 	struct stasis_topic *topic,
 	struct stasis_message *message)
@@ -1169,8 +1219,76 @@
 		old_snapshot = stasis_message_data(update->old_snapshot);
 		new_snapshot = stasis_message_data(update->new_snapshot);
 
+		update_bridge_primary(new_snapshot);
+
 		for (i = 0; i < ARRAY_LEN(cel_channel_monitors); ++i) {
 			cel_channel_monitors[i](old_snapshot, new_snapshot);
+		}
+	} else if (ast_bridge_snapshot_type() == update->type) {
+		RAII_VAR(struct bridge_assoc *, assoc, NULL, ao2_cleanup);
+		struct ast_bridge_snapshot *old_snapshot;
+		struct ast_bridge_snapshot *new_snapshot;
+
+		update = stasis_message_data(message);
+
+		old_snapshot = stasis_message_data(update->old_snapshot);
+		new_snapshot = stasis_message_data(update->new_snapshot);
+
+		if (!old_snapshot) {
+			return;
+		}
+
+		if (!new_snapshot) {
+			clear_bridge_primary(old_snapshot->uniqueid);
+			return;
+		}
+
+		if (old_snapshot->capabilities == new_snapshot->capabilities) {
+			return;
+		}
+
+		/* handle 1:1/native -> multimix */
+		if ((old_snapshot->capabilities & (AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE))
+			&& (new_snapshot->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX)) {
+			assoc = find_bridge_primary_by_bridge_id(new_snapshot->uniqueid);
+
+			/* this bridge will no longer be treated like a bridge, so mark the bridge_assoc as such */
+			assoc->track_as_conf = 1;
+			report_event_snapshot(assoc->primary_snapshot, AST_CEL_BRIDGE_TO_CONF, NULL, NULL, assoc->secondary_name);
+			return;
+		}
+
+		/* handle multimix -> 1:1/native */
+		if ((old_snapshot->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX)
+			&& (new_snapshot->capabilities & (AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE))) {
+			struct ao2_iterator i;
+			RAII_VAR(char *, channel_id, NULL, ao2_cleanup);
+			RAII_VAR(struct ast_channel_snapshot *, chan_snapshot, NULL, ao2_cleanup);
+
+			assoc = find_bridge_primary_by_bridge_id(new_snapshot->uniqueid);
+			if (assoc) {
+				assoc->track_as_conf = 1;
+				return;
+			}
+
+			/* get the first item in the container */
+			i = ao2_iterator_init(new_snapshot->channels, 0);
+			while ((channel_id = ao2_iterator_next(&i))) {
+				break;
+			}
+			ao2_iterator_destroy(&i);
+
+			/* create a bridge_assoc for this bridge and mark it as being tracked appropriately */
+			chan_snapshot = ast_channel_snapshot_get_latest(channel_id);
+			ast_assert(chan_snapshot != NULL);
+			assoc = bridge_assoc_alloc(chan_snapshot, new_snapshot->uniqueid, chan_snapshot->name);
+			if (!assoc) {
+				return;
+			}
+			assoc->track_as_conf = 1;
+
+			ao2_link(bridge_primaries, assoc);
+			return;
 		}
 	}
 }
@@ -1185,9 +1303,16 @@
 	struct ast_channel_snapshot *chan_snapshot = blob->channel;
 
 	if (snapshot->capabilities & (AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE)) {
+		RAII_VAR(struct bridge_assoc *, assoc, find_bridge_primary_by_bridge_id(snapshot->uniqueid), ao2_cleanup);
+		if (assoc && assoc->track_as_conf) {
+			report_event_snapshot(chan_snapshot, AST_CEL_CONF_ENTER, NULL, NULL, NULL);
+			return;
+		}
+
 		if (ao2_container_count(snapshot->channels) == 2) {
 			struct ao2_iterator i;
 			RAII_VAR(char *, channel_id, NULL, ao2_cleanup);
+			RAII_VAR(struct ast_channel_snapshot *, latest_primary, NULL, ao2_cleanup);
 
 			/* get the name of the channel in the container we don't already know the name of */
 			i = ao2_iterator_init(snapshot->channels, 0);
@@ -1200,8 +1325,12 @@
 			}
 			ao2_iterator_destroy(&i);
 
-			add_bridge_primary(channel_id, snapshot->uniqueid, chan_snapshot->uniqueid);
-		}
+			latest_primary = ast_channel_snapshot_get_latest(channel_id);
+			add_bridge_primary(latest_primary, snapshot->uniqueid, chan_snapshot->name);
+			report_event_snapshot(latest_primary, AST_CEL_BRIDGE_START, NULL, NULL, chan_snapshot->name);
+		}
+	} else if (snapshot->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
+		report_event_snapshot(chan_snapshot, AST_CEL_CONF_ENTER, NULL, NULL, NULL);
 	}
 }
 
@@ -1214,29 +1343,55 @@
 	struct ast_bridge_snapshot *snapshot = blob->bridge;
 	struct ast_channel_snapshot *chan_snapshot = blob->channel;
 
-	if ((snapshot->capabilities | AST_BRIDGE_CAPABILITY_1TO1MIX)
-		|| (snapshot->capabilities | AST_BRIDGE_CAPABILITY_NATIVE)) {
+	if (snapshot->capabilities & (AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE)) {
+		RAII_VAR(struct bridge_assoc *, assoc,
+			find_bridge_primary_by_bridge_id(snapshot->uniqueid),
+			ao2_cleanup);
+
+		if (!assoc) {
+			return;
+		}
+
+		if (assoc->track_as_conf) {
+			report_event_snapshot(chan_snapshot, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+			return;
+		}
+
 		if (ao2_container_count(snapshot->channels) == 1) {
-			RAII_VAR(struct bridge_assoc *, ao2_primary, ao2_find(bridge_primaries, chan_snapshot->uniqueid, OBJ_KEY), ao2_cleanup);
-			RAII_VAR(char *, channel_id_in_bridge, NULL, ao2_cleanup);
-			const char *primary;
-			struct ao2_iterator i;
-
-			/* get the only item in the container */
-			i = ao2_iterator_init(snapshot->channels, 0);
-			while ((channel_id_in_bridge = ao2_iterator_next(&i))) {
-				break;
-			}
-			ao2_iterator_destroy(&i);
-
-			if (ao2_primary) {
-				primary = chan_snapshot->uniqueid;
-			} else {
-				primary = channel_id_in_bridge;
-			}
-
-			remove_bridge_primary(primary);
-		}
+			report_event_snapshot(assoc->primary_snapshot, AST_CEL_BRIDGE_END, NULL, NULL, assoc->secondary_name);
+			remove_bridge_primary(assoc->primary_snapshot->uniqueid);
+			return;
+		}
+	} else if (snapshot->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
+		report_event_snapshot(chan_snapshot, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	}
+}
+
+static void cel_parking_cb(
+	void *data, struct stasis_subscription *sub,
+	struct stasis_topic *topic,
+	struct stasis_message *message)
+{
+	struct ast_parked_call_payload *parked_payload = stasis_message_data(message);
+
+	switch (parked_payload->event_type) {
+	case PARKED_CALL:
+		report_event_snapshot(parked_payload->parkee, AST_CEL_PARK_START, NULL,
+			parked_payload->parkinglot,
+			S_COR(parked_payload->parker, parked_payload->parker->name, NULL));
+		break;
+	case PARKED_CALL_TIMEOUT:
+		report_event_snapshot(parked_payload->parkee, AST_CEL_PARK_END, NULL, "ParkedCallTimeOut", NULL);
+		break;
+	case PARKED_CALL_GIVEUP:
+		report_event_snapshot(parked_payload->parkee, AST_CEL_PARK_END, NULL, "ParkedCallGiveUp", NULL);
+		break;
+	case PARKED_CALL_UNPARKED:
+		report_event_snapshot(parked_payload->parkee, AST_CEL_PARK_END, NULL, "ParkedCallUnparked", NULL);
+		break;
+	case PARKED_CALL_FAILED:
+		report_event_snapshot(parked_payload->parkee, AST_CEL_PARK_END, NULL, "ParkedCallFailed", NULL);
+		break;
 	}
 }
 
@@ -1270,6 +1425,7 @@
 	cel_state_topic = NULL;
 	cel_channel_forwarder = stasis_unsubscribe_and_join(cel_channel_forwarder);
 	cel_bridge_forwarder = stasis_unsubscribe_and_join(cel_bridge_forwarder);
+	cel_parking_forwarder = stasis_unsubscribe_and_join(cel_parking_forwarder);
 	ao2_cleanup(linkedids);
 	linkedids = NULL;
 	ast_cli_unregister(&cli_status);
@@ -1305,6 +1461,11 @@
 		return -1;
 	}
 
+	bridge_primaries = ao2_container_alloc(BRIDGE_PRIMARY_BUCKETS, bridge_assoc_hash, bridge_assoc_cmp);
+	if (!bridge_primaries) {
+		return -1;
+	}
+
 	cel_state_topic = stasis_topic_create("cel_state_topic");
 	if (!cel_state_topic) {
 		return -1;
@@ -1324,6 +1485,13 @@
 		return -1;
 	}
 
+	cel_parking_forwarder = stasis_forward_all(
+		ast_parking_topic(),
+		cel_state_topic);
+	if (!cel_parking_forwarder) {
+		return -1;
+	}
+
 	cel_state_router = stasis_message_router_create(cel_state_topic);
 	if (!cel_state_router) {
 		return -1;
@@ -1337,6 +1505,21 @@
 	ret |= stasis_message_router_add(cel_state_router,
 		ast_channel_dial_type(),
 		cel_dial_cb,
+		NULL);
+
+	ret |= stasis_message_router_add(cel_state_router,
+		ast_channel_entered_bridge_type(),
+		cel_bridge_enter_cb,
+		NULL);
+
+	ret |= stasis_message_router_add(cel_state_router,
+		ast_channel_left_bridge_type(),
+		cel_bridge_leave_cb,
+		NULL);
+
+	ret |= stasis_message_router_add(cel_state_router,
+		ast_parked_call_type(),
+		cel_parking_cb,
 		NULL);
 
 	/* If somehow we failed to add any routes, just shut down the whole
@@ -1347,30 +1530,7 @@
 		return -1;
 	}
 
-	bridge_primaries = ao2_container_alloc(BRIDGE_PRIMARY_BUCKETS, bridge_assoc_hash, bridge_assoc_cmp);
-	if (!bridge_primaries) {
-		return -1;
-	}
-
-	ret |= stasis_message_router_add(cel_state_router,
-		ast_channel_entered_bridge_type(),
-		cel_bridge_enter_cb,
-		NULL);
-
-	ret |= stasis_message_router_add(cel_state_router,
-		ast_channel_left_bridge_type(),
-		cel_bridge_leave_cb,
-		NULL);
-
-	/* If somehow we failed to add any routes, just shut down the whole
-	 * thing and fail it.
-	 */
-	if (ret) {
-		ast_cel_engine_term();
-		return -1;
-	}
-
-	ast_register_atexit(ast_cel_engine_term);
+	ast_register_cleanup(ast_cel_engine_term);
 
 	return 0;
 }

Modified: trunk/main/features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/features.c?view=diff&rev=391643&r1=391642&r2=391643
==============================================================================
--- trunk/main/features.c (original)
+++ trunk/main/features.c Thu Jun 13 08:46:40 2013
@@ -1425,7 +1425,6 @@
 		ast_channel_name(chan), pu->parkingnum, pu->parkinglot->name,
 		pu->context, pu->exten, pu->priority, (pu->parkingtime / 1000));
 
-	ast_cel_report_event(chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
 	/*** DOCUMENTATION
 		<managerEventInstance>
 			<synopsis>Raised when a call has been parked.</synopsis>
@@ -3969,7 +3968,6 @@
 			set_c_e_p(chan, pu->context, pu->exten, pu->priority);
 		}
 		post_manager_event("ParkedCallTimeOut", pu);
-		ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "ParkedCallTimeOut", NULL);
 
 		ast_verb(2, "Timeout for %s parked on %d (%s). Returning to %s,%s,%d\n",
 			ast_channel_name(pu->chan), pu->parkingnum, pu->parkinglot->name, ast_channel_context(pu->chan),
@@ -4029,8 +4027,6 @@
 					ast_frfree(f);
 				}
 				post_manager_event("ParkedCallGiveUp", pu);
-				ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "ParkedCallGiveUp",
-					NULL);
 
 				/* There's a problem, hang them up */
 				ast_verb(2, "%s got tired of being parked\n", ast_channel_name(chan));

Modified: trunk/main/parking.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/parking.c?view=diff&rev=391643&r1=391642&r2=391643
==============================================================================
--- trunk/main/parking.c (original)
+++ trunk/main/parking.c Thu Jun 13 08:46:40 2013
@@ -33,6 +33,7 @@
 #include "asterisk/bridging.h"
 #include "asterisk/parking.h"
 #include "asterisk/channel.h"
+#include "asterisk/_private.h"
 
 /*! \brief Message type for parked calls */
 STASIS_MESSAGE_TYPE_DEFN(ast_parked_call_type);
@@ -46,17 +47,25 @@
 /*! \brief Function Callback for handling a bridge channel trying to park itself */
 static ast_bridge_channel_park_fn ast_bridge_channel_park_func = NULL;
 
-void ast_parking_stasis_init(void)
-{
-	STASIS_MESSAGE_TYPE_INIT(ast_parked_call_type);
-	parking_topic = stasis_topic_create("ast_parking");
-}
-
-void ast_parking_stasis_disable(void)
+static void parking_stasis_cleanup(void)
 {
 	STASIS_MESSAGE_TYPE_CLEANUP(ast_parked_call_type);
 	ao2_cleanup(parking_topic);
 	parking_topic = NULL;
+}
+
+int ast_parking_stasis_init(void)
+{
+	if (STASIS_MESSAGE_TYPE_INIT(ast_parked_call_type)) {
+		return -1;
+	}
+
+	parking_topic = stasis_topic_create("ast_parking");
+	if (!parking_topic) {
+		return -1;
+	}
+	ast_register_cleanup(parking_stasis_cleanup);
+	return 0;
 }
 
 struct stasis_topic *ast_parking_topic(void)

Modified: trunk/res/parking/parking_manager.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_manager.c?view=diff&rev=391643&r1=391642&r2=391643
==============================================================================
--- trunk/res/parking/parking_manager.c (original)
+++ trunk/res/parking/parking_manager.c Thu Jun 13 08:46:40 2013
@@ -579,7 +579,6 @@
 
 static void parking_manager_enable_stasis(void)
 {
-	ast_parking_stasis_init();
 	if (!parking_sub) {
 		parking_sub = stasis_subscribe(ast_parking_topic(), parking_event_cb, NULL);
 	}
@@ -599,7 +598,6 @@
 static void parking_manager_disable_stasis(void)
 {
 	parking_sub = stasis_unsubscribe(parking_sub);
-	ast_parking_stasis_disable();
 }
 
 void unload_parking_manager(void)




More information about the asterisk-commits mailing list