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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Mar 20 16:22:06 CDT 2013


Author: jrose
Date: Wed Mar 20 16:22:03 2013
New Revision: 383481

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383481
Log:
Getting ready to split parking lots and parking lot state

Modified:
    team/jrose/bridge_projects/include/asterisk/parking.h
    team/jrose/bridge_projects/main/manager.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/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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/parking.h (original)
+++ team/jrose/bridge_projects/include/asterisk/parking.h Wed Mar 20 16:22:03 2013
@@ -26,7 +26,7 @@
 #include "asterisk/stringfields.h"
 
 /*! \brief Defines the type of parked call message */
-enum parked_call_event_type {
+enum ast_parked_call_event_type {
 	PARKED_CALL = 0,
 	PARKED_CALL_TIMEOUT,
 	PARKED_CALL_GIVEUP,
@@ -37,18 +37,15 @@
  * \brief A parked call message payload
  * \since 12
  */
-struct parked_call_payload {
+struct ast_parked_call_payload {
 	struct ast_channel_snapshot *parkee;
 	struct ast_channel_snapshot *parker;
-	enum parked_call_event_type event_type;
-	int list_item;
-	int list_size;
+	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);
-		AST_STRING_FIELD(list);
 	);
 };
 
@@ -56,37 +53,56 @@
  * \brief A parking lot message payload
  * \since 12
  */
-struct parking_lot_payload {
-	int list_item;
-	int list_size;
+struct ast_parking_lot_payload {
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(name);
 		AST_STRING_FIELD(starting_space);
 		AST_STRING_FIELD(ending_space);
 		AST_STRING_FIELD(timeout);
-		AST_STRING_FIELD(list);
 	);
 };
 
 /*!
+ * \brief Create a blank parked call payload and get a reference to it
  * \since 12
+ *
+ * \retval NULL if the payload could not be allocated
+ * \retval reference to the payload object
+ *
+ * \note This reference should be free'd when it is no longer in use.
+ */
+struct ast_parked_call_payload *ast_parked_call_payload_create(void);
+
+/*!
+ * \brief Create a blank parking lot payload and get a reference to it
+ * \since 12
+ *
+ * \retval NULL if the payload could not be allocated
+ * \retval reference to the payload object
+ *
+ * \note This reference should be free'd when it is no longer in use.
+ */
+struct ast_parking_lot_payload *ast_parking_lot_payload_create(void);
+
+/*!
  * \brief Message type for \ref ast_parked_call
+ * \since 12
  *
  * \retval Message type for \ref ast_parked_call
  */
 struct stasis_message_type *ast_parked_call(void);
 
 /*!
+ * \brief Message type for \ref ast_parking_lot
  * \since 12
- * \brief Message type for \ref ast_parking_lot
  *
  * \retval Message type for \ref ast_parking_lot
  */
 struct stasis_message_type *ast_parking_lot(void);
 
 /*!
+ * \brief A topic which publishes events pertaining generally to parking lots.
  * \since 12
- * \brief A topic which publishes events pertaining generally to parking lots.
  *
  * \retval Topic for parking lot events.
  */

Modified: team/jrose/bridge_projects/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/manager.c?view=diff&rev=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/main/manager.c (original)
+++ team/jrose/bridge_projects/main/manager.c Wed Mar 20 16:22:03 2013
@@ -7541,7 +7541,7 @@
 		      channel_name, name, value, uniqueid);
 }
 
-static void parked_call(struct parked_call_payload *parked_call)
+static void parked_call(struct ast_parked_call_payload *parked_call)
 {
 	char *event_type;
 
@@ -7562,59 +7562,42 @@
 
 	manager_event(EVENT_FLAG_DIALPLAN, event_type,
 			"ParkingSpace: %s\r\n"
-
 			"Channel: %s\r\n"
 			"CallerIDNum: %s\r\n"
 			"CallerIDName: %s\r\n"
 			"ConnectedLineNum: %s\r\n"
 			"ConnectedLineName: %s\r\n"
 			"UniqueID: %s\r\n"
-
 			"ParkingLot: %s\r\n"
 			"Parker: %s\r\n"
 			"Timeout: %s\r\n"
-			"Duration: %s\r\n"
-			"List: %s\r\n"
-			"Item: %d\r\n"
-			"Total: %d\r\n",
-
+			"Duration: %s\r\n",
 			parked_call->parkingspace,
-
 			parked_call->parkee->name,
 			parked_call->parkee->caller_number,
 			parked_call->parkee->caller_name,
 			parked_call->parkee->connected_number,
 			parked_call->parkee->connected_name,
 			parked_call->parkee->uniqueid,
-
 			parked_call->parkinglot,
 			parked_call->parker->name,
 			parked_call->timeout,
-			parked_call->duration,
-			parked_call->list,
-			parked_call->list_item,
-			parked_call->list_size
+			parked_call->duration
 		);
 }
 
