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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 25 15:52:20 CDT 2013


Author: jrose
Date: Mon Mar 25 15:52:16 2013
New Revision: 383777

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383777
Log:
Rearranging manager stuff, made manager actions stop using stasis.

Added:
    team/jrose/bridge_projects/res/parking/parking_manager.c   (with props)
Modified:
    team/jrose/bridge_projects/CHANGES
    team/jrose/bridge_projects/include/asterisk/channel.h
    team/jrose/bridge_projects/include/asterisk/parking.h
    team/jrose/bridge_projects/main/asterisk.c
    team/jrose/bridge_projects/main/manager_channels.c
    team/jrose/bridge_projects/main/parking.c
    team/jrose/bridge_projects/res/parking/parking_controller.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/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/CHANGES?view=diff&rev=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/CHANGES (original)
+++ team/jrose/bridge_projects/CHANGES Mon Mar 25 15:52:16 2013
@@ -50,6 +50,19 @@
  * The AMI event 'UserEvent' from app_userevent now contains the channel state
    fields. The channel state fields will come before the body fields.
 
+ * The AMI events 'ParkedCall', 'ParkedCallTimeOut', 'ParkedCallGiveUp', and
+   'UnParkedCall' have changed significantly in the new res_parking module.
+   First, channel snapshot data is included for both the parker and the parkee
+   in lieu of the "From" and "Channel" fields. They follow standard channel
+   snapshot format but each field is suffixed with '(parker)' or '(parkee')
+   depending on which side it applies to. The 'Exten' field is replaced with
+   'ParkingSpace' since the registration of extensions as for parking spaces
+   is no longer mandatory.
+
+ * The AMI event 'Parkinglot' (response to 'Parkinglots' command) in a similar
+   fashion has changed the field names 'StartExten' and 'StopExten' to
+   'StartSpace' and 'StopSpace' respectively.
+
 Channel Drivers
 ------------------
 
@@ -77,8 +90,8 @@
 
  * Add support for automixmonitor to the BRIDGE_FEATURES channel variable.
 
- * PARKINGSLOT and PARKEDLOT channel variables will now be set for a parked
-   channel even when comebactoorigin=yes
+ * Parking has been pulled from core and placed into a separate module called
+   res_parking. See Parking changes below for more details.
 
 Logging
 -------------------
@@ -96,6 +109,39 @@
   of audio samples in a voice frame will experience significant quality problems
   if a denoiser is attached to the channel; this option gives them the ability
   to remove the denoiser without having to unload func_speex.
+
+Parking
+-------------------
+ * Parking is now implemented as a module instead of as core functionality.
+   The preferred way to configure parking is now through res_parking.conf while
+   configuration through features.conf is not currently supported.
+
+ * Parked calls are now placed in bridges. This is a largely architectural change,
+   but it could have some implications in allowing for new parked call retrieval
+   methods and the contents of parking lots will be visible though certain bridge
+   commands.
+
+ * The order of arguments for the new parking application are different from the
+   old one to be more intuitive. Timeout and return context/exten/priority are now
+   implemented as options. parking_lot_name is now the first parameter. See the
+   application documentation for Park for more in-depth information.
+
+ * Extensions are no longer automatically created in the dialplan to park calls,
+   pickup parked calls, etc by default.
+
+   * NOTE *
+   An option should be implemented before release that will enable automatic
+   extension creation. The extensions will be different and there will be no
+   updating the dial plan as calls are parked and unparked, but the functionality
+   should remain essentially the same.
+
+ * adsipark is no longer supported under the new parking model
+
+ * PARKINGSLOT channel variable has been changed to PARKINGSPACE to match the naming
+   scheme of the new system.
+
+ * PARKINGSPACE and PARKEDLOT channel variables will now be set for a parked
+   channel even when comebactoorigin=yes
 
 Queue
 -------------------

