[asterisk-commits] jrose: branch jrose/bridge_projects r384114 - in /team/jrose/bridge_projects:...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Mar 27 13:35:28 CDT 2013


Author: jrose
Date: Wed Mar 27 13:35:24 2013
New Revision: 384114

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=384114
Log:
One army of findings later

Modified:
    team/jrose/bridge_projects/include/asterisk/parking.h
    team/jrose/bridge_projects/main/manager_channels.c
    team/jrose/bridge_projects/main/parking.c
    team/jrose/bridge_projects/res/parking/parking_applications.c
    team/jrose/bridge_projects/res/parking/parking_controller.c
    team/jrose/bridge_projects/res/parking/parking_manager.c
    team/jrose/bridge_projects/res/parking/parking_ui.c
    team/jrose/bridge_projects/res/parking/res_parking.h
    team/jrose/bridge_projects/res/res_parking.c

Modified: team/jrose/bridge_projects/include/asterisk/parking.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/parking.h?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/parking.h (original)
+++ team/jrose/bridge_projects/include/asterisk/parking.h Wed Mar 27 13:35:24 2013
@@ -22,3 +22,40 @@
  *
  * \author Jonathan Rose <jrose at digium.com>
  */
+
+#include "asterisk/stringfields.h"
+
+/*!
+ * \brief Defines the type of parked call message being published
+ * \since 12
+ */
+enum ast_parked_call_event_type {
+	PARKED_CALL = 0,
+	PARKED_CALL_TIMEOUT,
+	PARKED_CALL_GIVEUP,
+	PARKED_CALL_UNPARKED,
+};
+
+/*!
+ * \brief A parked call message payload
+ * \since 12
+ */
+struct ast_parked_call_payload {
+	struct ast_channel_snapshot *parkee;
+	struct ast_channel_snapshot *parker;
+	enum ast_parked_call_event_type event_type;
+	AST_DECLARE_STRING_FIELDS(
+		AST_STRING_FIELD(parkinglot);
+		AST_STRING_FIELD(parkingspace);
+		AST_STRING_FIELD(timeout);
+		AST_STRING_FIELD(duration);
+	);
+};
+
+/*! \brief Constructor for parked_call_payload objects */
+struct ast_parked_call_payload *ast_parked_call_payload_create(enum ast_parked_call_event_type event_type, struct ast_channel_snapshot *parkee_snapshot, struct ast_channel_snapshot *parker_snapshot, const char *parkinglot, int parkingspace, long int timeout, long int duration);
+
+void ast_parking_stasis_init(void);
+void ast_parking_stasis_disable(void);
+struct stasis_topic *ast_parking_topic(void);
+struct stasis_message_type *ast_parked_call_type(void);

Modified: team/jrose/bridge_projects/main/manager_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/manager_channels.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/main/manager_channels.c (original)
+++ team/jrose/bridge_projects/main/manager_channels.c Wed Mar 27 13:35:24 2013
@@ -182,9 +182,7 @@
 		"Context%s: %s\r\n"
 		"Exten%s: %s\r\n"
 		"Priority%s: %d\r\n"
-		"Uniqueid%s: %s\r\n"
-		"Cause%s: %d\r\n"
-		"Cause-txt%s: %s\r\n",
+		"Uniqueid%s: %s\r\n",
 		suffix, snapshot->name,
 		suffix, snapshot->state,
 		suffix, ast_state2str(snapshot->state),
@@ -196,9 +194,8 @@
 		suffix, snapshot->context,
 		suffix, snapshot->exten,
 		suffix, snapshot->priority,
-		suffix, snapshot->uniqueid,
-		suffix, snapshot->hangupcause,
-		suffix, ast_cause2str(snapshot->hangupcause));
+		suffix, snapshot->uniqueid
+		);
 
 	if (!res) {
 		return NULL;

Modified: team/jrose/bridge_projects/main/parking.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/parking.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/main/parking.c (original)
+++ team/jrose/bridge_projects/main/parking.c Wed Mar 27 13:35:24 2013
@@ -30,3 +30,74 @@
 #include "asterisk/_private.h"
 #include "asterisk/parking.h"
 #include "asterisk/channel.h"
+
+/*! \brief Message type for parked calls */
+static struct stasis_message_type *parked_call_type;
+
+/*! \brief Topic for parking lots */
+static struct stasis_topic *parking_topic;
+
+void ast_parking_stasis_init(void)
+{
+	parked_call_type = stasis_message_type_create("ast_parked_call");
+	parking_topic = stasis_topic_create("ast_parking");
+}
+
+void ast_parking_stasis_disable(void)
+{
+	ao2_cleanup(parked_call_type);
+	ao2_cleanup(parking_topic);
+	parked_call_type = NULL;
+	parking_topic = NULL;
+}
+
+struct stasis_topic *ast_parking_topic(void)
+{
+	return parking_topic;
+}
+
+struct stasis_message_type *ast_parked_call_type(void)
+{
+	return parked_call_type;
+}
+
+/*! \brief Destructor for parked_call_payload objects */
+static void parked_call_payload_destructor(void *obj)
+{
+	struct ast_parked_call_payload *park_obj = obj;
+
+	ao2_cleanup(park_obj->parkee);
+	ao2_cleanup(park_obj->parker);
+	ast_string_field_free_memory(park_obj);
+}
+
+struct ast_parked_call_payload *ast_parked_call_payload_create(enum ast_parked_call_event_type event_type, struct ast_channel_snapshot *parkee_snapshot, struct ast_channel_snapshot *parker_snapshot, const char *parkinglot, int parkingspace, long int timeout, long int duration)
+{
+	RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
+
+	payload = ao2_alloc(sizeof(*payload), parked_call_payload_destructor);
+	if (!payload) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(payload, 32)) {
+		return NULL;
+	}
+
+	payload->event_type = event_type;
+
+	ao2_ref(parkee_snapshot, +1);
+	payload->parkee = parkee_snapshot;
+
+	ao2_ref(parker_snapshot, +1);
+	payload->parker = parker_snapshot;
+
+	ast_string_field_set(payload, parkinglot, parkinglot);
+	ast_string_field_build(payload, parkingspace, "%d", parkingspace);
+	ast_string_field_build(payload, timeout, "%ld", timeout);
+	ast_string_field_build(payload, duration, "%ld", duration);
+
+	/* Bump the ref count by one since RAII_VAR is going to eat one when we leave. */
+	ao2_ref(payload, +1);
+	return payload;
+}