-static void parking_lot(struct parking_lot_payload *parking_lot)
+static void parking_lot(struct ast_parking_lot_payload *parking_lot)
 {
 	manager_event(EVENT_FLAG_DIALPLAN, "Parkinglot",
-		"Name: %s\r\n"
-		"StartSpace: %s\r\n"
-		"EndSpace: %s\r\n"
-		"Timeout: %s\r\n"
-		"List: %s\r\n"
-		"Item: %d\r\n"
-		"Total: %d\r\n",
-
-		parking_lot->name,
-		parking_lot->starting_space,
-		parking_lot->ending_space,
-		parking_lot->timeout,
-		parking_lot->list,
-		parking_lot->list_item,
-		parking_lot->list_size);
+			"Name: %s\r\n"
+			"StartSpace: %s\r\n"
+			"EndSpace: %s\r\n"
+			"Timeout: %s\r\n",
+			parking_lot->name,
+			parking_lot->starting_space,
+			parking_lot->ending_space,
+			parking_lot->timeout
+		);
 }
 
 static void channel_event_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
@@ -7634,7 +7617,7 @@
 		const char *uniqueid = varset->snapshot ? varset->snapshot->uniqueid : "none";
 		channel_varset(name, uniqueid, varset->variable, varset->value);
 	} else if (stasis_message_type(message) == ast_parked_call()) {
-		struct parked_call_payload *parked_call_message = stasis_message_data(message);
+		struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
 		parked_call(parked_call_message);
 	}
 }
@@ -7642,7 +7625,7 @@
 static void parking_lot_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
 {
 	if (stasis_message_type(message) == ast_parking_lot()) {
-		struct parking_lot_payload *parking_lot_message = stasis_message_data(message);
+		struct ast_parking_lot_payload *parking_lot_message = stasis_message_data(message);
 		parking_lot(parking_lot_message);
 	}
 }
@@ -7672,8 +7655,7 @@
 
 	channel_state_sub = stasis_unsubscribe(channel_state_sub);
 
-	stasis_unsubscribe(parking_lot_sub);
-	parking_lot_sub = NULL;
+	parking_lot_sub = stasis_unsubscribe(parking_lot_sub);
 
 	if (registered) {
 		ast_manager_unregister("Ping");

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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/main/parking.c (original)
+++ team/jrose/bridge_projects/main/parking.c Wed Mar 20 16:22:03 2013
@@ -42,28 +42,80 @@
  * res_parking.
  */
 
+/*! \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()
+{
+	struct ast_parked_call_payload *payload;
+
+	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;
+	}
+
+	return payload;
+}
+
+/*! \brief destructor for parking_lot_payload objects */
+static void parking_lot_payload_destructor(void *obj)
+{
+	struct ast_parking_lot_payload *park_obj = obj;
+
+	ast_string_field_free_memory(park_obj);
+}
+
+struct ast_parking_lot_payload *ast_parking_lot_payload_create()
+{
+	struct ast_parking_lot_payload *payload;
+
+	payload = ao2_alloc(sizeof(*payload), parking_lot_payload_destructor);
+	if (!payload) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(payload, 32)) {
+		ao2_cleanup(payload);
+		return NULL;
+	}
+
+	return payload;
+}
+
 /*! \brief Message type for parked calls */
-static struct stasis_message_type *__parked_call;
+static struct stasis_message_type *parked_call;
 
 /*! \brief Message type for parking lots */
-static struct stasis_message_type *__parking_lot;
+static struct stasis_message_type *parking_lot;
 
 /*! \brief Topic for parking lots */
-static struct stasis_topic *__parking_lot_topic;
+static struct stasis_topic *parking_lot_topic;
 
 struct stasis_message_type *ast_parked_call(void)
 {
-	return __parked_call;
+	return parked_call;
 }
 
 struct stasis_message_type *ast_parking_lot(void)
 {
-	return __parking_lot;
+	return parking_lot;
 }
 
 struct stasis_topic *ast_parking_lot_topic(void)
 {
-	return __parking_lot_topic;
+	return parking_lot_topic;
 }
 
 /*! \internal
@@ -71,17 +123,17 @@
  */
 static void parking_shutdown(void)
 {
-	ao2_cleanup(__parked_call);
-	ao2_cleanup(__parking_lot);
-	ao2_cleanup(__parking_lot_topic);
-	__parked_call = NULL;
+	ao2_cleanup(parked_call);
+	ao2_cleanup(parking_lot);
+	ao2_cleanup(parking_lot_topic);
+	parked_call = NULL;
 }
 
 void ast_parking_init(void)
 {
-	__parked_call = stasis_message_type_create("ast_parked_call");
-	__parking_lot = stasis_message_type_create("ast_parking_lot");
+	parked_call = stasis_message_type_create("ast_parked_call");
+	parking_lot = stasis_message_type_create("ast_parking_lot");
 
-	__parking_lot_topic = stasis_topic_create("ast_parking_lot_topic");
+	parking_lot_topic = stasis_topic_create("ast_parking_lot_topic");
 	ast_register_atexit(parking_shutdown);
 }

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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_applications.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_applications.c Wed Mar 20 16:22:03 2013
@@ -77,17 +77,18 @@
 						<argument name="duration" required="true" />
 						<para>Use a timeout of <literal>duration</literal> seconds instead
 							of the timeout specified by the parking lot.</para>