Modified: team/jrose/bridge_projects/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/channel.h?view=diff&rev=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/channel.h (original)
+++ team/jrose/bridge_projects/include/asterisk/channel.h Mon Mar 25 15:52:16 2013
@@ -4151,6 +4151,21 @@
 
 /*!
  * \since 12
+ * \brief Generate the AMI message body from a channel snapshot
+ *
+ * \param snapshot the channel snapshot for which to generate an AMI message
+ *                 body
+ * \param suffix Optional suffix string to attach to all of the channel state
+ *               messages. Useful when dealing with multiple channel snapshots
+ *               in a single event.
+ *
+ * \retval NULL on error
+ * \retval ast_str* on success (must be ast_freed by caller)
+ */
+struct ast_str *ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot, const char *suffix);
+
+/*!
+ * \since 12
  * \brief Message type for \ref ast_channel_snapshot.
  *
  * \retval Message type for \ref ast_channel_snapshot.

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=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/parking.h (original)
+++ team/jrose/bridge_projects/include/asterisk/parking.h Mon Mar 25 15:52:16 2013
@@ -22,91 +22,3 @@
  *
  * \author Jonathan Rose <jrose at digium.com>
  */
-
-#include "asterisk/stringfields.h"
-
-/*!
- * \brief Defines the type of parked call message
- * \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 A parking lot message payload
- * \since 12
- */
-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);
-	);
-};
-
-/*!
- * \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 ao2_cleanup this reference once 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 ao2_cleanup this reference once 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
- *
- * \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
- *
- * \retval Topic for parking lot events.
- */
-struct stasis_topic *ast_parking_lot_topic(void);

Modified: team/jrose/bridge_projects/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/asterisk.c?view=diff&rev=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/main/asterisk.c (original)
+++ team/jrose/bridge_projects/main/asterisk.c Mon Mar 25 15:52:16 2013
@@ -4202,7 +4202,6 @@
 	}
 
 	ast_channels_init();