Modified: team/jrose/bridge_projects/res/parking/parking_applications.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_applications.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_applications.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_applications.c Wed Mar 27 13:35:24 2013
@@ -171,9 +171,9 @@
 	}
 
 	if (ast_strlen_zero(args.lot_name)) {
-		lot = channel_find_parkinglot(chan);
+		lot = channel_find_parking_lot_state(chan);
 	} else {
-		lot = parking_lot_find_by_name(args.lot_name);
+		lot = parking_lot_state_find_by_name(args.lot_name);
 	}
 
 	if (!lot) {
@@ -182,7 +182,7 @@
 	}
 
 	ao2_lock(lot);
-	parking_bridge = get_parkinglot_bridge(lot);
+	parking_bridge = parking_lot_state_get_bridge(lot);
 	ao2_unlock(lot);
 
 	if (!parking_bridge) {
@@ -220,10 +220,12 @@
 	/* At this point the channel is no longer in the bridge. Start breaking things down. */
 	ast_bridge_features_cleanup(&chan_features);
 
-	/* If the parked channel exits without a resolution set, it gave up. Issue a ParkedCallGiveUp message. */
+	/* If the parked channel exits without a resolution set, it gave up. Issue a ParkedCallGiveUp message and exit early. */
 	if (pu->resolution == PARK_UNSET) {
 		pu->resolution = PARK_ABANDON;
 		publish_parked_call(pu, PARKED_CALL_GIVEUP);
+		unpark_parked_user(pu);
+		return -1;
 	}
 
 	unpark_parked_user(pu);
@@ -239,7 +241,7 @@
 		}
 	}
 
-	/* Since this is executed from pbx, it'll automatically bump the priority when we return. We can address that by reducing it by 1 in before returning. Smooth. */
+	/* Since this is executed from pbx, it'll automatically bump the priority when we return. We can address that by reducing it by 1 before returning. Smooth. */
 	ast_channel_priority_set(chan, ast_channel_priority(chan) - 1);
 
 	return ast_check_hangup_locked(chan) ? -1 : 0;

Modified: team/jrose/bridge_projects/res/parking/parking_controller.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_controller.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Wed Mar 27 13:35:24 2013
@@ -18,7 +18,7 @@
 
 /*! \file
  *
- * \brief Parking Entry, Exit, Events, and other assorted controls.
+ * \brief Parking Entry, Exit, and other assorted controls.
  *
  * \author Jonathan Rose <jrose at digium.com>
  */
@@ -31,7 +31,7 @@
 #include "asterisk/manager.h"
 #include "asterisk/test.h"
 
-struct ast_bridge *get_parkinglot_bridge(struct parking_lot_state *state)
+struct ast_bridge *parking_lot_state_get_bridge(struct parking_lot_state *state)
 {
 	struct ast_bridge *lot_bridge;
 
@@ -41,7 +41,7 @@
 	}
 
 	/* XXX Richard has changed some things here. Need to implement subclass of bridge as part of the next phase */
-	lot_bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM);
+	lot_bridge = bridge_parking_new(state);
 	if (!lot_bridge) {
 		return NULL;
 	}
@@ -137,7 +137,7 @@
 {
 	if (pu->lot_state) {
 		ao2_unlink(pu->lot_state->parked_user_list, pu);
-		parking_lot_remove_if_unused(pu->lot_state);
+		parking_lot_state_remove_if_unused(pu->lot_state);
 		pu->lot_state = NULL;
 		return 0;
 	}
@@ -169,7 +169,7 @@
 	}
 }
 
-int parking_lot_get_space(struct parking_lot_state *lot, int target_override)
+int parking_lot_state_get_space(struct parking_lot_state *lot, int target_override)
 {
 	int original_target;
 	int current_target;
@@ -335,10 +335,10 @@
 		}
 	}
 
-	/* We need to keep the lot state locked between parking_lot_get_space and actually placing it in the lot. Or until we decide not to. */
+	/* We need to keep the lot state locked between parking_lot_state_get_space and actually placing it in the lot. Or until we decide not to. */
 	ao2_lock(lot_state);
 