-						<para>If you set the <variable>PARKINGEXTEN</variable> variable to a
-							parking space extension in the parking lot, Park() will attempt to park the call
-							on that extension.  If the extension is already is in use then execution
-							will continue at the next priority.</para>
 					</option>
 				</optionlist>
 			</parameter>
 		</syntax>
 		<description>
-			<para>Used to park yourself (typically in combination with a supervised
+			<para>Used to park yourself (typically in combination with an attended
 			transfer to know the parking space).</para>
+			<para>If you set the <variable>PARKINGEXTEN</variable> variable to a
+				parking space extension in the parking lot, Park() will attempt to park the
+				call on that extension. If the extension is already in use then execution
+				will continue at the next priority.
+			</para>
 		</description>
 		<see-also>
 			<ref type="application">ParkedCall</ref>
@@ -101,7 +102,7 @@
 enum park_args {
 	OPT_ARG_COMEBACK,
 	OPT_ARG_TIMEOUT,
-	OPT_ARG_ARRAY_SIZE, /* Always the last element of the enum */
+	OPT_ARG_ARRAY_SIZE /* Always the last element of the enum */
 };
 
 enum park_flags {
@@ -138,9 +139,9 @@
 static int park_exec(struct ast_channel *chan, const char *data)
 {
 	RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
-	RAII_VAR(struct parkeduser *, pu, NULL, ao2_cleanup);
-
-	struct ast_bridge *parking_bridge;
+	RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
+
 	struct ast_bridge_features chan_features;
 	struct ast_flags flags = { 0 };
 	char *parse;

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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Wed Mar 20 16:22:03 2013
@@ -31,28 +31,15 @@
 #include "asterisk/manager.h"
 #include "asterisk/test.h"
 
-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);
-}
-
-void publish_parked_call(struct parkeduser *pu, const char *list, int list_item, int list_size, 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);
 	struct timeval now = ast_tvnow();
 	char timeout_text[32] = "";
 
-	payload = ao2_alloc(sizeof(*payload), parked_call_payload_destructor);
+	payload = ast_parked_call_payload_create();
 	if (!payload) {
-		return;
-	}
-
-	if (ast_string_field_init(payload, 32)) {
 		return;
 	}
 
@@ -84,12 +71,6 @@
 	ast_string_field_set(payload, timeout, timeout_text);
 	ast_string_field_build(payload, duration, "%ld", now.tv_sec - pu->start.tv_sec);
 
-	if (list) {
-		ast_string_field_set(payload, list, list);
-		payload->list_item = list_item;
-		payload->list_size = list_size;
-	}
-
 	msg = stasis_message_create(ast_parked_call(), payload);
 	if (!msg) {
 		return;
@@ -100,24 +81,13 @@
 	}
 }
 