-	ast_parking_init();
 
 	if ((moduleresult = load_modules(1))) {		/* Load modules, pre-load only */
 		printf("%s", term_quit());

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=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/main/manager_channels.c (original)
+++ team/jrose/bridge_projects/main/manager_channels.c Mon Mar 25 15:52:16 2013
@@ -107,53 +107,49 @@
 	</managerEvent>
  ***/
 
-/*!
- * \brief Generate the AMI message body from a channel snapshot
- * \internal
- *
- * \param snapshot the channel snapshot for which to generate an AMI message
- *                 body
- *
- * \retval NULL on error
- * \retval ast_str* on success (must be ast_freed by caller)
- */
-static struct ast_str *manager_build_channel_state_string(
-	const struct ast_channel_snapshot *snapshot)
+struct ast_str *ast_manager_build_channel_state_string(
+	const struct ast_channel_snapshot *snapshot,
+	const char *suffix)
 {
 	struct ast_str *out = ast_str_create(1024);
 	int res = 0;
 	if (!out) {
 		return NULL;
 	}
+
+	if (!suffix) {
+		suffix = "";
+	}
+
 	res = ast_str_set(&out, 0,
-		"Channel: %s\r\n"
-		"ChannelState: %d\r\n"
-		"ChannelStateDesc: %s\r\n"
-		"CallerIDNum: %s\r\n"
-		"CallerIDName: %s\r\n"
-		"ConnectedLineNum: %s\r\n"
-		"ConnectedLineName: %s\r\n"
-		"AccountCode: %s\r\n"
-		"Context: %s\r\n"
-		"Exten: %s\r\n"
-		"Priority: %d\r\n"
-		"Uniqueid: %s\r\n"
-		"Cause: %d\r\n"
-		"Cause-txt: %s\r\n",
-		snapshot->name,
-		snapshot->state,
-		ast_state2str(snapshot->state),
-		snapshot->caller_number,
-		snapshot->caller_name,
-		snapshot->connected_number,
-		snapshot->connected_name,
-		snapshot->accountcode,
-		snapshot->context,
-		snapshot->exten,
-		snapshot->priority,
-		snapshot->uniqueid,
-		snapshot->hangupcause,
-		ast_cause2str(snapshot->hangupcause));
+		"Channel%s: %s\r\n"
+		"ChannelState%s: %d\r\n"
+		"ChannelStateDesc%s: %s\r\n"
+		"CallerIDNum%s: %s\r\n"
+		"CallerIDName%s: %s\r\n"
+		"ConnectedLineNum%s: %s\r\n"
+		"ConnectedLineName%s: %s\r\n"
+		"AccountCode%s: %s\r\n"
+		"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",
+		suffix, snapshot->name,
+		suffix, snapshot->state,
+		suffix, ast_state2str(snapshot->state),
+		suffix, snapshot->caller_number,
+		suffix, snapshot->caller_name,
+		suffix, snapshot->connected_number,
+		suffix, snapshot->connected_name,
+		suffix, snapshot->accountcode,
+		suffix, snapshot->context,
+		suffix, snapshot->exten,
+		suffix, snapshot->priority,
+		suffix, snapshot->uniqueid,
+		suffix, snapshot->hangupcause,
+		suffix, ast_cause2str(snapshot->hangupcause));
 
 	if (!res) {
 		return NULL;
@@ -225,7 +221,7 @@
 
 	if (manager_event || new_exten) {
 		channel_event_string =
-			manager_build_channel_state_string(new_snapshot);
+			ast_manager_build_channel_state_string(new_snapshot, NULL);
 	}
 
 	if (!channel_event_string) {
@@ -278,7 +274,7 @@
 	const char *value = ast_json_string_get(ast_json_object_get(obj->blob, "value"));
 
 	if (obj->snapshot) {
-		channel_event_string = manager_build_channel_state_string(obj->snapshot);
+		channel_event_string = ast_manager_build_channel_state_string(obj->snapshot, NULL);
 	} else {
 		channel_event_string = ast_str_create(35);
 		ast_str_set(&channel_event_string, 0,
@@ -320,7 +316,7 @@
 
 	eventname = ast_json_string_get(ast_json_object_get(obj->blob, "eventname"));
 	body = ast_json_string_get(ast_json_object_get(obj->blob, "body"));
-	channel_event_string = manager_build_channel_state_string(obj->snapshot);
+	channel_event_string = ast_manager_build_channel_state_string(obj->snapshot, NULL);
 
 	if (!channel_event_string) {
 		return;

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=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/main/parking.c (original)
+++ team/jrose/bridge_projects/main/parking.c Mon Mar 25 15:52:16 2013
@@ -28,112 +28,5 @@
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include "asterisk/_private.h"
-
 #include "asterisk/parking.h"
-#include "asterisk/stasis.h"
-#include "asterisk/astobj2.h"
 #include "asterisk/channel.h"
-
-/*!
- * On it's own, this component just provides a means of creating
- * and retrieving stasis elements for the purpose of issuing
- * stasis messages related to parking. Actual channel parking
- * functionality is implemented by resource modules such as
- * 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;
-
-/*! \brief Message type for parking lots */
-static struct stasis_message_type *parking_lot;
-
-/*! \brief Topic for parking lots */
-static struct stasis_topic *parking_lot_topic;
-
-struct stasis_message_type *ast_parked_call(void)
-{
-	return parked_call;
-}
-
-struct stasis_message_type *ast_parking_lot(void)
-{
-	return parking_lot;
-}
-
-struct stasis_topic *ast_parking_lot_topic(void)
-{
-	return parking_lot_topic;
-}
-
-/*! \internal
- * \brief Callback to clean up stasis element
- */
-static void parking_shutdown(void)
-{
-	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");
-
-	parking_lot_topic = stasis_topic_create("ast_parking_lot_topic");
-	ast_register_atexit(parking_shutdown);
-}

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=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Mon Mar 25 15:52:16 2013
@@ -30,79 +30,6 @@
 #include "asterisk/utils.h"
 #include "asterisk/manager.h"
 #include "asterisk/test.h"
-
-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 = ast_parked_call_payload_create();
-	if (!payload) {
-		return;
-	}
-
-	if (pu->chan) {
-		payload->parkee = ast_channel_snapshot_create(pu->chan);
-		if (!payload->parkee) {
-			return;
-		}
-	}
-
-	payload->event_type = event_type;
-
-	/* The parked user absolutely must have a parker snapshot for events to be valid. */
-	if (!pu->parker) {
-		return;
-	}
-
-	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);
-
-	msg = stasis_message_create(ast_parked_call(), payload);
-	if (!msg) {
-		return;
-	}
-
-	if (pu->chan) {
-		stasis_publish(ast_channel_topic(pu->chan), msg);
-	}
-}
-
-void publish_parking_lot_state(struct parking_lot_state *lot)
-{
-	RAII_VAR(struct ast_parking_lot_payload *, payload, NULL, ao2_cleanup);
-	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
-
-	payload = ast_parking_lot_payload_create();
-	if (!payload) {
-		return;
-	}
-
-	ast_string_field_set(payload, name, lot->name);
-	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);
-
-	msg = stasis_message_create(ast_parking_lot(), payload);
-	if (!msg) {
-		return;
-	}
-
-	stasis_publish(ast_parking_lot_topic(), msg);
-}
 
 struct ast_bridge *get_parkinglot_bridge(struct parking_lot_state *state)
 {

Added: 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=auto&rev=383777
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_manager.c (added)
+++ team/jrose/bridge_projects/res/parking/parking_manager.c Mon Mar 25 15:52:16 2013
@@ -1,0 +1,328 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Jonathan Rose <jrose at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Call Parking Manager Actions and Events
+ *
+ * \author Jonathan Rose <jrose at digium.com>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "res_parking.h"
+#include "asterisk/config.h"
+#include "asterisk/config_options.h"
+#include "asterisk/event.h"
+#include "asterisk/utils.h"
+#include "asterisk/module.h"
+#include "asterisk/cli.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/features.h"
+#include "asterisk/manager.h"
+
+/*** DOCUMENTATION
+	<manager name="Parkinglots" language="en_US">
+		<synopsis>
+			Get a list of parking lots
+		</synopsis>
+		<syntax>
+			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+		</syntax>
+		<description>
+			<para>List all parking lots as a series of AMI events</para>
+		</description>
+	</manager>
+	<manager name="ParkedCalls" language="en_US">
+		<synopsis>
+			List parked calls.
+		</synopsis>
+		<syntax>
+			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+		</syntax>
+		<description>
+			<para>List parked calls.</para>
+		</description>
+	</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 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);
+}
+
+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] = "";
+	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;
+
+	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;
+}
+
+static struct ast_str *manager_build_parkedcall_string(const struct parked_call_payload *payload)
+{
+	struct ast_str *out = ast_str_create(1024);
+	int res = 0;
+	RAII_VAR(struct ast_str *, parkee_string, NULL, ast_free);
+	RAII_VAR(struct ast_str *, parker_string, NULL, ast_free);
+
+	if (!out) {
+		return NULL;
+	}
+
+	parkee_string = ast_manager_build_channel_state_string(payload->parkee, "(parkee)");
+	parker_string = ast_manager_build_channel_state_string(payload->parker, "(parker)");
+
+	res = ast_str_set(&out, 0,
+		"%s" /* parkee channel state */
+		"%s" /* parker channel state */
+		"Parkinglot: %s\r\n"
+		"ParkingSpace: %s\r\n"
+		"ParkingTimeout: %s\r\n"
+		"ParkingDuration: %s\r\n",
+
+		ast_str_buffer(parkee_string),
+		ast_str_buffer(parker_string),
+		payload->parkinglot,
+		payload->parkingspace,
+		payload->timeout,
+		payload->duration);
+
+	if (!res) {
+		return NULL;
+	}
+
+	return out;
+}
+
+static int manager_parking_status(struct mansession *s, const struct message *m)
+{
+	struct parked_user *curuser;
+	const char *id = astman_get_header(m, "ActionID");
+	char id_text[256] = "";
+	struct ao2_iterator *iter_lots;
+	struct ao2_iterator iter_users;
+	struct parking_lot_state *curlot;
+	int total = 0;
+
+	if (!ast_strlen_zero(id)) {
+		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");
+		astman_send_error(s, m, "Could not create parking lot list");
+		return -1;
+	}
+
+	astman_send_ack(s, m, "Parked calls will follow");
+
+	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_str *, parkedcall_string, NULL, ast_free);
+			payload = parked_call_payload_create(curuser, PARKED_CALL);
+			parkedcall_string = manager_build_parkedcall_string(payload);
+			total++;
+
+			astman_append(s, "Event: ParkedCall\r\n"
+				"%s" /* The parked call string */
+				"%s" /* The action ID */
+				"\r\n",
+				ast_str_buffer(parkedcall_string),
+				id_text);
+
+			ao2_ref(curuser, -1);
+		}
+		ao2_iterator_destroy(&iter_users);
+		ao2_ref(curlot, -1);
+	}
+
+	parking_lot_state_iterator_destroy(iter_lots);
+
+	astman_append(s,
+		"Event: ParkedCallsComplete\r\n"
+		"Total: %d\r\n"
+		"%s"
+		"\r\n",
+		total, id_text);
+
+	return RESULT_SUCCESS;
+}
+
+static int manager_parkinglot_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;
+
+	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");
+		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);
+
+	astman_append(s,
+		"Event: ParkinglotsComplete\r\n"
+		"%s"
+		"\r\n",id_text);
+
+	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);
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+
+	payload = parked_call_payload_create(pu, event_type);
+	if (!payload) {
+		return;
+	}
+
+	msg = stasis_message_create(parked_call_message_type, payload);
+	if (!msg) {
+		return;
+	}
+
+	if (pu->chan) {
+		stasis_publish(ast_channel_topic(pu->chan), msg);
+	}
+}
+
+static void parking_manager_disable_stasis(void)
+{
+	ao2_cleanup(parked_call_message_type);
+	ao2_cleanup(parking_topic);
+	parked_call_message_type = NULL;
+	parking_topic = NULL;
+}
+
+int load_parking_manager(void)
+{
+	int res;
+
+	res = ast_manager_register_xml_core("Parkinglots", 0, manager_parkinglot_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");
+
+	return res ? -1 : 0;
+}
+
+void unload_parking_manager(void)
+{
+	ast_manager_unregister("Parkinglots");
+	ast_manager_unregister("ParkedCalls");
+	parking_manager_disable_stasis();
+}

Propchange: team/jrose/bridge_projects/res/parking/parking_manager.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/jrose/bridge_projects/res/parking/parking_manager.c
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Rev URL"

Propchange: team/jrose/bridge_projects/res/parking/parking_manager.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

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=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_ui.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_ui.c Mon Mar 25 15:52:16 2013
@@ -18,7 +18,7 @@
 
 /*! \file
  *
- * \brief Call Parking CLI commands and Manager Actions
+ * \brief Call Parking CLI commands
  *
  * \author Jonathan Rose <jrose at digium.com>
  */
@@ -38,31 +38,6 @@
 #include "asterisk/features.h"
 #include "asterisk/manager.h"
 
-/*** DOCUMENTATION
-	<manager name="Parkinglots" language="en_US">
-		<synopsis>
-			Get a list of parking lots
-		</synopsis>
-		<syntax>
-			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-		</syntax>
-		<description>
-			<para>List all parking lots as a series of AMI events</para>
-		</description>
-	</manager>
-	<manager name="ParkedCalls" language="en_US">
-		<synopsis>
-			List parked calls.
-		</synopsis>
-		<syntax>
-			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-		</syntax>
-		<description>
-			<para>List parked calls.</para>
-		</description>
-	</manager>
- ***/
-
 static void cli_display_parking_lot(int fd, const char *name)
 {
 	RAII_VAR(struct parking_lot_state *, lot, NULL, ao2_cleanup);
@@ -81,7 +56,7 @@
 	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, "Parked Call Extensions :      %d-%d\n", lot->parking_start, lot->parking_stop);
+	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)" : "");
@@ -128,10 +103,10 @@
 		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, "Parked Call Extensions :      %d-%d\n", lot->parking_start, lot->parking_stop);