-	parking_space = parking_lot_get_space(lot_state, preferred_space);
+	parking_space = parking_lot_state_get_space(lot_state, preferred_space);
 	if (parking_space == -1) {
 		ast_log(LOG_NOTICE, "Failed to get parking space in lot '%s'. All full.\n", lot_state->name);
 		ao2_ref(new_parked_user, -1);

Modified: team/jrose/bridge_projects/res/parking/parking_manager.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_manager.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_manager.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_manager.c Wed Mar 27 13:35:24 2013
@@ -63,88 +63,37 @@
 	</manager>
  ***/
 
-/*! \brief Message type for parked calls */
-static struct stasis_message_type *parked_call_message_type;
-
-/*! \brief Topic for parking lots */
-static struct stasis_topic *parking_topic;
-
 /*! \brief subscription to the parking lot topic */
 static struct stasis_subscription *parking_sub;
 
-/*!
- * \brief A parked call message payload
- * \since 12
- */
-struct parked_call_payload {
-	struct ast_channel_snapshot *parkee;
-	struct ast_channel_snapshot *parker;
-	enum parked_call_event_type event_type;
-	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(parkinglot);
-		AST_STRING_FIELD(parkingspace);
-		AST_STRING_FIELD(timeout);
-		AST_STRING_FIELD(duration);
-	);
-};
-
-/*! \brief Destructor for parked_call_payload objects */
-static void parked_call_payload_destructor(void *obj)
-{
-	struct parked_call_payload *park_obj = obj;
-
-	ao2_cleanup(park_obj->parkee);
-	ao2_cleanup(park_obj->parker);
-	ast_string_field_free_memory(park_obj);
-}
-
-/*! \brief Constructor for parked_call_payload objects */
-static struct parked_call_payload *parked_call_payload_create(struct parked_user *pu, enum parked_call_event_type event_type)
-{
-	struct parked_call_payload *payload;
-	char timeout_text[32] = "";
+static struct ast_parked_call_payload *parked_call_payload_from_parked_user(struct parked_user *pu, enum ast_parked_call_event_type event_type)
+{
+	RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_channel_snapshot *, parkee_snapshot, NULL, ao2_cleanup);
+	long int timeout;
+	long int duration;
 	struct timeval now = ast_tvnow();
-
-	payload = ao2_alloc(sizeof(*payload), parked_call_payload_destructor);
-	if (!payload) {
-		return NULL;
-	}
-
-	if (ast_string_field_init(payload, 32)) {
-		ao2_cleanup(payload);
-		return NULL;
-	}
-
-	payload->parkee = ast_channel_snapshot_create(pu->chan);
-	if (!payload->parkee) {
-		ao2_cleanup(payload);
-		return NULL;
-	}
-
-	payload->event_type = event_type;
+	const char *lot_name = pu->lot_state->name;
 
 	if (!pu->parker) {
 		return NULL;
 	}
-	ao2_ref(pu->parker, +1);
-	payload->parker = pu->parker;
-
-	if (!pu->time_limit) {
-		snprintf(timeout_text, sizeof(timeout_text), "(no time limit)");
-	} else {
-		snprintf(timeout_text, sizeof(timeout_text), "%ld", pu->start.tv_sec + (long) pu->time_limit - now.tv_sec);
-	}
-
-	ast_string_field_set(payload, parkinglot, pu->lot_state->name);
-	ast_string_field_build(payload, parkingspace, "%d", pu->parking_space);
-	ast_string_field_set(payload, timeout, timeout_text);
-	ast_string_field_build(payload, duration, "%ld", now.tv_sec - pu->start.tv_sec);
-
-	return payload;
+
+	parkee_snapshot = ast_channel_snapshot_create(pu->chan);
+
+	if (!parkee_snapshot) {
+		return NULL;
+	}
+
+	timeout = pu->start.tv_sec + (long) pu->time_limit - now.tv_sec;
+	duration = now.tv_sec - pu->start.tv_sec;
+
+	return ast_parked_call_payload_create(event_type, parkee_snapshot, pu->parker, lot_name, pu->parking_space, timeout, duration);
+
 }
 
 /*! \brief Builds a manager string based on the contents of a parked call payload */
-static struct ast_str *manager_build_parked_call_string(const struct parked_call_payload *payload)
+static struct ast_str *manager_build_parked_call_string(const struct ast_parked_call_payload *payload)
 {
 	struct ast_str *out = ast_str_create(1024);
 	int res = 0;
@@ -185,7 +134,8 @@
 	struct parked_user *curuser;
 	const char *id = astman_get_header(m, "ActionID");
 	char id_text[256] = "";
-	struct ao2_iterator *iter_lots;
+	struct ao2_container *lot_container;
+	struct ao2_iterator iter_lots;
 	struct ao2_iterator iter_users;
 	struct parking_lot_state *curlot;
 	int total = 0;
@@ -194,22 +144,24 @@
 		snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
 	}
 