-static void parking_lot_payload_destructor(void *obj)
-{
-	struct parking_lot_payload *park_obj = obj;
-
-	ast_string_field_free_memory(park_obj);
-}
-
-void publish_parking_lot(struct parking_lot *lot, const char *list, int list_item, int list_size)
-{
-	RAII_VAR(struct parking_lot_payload *, payload, NULL, ao2_cleanup);
+void publish_parking_lot(struct parking_lot *lot)
+{
+	RAII_VAR(struct ast_parking_lot_payload *, payload, NULL, ao2_cleanup);
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
-	payload = ao2_alloc(sizeof(*payload), parking_lot_payload_destructor);
+	payload = ast_parking_lot_payload_create();
 	if (!payload) {
-		return;
-	}
-
-	if (ast_string_field_init(payload, 32)) {
 		return;
 	}
 
@@ -125,9 +95,6 @@
 	ast_string_field_build(payload, starting_space, "%d", lot->parking_start);
 	ast_string_field_build(payload, ending_space, "%d", lot->parking_stop);
 	ast_string_field_build(payload, timeout, "%u", lot->parkingtime);
-	ast_string_field_set(payload, list, list);
-	payload->list_item = list_item;
-	payload->list_size = list_size;
 
 	msg = stasis_message_create(ast_parking_lot(), payload);
 	if (!msg) {
@@ -137,17 +104,24 @@
 	stasis_publish(ast_parking_lot_topic(), msg);
 }
 
-/*! This should only be called while holding an ao2 lock on the parking_lot */
 struct ast_bridge *get_parkinglot_bridge(struct parking_lot *lot)
 {
 	struct ast_bridge *lot_bridge;
 
 	if (lot->parking_bridge) {
+		ao2_ref(lot->parking_bridge, +1);
 		return lot->parking_bridge;
 	}
 
 	/* XXX Richard is going to change some things here. Name will be an argument */
 	lot_bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_HOLDING, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM);
+	if (!lot_bridge) {
+		return NULL;
+	}
+
+	/* The parking lot needs a reference to the bridge as well. */
+	lot->parking_bridge = lot_bridge;
+	ao2_ref(lot->parking_bridge, +1);
 
 	return lot_bridge;
 }
@@ -166,7 +140,7 @@
 }
 
 struct parking_limits_pvt {
-	struct parkeduser *user;
+	struct parked_user *user;
 };
 
 /*! \internal
@@ -174,11 +148,11 @@
  *
  * \param bridge Which bridge the channel was parked in
  * \param bridge_channel bridge channel this interval hook is being executed on
- * \param hook_pvt A pointer to the parkeduser struct associated with the channel is stuffed in here
+ * \param hook_pvt A pointer to the parked_user struct associated with the channel is stuffed in here
  */
 static int parking_duration_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 {
-	struct parkeduser *user = hook_pvt;
+	struct parked_user *user = hook_pvt;
 
 	ao2_lock(bridge_channel);
 	switch (bridge_channel->state) {
@@ -195,18 +169,18 @@
 
 	/* Set the resolution for the user to timeout */
 	user->resolution = PARK_TIMEOUT;
-	publish_parked_call(user, NULL, 0, 0, PARKED_CALL_TIMEOUT);
+	publish_parked_call(user, PARKED_CALL_TIMEOUT);
 
 	return -1;
 }
 
 static void parking_duration_cb_destroyer(void *hook_pvt)
 {
-	struct parkeduser *user = hook_pvt;
+	struct parked_user *user = hook_pvt;
 	ao2_ref(user, -1);
 }
 
-int unpark_parked_user(struct parkeduser *pu)
+int unpark_parked_user(struct parked_user *pu)
 {
 	if (pu->lot) {
 		ao2_unlink(pu->lot->parked_user_list, pu);
@@ -217,7 +191,7 @@
 	return -1;
 }
 
-void parking_set_duration(struct ast_bridge_features *features, struct parkeduser *user, int override_time)
+void parking_set_duration(struct ast_bridge_features *features, struct parked_user *user, int override_time)
 {
 	unsigned int time_limit;
 
@@ -232,7 +206,7 @@
 		return;
 	}
 
-	/* The interval hook is going to need a reference to the parkeduser */
+	/* The interval hook is going to need a reference to the parked_user */
 	ao2_ref(user, +1);
 
 	if (ast_bridge_interval_hook(features, time_limit,
@@ -241,14 +215,12 @@
 	}
 }
 
-/* Returns -1 if no slot is available, call it with a read lock taken? */
 int parking_lot_get_space(struct parking_lot *lot, int target_override)
 {
 	int original_target = lot->parkfindnext ? lot->next_space ? lot->next_space : lot->parking_start : lot->parking_start;
 	int current_target;
 	struct ao2_iterator i;
-	struct parkeduser *user;
-	int found_mode = 0;
+	struct parked_user *user;
 	int wrap;
 
 	if (target_override != -1 && target_override >= lot->parking_start && target_override <= lot->parking_stop) {
@@ -267,25 +239,20 @@
 		}
 
 		if (user->parking_space < current_target) {
+			/* It's lower than the anticipated target, so we haven't reached the target yet. */
 			ao2_ref(user, -1);
 			continue;
 		}
 
-		switch (found_mode) {
-		case 0:
-			if (user->parking_space > current_target) {
-				/* The current target is usable. */
-				ao2_ref(user, -1);
-				break;
-			}
-
-			found_mode = 1;
-			/* We want to fall through here */
-		case 1:
-			/* We found one already parked here. Bump the target by 1 and try again. */
-			current_target += 1;
-			found_mode = 0;
-		}
+		if (user->parking_space > current_target) {
+			/* The current target is usable because all items below have been read and the next target is higher than the one we want. */
+			ao2_ref(user, -1);
+			break;
+		}
+
+		/* We found one already parked here. Bump the target by 1 and try again. */
+		current_target += 1;
+		ao2_ref(user, -1);
 	}
 	ao2_iterator_destroy(&i);
 
@@ -300,9 +267,9 @@
 	return -1;
 }
 
-static void destroy_parkeduser(void *obj)
-{
-	struct parkeduser *pu = obj;
+static void destroy_parked_user(void *obj)
+{
+	struct parked_user *pu = obj;
 	ao2_cleanup(pu->parker);
 }
 
@@ -333,7 +300,7 @@
 	ast_channel_priority_set(chan, priority);
 }
 
-int comeback_goto(struct parkeduser *pu, struct parking_lot *lot)
+int comeback_goto(struct parked_user *pu, struct parking_lot *lot)
 {
 	struct ast_channel *chan = pu->chan;
 	char *peername = ast_strdupa(pu->parker->name);
@@ -369,19 +336,19 @@
 	return 0;
 }
 
-void reset_parked_time(struct parkeduser *pu)
+void reset_parked_time(struct parked_user *pu)
 {
 	pu->start = ast_tvnow();
 }
 
-struct parkeduser *generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, struct ast_channel *parker, int use_random_space, int time_limit)
-{
-	struct parkeduser *new_parked_user;
+struct parked_user *generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, struct ast_channel *parker, int use_random_space, int time_limit)
+{
+	struct parked_user *new_parked_user;
 	int preferred_space = -1; /* Initialize to use parking lot defaults */
 	int parking_space;
 	const char *parkingexten;
 
-	new_parked_user = ao2_alloc(sizeof(*new_parked_user), destroy_parkeduser);
+	new_parked_user = ao2_alloc(sizeof(*new_parked_user), destroy_parked_user);
 	if (!new_parked_user) {
 		return NULL;
 	}
@@ -399,10 +366,14 @@
 		}
 	}
 