+		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 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");
@@ -188,93 +163,16 @@
 	return CLI_SHOWUSAGE;
 }
 
-static int manager_parkinglot_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;
-
-	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");
-		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))) {
-		publish_parking_lot_state(curlot);
-		ao2_ref(curlot, -1);
-	}
-
-	parking_lot_state_iterator_destroy(iter);
-
-	return RESULT_SUCCESS;
-}
-
-static int manager_parking_status(struct mansession *s, const struct message *m)
-{
-	struct parked_user *curuser;
-	const char *id = astman_get_header(m, "ActionID");
-	char id_text[256] = "";
-	struct ao2_iterator *iter_lots;
-	struct ao2_iterator iter_users;
-	struct parking_lot_state *curlot;
-
-	if (!ast_strlen_zero(id)) {
-		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");
-		astman_send_error(s, m, "Could not create parking lot list");
-		return -1;
-	}
-
-	astman_send_ack(s, m, "Parked calls will follow");
-
-	while ((curlot = ao2_iterator_next(iter_lots))) {
-		iter_users = ao2_iterator_init(curlot->parked_user_list, 0);
-		while ((curuser = ao2_iterator_next(&iter_users))) {
-			publish_parked_call(curuser, PARKED_CALL);
-			ao2_ref(curuser, -1);
-		}
-		ao2_iterator_destroy(&iter_users);
-		ao2_ref(curlot, -1);
-	}
-
-	parking_lot_state_iterator_destroy(iter_lots);
-
-	return RESULT_SUCCESS;
-}
-
 static struct ast_cli_entry cli_parking_lot[] = {
 	AST_CLI_DEFINE(handle_show_parking_lot_cmd, "Show a parking lot or a list of all parking lots."),
 };
 
 int load_parking_ui(void)
 {
-	int res;
-
-	ast_cli_register_multiple(cli_parking_lot, ARRAY_LEN(cli_parking_lot));
-	res = ast_manager_register_xml_core("Parkinglots", 0, manager_parkinglot_list);
-	res |= ast_manager_register_xml_core("ParkedCalls", 0, manager_parking_status);
-
-	return res ? -1 : 0;
+	return ast_cli_register_multiple(cli_parking_lot, ARRAY_LEN(cli_parking_lot));
 }
 
 void unload_parking_ui(void)
 {
 	ast_cli_unregister_multiple(cli_parking_lot, ARRAY_LEN(cli_parking_lot));
-	ast_manager_unregister("Parkinglots");
-	ast_manager_unregister("ParkedCalls");
 }

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=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/res/parking/res_parking.h (original)
+++ team/jrose/bridge_projects/res/parking/res_parking.h Mon Mar 25 15:52:16 2013
@@ -123,6 +123,17 @@
 	);
 };
 