-	iter_lots = parking_lot_state_iterator_create();
-
-	if (!iter_lots) {
-		ast_log(LOG_ERROR, "Failed to create parking lot iterator. Action canceled.\n");
+	lot_container = get_parking_lot_state_container();
+
+	if (!lot_container) {
+		ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
 		astman_send_error(s, m, "Could not create parking lot list");
 		return -1;
 	}
 
+	iter_lots = ao2_iterator_init(lot_container, 0);
+
 	astman_send_ack(s, m, "Parked calls will follow");
 
-	while ((curlot = ao2_iterator_next(iter_lots))) {
+	while ((curlot = ao2_iterator_next(&iter_lots))) {
 		iter_users = ao2_iterator_init(curlot->parked_user_list, 0);
 		while ((curuser = ao2_iterator_next(&iter_users))) {
-			RAII_VAR(struct parked_call_payload *, payload, NULL, ao2_cleanup);
+			RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
 			RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
-			payload = parked_call_payload_create(curuser, PARKED_CALL);
+			payload = parked_call_payload_from_parked_user(curuser, PARKED_CALL);
 			parked_call_string = manager_build_parked_call_string(payload);
 			total++;
 
@@ -226,7 +178,7 @@
 		ao2_ref(curlot, -1);
 	}
 
-	parking_lot_state_iterator_destroy(iter_lots);
+	ao2_iterator_destroy(&iter_lots);
 
 	astman_append(s,
 		"Event: ParkedCallsComplete\r\n"
@@ -238,43 +190,62 @@
 	return RESULT_SUCCESS;
 }
 
-static int manager_parkinglot_list(struct mansession *s, const struct message *m)
+static void manager_append_event_parking_lot(struct mansession *s, struct parking_lot_state *curlot, char *id_text)
+{
+	astman_append(s, "Event: Parkinglot\r\n"
+		"Name: %s\r\n"
+		"StartSpace: %d\r\n"
+		"StopSpace: %d\r\n"
+		"Timeout: %d\r\n"
+		"%s" /* The Action ID */
+		"\r\n",
+		curlot->name,
+		curlot->parking_start,
+		curlot->parking_stop,
+		curlot->parkingtime,
+		id_text);
+}
+
+struct manager_append_event_cb_data {
+	struct mansession *s;
+	char *id_text;
+};
+
+static int manager_append_event_parking_lot_cb(void *obj, void *arg, int flags)
+{
+	struct parking_lot_state *lot = obj;
+	struct manager_append_event_cb_data *data = arg;
+	struct mansession *s = data->s;
+	char *id_text = data->id_text;
+	manager_append_event_parking_lot(s, lot, id_text);
+	return 0;
+}
+
+static int manager_parking_lot_list(struct mansession *s, const struct message *m)
 {
 	const char *id = astman_get_header(m, "ActionID");
 	char id_text[256] = "";
-	struct ao2_iterator *iter;
-	struct parking_lot_state *curlot;
+	struct ao2_container *lot_container;
+	struct manager_append_event_cb_data cb_data = {
+		.s = s,
+		.id_text = id_text,
+	};
 
 	if (!ast_strlen_zero(id)) {
 		snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
 	}
 
-	iter = parking_lot_state_iterator_create();
-
-	if (!iter) {
-		ast_log(LOG_ERROR, "Failed to create parking lot iterator. Action canceled.\n");
+	lot_container = get_parking_lot_state_container();
+
+	if (!lot_container) {
+		ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
 		astman_send_error(s, m, "Could not create parking lot list");
 		return -1;
 	}
 
 	astman_send_ack(s, m, "Parking lots will follow");
 
-	while ((curlot = ao2_iterator_next(iter))) {
-		astman_append(s, "Event: Parkinglot\r\n"
-			"Name: %s\r\n"
-			"StartSpace: %d\r\n"
-			"StopSpace: %d\r\n"
-			"Timeout: %d\r\n"
-			"\r\n",
-			curlot->name,
-			curlot->parking_start,
-			curlot->parking_stop,
-			curlot->parkingtime);
-
-		ao2_ref(curlot, -1);
-	}
-
-	parking_lot_state_iterator_destroy(iter);
+	ao2_callback(lot_container, OBJ_MULTIPLE | OBJ_NODATA, manager_append_event_parking_lot_cb, &cb_data);
 
 	astman_append(s,
 		"Event: ParkinglotsComplete\r\n"
@@ -284,27 +255,27 @@
 	return RESULT_SUCCESS;
 }
 
-void publish_parked_call(struct parked_user *pu, enum parked_call_event_type event_type)
-{
-	RAII_VAR(struct parked_call_payload *, payload, NULL, ao2_cleanup);
+void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type event_type)
+{
+	RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
-	payload = parked_call_payload_create(pu, event_type);
+	payload = parked_call_payload_from_parked_user(pu, event_type);
 	if (!payload) {
 		return;
 	}
 
-	msg = stasis_message_create(parked_call_message_type, payload);
+	msg = stasis_message_create(ast_parked_call_type(), payload);
 	if (!msg) {
 		return;
 	}
 
 	if (pu->chan) {
-		stasis_publish(parking_topic, msg);
-	}
-}
-
-static void parked_call_message_response(struct parked_call_payload *parked_call)
+		stasis_publish(ast_parking_topic(), msg);
+	}
+}
+
+static void parked_call_message_response(struct ast_parked_call_payload *parked_call)
 {
 	char *event_type;
 	RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
@@ -334,8 +305,8 @@
 
 static void parking_event_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
 {
-	if (stasis_message_type(message) == parked_call_message_type) {
-		struct parked_call_payload *parked_call_message = stasis_message_data(message);
+	if (stasis_message_type(message) == ast_parked_call_type()) {
+		struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
 		parked_call_message_response(parked_call_message);
 	}
 }
@@ -343,24 +314,20 @@
 static void parking_manager_disable_stasis(void)
 {
 	parking_sub = stasis_unsubscribe(parking_sub);
-	ao2_cleanup(parked_call_message_type);
-	ao2_cleanup(parking_topic);
-	parked_call_message_type = NULL;
-	parking_topic = NULL;
+	ast_parking_stasis_disable();
 }
 
 int load_parking_manager(void)
 {
 	int res;
 
-	res = ast_manager_register_xml_core("Parkinglots", 0, manager_parkinglot_list);
+	res = ast_manager_register_xml_core("Parkinglots", 0, manager_parking_lot_list);
 	res |= ast_manager_register_xml_core("ParkedCalls", 0, manager_parking_status);
 
-	parked_call_message_type = stasis_message_type_create("parked_call");
-	parking_topic = stasis_topic_create("ast_parking_topic");
+	ast_parking_stasis_init();
 
 	if (!parking_sub) {
-		parking_sub = stasis_subscribe(parking_topic, parking_event_cb, NULL);
+		parking_sub = stasis_subscribe(ast_parking_topic(), parking_event_cb, NULL);
 	}
 
 	return res ? -1 : 0;

Modified: team/jrose/bridge_projects/res/parking/parking_ui.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_ui.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_ui.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_ui.c Wed Mar 27 13:35:24 2013
@@ -38,14 +38,48 @@
 #include "asterisk/features.h"
 #include "asterisk/manager.h"
 
+static void display_parked_call(struct parked_user *user, int fd)
+{
+	ast_cli(fd, "  Space: %d\n", user->parking_space);
+	ast_cli(fd, "  Channel: %s\n", ast_channel_name(user->chan));
+	ast_cli(fd, "\n");
+}
+
+static int display_parked_users_cb(void *obj, void *arg, int flags)
+{
+	int *fd = arg;
+	struct parked_user *user = obj;
+	display_parked_call(user, *fd);
+	return 0;
+}
+
+static void display_parking_lot_state(struct parking_lot_state *lot, int fd)
+{
+	ast_cli(fd, "Parking Lot: %s\n--------------------------------------------------------------------------\n", lot->name);
+	ast_cli(fd, "Parking Extension   :  %s\n", lot->parkext);
+	ast_cli(fd, "Parking Context     :  %s\n", lot->parking_con);
+	ast_cli(fd, "Parking Spaces      :  %d-%d\n", lot->parking_start, lot->parking_stop);
+	ast_cli(fd, "Parking Time        :  %u sec\n", lot->parkingtime);
+	ast_cli(fd, "Comeback to Origin  :  %s\n", lot->comebacktoorigin ? "yes" : "no");
+	ast_cli(fd, "Comeback Context    :  %s%s\n", lot->comebackcontext, lot->comebacktoorigin ? " (comebacktoorigin=yes, not used)" : "");
+	ast_cli(fd, "Comeback Dial Time  :  %u sec\n", lot->comebackdialtime);
+	ast_cli(fd, "MusicOnHold Class   :  %s\n", lot->mohclass);
+	ast_cli(fd, "Enabled             :  %s\n", lot->parking_disabled ? "no" : "yes");
+	ast_cli(fd, "\n");
+}
+
+static int display_parking_lot_state_cb(void *obj, void *arg, int flags)
+{
+	int *fd = arg;
+	struct parking_lot_state *lot = obj;
+	display_parking_lot_state(lot, *fd);
+	return 0;
+}
+
 static void cli_display_parking_lot(int fd, const char *name)
 {
 	RAII_VAR(struct parking_lot_state *, lot, NULL, ao2_cleanup);
-	struct ao2_iterator i;
-	struct parked_user *user;
-	int total = 0;
-
-	lot = parking_lot_find_by_name(name);
+	lot = parking_lot_state_find_by_name(name);
 
 	/* If the parking lot couldn't be found with the search, also abort. */
 	if (!lot) {
@@ -53,68 +87,33 @@
 		return;
 	}
 
-	ast_cli(fd, "\nParking Lot: %s\n------------------------------------------------------------------------\n", name);
-	ast_cli(fd, "Parking Extension      :      %s\n", lot->parkext);
-	ast_cli(fd, "Parking Context        :      %s\n", lot->parking_con);
-	ast_cli(fd, "Parking Spaces         :      %d-%d\n", lot->parking_start, lot->parking_stop);
-	ast_cli(fd, "Parking Time           :      %u sec\n", lot->parkingtime);
-	ast_cli(fd, "Comeback to Origin     :      %s\n", lot->comebacktoorigin ? "yes" : "no");
-	ast_cli(fd, "Comeback Context       :      %s%s\n", lot->comebackcontext, lot->comebacktoorigin ? " (comebacktoorigin=yes, not used)" : "");
-	ast_cli(fd, "Comeback Dial Time     :      %u sec\n", lot->comebackdialtime);
-	ast_cli(fd, "MusicOnHold Class      :      %s\n", lot->mohclass);
-	ast_cli(fd, "Enabled                :      %s\n", lot->parking_disabled ? "no" : "yes");
-	ast_cli(fd, "\n");
+	display_parking_lot_state(lot, fd);
+
 	ast_cli(fd, "Parked Calls\n------------\n");
 
-	i = ao2_iterator_init(lot->parked_user_list, 0);
-	while ((user = ao2_iterator_next(&i))) {
-		ast_cli(fd, "  Space: %d\n", user->parking_space);
-		ast_cli(fd, "  Channel: %s\n", ast_channel_name(user->chan));
-		ast_cli(fd, "\n");
-		ao2_ref(user, -1);
-		total++;
-	}
-	ao2_iterator_destroy(&i);
-
-	if (!total) {
+	if (!ao2_container_count(lot->parked_user_list)) {
 		ast_cli(fd, "  (none)\n");
-		ast_cli(fd, "\n");
+		ast_cli(fd, "\n\n");
+		return;
 	}
 
+	ao2_callback(lot->parked_user_list, OBJ_MULTIPLE | OBJ_NODATA, display_parked_users_cb, &fd);
 	ast_cli(fd, "\n");
 }
 
 static void cli_display_parking_lot_list(int fd)
 {
-	struct ao2_iterator *i;
-	void *o;
+	struct ao2_container *lot_container;
 
-	i = parking_lot_state_iterator_create();
+	lot_container = get_parking_lot_state_container();
 
-	if (!i) {
-		ast_cli(fd, "Parking Lot configuration is unavailable.\n");
+	if (!lot_container) {
+		ast_cli(fd, "Failed to obtain parking lot list.\n\n");
 		return;
 	}
 
-	while ((o = ao2_iterator_next(i))) {
-		struct parking_lot_state *lot = o;
-		ast_cli(fd, "\n");
-		ast_cli(fd, "Parking lot: %s\n", lot->name);
-		ast_cli(fd, "------------\n");
-		ast_cli(fd, "Parking Extension      :      %s\n", lot->parkext);
-		ast_cli(fd, "Parking Context        :      %s\n", lot->parking_con);
-		ast_cli(fd, "Parking Spaces         :      %d-%d\n", lot->parking_start, lot->parking_stop);
-		ast_cli(fd, "Parking Time           :      %u sec\n", lot->parkingtime);
-		ast_cli(fd, "Comeback to Origin     :      %s\n", lot->comebacktoorigin ? "yes" : "no");
-		ast_cli(fd, "Comeback Context       :      %s%s\n", lot->comebackcontext, lot->comebacktoorigin ? " (comebacktoorigin=yes, not used)" : "");
-		ast_cli(fd, "Comeback Dial Time     :      %u sec\n", lot->comebackdialtime);
-		ast_cli(fd, "MusicOnHold Class      :      %s\n", lot->mohclass);
-		ast_cli(fd, "Enabled                :      %s\n", lot->parking_disabled ? "no" : "yes");
-		ast_cli(fd, "\n");
-		ao2_ref(o, -1);
-	}
-
-	parking_lot_state_iterator_destroy(i);
+	ao2_callback(lot_container, OBJ_MULTIPLE | OBJ_NODATA, display_parking_lot_state_cb, &fd);
+	ast_cli(fd, "\n");
 }
 
 /* \brief Parkinglots command show <name> */
@@ -122,7 +121,8 @@
 {
 	int length;
 	int which;
-	struct ao2_iterator *i;
+	struct ao2_container *lot_container;
+	struct ao2_iterator iter;
 	struct parking_lot_state *lot;
 	char *match = NULL;
 
@@ -136,8 +136,16 @@
 	case CLI_GENERATE:
 		length = strlen(a->word);
 		which = 0;
-		i = parking_lot_state_iterator_create();
-		while ((lot = ao2_iterator_next(i))) {
+
+		lot_container = get_parking_lot_state_container();
+
+		if (!lot_container) {
+			/* This should never be possible, but if it is, there certainly aren't any parking lots to look at */
+			return NULL;
+		}
+
+		iter = ao2_iterator_init(lot_container, 0);
+		while ((lot = ao2_iterator_next(&iter))) {
 			if (!strncasecmp(a->word, lot->name, length) && ++which > a->n) {
 				match = ast_strdup(lot->name);
 				ao2_ref(lot, -1);
@@ -145,10 +153,12 @@
 			}
 			ao2_ref(lot, -1);
 		}
-		parking_lot_state_iterator_destroy(i);
+		ao2_iterator_destroy(&iter);
+
 		return match;
-		return NULL;
 	}
+
+	ast_cli(a->fd, "\n");
 
 	if (a->argc == 2) {
 		cli_display_parking_lot_list(a->fd);

Modified: team/jrose/bridge_projects/res/parking/res_parking.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/res_parking.h?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/res_parking.h (original)
+++ team/jrose/bridge_projects/res/parking/res_parking.h Wed Mar 27 13:35:24 2013
@@ -34,7 +34,7 @@
 enum park_call_resolution {
 	PARK_UNSET = 0,		/*! Nothing set a resolution. This should never be observed in practice. */
 	PARK_ABANDON,		/*! The channel for the parked call hung up */
-	PARK_TIMEOUT,		/*! The parked call stayed parked until the parkinglot timeout was reached and was removed */
+	PARK_TIMEOUT,		/*! The parked call stayed parked until the parking lot timeout was reached and was removed */
 	PARK_FORCED,		/*! The parked call was forcibly terminated by an unusual means in Asterisk */
 	PARK_ANSWERED,		/*! The parked call was retrieved successfully */
 };
@@ -48,90 +48,69 @@
 };
 
 struct parking_lot_state {
-	int parking_start;
-	int parking_stop;
-	int next_space;
-
-	unsigned int parkingtime;
-	unsigned int comebackdialtime;
-	unsigned int parkfindnext;
-	unsigned int parkext_exclusive;
-	unsigned int parkaddhints;
-	unsigned int comebacktoorigin;
-	int parkedplay;
-	int parkedcalltransfers;
-	int parkedcallreparking;
-	int parkedcallhangup;
-	int parkedcallrecording;
-
-	/* When a parking lot becomes unconfigured, this flag is raised to keep new calls from entering */
-	int parking_disabled;
-
-	/*! Which holding bridge the parking lot uses for placing calls */
-	struct ast_bridge *parking_bridge;
-
-	/*! Ordered list of active parkings in this parkinglot */
-	struct ao2_container *parked_user_list;
-
-	/*! Does this parking lot have a configuration that owns it? Used to determine if we should unlink ourselves from the global state list */
-	int has_owner;
+	int parking_start;                        /*!< First space in the parking lot */
+	int parking_stop;                         /*!< Last space in the parking lot */
+	int next_space;                           /*!< When using parkfindnext, which space we should start searching from next time we park */
+
+	unsigned int parkingtime;                 /*!< Analogous to parkingtime config option */
+	unsigned int comebackdialtime;            /*!< Analogous to comebackdialtime config option */
+	unsigned int parkfindnext;                /*!< Analogous to parkfindnext config option */
+	unsigned int parkext_exclusive;           /*!< Analogous to parkext_exclusive config option */
+	unsigned int parkaddhints;                /*!< Analogous to parkaddhints config option */
+	unsigned int comebacktoorigin;            /*!< Analogous to comebacktoorigin config option */
+	int parkedplay;                           /*!< Analogous to parkedplay config option */
+	int parkedcalltransfers;                  /*!< Analogous to parkedcalltransfers config option */
+	int parkedcallreparking;                  /*!< Analogous to parkedcallreparking config option */
+	int parkedcallhangup;                     /*!< Analogous to parkedcallhangup config option */
+	int parkedcallrecording;                  /*!< Analogous to parkedcallrecording config option */
+
+	int parking_disabled;                     /*!< Used for reloading, keeps calls from being parked to a parking lot removed from configs */
+	struct ast_bridge *parking_bridge;        /*!< Bridged where parked calls will rest until they are answered or otherwise leave */
+	struct ao2_container *parked_user_list;   /*!< List of parked users rigidly ordered by their parking space */
+
+	int has_owner;							  /*!< Used for reloading, marks a parking lot to be removed from the list of parking lots when
+	                                           *   its last parked call has departed the parking_brige.
+	                                           */
 
 	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(name);
-		AST_STRING_FIELD(mohclass);
-		AST_STRING_FIELD(parkext);
-		AST_STRING_FIELD(parking_con);
-		AST_STRING_FIELD(comebackcontext);
-		AST_STRING_FIELD(courtesytone);
+		AST_STRING_FIELD(name);               /*!< Name of the parking lot state object */
+		AST_STRING_FIELD(mohclass);           /*!< Analogous to mohclass config option */
+		AST_STRING_FIELD(parkext);            /*!< Analogous to parkext config option */
+		AST_STRING_FIELD(parking_con);        /*!< Analogous to context config option */
+		AST_STRING_FIELD(comebackcontext);    /*!< Analogous to comebackcontext config option */
+		AST_STRING_FIELD(courtesytone);       /*!< Analogous to courtesytone config option */
 	);
 };
 
 struct parking_lot_cfg {
-	int parking_start;
-	int parking_stop;
-
-	unsigned int parkingtime;
-	unsigned int comebackdialtime;
-
-	unsigned int parkfindnext;
-	unsigned int parkext_exclusive;
-	unsigned int parkaddhints;
-	unsigned int comebacktoorigin;
-
-	/* These all need to be handled by a special configuration handler */
-	int parkedplay;
-	int parkedcalltransfers;
-	int parkedcallreparking;
-	int parkedcallhangup;
-	int parkedcallrecording;
-
-	/*!
-	 * State of the parkinglot
-	 * Generated on creation of the parking lot
-	 * Unlinked (and destroyed) when the parking lot is destroyed if and only if the parked call list is empty
-	 * If not referenced by a parking lot, this will be destroyed when the last call is unparked
-	 */
-	struct parking_lot_state *state;
+	int parking_start;                        /*!< First space in the parking lot */
+	int parking_stop;                         /*!< Last space in the parking lot */
+
+	unsigned int parkingtime;                 /*!< Analogous to parkingtime config option */
+	unsigned int comebackdialtime;            /*!< Analogous to comebackdialtime config option */
+	unsigned int parkfindnext;                /*!< Analogous to parkfindnext config option */
+	unsigned int parkext_exclusive;           /*!< Analogous to parkext_exclusive config option */
+	unsigned int parkaddhints;                /*!< Analogous to parkaddhints config option */
+	unsigned int comebacktoorigin;            /*!< Analogous to comebacktoorigin config option */
+	int parkedplay;                           /*!< Analogous to parkedplay config option */
+	int parkedcalltransfers;                  /*!< Analogous to parkedcalltransfers config option */
+	int parkedcallreparking;                  /*!< Analogous to parkedcallreparking config option */
+	int parkedcallhangup;                     /*!< Analogous to parkedcallhangup config option */
+	int parkedcallrecording;                  /*!< Analogous to parkedcallrecording config option */
+
+	struct parking_lot_state *state;          /*!< State of the parking lot, generated on creation of the parking lot and
+	                                           *   unlinked from the parking lot and destroyed if and only if its call list
+	                                           *   is empty and it is removed from configuration.
+	                                           */
 
 	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(name);
-		AST_STRING_FIELD(mohclass);
-		AST_STRING_FIELD(parkext);
-		AST_STRING_FIELD(parking_con);
-		AST_STRING_FIELD(comebackcontext);
-		AST_STRING_FIELD(courtesytone);
+		AST_STRING_FIELD(name);               /*!< Name of the parking lot configuration object */
+		AST_STRING_FIELD(mohclass);           /*!< Analogous to mohclass config option */
+		AST_STRING_FIELD(parkext);            /*!< Analogous to parkext config option */
+		AST_STRING_FIELD(parking_con);        /*!< Analogous to context config option */
+		AST_STRING_FIELD(comebackcontext);    /*!< Analogous to comebackcontext config option */
+		AST_STRING_FIELD(courtesytone);       /*!< Analogous to courtesytone config option */
 	);
-};
-
-/*!
- * \brief Defines the type of parked call message being published
- * \since 12
- */
-enum parked_call_event_type {
-	PARKED_CALL = 0,
-	PARKED_CALL_TIMEOUT,
-	PARKED_CALL_GIVEUP,
-	PARKED_CALL_UNPARKED,
 };
 
 struct parked_user {
@@ -148,18 +127,19 @@
 
 /*!
  * \since 12
- * \brief If a parking lot state exists in the state list already, return a reference to it. Otherwise,
- *        create a parking lot state struct based on a parking lot configuration and return a reference
+ * \brief If a parking lot state exists in the state list already, update its status to match the provided
+ *        configuration and return a reference return a reference to it. Otherwise, create a parking lot
+ *        state struct based on a parking lot configuration and return a reference to the new one.
  *
  * \param lot The lot being used as a reference to build the parking lot state from.
  *
  * \retval A reference to the new parking lot state
- * \retval NULL if it couldn't be allocated
+ * \retval NULL if it was not found and could not be be allocated
  *
  * \note The state will need to be unreffed if it ever falls out of scope
  * \note The state will automatically be added to the state container if needed as part of this process
  */
-struct parking_lot_state *parking_lot_state_build_or_find(struct parking_lot_cfg *lot);
+struct parking_lot_state *parking_lot_state_build_or_update(struct parking_lot_cfg *lot);
 
 /*!
  * \since 12
@@ -170,7 +150,18 @@
  * \note This should generally be called when something is happening that could cause a parking lot to die such as a call being unparked or
  *       a parking lot no longer existing in configurations.
  */
-void parking_lot_remove_if_unused(struct parking_lot_state *lot);
+void parking_lot_state_remove_if_unused(struct parking_lot_state *lot);
+
+/*!
+ * \since 12
+ * \brief Create a new parking bridge
+ *
+ * \param bridge_lot Parking lot which the new bridge should be based on
+ *
+ * \retval NULL if the bridge can not be created
+ * \retval Newly created parking bridge
+ */
+struct ast_bridge *bridge_parking_new(struct parking_lot_state *bridge_lot);
 
 /*!
  * \since 12
@@ -183,7 +174,7 @@
  *
  * \note This bridge will need to be unreffed if it ever falls out of scope.
  */
-struct ast_bridge *get_parkinglot_bridge(struct parking_lot_state *state);
+struct ast_bridge *parking_lot_state_get_bridge(struct parking_lot_state *state);
 
 /*!
  * \since 12
@@ -198,7 +189,7 @@
  * \note lot should be locked before this is called and unlocked only after a parked_user with the space
  *       returned has been added to the parking lot.
  */
-int parking_lot_get_space(struct parking_lot_state *lot, int target_override);
+int parking_lot_state_get_space(struct parking_lot_state *lot, int target_override);
 
 /*!
  * \since 12
@@ -222,21 +213,11 @@
 
 /*!
  * \since 12
- * \brief Create an iterator which will iterate through all parking_lot_state structs
- *
- * \retval iterator for parking lot states if successful
- * \retval NULL if the iterator could not be initialized
- *
- * \note If this succeeds, the iterator should be destroyed using parking_lot_iterator_destroy when it is no longer needed.
- */
-struct ao2_iterator *parking_lot_state_iterator_create(void);
-
-/*!
- * \since 12
- * \brief Call this to free an iterator created by parking_lot_state_iterator_create
- */
-void parking_lot_state_iterator_destroy(struct ao2_iterator *iter);
-
+ * \brief Get a pointer to the parking lot state container for purposes such as iteration
+ *
+ * \retval pointer to the parking lot state container.
+ */
+struct ao2_container *get_parking_lot_state_container(void);
 /*!
  * \since 12
  * \brief Find a parking lot state based on its name
@@ -248,13 +229,13 @@
  *
  * \note ao2_cleanup this reference when you are done using it or you'll cause leaks.
  */
-struct parking_lot_state *parking_lot_find_by_name(const char *lot_name);
-
-/*!
- * \since 12
- * \brief Get the parkinglot state that a channel should be parked in
- *
- * \param chan Channel which a parkinglot state is sought for
+struct parking_lot_state *parking_lot_state_find_by_name(const char *lot_name);
+
+/*!
+ * \since 12
+ * \brief Get the parking lot state that a channel should be parked in
+ *
+ * \param chan Channel which a parking lot state is sought for
  *
  * \retval The parking lot state that the channel should go into

[... 169 lines stripped ...]



More information about the asterisk-commits mailing list