+	/* We need to keep the lot locked between parking_lot_get_space and actually placing it in the lot. Or until we decide not to. */
+	ao2_lock(lot);
+
 	parking_space = parking_lot_get_space(lot, preferred_space);
 	if (parking_space == -1) {
 		ast_log(LOG_NOTICE, "Failed to get parking space in lot '%s'. All full.\n", lot->name);
 		ao2_ref(new_parked_user, -1);
+		ao2_unlock(lot);
 		return NULL;
 	}
 	lot->next_space = ((parking_space + 1) - lot->parking_start) % (lot->parking_stop - lot->parking_start + 1) + lot->parking_start;
@@ -415,14 +386,16 @@
 	if (!new_parked_user->parker) {
 		ast_log(LOG_ERROR, "Allocation error\n");
 		ao2_ref(new_parked_user, -1);
+		ao2_unlock(lot);
 		return NULL;
 	}
 
 	/* Generate ParkedCall Stasis Message */
-	publish_parked_call(new_parked_user, NULL, 0, 0, PARKED_CALL);
-
-	/* Insert into the parking lot's parked user list */
+	publish_parked_call(new_parked_user, PARKED_CALL);
+
+	/* Insert into the parking lot's parked user list. We can unlock the lot now. */
 	ao2_link(lot->parked_user_list, new_parked_user);
+	ao2_unlock(lot);
 
 	return new_parked_user;
 }

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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/res/parking/res_parking.h (original)
+++ team/jrose/bridge_projects/res/parking/res_parking.h Wed Mar 20 16:22:03 2013
@@ -48,15 +48,6 @@
 };
 
 struct parking_lot {
-	/*! Name of the parking lot */
-	char name[AST_MAX_CONTEXT];
-
-	char mohclass[MAX_MUSICCLASS];
-	char parkext[AST_MAX_EXTENSION];
-	char parking_con[AST_MAX_CONTEXT];
-	char comebackcontext[AST_MAX_CONTEXT];
-	char courtesytone[256];
-
 	int parking_start;
 	int parking_stop;
 
@@ -67,8 +58,6 @@
 	unsigned int parkext_exclusive;
 	unsigned int parkaddhints;
 	unsigned int comebacktoorigin;
-
-	unsigned int is_invalid; /* XXX Is this necessary? Probably not. */
 
 	/* These all need to be handled by a special configuration handler */
 	int parkedplay;
@@ -83,19 +72,28 @@
 	/*! Was this parking space created dynamically? (break down the parking lot once it empties) */
 	int dynamic;
 
+	/*! 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;
+
+	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);
+	);
+
 	/*! Destroy unused parking lot on deletion marker */
 	unsigned int the_mark:1;
 	/*! TRUE if the parking lot is disabled */
 	unsigned int disabled:1;
-
-	/*! 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;
-};
-
-struct parkeduser {
+};
+
+struct parked_user {
 	struct ast_channel *chan;				/*!< Parked channel */
 	struct ast_channel_snapshot *parker;	/*!< Snapshot of the channel that parked the call at the time of parking */
 	struct timeval start;					/*!< When the call was parked */
@@ -107,6 +105,16 @@
 	enum park_call_resolution resolution;	/*!< How did the parking session end? */
 };
 
