[asterisk-commits] jrose: branch jrose/bridge_projects r383396 - in /team/jrose/bridge_projects:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Mar 19 16:06:02 CDT 2013
Author: jrose
Date: Tue Mar 19 16:05:58 2013
New Revision: 383396
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383396
Log:
Parking 3/19 - Configuration and entry
Added:
team/jrose/bridge_projects/include/asterisk/parking.h (with props)
team/jrose/bridge_projects/main/parking.c (with props)
team/jrose/bridge_projects/res/parking/
team/jrose/bridge_projects/res/parking/parking_applications.c (with props)
team/jrose/bridge_projects/res/parking/parking_controller.c (with props)
team/jrose/bridge_projects/res/parking/parking_tools.c (with props)
team/jrose/bridge_projects/res/parking/res_parking.h (with props)
team/jrose/bridge_projects/res/res_parking.c (with props)
Modified:
team/jrose/bridge_projects/include/asterisk/_private.h
team/jrose/bridge_projects/include/asterisk/config_options.h
team/jrose/bridge_projects/main/asterisk.c
team/jrose/bridge_projects/main/config_options.c
team/jrose/bridge_projects/main/features.c
team/jrose/bridge_projects/main/manager.c
team/jrose/bridge_projects/res/Makefile
Modified: team/jrose/bridge_projects/include/asterisk/_private.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/_private.h?view=diff&rev=383396&r1=383395&r2=383396
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/_private.h (original)
+++ team/jrose/bridge_projects/include/asterisk/_private.h Tue Mar 19 16:05:58 2013
@@ -23,6 +23,7 @@
int ast_term_init(void); /*!< Provided by term.c */
int astdb_init(void); /*!< Provided by db.c */
void ast_channels_init(void); /*!< Provided by channel.c */
+void ast_parking_init(void); /*!< Provided by parking.c */
void ast_builtins_init(void); /*!< Provided by cli.c */
int ast_cli_perms_init(int reload); /*!< Provided by cli.c */
int dnsmgr_init(void); /*!< Provided by dnsmgr.c */
Modified: team/jrose/bridge_projects/include/asterisk/config_options.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/config_options.h?view=diff&rev=383396&r1=383395&r2=383396
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/config_options.h (original)
+++ team/jrose/bridge_projects/include/asterisk/config_options.h Tue Mar 19 16:05:58 2013
@@ -574,6 +574,13 @@
* \retval -1 Failure
*/
int aco_option_register_deprecated(struct aco_info *info, const char *name, struct aco_type **types, const char *aliased_to);
+
+/*! \brief Read the flags of a config option - useful when using a custom callback for a config option
+ * \param option Pointer to the aco_option struct
+ *
+ * \retval value of the flags on the config option
+ */
+unsigned int aco_option_get_flags(const struct aco_option *option);
/*! \note Everything below this point is to handle converting varargs
* containing field names, to varargs containing a count of args, followed
Added: team/jrose/bridge_projects/include/asterisk/parking.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/parking.h?view=auto&rev=383396
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/parking.h (added)
+++ team/jrose/bridge_projects/include/asterisk/parking.h Tue Mar 19 16:05:58 2013
@@ -1,0 +1,93 @@
+/*
+ * 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 API
+ *
+ * \author Jonathan Rose <jrose at digium.com>
+ */
+
+#include "asterisk/stringfields.h"
+
+/*! \brief Defines the type of parked call message */
+enum 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 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;
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(parkinglot);
+ AST_STRING_FIELD(parkingspace);
+ AST_STRING_FIELD(timeout);
+ AST_STRING_FIELD(duration);
+ AST_STRING_FIELD(list);
+ );
+};
+
+/*!
+ * \brief A parking lot message payload
+ * \since 12
+ */
+struct parking_lot_payload {
+ int list_item;
+ int list_size;
+ 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);
+ );
+};
+
+/*!
+ * \since 12
+ * \brief Message type for \ref ast_parked_call
+ *
+ * \retval Message type for \ref ast_parked_call
+ */
+struct stasis_message_type *ast_parked_call(void);
+
+/*!
+ * \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);
+
+/*!
+ * \since 12
+ * \brief A topic which publishes events pertaining generally to parking lots.
+ *
+ * \retval Topic for parking lot events.
+ */
+struct stasis_topic *ast_parking_lot_topic(void);
Propchange: team/jrose/bridge_projects/include/asterisk/parking.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/jrose/bridge_projects/include/asterisk/parking.h
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Rev URL"
Propchange: team/jrose/bridge_projects/include/asterisk/parking.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=383396&r1=383395&r2=383396
==============================================================================
--- team/jrose/bridge_projects/main/asterisk.c (original)
+++ team/jrose/bridge_projects/main/asterisk.c Tue Mar 19 16:05:58 2013
@@ -4200,6 +4200,7 @@
}
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/config_options.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/config_options.c?view=diff&rev=383396&r1=383395&r2=383396
==============================================================================
--- team/jrose/bridge_projects/main/config_options.c (original)
+++ team/jrose/bridge_projects/main/config_options.c Tue Mar 19 16:05:58 2013
@@ -220,6 +220,11 @@
}
return 0;
+}
+
+unsigned int aco_option_get_flags(const struct aco_option *option)
+{
+ return option->flags;
}
#ifdef AST_XML_DOCS
Modified: team/jrose/bridge_projects/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/features.c?view=diff&rev=383396&r1=383395&r2=383396
==============================================================================
--- team/jrose/bridge_projects/main/features.c (original)
+++ team/jrose/bridge_projects/main/features.c Tue Mar 19 16:05:58 2013
@@ -283,95 +283,6 @@
<ref type="application">ParkAndAnnounce</ref>
</see-also>
</application>
- <application name="Park" language="en_US">
- <synopsis>
- Park yourself.
- </synopsis>
- <syntax>
- <parameter name="timeout">
- <para>A custom parking timeout for this parked call. Value in milliseconds.</para>
- </parameter>
- <parameter name="return_context">
- <para>The context to return the call to after it times out.</para>
- </parameter>
- <parameter name="return_exten">
- <para>The extension to return the call to after it times out.</para>
- </parameter>
- <parameter name="return_priority">
- <para>The priority to return the call to after it times out.</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="s">
- <para>Silence announcement of the parking space number.</para>
- </option>
- </optionlist>
- </parameter>
- <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</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>
- </syntax>
- <description>
- <para>Used to park yourself (typically in combination with a supervised
- 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 is in use then execution
- will continue at the next priority.</para>
- <para>If the <literal>parkeddynamic</literal> option is enabled in <filename>features.conf</filename>
- the following variables can be used to dynamically create new parking lots.</para>
- <para>If you set the <variable>PARKINGDYNAMIC</variable> variable and this parking lot
- exists then it will be used as a template for the newly created dynamic lot. Otherwise,
- the default parking lot will be used.</para>
- <para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable then the newly created dynamic
- parking lot will use this context.</para>
- <para>If you set the <variable>PARKINGDYNEXTEN</variable> variable then the newly created dynamic
- parking lot will use this extension to access the parking lot.</para>
- <para>If you set the <variable>PARKINGDYNPOS</variable> variable then the newly created dynamic parking lot
- will use those parking postitions.</para>
- <note>
- <para>This application must be used as the first extension priority
- to be recognized as a parking access extension. DTMF transfers
- and some channel drivers need this distinction to operate properly.
- The parking access extension in this case is treated like a dialplan
- hint.</para>
- </note>
- <note>
- <para>Parking lots automatically create and manage dialplan extensions in
- the parking lot context. You do not need to explicitly use this
- application in your dialplan. Instead, all you should do is include the
- parking lot context in your dialplan.</para>
- </note>
- </description>
- <see-also>
- <ref type="application">ParkAndAnnounce</ref>
- <ref type="application">ParkedCall</ref>
- </see-also>
- </application>
- <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>
<manager name="Park" language="en_US">
<synopsis>
Park a channel.
@@ -417,17 +328,6 @@
</syntax>
<description>
<para>Bridge together two channels already in the PBX.</para>
- </description>
- </manager>
- <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>
<function name="FEATURE" language="en_US">
@@ -5019,116 +4919,6 @@
AST_APP_OPTION('s', AST_PARK_OPT_SILENCE),
END_OPTIONS );
-/*! \brief Park a call */
-static int park_call_exec(struct ast_channel *chan, const char *data)
-{
- struct ast_park_call_args args = { 0, };
- struct ast_flags flags = { 0 };
- char orig_exten[AST_MAX_EXTENSION];
- int orig_priority;
- int res;
- const char *pl_name;
- char *parse;
- struct park_app_args app_args;
-
- /*
- * Cache the original channel name because we are going to
- * masquerade the channel. Prefer the BLINDTRANSFER channel
- * name over this channel name. BLINDTRANSFER could be set if
- * the parking access extension did not get detected and we are
- * executing the Park application from the dialplan.
- *
- * The orig_chan_name is used to return the call to the
- * originator on parking timeout.
- */
- args.orig_chan_name = ast_strdupa(S_OR(
- pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"), ast_channel_name(chan)));
-
- /* Answer if call is not up */
- if (ast_channel_state(chan) != AST_STATE_UP) {
- if (ast_answer(chan)) {
- return -1;
- }
-
- /* Sleep to allow VoIP streams to settle down */
- if (ast_safe_sleep(chan, 1000)) {
- return -1;
- }
- }
-
- /* Process the dialplan application options. */
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(app_args, parse);
-
- if (!ast_strlen_zero(app_args.timeout)) {
- if (sscanf(app_args.timeout, "%30d", &args.timeout) != 1) {
- ast_log(LOG_WARNING, "Invalid timeout '%s' provided\n", app_args.timeout);
- args.timeout = 0;
- }
- }
- if (!ast_strlen_zero(app_args.return_con)) {
- args.return_con = app_args.return_con;
- }
- if (!ast_strlen_zero(app_args.return_ext)) {
- args.return_ext = app_args.return_ext;
- }
- if (!ast_strlen_zero(app_args.return_pri)) {
- if (sscanf(app_args.return_pri, "%30d", &args.return_pri) != 1) {
- ast_log(LOG_WARNING, "Invalid priority '%s' specified\n", app_args.return_pri);
- args.return_pri = 0;
- }
- }
-
- ast_app_parse_options(park_call_options, &flags, NULL, app_args.options);
- args.flags = flags.flags;
-
- /*
- * Setup the exten/priority to be s/1 since we don't know where
- * this call should return.
- */
- ast_copy_string(orig_exten, ast_channel_exten(chan), sizeof(orig_exten));
- orig_priority = ast_channel_priority(chan);
- ast_channel_exten_set(chan, "s");
- ast_channel_priority_set(chan, 1);
-
- /* Park the call */
- if (!ast_strlen_zero(app_args.pl_name)) {
- pl_name = app_args.pl_name;
- } else {
- pl_name = findparkinglotname(chan);
- }
- if (ast_strlen_zero(pl_name)) {
- /* Parking lot is not specified, so use the default parking lot. */
- args.parkinglot = parkinglot_addref(default_parkinglot);
- } else {
- args.parkinglot = find_parkinglot(pl_name);
- if (!args.parkinglot && parkeddynamic) {
- args.parkinglot = create_dynamic_parkinglot(pl_name, chan);
- }
- }
- if (args.parkinglot) {
- res = masq_park_call(chan, chan, &args);
- parkinglot_unref(args.parkinglot);
- } else {
- /* Parking failed because the parking lot does not exist. */
- if (!ast_test_flag(&args, AST_PARK_OPT_SILENCE)) {
- ast_stream_and_wait(chan, "pbx-parkingfailed", "");
- }
- res = -1;
- }
- if (res) {
- /* Park failed, try to continue in the dialplan. */
- ast_channel_exten_set(chan, orig_exten);
- ast_channel_priority_set(chan, orig_priority);
- res = 0;
- } else {
- /* Park succeeded. */
- res = -1;
- }
-
- return res;
-}
-
/*! \brief Pickup parked call */
static int parked_call_exec(struct ast_channel *chan, const char *data)
{
@@ -7184,107 +6974,6 @@
AST_CLI_DEFINE(handle_parkedcalls, "List currently parked calls"),
};
-static int manager_parkinglot_list(struct mansession *s, const struct message *m)
-{
- const char *id = astman_get_header(m, "ActionID");
- char idText[256] = "";
- struct ao2_iterator iter;
- struct ast_parkinglot *curlot;
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
-
- astman_send_ack(s, m, "Parking lots will follow");
-
- iter = ao2_iterator_init(parkinglots, 0);
- while ((curlot = ao2_iterator_next(&iter))) {
- astman_append(s, "Event: Parkinglot\r\n"
- "Name: %s\r\n"
- "StartExten: %d\r\n"
- "StopExten: %d\r\n"
- "Timeout: %d\r\n"
- "\r\n",
- curlot->name,
- curlot->cfg.parking_start,
- curlot->cfg.parking_stop,
- curlot->cfg.parkingtime ? curlot->cfg.parkingtime / 1000 : curlot->cfg.parkingtime);
- ao2_ref(curlot, -1);
- }
-
- astman_append(s,
- "Event: ParkinglotsComplete\r\n"
- "%s"
- "\r\n",idText);
-
- return RESULT_SUCCESS;
-}
-
-/*!
- * \brief Dump parking lot status
- * \param s
- * \param m
- *
- * Lock parking lot, iterate list and append parked calls status, unlock parking lot.
- * \return Always RESULT_SUCCESS
- */
-static int manager_parking_status(struct mansession *s, const struct message *m)
-{
- struct parkeduser *cur;
- const char *id = astman_get_header(m, "ActionID");
- char idText[256] = "";
- struct ao2_iterator iter;
- struct ast_parkinglot *curlot;
- int numparked = 0;
- long now = time(NULL);
-
- if (!ast_strlen_zero(id))
- snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
-
- astman_send_ack(s, m, "Parked calls will follow");
-
- iter = ao2_iterator_init(parkinglots, 0);
- while ((curlot = ao2_iterator_next(&iter))) {
- AST_LIST_LOCK(&curlot->parkings);
- AST_LIST_TRAVERSE(&curlot->parkings, cur, list) {
- astman_append(s, "Event: ParkedCall\r\n"
- "Parkinglot: %s\r\n"
- "Exten: %d\r\n"
- "Channel: %s\r\n"
- "From: %s\r\n"
- "Timeout: %ld\r\n"
- "Duration: %ld\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "ConnectedLineNum: %s\r\n"
- "ConnectedLineName: %s\r\n"
- "%s"
- "\r\n",
- curlot->name,
- cur->parkingnum, ast_channel_name(cur->chan), cur->peername,
- (long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - now,
- now - (long) cur->start.tv_sec,
- S_COR(ast_channel_caller(cur->chan)->id.number.valid, ast_channel_caller(cur->chan)->id.number.str, ""), /* XXX in other places it is <unknown> */
- S_COR(ast_channel_caller(cur->chan)->id.name.valid, ast_channel_caller(cur->chan)->id.name.str, ""),
- S_COR(ast_channel_connected(cur->chan)->id.number.valid, ast_channel_connected(cur->chan)->id.number.str, ""), /* XXX in other places it is <unknown> */
- S_COR(ast_channel_connected(cur->chan)->id.name.valid, ast_channel_connected(cur->chan)->id.name.str, ""),
- idText);
- ++numparked;
- }
- AST_LIST_UNLOCK(&curlot->parkings);
- ao2_ref(curlot, -1);
- }
- ao2_iterator_destroy(&iter);
-
- astman_append(s,
- "Event: ParkedCallsComplete\r\n"
- "Total: %d\r\n"
- "%s"
- "\r\n",
- numparked, idText);
-
- return RESULT_SUCCESS;
-}
-
/*!
* \brief Create manager event for parked calls
* \param s
@@ -8644,9 +8333,7 @@
ast_custom_function_unregister(&feature_function);
ast_manager_unregister("Bridge");
ast_manager_unregister("Park");
- ast_manager_unregister("Parkinglots");
- ast_manager_unregister("ParkedCalls");
- ast_unregister_application(parkcall);
+
ast_unregister_application(parkedcall);
ast_unregister_application(app_bridge);
@@ -8673,11 +8360,7 @@
}
ast_register_application2(app_bridge, bridge_exec, NULL, NULL, NULL);
res = ast_register_application2(parkedcall, parked_call_exec, NULL, NULL, NULL);
- if (!res)
- res = ast_register_application2(parkcall, park_call_exec, NULL, NULL, NULL);
if (!res) {
- ast_manager_register_xml_core("ParkedCalls", 0, manager_parking_status);
- ast_manager_register_xml_core("Parkinglots", 0, manager_parkinglot_list);
ast_manager_register_xml_core("Park", EVENT_FLAG_CALL, manager_park);
ast_manager_register_xml_core("Bridge", EVENT_FLAG_CALL, action_bridge);
}
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=383396&r1=383395&r2=383396
==============================================================================
--- team/jrose/bridge_projects/main/manager.c (original)
+++ team/jrose/bridge_projects/main/manager.c Tue Mar 19 16:05:58 2013
@@ -92,6 +92,7 @@
#include "asterisk/stringfields.h"
#include "asterisk/presencestate.h"
#include "asterisk/stasis.h"
+#include "asterisk/parking.h"
/*** DOCUMENTATION
<manager name="Ping" language="en_US">
@@ -1129,6 +1130,8 @@
};
static struct stasis_subscription *channel_state_sub;
+
+static struct stasis_subscription *parking_lot_sub;
static void acl_change_event_cb(const struct ast_event *event, void *userdata);
@@ -7538,6 +7541,82 @@
channel_name, name, value, uniqueid);
}
+static void parked_call(struct parked_call_payload *parked_call)
+{
+ char *event_type;
+
+ switch (parked_call->event_type) {
+ case PARKED_CALL:
+ event_type = "ParkedCall";
+ break;
+ case PARKED_CALL_TIMEOUT:
+ event_type = "ParkedCallTimeOut";
+ break;
+ case PARKED_CALL_GIVEUP:
+ event_type = "ParkedCallGiveUp";
+ break;
+ case PARKED_CALL_UNPARKED:
+ event_type = "UnParkedCall";
+ break;
+ }
+
+ 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",
+
+ 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
+ );
+}
+
+static void parking_lot(struct 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);
+}
+
static void channel_event_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
{
if (stasis_message_type(message) == stasis_cache_update()) {
@@ -7554,6 +7633,17 @@
const char *name = varset->snapshot ? varset->snapshot->name : "none";
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);
+ parked_call(parked_call_message);
+ }
+}
+
+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);
+ parking_lot(parking_lot_message);
}
}
@@ -7581,6 +7671,9 @@
struct ast_manager_user *user;
channel_state_sub = stasis_unsubscribe(channel_state_sub);
+
+ stasis_unsubscribe(parking_lot_sub);
+ parking_lot_sub = NULL;
if (registered) {
ast_manager_unregister("Ping");
@@ -7679,6 +7772,10 @@
channel_event_cb, NULL);
}
+ if (!parking_lot_sub) {
+ parking_lot_sub = stasis_subscribe(ast_parking_lot_topic(), parking_lot_cb, NULL);
+ }
+
if (!registered) {
/* Register default actions */
ast_manager_register_xml_core("Ping", 0, action_ping);
Added: team/jrose/bridge_projects/main/parking.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/parking.c?view=auto&rev=383396
==============================================================================
--- team/jrose/bridge_projects/main/parking.c (added)
+++ team/jrose/bridge_projects/main/parking.c Tue Mar 19 16:05:58 2013
@@ -1,0 +1,87 @@
+/*
+ * 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 Parking Core
+ *
+ * \author Jonathan Rose <jrose at digium.com>
+ */
+
+#include "asterisk.h"
+
+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 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);
+}
Propchange: team/jrose/bridge_projects/main/parking.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/jrose/bridge_projects/main/parking.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Rev URL"
Propchange: team/jrose/bridge_projects/main/parking.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/jrose/bridge_projects/res/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/Makefile?view=diff&rev=383396&r1=383395&r2=383396
==============================================================================
--- team/jrose/bridge_projects/res/Makefile (original)
+++ team/jrose/bridge_projects/res/Makefile Tue Mar 19 16:05:58 2013
@@ -68,3 +68,7 @@
clean::
rm -f snmp/*.o snmp/*.i ael/*.o ael/*.i ais/*.o ais/*.i
+ rm -f parking/*.o parking/*.i
+
+$(if $(filter res_parking,$(EMBEDDED_MODS)),modules.link,res_parking.so): $(subst .c,.o,$(wildcard parking/*.c))
+$(subst .c,.o,$(wildcard parking/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_parking)
Added: 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=auto&rev=383396
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_applications.c (added)
+++ team/jrose/bridge_projects/res/parking/parking_applications.c Tue Mar 19 16:05:58 2013
@@ -1,0 +1,245 @@
+/*
+ * 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 Applications
+ *
+ * \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/astobj2.h"
+#include "asterisk/features.h"
+#include "asterisk/module.h"
+#include "asterisk/app.h"
+#include "asterisk/say.h"
+
+/*** DOCUMENTATION
+ <application name="Park" language="en_US">
+ <synopsis>
+ Park yourself.
+ </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="s">
+ <para>Silence announcement of the parking space number.</para>
+ </option>
+ <option name="c">
+ <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>
+ <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
+ transfer to know the parking space).</para>
+ </description>
+ <see-also>
+ <ref type="application">ParkedCall</ref>
+ </see-also>
+ </application>
+
+ ***/
+
+/* Park a call */
+
+enum park_args {
+ OPT_ARG_COMEBACK,
+ OPT_ARG_TIMEOUT,
+ OPT_ARG_ARRAY_SIZE, /* Always the last element of the enum */
+};
+
+enum park_flags {
+ MUXFLAG_RINGING = (1 << 0),
+ MUXFLAG_RANDOMIZE = (1 << 1),
+ MUXFLAG_NOANNOUNCE = (1 << 2),
+ MUXFLAG_COMEBACK_OVERRIDE = (1 << 3),
+ MUXFLAG_TIMEOUT_OVERRIDE = (1 << 4),
+};
+
+AST_APP_OPTIONS(park_opts, {
+ AST_APP_OPTION('r', MUXFLAG_RINGING),
+ AST_APP_OPTION('R', MUXFLAG_RANDOMIZE),
+ AST_APP_OPTION('s', MUXFLAG_NOANNOUNCE),
+ AST_APP_OPTION_ARG('c', MUXFLAG_COMEBACK_OVERRIDE, OPT_ARG_COMEBACK),
+ AST_APP_OPTION_ARG('t', MUXFLAG_TIMEOUT_OVERRIDE, OPT_ARG_TIMEOUT),
+});
+
+static int apply_option_timeout (int *var, char *timeout_arg)
+{
+ if (ast_strlen_zero(timeout_arg)) {
+ ast_log(LOG_ERROR, "No duration value provided for the timeout ('t') option.\n");
+ return -1;
+ }
+
+ if (sscanf(timeout_arg, "%d", var) != 1 || *var < 0) {
+ ast_log(LOG_ERROR, "Duration value provided for timeout ('t') option must be 0 or greater.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+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;
+ struct ast_bridge_features chan_features;
+ struct ast_flags flags = { 0 };
+ char *parse;
+ int time_limit = -1;
+ char *comeback_override = NULL;
+
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(lot_name);
+ AST_APP_ARG(options);
+ AST_APP_ARG(other); /* Any remaining unused arguments */
+ );
+
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ if (args.options) {
+ char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
+ ast_app_parse_options(park_opts, &flags, opts, args.options);
+ if (ast_test_flag(&flags, MUXFLAG_TIMEOUT_OVERRIDE)) {
+ if (apply_option_timeout(&time_limit, opts[OPT_ARG_TIMEOUT])) {
+ return -1;
+ }
+ }
+ if (ast_test_flag(&flags, MUXFLAG_COMEBACK_OVERRIDE)) {
+ comeback_override = ast_strdupa(opts[OPT_ARG_COMEBACK]);
+ }
+ }
+
+ if (ast_strlen_zero(args.lot_name)) {
+ lot = channel_find_parkinglot(chan);
+ } else {
+ lot = parking_lot_get(args.lot_name);
+ }
+
+ if (!lot) {
+ ast_log(LOG_ERROR, "Could not find the requested parking lot\n");
+ return -1;
+ }
+
+ ao2_lock(lot);
+ parking_bridge = get_parkinglot_bridge(lot);
+ ao2_unlock(lot);
+
+ if (!parking_bridge) {
+ ast_log(LOG_ERROR, "Could not acquire holding bridge to park into\n");
+ return -1;
+ }
+
+ /* answer the channel if needed */
+ if (ast_channel_state(chan) != AST_STATE_UP) {
+ ast_answer(chan);
+ }
+
+ pu = generate_parked_user(lot, chan, chan, ast_test_flag(&flags, MUXFLAG_RANDOMIZE), time_limit);
+
+ if (!pu) {
+ ast_log(LOG_ERROR, "Failed to create parked user for channel %s, can not park.\n", ast_channel_name(chan));
+ return -1;
+ }
+
+ /* If we aren't in silence mode, go ahead and announce the parking space */
+ if (!ast_test_flag(&flags, MUXFLAG_NOANNOUNCE)) {
+ ast_say_digits(chan, pu->parking_space, "", ast_channel_language(chan));
+ }
+
+ ast_bridge_features_init(&chan_features);
+
+ /* Set limits and apply channel roles */
+ parking_set_duration(&chan_features, pu, time_limit);
+ parking_channel_set_roles(chan, lot, ast_test_flag(&flags, MUXFLAG_RINGING));
+
+ /* Alright, now wait in the holding bridge until we get removed from it for some reason. */
+ reset_parked_time(pu);
+ ast_bridge_join(parking_bridge, chan, NULL, &chan_features, NULL, 0);
+ /* XXX After this, depending on the conditions of exit we might want to return early. But that comes later. */
+
+ ast_bridge_features_cleanup(&chan_features);
+
+ /* Remove the parked user from the parking lot if it is still in */
+ unpark_parked_user(pu);
+
+ /* Figure out if we need to go somewhere special now that the timeout has occured */
+ if (ast_test_flag(&flags, MUXFLAG_COMEBACK_OVERRIDE)) {
+ if (ast_parseable_goto(chan, comeback_override)) {
+ return -1;
+ }
+ } else {
+ if (comeback_goto(pu, lot)) {
+ return -1;
+ }
+ }
+
+ /* Since this is executed from pbx, it'll automatically bump the priority when we return. We can address that by reducing it by 1 in before returning. Smooth. */
+ ast_channel_priority_set(chan, ast_channel_priority(chan) - 1);
+
+ return ast_check_hangup_locked(chan) ? -1 : 0;
+}
+
+void *parking_get_park_app_cb()
+{
+ return park_exec;
+}
Propchange: team/jrose/bridge_projects/res/parking/parking_applications.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/jrose/bridge_projects/res/parking/parking_applications.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Rev URL"
Propchange: team/jrose/bridge_projects/res/parking/parking_applications.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: 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=auto&rev=383396
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (added)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Tue Mar 19 16:05:58 2013
@@ -1,0 +1,429 @@
+/*
+ * 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 Parking Entry, Exit, Events, and other assorted controls.
+ *
+ * \author Jonathan Rose <jrose at digium.com>
+ */
+#include "asterisk.h"
+
+#include "asterisk/logger.h"
+#include "res_parking.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/utils.h"
+#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);
+ 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);
+ if (!payload) {
+ return;
+ }
+
+ if (ast_string_field_init(payload, 32)) {
+ 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->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);
+
+ if (list) {
+ ast_string_field_set(payload, list, list);
+ payload->list_item = list_item;
+ payload->list_size = list_size;
+ }
+
[... 1564 lines stripped ...]
More information about the asterisk-commits
mailing list