+/*!
+ * \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 {
 	struct ast_channel *chan;               /*!< Parked channel */
 	struct ast_channel_snapshot *parker;    /*!< Snapshot of the channel that parked the call at the time of parking */
@@ -315,15 +326,7 @@
  * \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);
-
-/*!
- * \since 12
- * \brief Publish a stasis parking lot message for a given parking lot state object
- *
- * \param lot pointer to a parking lot state object that we are generating the message for
- */
-void publish_parking_lot_state(struct parking_lot_state *lot);
+void publish_parked_call(struct parked_user *pu, enum parked_call_event_type event_type);
 
 /*!
  * \since 12
@@ -341,7 +344,7 @@
 
 /*!
  * \since 12
- * \brief Register CLI commands and manager actions
+ * \brief Register CLI commands
  *
  * \retval 0 if successful
  * \retval -1 on failure
@@ -350,6 +353,18 @@
 
 /*!
  * \since 12
- * \brief Unregister CLI commands and manager actions
+ * \brief Unregister CLI commands
  */
 void unload_parking_ui(void);
+
+/*!
+ * \since 12
+ * \brief Register manager actions and setup subscriptions for stasis events
+ */
+int load_parking_manager(void);
+
+/*!
+ * \since 12
+ * \brief Unregister manager actions and remove subscriptions for stasis events
+ */
+void unload_parking_manager(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=383777&r1=383776&r2=383777
==============================================================================
--- team/jrose/bridge_projects/res/res_parking.c (original)
+++ team/jrose/bridge_projects/res/res_parking.c Mon Mar 25 15:52:16 2013
@@ -32,18 +32,24 @@
 			<configObject name="parking_lot">
 				<synopsis>Defined parkinglots for res_parking to use to park calls on</synopsis>
 				<configOption name="context" default="parkedcalls">
-					<synopsis>The name of the context where extensions for picking up parked calls will be created</synopsis>
-				</configOption>
-				<configOption name="parkext" default="700">
+					<synopsis>The name of the context where calls are parked and picked up from.</synopsis>
+					<description><para>This option is only used if parkext is set.</para></description>
+				</configOption>
+				<configOption name="parkext">
 					<synopsis>Extension to park calls to this parking lot.</synopsis>
-					<description><para>This extension will park calls into the associated parking lot. It will be
-						created in the context defined by the <literal>context</literal> option.</para></description>
+					<description><para>If this option is used, this extension will automatically be created to place calls into
+                        parking lots. In addition, if parkext_exclusive is set for this parking lot, the name of the parking lot
+                        will be included in the application's arguments so that it only parks to this parking lot. The extension
+                        will be created in <literal>context</literal>. Using this option also creates extensions for retrieving
+                        parked calls from the parking spaces in the same context.</para></description>
 				</configOption>
 				<configOption name="parkext_exclusive" default="no">
-					<synopsis>If yes, the parkext will park exclusively to this parking lot.</synopsis>
+					<synopsis>If yes, the extension registered as parkext will park exclusively to this parking lot.</synopsis>
 				</configOption>
 				<configOption name="parkpos" default="701-750">
-					<synopsis>Numerical range of extensions which can be used to retrieve parked calls</synopsis>
+					<synopsis>Numerical range of parking spaces which can be used to retrieve parked calls.</synopsis>
+					<description><para>If parkext is set, these extensions will automatically be mapped in <literal>context</literal>
+						in order to pick up calls parked to these parking spaces.</para></description>
 				</configOption>
 				<configOption name="parkinghints" default="no">
 					<synopsis>If yes, this parking lot will add hints automatically for parking slots.</synopsis>
@@ -702,7 +708,7 @@
 	/* Global options */
 
 	/* Register the per parkinglot options. */
-	aco_option_register(&cfg_info, "parkext", ACO_EXACT, parking_lot_types, "700", OPT_STRINGFIELD_T, 0, STRFLDSET(struct parking_lot_cfg, parkext));
+	aco_option_register(&cfg_info, "parkext", ACO_EXACT, parking_lot_types, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct parking_lot_cfg, parkext));
 	aco_option_register(&cfg_info, "context", ACO_EXACT, parking_lot_types, "parkedcalls", OPT_STRINGFIELD_T, 0, STRFLDSET(struct parking_lot_cfg, parking_con));
 	aco_option_register(&cfg_info, "parkingtime", ACO_EXACT, parking_lot_types, "45", OPT_UINT_T, 0, FLDSET(struct parking_lot_cfg, parkingtime));

[... 24 lines stripped ...]



More information about the asterisk-commits mailing list