[asterisk-commits] jrose: branch group/bridge_construction r388967 - in /team/group/bridge_const...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri May 17 12:09:27 CDT 2013
Author: jrose
Date: Fri May 17 12:09:17 2013
New Revision: 388967
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=388967
Log:
Recreate the ParkAndAnnounce application within the new parking system
(closes issue ASTERSISK-21352)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2537/
Removed:
team/group/bridge_construction/apps/app_parkandannounce.c
Modified:
team/group/bridge_construction/CHANGES
team/group/bridge_construction/UPGRADE.txt
team/group/bridge_construction/res/parking/parking_applications.c
team/group/bridge_construction/res/parking/parking_bridge.c
team/group/bridge_construction/res/parking/res_parking.h
team/group/bridge_construction/res/res_parking.c
Modified: team/group/bridge_construction/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/CHANGES?view=diff&rev=388967&r1=388966&r2=388967
==============================================================================
--- team/group/bridge_construction/CHANGES (original)
+++ team/group/bridge_construction/CHANGES Fri May 17 12:09:17 2013
@@ -151,10 +151,11 @@
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
+ * The order of arguments for the new parking applications are different from the
+ old ones 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.
+ application documentation for Park, ParkedCall, and ParkAndAnnounce for more
+ in-depth information as well as syntax.
* Extensions are no longer automatically created in the dialplan to park calls,
pickup parked calls, etc by default.
@@ -176,6 +177,13 @@
* The AMI command 'ParkedCalls' will now accept a 'ParkingLot' argument which
can be used to get a list of parked calls only for a specific parking lot.
+
+ * The ParkAndAnnounce application is now provided through res_parking instead
+ of through the separate app_parkandannounce module.
+
+ * ParkAndAnnounce will no longer go to the next position in dialplan on timeout
+ by default. Instead, it will follow the timeout rules of the parking lot. The
+ old behavior can be reproduced by using the 'c' option.
Queue
-------------------
Modified: team/group/bridge_construction/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/UPGRADE.txt?view=diff&rev=388967&r1=388966&r2=388967
==============================================================================
--- team/group/bridge_construction/UPGRADE.txt (original)
+++ team/group/bridge_construction/UPGRADE.txt Fri May 17 12:09:17 2013
@@ -89,6 +89,12 @@
no longer honored. The feature is activated by which channel
DYNAMIC_FEATURES includes the feature is on. Use predial to set different
values of DYNAMIC_FEATURES on the channels
+
+Parking:
+ - The arguments for the Park, ParkedCall, and ParkAndAnnounce applications have
+ been modified significantly. See the application documents for specific details.
+ Also parking lot configuration is now done in res_parking.conf instead of
+ features.conf
From 10 to 11:
Modified: team/group/bridge_construction/res/parking/parking_applications.c
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/res/parking/parking_applications.c?view=diff&rev=388967&r1=388966&r2=388967
==============================================================================
--- team/group/bridge_construction/res/parking/parking_applications.c (original)
+++ team/group/bridge_construction/res/parking/parking_applications.c Fri May 17 12:09:17 2013
@@ -131,6 +131,69 @@
<ref type="application">Park</ref>
</see-also>
</application>
+
+ <application name="ParkAndAnnounce" language="en_US">
+ <synopsis>
+ Park and Announce.
+ </synopsis>
+ <syntax>
+ <parameter name="parking_lot_name">
+ <para>Specify in which parking lot to park a call.</para>
+ <para>The parking lot used is selected in the following order:</para>
+ <para>1) parking_lot_name option to this application</para>
+ <para>2) <variable>PARKINGLOT</variable> variable</para>
+ <para>3) <literal>CHANNEL(parkinglot)</literal> function
+ (Possibly preset by the channel driver.)</para>
+ <para>4) Default parking lot.</para>
+ </parameter>
+ <parameter name="options">
+ <para>A list of options for this parked call.</para>
+ <optionlist>
+ <option name="r">
+ <para>Send ringing instead of MOH to the parked call.</para>
+ </option>
+ <option name="R">
+ <para>Randomize the selection of a parking space.</para>
+ </option>
+ <option name="c" argsep=",">
+ <argument name="context" required="false" />
+ <argument name="extension" required="false" />
+ <argument name="priority" required="true" />
+ <para>If the parking times out, go to this place in the dialplan
+ instead of where the parking lot defines the call should go.
+ </para>
+ </option>
+ <option name="t">
+ <argument name="duration" required="true" />
+ <para>Use a timeout of <literal>duration</literal> seconds instead
+ of the timeout specified by the parking lot.</para>
+ </option>
+ </optionlist>
+ </parameter>
+ <parameter name="announce_template" required="true" argsep=":">
+ <argument name="announce" required="true">
+ <para>Colon-separated list of files to announce. The word
+ <literal>PARKED</literal> will be replaced by a say_digits of the extension in which
+ the call is parked.</para>
+ </argument>
+ <argument name="announce1" multiple="true" />
+ </parameter>
+ <parameter name="dial" required="true">
+ <para>The app_dial style resource to call to make the
+ announcement. Console/dsp calls the console.</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Park a call into the parkinglot and announce the call to another channel.</para>
+ <para>The variable <variable>PARKEDAT</variable> will contain the parking extension
+ into which the call was placed. Use with the Local channel to allow the dialplan to make
+ use of this information.</para>
+ </description>
+ <see-also>
+ <ref type="application">Park</ref>
+ <ref type="application">ParkedCall</ref>
+ </see-also>
+ </application>
***/
/* Park a call */
@@ -281,7 +344,8 @@
return 0;
}
-void get_park_common_datastore_data(struct ast_channel *parkee, char **parker_uuid, char **comeback_override, int *randomize, int *time_limit, int *silence_announce)
+void get_park_common_datastore_data(struct ast_channel *parkee, char **parker_uuid, char **comeback_override,
+ int *randomize, int *time_limit, int *silence_announce)
{
struct ast_datastore *datastore;
struct park_common_datastore *data;
@@ -311,7 +375,8 @@
ast_channel_unlock(parkee);
}
-struct ast_bridge *park_common_setup(struct ast_channel *parkee, struct ast_channel *parker, const char *app_data, int *silence_announcements)
+struct ast_bridge *park_common_setup(struct ast_channel *parkee, struct ast_channel *parker, const char *app_data,
+ int *silence_announcements)
{
int use_ringing = 0;
int randomize = 0;
@@ -380,11 +445,6 @@
int silence_announcements = 0;
const char *blind_transfer;
- /* answer the channel if needed */
- if (ast_channel_state(chan) != AST_STATE_UP) {
- ast_answer(chan);
- }
-
ast_channel_lock(chan);
if ((blind_transfer = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"))) {
blind_transfer = ast_strdupa(blind_transfer);
@@ -426,6 +486,8 @@
return res;
}
+
+/* Retrieve a parked call */
int parked_call_app_exec(struct ast_channel *chan, const char *data)
{
@@ -524,3 +586,218 @@
return 0;
}
+struct park_announce_subscription_data {
+ char *parkee_uuid;
+ char *dial_string;
+ char *announce_string;
+};
+
+static void park_announce_subscription_data_destroy(void *data)
+{
+ struct park_announce_subscription_data *pa_data = data;
+ ast_free(pa_data->parkee_uuid);
+ ast_free(pa_data->dial_string);
+ ast_free(pa_data->announce_string);
+ ast_free(pa_data);
+}
+
+static struct park_announce_subscription_data *park_announce_subscription_data_create(const char *parkee_uuid,
+ const char *dial_string,
+ const char *announce_string)
+{
+ struct park_announce_subscription_data *pa_data;
+
+ if (!(pa_data = ast_calloc(1, sizeof(*pa_data)))) {
+ return NULL;
+ }
+
+ if (!(pa_data->parkee_uuid = ast_strdup(parkee_uuid))
+ || !(pa_data->dial_string = ast_strdup(dial_string))
+ || !(pa_data->announce_string = ast_strdup(announce_string))) {
+ park_announce_subscription_data_destroy(pa_data);
+ return NULL;
+ }
+
+ return pa_data;
+}
+
+static void announce_to_dial(char *dial_string, char *announce_string, int parkingspace, struct ast_channel_snapshot *parkee_snapshot)
+{
+ struct ast_channel *dchan;
+ struct outgoing_helper oh = { 0, };
+ int outstate;
+ struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
+ char buf[13];
+ char *dial_tech;
+ char *cur_announce;
+ struct ast_format tmpfmt;
+
+ dial_tech = strsep(&dial_string, "/");
+ ast_verb(3, "Dial Tech,String: (%s,%s)\n", dial_tech, dial_string);
+
+ if (!cap_slin) {
+ ast_log(LOG_WARNING, "PARK: Failed to announce park.\n");
+ goto announce_cleanup;
+ }
+ ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+
+ snprintf(buf, sizeof(buf), "%d", parkingspace);
+ oh.vars = ast_variable_new("_PARKEDAT", buf, "");
+ dchan = __ast_request_and_dial(dial_tech, cap_slin, NULL, dial_string, 30000,
+ &outstate,
+ parkee_snapshot->caller_number,
+ parkee_snapshot->caller_name,
+ &oh);
+
+ ast_variables_destroy(oh.vars);
+ if (!dchan) {
+ ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
+ goto announce_cleanup;
+ }
+
+ ast_verb(4, "Announce Template: %s\n", announce_string);
+
+ for (cur_announce = strsep(&announce_string, ":"); cur_announce; cur_announce = strsep(&announce_string, ":")) {
+ ast_verb(4, "Announce:%s\n", cur_announce);
+ if (!strcmp(cur_announce, "PARKED")) {
+ ast_say_digits(dchan, parkingspace, "", ast_channel_language(dchan));
+ } else {
+ int dres = ast_streamfile(dchan, cur_announce, ast_channel_language(dchan));
+ if (!dres) {
+ dres = ast_waitstream(dchan, "");
+ } else {
+ ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", cur_announce, ast_channel_name(dchan));
+ }
+ }
+ }
+
+ ast_stopstream(dchan);
+ ast_hangup(dchan);
+
+announce_cleanup:
+ cap_slin = ast_format_cap_destroy(cap_slin);
+}
+
+static void park_announce_update_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
+{
+ struct park_announce_subscription_data *pa_data = data;
+ char *dial_string = pa_data->dial_string;
+
+ struct ast_parked_call_payload *payload = stasis_message_data(message);
+ struct ast_channel_snapshot *parkee_snapshot;
+
+ if (stasis_subscription_final_message(sub, message)) {
+ park_announce_subscription_data_destroy(data);
+ return;
+ }
+
+ if (payload->event_type != PARKED_CALL) {
+ /* We are only concerned with calls parked */
+ return;
+ }
+
+ parkee_snapshot = payload->parkee;
+ if (strcmp(payload->parkee->uniqueid, pa_data->parkee_uuid)) {
+ /* We are only concerned with the parkee we are subscribed for. */
+ return;
+ }
+
+ if (!ast_strlen_zero(dial_string)) {
+ announce_to_dial(dial_string, pa_data->announce_string, payload->parkingspace, payload->parkee);
+ }
+
+ *dial_string = '\0'; /* If we observe this dial string on a second pass, we don't want to do anything with it. */
+}
+
+int park_and_announce_app_exec(struct ast_channel *chan, const char *data)
+{
+ struct ast_bridge_features chan_features;
+ char *parse;
+ int res;
+ int silence_announcements = 1;
+
+ struct stasis_subscription *parking_subscription;
+ struct park_announce_subscription_data *pa_data;
+
+ RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
+
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(lot_name);
+ AST_APP_ARG(options);
+ AST_APP_ARG(announce_template);
+ AST_APP_ARG(dial);
+ AST_APP_ARG(others);/* Any remaining unused arguments */
+ );
+
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_ERROR, "ParkAndAnnounce has required arguments. No arguments were provided.\n");
+ return -1;
+ }
+
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ if (ast_strlen_zero(args.announce_template)) {
+ /* improperly configured arguments for the application */
+ ast_log(LOG_ERROR, "ParkAndAnnounce requires the announce_template argument.\n");
+ return -1;
+ }
+
+ if (ast_strlen_zero(args.dial)) {
+ /* improperly configured arguments */
+ ast_log(LOG_ERROR, "ParkAndAnnounce requires the dial argument.\n");
+ return -1;
+ }
+
+ if (!strchr(args.dial, '/')) {
+ ast_log(LOG_ERROR, "ParkAndAnnounce dial string '%s' is improperly formed.\n", args.dial);
+ return -1;
+ }
+
+ /* Handle the common parking setup stuff */
+ if (!(parking_bridge = park_common_setup(chan, chan, data, &silence_announcements))) {
+ return 0;
+ }
+
+ /* Initialize bridge features for the channel. */
+ res = ast_bridge_features_init(&chan_features);
+ if (res) {
+ ast_bridge_features_cleanup(&chan_features);
+ return -1;
+ }
+
+ /* subscribe to the parking message so that we can announce once it is parked */
+ pa_data = park_announce_subscription_data_create(ast_channel_uniqueid(chan), args.dial, args.announce_template);
+ if (!pa_data) {
+ return -1;
+ }
+
+ if (!(parking_subscription = stasis_subscribe(ast_parking_topic(), park_announce_update_cb, pa_data))) {
+ /* Failed to create subscription */
+ park_announce_subscription_data_destroy(pa_data);
+ return -1;
+ }
+
+ /* Now for the fun part... park it! */
+ ast_bridge_join(parking_bridge, chan, NULL, &chan_features, NULL, 0);
+
+ /* Toss the subscription since we aren't bridged at this point. */
+ stasis_unsubscribe(parking_subscription);
+
+ /*
+ * If the bridge was broken for a hangup that isn't real, then
+ * don't run the h extension, because the channel isn't really
+ * hung up. This should only happen with AST_SOFTHANGUP_ASYNCGOTO.
+ */
+ res = -1;
+
+ ast_channel_lock(chan);
+ if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
+ res = 0;
+ }
+ ast_channel_unlock(chan);
+
+ ast_bridge_features_cleanup(&chan_features);
+
+ return res;
+}
Modified: team/group/bridge_construction/res/parking/parking_bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/res/parking/parking_bridge.c?view=diff&rev=388967&r1=388966&r2=388967
==============================================================================
--- team/group/bridge_construction/res/parking/parking_bridge.c (original)
+++ team/group/bridge_construction/res/parking/parking_bridge.c Fri May 17 12:09:17 2013
@@ -199,6 +199,11 @@
RAII_VAR(char *, comeback_override, NULL, ast_free);
ast_bridge_base_v_table.push(&self->base, bridge_channel, swap);
+
+ /* Answer the channel if needed */
+ if (ast_channel_state(bridge_channel->chan) != AST_STATE_UP) {
+ ast_answer(bridge_channel->chan);
+ }
if (swap) {
ao2_lock(swap);
Modified: team/group/bridge_construction/res/parking/res_parking.h
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/res/parking/res_parking.h?view=diff&rev=388967&r1=388966&r2=388967
==============================================================================
--- team/group/bridge_construction/res/parking/res_parking.h (original)
+++ team/group/bridge_construction/res/parking/res_parking.h Fri May 17 12:09:17 2013
@@ -381,6 +381,20 @@
/*!
* \since 12
+ * \brief Execution function for the park and retrieve application
+ *
+ * \param chan ast_channel entering the application
+ * \param data arguments to the application
+ *
+ * \retval 0 the application executed in such a way that the channel should proceed in the dial plan
+ * \retval -1 the channel should no longer proceed through the dial plan
+ *
+ * \note this function should only be used to register the park and announce application and not generally to park and announce.
+ */
+int park_and_announce_app_exec(struct ast_channel *chan, const char *data);
+
+/*!
+ * \since 12
* \brief Register CLI commands
*
* \retval 0 if successful
Modified: team/group/bridge_construction/res/res_parking.c
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/res/res_parking.c?view=diff&rev=388967&r1=388966&r2=388967
==============================================================================
--- team/group/bridge_construction/res/res_parking.c (original)
+++ team/group/bridge_construction/res/res_parking.c Fri May 17 12:09:17 2013
@@ -193,6 +193,7 @@
#include "asterisk/manager.h"
#define PARKED_CALL_APPLICATION "ParkedCall"
+#define PARK_AND_ANNOUNCE_APPLICATION "ParkAndAnnounce"
/* TODO Add unit tests for parking */
@@ -751,6 +752,10 @@
goto error;
}
+ if (ast_register_application_xml(PARK_AND_ANNOUNCE_APPLICATION, park_and_announce_app_exec)) {
+ goto error;
+ }
+
if (load_parking_ui()) {
goto error;
}
More information about the asterisk-commits
mailing list