+/*!
+ * \brief Get a reference to a parking lot's bridge. If it doesn't exist, create it and get a reference.
+ *
+ * \param lot Which parking lot we need the bridge from. This parking lot must be locked before calling this function.
+ *
+ * \retval A reference to the ast_bridge associated with the parking lot
+ * \retval NULL if it didn't already have a bridge and one couldn't be created
+ *
+ * \note This bridge will need to be unreffed if it ever falls out of scope.
+ */
 struct ast_bridge *get_parkinglot_bridge(struct parking_lot *lot);
 
 /*!
@@ -118,7 +126,7 @@
  * retval -1 if No slot can be found
  * retval integer value of parking space selected
  *
- * \note lot should be locked before this is called and unlocked only after a parkeduser with the space
+ * \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 *lot, int target_override);
@@ -136,10 +144,10 @@
  * \brief Setup timeout interval feature on an ast_bridge_features for parking
  *
  * \param features The ast_bridge_features we are establishing the interval hook on
- * \param user The parkeduser receiving the timeout duration limits
+ * \param user The parked_user receiving the timeout duration limits
  * \param override_time If >= 0, use this instead of the user's timeout inherited from its lot
  */
-void parking_set_duration(struct ast_bridge_features *features, struct parkeduser *user, int override_time);
+void parking_set_duration(struct ast_bridge_features *features, struct parked_user *user, int override_time);
 
 /*!
  * \brief Create an iterator which will iterate through all configured parking_lot structs
@@ -190,7 +198,7 @@
  * \param use_random_space if true, prioritize using a random parking space instead
  *        of ${PARKINGEXTEN} and/or automatic assignment from the parking lot
  * \param time_limit If using a custom timeout, this should be supplied so that the
- *        parkeduser struct can provide this information for manager events. If <0,
+ *        parked_user struct can provide this information for manager events. If <0,
  *        use the parking lot limit instead.
  *
  * \retval NULL on failure
@@ -198,7 +206,7 @@
  *
  * \note This reference will need to be free'd when you are done using it.
  */
-struct parkeduser *generate_parked_user(struct parking_lot *lot, struct ast_channel *parkee, struct ast_channel *parker, int use_random_space, int time_limit);
+struct parked_user *generate_parked_user(struct parking_lot *lot, struct ast_channel *parkee, struct ast_channel *parker, int use_random_space, int time_limit);
 
 /*!
  * \brief Reset the start time of a parked user to now
@@ -210,7 +218,7 @@
  *       channel is placed into the parking bridge then there will likely be some discrepencies
  *       between real timeouts and expected timeouts when reporting for manager events.
  */
-void reset_parked_time(struct parkeduser *pu);
+void reset_parked_time(struct parked_user *pu);
 
 /*!
  * \brief Set a channel's position in the PBX after timeout using the parking lot settings
@@ -221,7 +229,7 @@
  * \retval 0 Position set successfully
  * \retval -1 Failed to set the position
  */
-int comeback_goto(struct parkeduser *pu, struct parking_lot *lot);
+int comeback_goto(struct parked_user *pu, struct parking_lot *lot);
 
 /*!
  * \brief Pull a parked user out of its parking lot.
@@ -230,27 +238,22 @@
  * \retval 0 on success
  * \retval -1 if the user didn't have its parking lot set
  */
-int unpark_parked_user(struct parkeduser *user);
+int unpark_parked_user(struct parked_user *user);
 
 /*!
  * \brief Publish a stasis parked call message for a given parked user
  *
- * \param pu pointer to a parkeduser that we are generating the message for
- * \param list If the item is part of a list, the name of the list
- * \param list_item If the item is part of a list, which entry it is (1 to n where n is the number of items)
- * \param list_size If the item is part of a list, how many total entries there are in the list to expect
- */
-void publish_parked_call(struct parkeduser *pu, const char *list, int list_item, int list_size, enum parked_call_event_type event_type);
+ * \param pu pointer to a parked_user that we are generating the message for
+ * \param event_type What parked call event type is provoking this message
+ */
+void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type event_type);
 
 /*!
  * \brief Publish a stasis parking lot message for a given parking lot
  *
  * \param lot pointer to a parking lot that we are generating the message for
- * \param list If the item is part of a list, the name of the list.
- * \param list_item If the item is part of a list, which entry it is (1 to n where n is number of items)
- * \param list_size If the item is part of a list, how many total entries there are in the list to expect
- */
-void publish_parking_lot(struct parking_lot *lot, const char *list, int list_item, int list_size);
+ */
+void publish_parking_lot(struct parking_lot *lot);
 
 /*!
  * \brief Get a pointer to the Park application function.
@@ -261,12 +264,12 @@
 
 /*!
  * \brief Register CLI commands and manager actions
- */
-void load_tools(void);
+ * \retval 0 if successful
+ * \retval -1 on failure
+ */
+int load_tools(void);
 
 /*!
  * \brief Unregister CLI commands and manager actions
- *
- * \note Not implemented yet. Currently a No-Op.
  */
 void unload_tools(void);

Modified: team/jrose/bridge_projects/res/res_parking.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/res_parking.c?view=diff&rev=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/res/res_parking.c (original)
+++ team/jrose/bridge_projects/res/res_parking.c Wed Mar 20 16:22:03 2013
@@ -113,9 +113,10 @@
 					<synopsis>Who we should play the courtesytone to on the pickup of a parked call from this lot</synopsis>
 					<description>
 						<enumlist>
-							<enum name="caller"><para>Play the courtesy tone only to the caller picking up the parked call.</para></enum>
-							<enum name="callee"><para>Play the courtesy tone only to the parked call being picked up.</para></enum>
-							<enum name="both"><para>Play the courtesy tone to both the caller and the callee.</para></enum></enumlist>
+							<enum name="caller"><para>Apply to only to the caller picking up the parked call.</para></enum>
+							<enum name="callee"><para>Apply to only to the parked call being picked up.</para></enum>
+							<enum name="both"><para>Apply to both the caller and the callee.</para></enum>
+						</enumlist>
 						<note><para>If courtesy tone is not specified then this option will be ignored. If any value not listed above
 							is used then the coutesy tone will not be played to either side.</para></note>
 					</description>
@@ -123,53 +124,29 @@
 				<configOption name="parkedcalltransfers" default="none">
 					<synopsis>Apply the DTMF transfer features to the caller and/or callee when parked calls are picked up.</synopsis>
 					<description>
-						<enumlist>
-							<enum name="caller"><para>The Caller may use the <literal>blindxfer</literal> and <literal>atxfer</literal>
-								features</para></enum>
-							<enum name="callee"><para>The Callee (parked call that is picked up) may use the <literal>blindxfer</literal>
-								and <literal>atxfer</literal> features</para></enum>
-							<enum name="both"><para>Both Caller and Callee may use the <literal>blindxfer</literal> and
-								<literal>atxfer</literal> features</para></enum>
-							</enumlist>
-						<note><para>If any value not listed above is used, these features are applied to neither side.</para></note>
+						<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedplay']/description/enumlist)" />
+						<note><para>If any value not listed above is used, this feature is applied to neither side</para></note>
 					</description>
 				</configOption>
 				<configOption name="parkedcallreparking" default="none">
 					<synopsis>Apply the DTMF parking feature to the caller and/or callee when parked calls are picked up.</synopsis>
 					<description>
-						<enumlist>
-							<enum name="caller"><para>The Caller may use the <literal>parkcall</literal> feature</para></enum>
-							<enum name="callee"><para>The Callee (parked call that is picked up) may use the <literal>parkcall</literal>
-								feature</para></enum>
-							<enum name="both"><para>Both Caller and Callee may use the <literal>parkcall</literal> feature</para></enum>
-						</enumlist>
-						<note><para>If any value not listed above is used, this feature is applied to neither side.</para></note>
+						<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedplay']/description/enumlist)" />
+						<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedcalltransfers']/description/note)" />
 					</description>
 				</configOption>
 				<configOption name="parkedcallhangup" default="none">
 					<synopsis>Apply the DTMF Hangup feature to the caller and/or callee when parked calls are picked up.</synopsis>
 					<description>
-						<enumlist>
-							<enum name="caller"><para>The Caller may use the <literal>disconnect</literal> feature</para></enum>
-							<enum name="callee"><para>The Callee (parked call that is picked up) may use the <literal>disconnect</literal>
-								feature</para></enum>
-							<enum name="both"><para>Both Caller and Callee may use the <literal>disconnect</literal> feature</para></enum>
-						</enumlist>
-						<note><para>If any value not listed above is used, this feature is applied to neither side.</para></note>
+						<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedplay']/description/enumlist)" />
+						<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedcalltransfers']/description/note)" />
 					</description>
 				</configOption>
 				<configOption name="parkedcallrecording" default="none">
 					<synopsis>Apply the DTMF recording features to the caller and/or callee when parked calls are picked up</synopsis>
 					<description>
-						<enumlist>
-							<enum name="caller"><para>The Caller may use the <literal>automon</literal> and <literal>automixmon</literal>
-								features</para></enum>
-							<enum name="callee"><para>The Callee (parked call that is picked up) may use the <literal>automon</literal> and
-								<literal>automixmon</literal> features</para></enum>
-							<enum name="both"><para>Both Caller and Callee may use use the <literal>automon</literal> and
-								<literal>automixmon</literal> features</para></enum>
-						</enumlist>
-						<note><para>If any value not listed above is used, these features are applied to neither side.</para></note>
+						<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedplay']/description/enumlist)" />
+						<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedcalltransfers']/description/note)" />
 					</description>
 				</configOption>
 				<configOption name="findslot" default="first">
@@ -253,16 +230,44 @@
 
 static int parking_lot_hash_fn(const void *obj, const int flags)
 {
-	const struct parking_lot *entry = obj;
-	return ast_str_hash(entry->name);
+	const struct parking_lot *entry;
+	const char *key;
+
+	switch (flags & (OBJ_POINTER | OBJ_KEY)) {
+	case OBJ_KEY:
+		key = obj;
+		return ast_str_hash(key);
+	case OBJ_POINTER:
+		entry = obj;
+		return ast_str_hash(entry->name);
+	}
+
+	/* It should be impossible to reach this point */
+	return 0;
 }
 
 static int parking_lot_cmp_fn(void *obj, void *arg, const int flags)
 {
 	struct parking_lot *entry1 = obj;
-	struct parking_lot *entry2 = arg;
-
-	return (!strcmp(entry1->name, entry2->name)) ? (CMP_MATCH | CMP_STOP) : 0;
+
+	char *key;
+	size_t key_size;
+	struct parking_lot *entry2;
+
+	switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+	case OBJ_KEY:
+		key = arg;
+		return (!strcmp(entry1->name, key)) ? (CMP_MATCH | CMP_STOP) : 0;
+	case OBJ_PARTIAL_KEY:
+		key = arg;
+		key_size = strlen(key);
+		return (!strncmp(entry1->name, key, key_size)) ? (CMP_MATCH | CMP_STOP) : 0;
+	case OBJ_POINTER:
+		entry2 = arg;
+		return (!strcmp(entry1->name, entry2->name)) ? (CMP_MATCH | CMP_STOP) : 0;
+	}
+
+	return CMP_STOP;
 }
 
 /*! \brief destructor for parking_lot_config */
@@ -270,6 +275,7 @@
 {
 	struct parking_lot_config *cfg = obj;
 	ao2_cleanup(cfg->parking_lot_list);
+	ao2_cleanup(cfg->global);
 }
 
 /*! \brief destructor for parking_global_config */
@@ -303,17 +309,19 @@
 }
 
 /*! \brief Destroy a parking lot object */
-static void destroy_parking_lot(void *obj)
+static void parking_lot_destructor(void *obj)
 {
 	struct parking_lot *lot = obj;
 	ao2_cleanup(lot->parking_bridge);
+	ao2_cleanup(lot->parked_user_list);
+	ast_string_field_free_memory(lot);
 }
 
 /* The arg just needs to have the parking space with it */
 static int parked_user_cmp_fn(void *obj, void *arg, int flags)
 {
 	int *search_space = arg;
-	struct parkeduser *user = obj;
+	struct parked_user *user = obj;
 	int object_space = user->parking_space;
 
 	if (*search_space == object_space) {
@@ -324,16 +332,10 @@
 
 static int parked_user_sort_fn(const void *obj_left, const void *obj_right, int flags)
 {
-	const struct parkeduser *left = obj_left;
-	const struct parkeduser *right = obj_right;
-
-	if (left->parking_space < right->parking_space) {
-		return -1;
-	} else if (left->parking_space > right->parking_space) {
-		return 1;
-	} else {
-		return 0;
-	}
+	const struct parked_user *left = obj_left;
+	const struct parked_user *right = obj_right;
+
+	return left->parking_space - right->parking_space;
 }
 
 /*!
@@ -346,8 +348,13 @@
 {
 	struct parking_lot *lot;
 
-	lot = ao2_alloc(sizeof(*lot), destroy_parking_lot);
+	lot = ao2_alloc(sizeof(*lot), parking_lot_destructor);
 	if (!lot) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(lot, 32)) {
+		ao2_cleanup(lot);
 		return NULL;
 	}
 
@@ -362,7 +369,7 @@
 		return NULL;
 	}
 
-	ast_copy_string(lot->name, cat, sizeof(lot->name));
+	ast_string_field_set(lot, name, cat);
 
 	return lot;
 }
@@ -377,9 +384,8 @@
  */
 static void *parking_lot_find(struct ao2_container *container, const char *cat)
 {
-	struct parking_lot tmp;
-	ast_copy_string(tmp.name, cat, sizeof(tmp.name));
-	return ao2_find(container, &tmp, OBJ_POINTER);
+	char *search_key = ast_strdupa(cat);

[... 49 lines stripped ...]



More information about the asterisk-commits mailing list