[asterisk-commits] jrose: branch jrose/bridge_projects r383612 - in /team/jrose/bridge_projects:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Mar 22 14:28:53 CDT 2013
Author: jrose
Date: Fri Mar 22 14:28:49 2013
New Revision: 383612
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383612
Log:
Getting ready for stasis changes
Modified:
team/jrose/bridge_projects/include/asterisk/config_options.h
team/jrose/bridge_projects/include/asterisk/parking.h
team/jrose/bridge_projects/res/parking/parking_applications.c
team/jrose/bridge_projects/res/parking/parking_controller.c
team/jrose/bridge_projects/res/parking/parking_ui.c
team/jrose/bridge_projects/res/parking/res_parking.h
team/jrose/bridge_projects/res/res_parking.c
Modified: team/jrose/bridge_projects/include/asterisk/config_options.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/config_options.h?view=diff&rev=383612&r1=383611&r2=383612
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/config_options.h (original)
+++ team/jrose/bridge_projects/include/asterisk/config_options.h Fri Mar 22 14:28:49 2013
@@ -575,7 +575,10 @@
*/
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
+/*!
+ * \brief Read the flags of a config option - useful when using a custom callback for a config option
+ * \since 12
+ *
* \param option Pointer to the aco_option struct
*
* \retval value of the flags on the config option
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=383612&r1=383611&r2=383612
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/parking.h (original)
+++ team/jrose/bridge_projects/include/asterisk/parking.h Fri Mar 22 14:28:49 2013
@@ -25,7 +25,10 @@
#include "asterisk/stringfields.h"
-/*! \brief Defines the type of parked call message */
+/*!
+ * \brief Defines the type of parked call message
+ * \since 12
+ */
enum ast_parked_call_event_type {
PARKED_CALL = 0,
PARKED_CALL_TIMEOUT,
@@ -69,7 +72,7 @@
* \retval NULL if the payload could not be allocated
* \retval reference to the payload object
*
- * \note This reference should be free'd when it is no longer in use.
+ * \note ao2_cleanup this reference once it is no longer in use.
*/
struct ast_parked_call_payload *ast_parked_call_payload_create(void);
@@ -80,7 +83,7 @@
* \retval NULL if the payload could not be allocated
* \retval reference to the payload object
*
- * \note This reference should be free'd when it is no longer in use.
+ * \note ao2_cleanup this reference once it is no longer in use.
*/
struct ast_parking_lot_payload *ast_parking_lot_payload_create(void);
Modified: team/jrose/bridge_projects/res/parking/parking_applications.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_applications.c?view=diff&rev=383612&r1=383611&r2=383612
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_applications.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_applications.c Fri Mar 22 14:28:49 2013
@@ -136,9 +136,9 @@
return 0;
}
-static int park_exec(struct ast_channel *chan, const char *data)
+int park_app_exec(struct ast_channel *chan, const char *data)
{
- RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
+ RAII_VAR(struct parking_lot_state *, lot, NULL, ao2_cleanup);
RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup);
RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
@@ -173,7 +173,7 @@
if (ast_strlen_zero(args.lot_name)) {
lot = channel_find_parkinglot(chan);
} else {
- lot = parking_lot_get(args.lot_name);
+ lot = parking_lot_find_by_name(args.lot_name);
}
if (!lot) {
@@ -239,8 +239,3 @@
return ast_check_hangup_locked(chan) ? -1 : 0;
}
-
-void *parking_get_park_app_cb()
-{
- return park_exec;
-}
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=383612&r1=383611&r2=383612
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Fri Mar 22 14:28:49 2013
@@ -66,7 +66,7 @@
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_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);
@@ -81,7 +81,7 @@
}
}
-void publish_parking_lot(struct parking_lot *lot)
+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);
@@ -104,13 +104,13 @@
stasis_publish(ast_parking_lot_topic(), msg);
}
-struct ast_bridge *get_parkinglot_bridge(struct parking_lot *lot)
+struct ast_bridge *get_parkinglot_bridge(struct parking_lot_state *state)
{
struct ast_bridge *lot_bridge;
- if (lot->parking_bridge) {
- ao2_ref(lot->parking_bridge, +1);
- return lot->parking_bridge;
+ if (state->parking_bridge) {
+ ao2_ref(state->parking_bridge, +1);
+ return state->parking_bridge;
}
/* XXX Richard is going to change some things here. Name will be an argument */
@@ -120,21 +120,21 @@
}
/* The parking lot needs a reference to the bridge as well. */
- lot->parking_bridge = lot_bridge;
- ao2_ref(lot->parking_bridge, +1);
+ state->parking_bridge = lot_bridge;
+ ao2_ref(state->parking_bridge, +1);
return lot_bridge;
}
-void parking_channel_set_roles(struct ast_channel *chan, struct parking_lot *lot, int force_ringing)
+void parking_channel_set_roles(struct ast_channel *chan, struct parking_lot_state *lot_state, int force_ringing)
{
ast_channel_add_bridge_role(chan, "holding_participant");
if (force_ringing) {
ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "ringing");
} else {
ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "musiconhold");
- if (!ast_strlen_zero(lot->mohclass)) {
- ast_channel_set_bridge_role_option(chan, "holding_participant", "moh_class", lot->mohclass);
+ if (!ast_strlen_zero(lot_state->mohclass)) {
+ ast_channel_set_bridge_role_option(chan, "holding_participant", "moh_class", lot_state->mohclass);
}
}
}
@@ -182,9 +182,10 @@
int unpark_parked_user(struct parked_user *pu)
{
- if (pu->lot) {
- ao2_unlink(pu->lot->parked_user_list, pu);
- pu->lot = NULL;
+ if (pu->lot_state) {
+ ao2_unlink(pu->lot_state->parked_user_list, pu);
+ parking_lot_remove_if_unused(pu->lot_state);
+ pu->lot_state = NULL;
return 0;
}
@@ -198,7 +199,7 @@
if (override_time >= 0) {
time_limit = override_time * 1000;
} else {
- time_limit = user->lot ? user->lot->parkingtime * 1000 : 0;
+ time_limit = user->lot_state ? user->lot_state->parkingtime * 1000 : 0;
}
if (!time_limit) {
@@ -215,15 +216,23 @@
}
}
-int parking_lot_get_space(struct parking_lot *lot, int target_override)
-{
- int original_target = lot->parkfindnext ? lot->next_space ? lot->next_space : lot->parking_start : lot->parking_start;
+int parking_lot_get_space(struct parking_lot_state *lot, int target_override)
+{
+ int original_target;
int current_target;
struct ao2_iterator i;
struct parked_user *user;
int wrap;
- if (target_override != -1 && target_override >= lot->parking_start && target_override <= lot->parking_stop) {
+ if (lot->parkfindnext) {
+ /* Use next_space if the lot has already has next_space set; otherwise use lot start. */
+ original_target = lot->next_space ? lot->next_space : lot->parking_start;
+ } else {
+ /* If not using find next mode, we just start at the start of the parking lot always. */
+ original_target = lot->parking_start;
+ }
+
+ if (target_override >= lot->parking_start && target_override <= lot->parking_stop) {
original_target = target_override;
}
@@ -300,7 +309,7 @@
ast_channel_priority_set(chan, priority);
}
-int comeback_goto(struct parked_user *pu, struct parking_lot *lot)
+int comeback_goto(struct parked_user *pu, struct parking_lot_state *lot_state)
{
struct ast_channel *chan = pu->chan;
char *peername = ast_strdupa(pu->parker->name);
@@ -308,7 +317,7 @@
/* Flatten the peername so that it can be used for performing the timeout PBX operations */
flatten_peername(peername);
- if (lot->comebacktoorigin) {
+ if (lot_state->comebacktoorigin) {
if (ast_exists_extension(chan, PARK_DIAL_CONTEXT, peername, 1, NULL)) {
set_c_e_p(chan, PARK_DIAL_CONTEXT, peername, 1);
} else {
@@ -318,19 +327,19 @@
}
}
- if (ast_exists_extension(chan, lot->comebackcontext, peername, 1, NULL)) {
- set_c_e_p(chan, lot->comebackcontext, peername, 1);
- }
-
- if (ast_exists_extension(chan, lot->comebackcontext, "s", 1, NULL)) {
+ if (ast_exists_extension(chan, lot_state->comebackcontext, peername, 1, NULL)) {
+ set_c_e_p(chan, lot_state->comebackcontext, peername, 1);
+ }
+
+ if (ast_exists_extension(chan, lot_state->comebackcontext, "s", 1, NULL)) {
ast_verb(2, "Could not start %s at %s,%s,1. Using 's@%s' instead.\n", ast_channel_name(chan),
- lot->comebackcontext, peername, lot->comebackcontext);
- set_c_e_p(chan, lot->comebackcontext, "s", 1);
+ lot_state->comebackcontext, peername, lot_state->comebackcontext);
+ set_c_e_p(chan, lot_state->comebackcontext, "s", 1);
}
ast_verb(2, "Can not start %s at %s,%s,1 and exten 's@%s' does not exist. Using 's at default'\n",
ast_channel_name(chan),
- lot->comebackcontext, peername, lot->comebackcontext);
+ lot_state->comebackcontext, peername, lot_state->comebackcontext);
set_c_e_p(chan, "default", "s", 1);
return 0;
@@ -341,21 +350,26 @@
pu->start = ast_tvnow();
}
-struct parked_user *generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, struct ast_channel *parker, int use_random_space, int time_limit)
+struct parked_user *generate_parked_user(struct parking_lot_state *lot_state, struct ast_channel *chan, struct ast_channel *parker, int use_random_space, int time_limit)
{
struct parked_user *new_parked_user;
int preferred_space = -1; /* Initialize to use parking lot defaults */
int parking_space;
const char *parkingexten;
+ if (lot_state->parking_disabled) {
+ ast_log(LOG_NOTICE, "Tried to park in a parking lot that is no longer able to be parked to.\n");
+ return NULL;
+ }
+
new_parked_user = ao2_alloc(sizeof(*new_parked_user), destroy_parked_user);
if (!new_parked_user) {
return NULL;
}
if (use_random_space) {
- preferred_space = ast_random() % (lot->parking_stop - lot->parking_start + 1);
- preferred_space += lot->parking_start;
+ preferred_space = ast_random() % (lot_state->parking_stop - lot_state->parking_start + 1);
+ preferred_space += lot_state->parking_start;
} else if ((parkingexten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"), "")))) {
if (!ast_strlen_zero(parkingexten)) {
if (sscanf(parkingexten, "%30d", &preferred_space) != 1 || preferred_space <= 0) {
@@ -366,27 +380,28 @@
}
}
- /* We need to keep the lot locked between parking_lot_get_space and actually placing it in the lot. Or until we decide not to. */
- ao2_lock(lot);
-
- parking_space = parking_lot_get_space(lot, preferred_space);
+ /* We need to keep the lot state locked between parking_lot_get_space and actually placing it in the lot. Or until we decide not to. */
+ ao2_lock(lot_state);
+
+ parking_space = parking_lot_get_space(lot_state, preferred_space);
if (parking_space == -1) {
- ast_log(LOG_NOTICE, "Failed to get parking space in lot '%s'. All full.\n", lot->name);
+ ast_log(LOG_NOTICE, "Failed to get parking space in lot '%s'. All full.\n", lot_state->name);
ao2_ref(new_parked_user, -1);
- ao2_unlock(lot);
+ ao2_unlock(lot_state);
return NULL;
}
- lot->next_space = ((parking_space + 1) - lot->parking_start) % (lot->parking_stop - lot->parking_start + 1) + lot->parking_start;
+
+ lot_state->next_space = ((parking_space + 1) - lot_state->parking_start) % (lot_state->parking_stop - lot_state->parking_start + 1) + lot_state->parking_start;
new_parked_user->chan = chan;
new_parked_user->parking_space = parking_space;
- new_parked_user->lot = lot;
+ new_parked_user->lot_state = lot_state;
new_parked_user->start = ast_tvnow();
- new_parked_user->time_limit = (time_limit >= 0) ? time_limit : lot->parkingtime;
+ new_parked_user->time_limit = (time_limit >= 0) ? time_limit : lot_state->parkingtime;
new_parked_user->parker = ast_channel_snapshot_create(parker);
if (!new_parked_user->parker) {
ast_log(LOG_ERROR, "Allocation error\n");
ao2_ref(new_parked_user, -1);
- ao2_unlock(lot);
+ ao2_unlock(lot_state);
return NULL;
}
@@ -394,8 +409,8 @@
publish_parked_call(new_parked_user, PARKED_CALL);
/* Insert into the parking lot's parked user list. We can unlock the lot now. */
- ao2_link(lot->parked_user_list, new_parked_user);
- ao2_unlock(lot);
+ ao2_link(lot_state->parked_user_list, new_parked_user);
+ ao2_unlock(lot_state);
return new_parked_user;
}
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=383612&r1=383611&r2=383612
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_ui.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_ui.c Fri Mar 22 14:28:49 2013
@@ -65,15 +65,16 @@
static void cli_display_parking_lot(int fd, const char *name)
{
- RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
+ RAII_VAR(struct parking_lot_state *, lot, NULL, ao2_cleanup);
struct ao2_iterator i;
struct parked_user *user;
int total = 0;
- lot = parking_lot_get(name);
+ lot = parking_lot_find_by_name(name);
/* If the parking lot couldn't be found with the search, also abort. */
if (!lot) {
+ ast_cli(fd, "Could not find parking lot '%s'\n\n", name);
return;
}
@@ -86,7 +87,7 @@
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->disabled ? "no" : "yes");
+ ast_cli(fd, "Enabled : %s\n", lot->parking_disabled ? "no" : "yes");
ast_cli(fd, "\n");
ast_cli(fd, "Parked Calls\n------------\n");
@@ -113,7 +114,7 @@
struct ao2_iterator *i;
void *o;
- i = parking_lot_iterator_create();
+ i = parking_lot_state_iterator_create();
if (!i) {
ast_cli(fd, "Parking Lot configuration is unavailable.\n");
@@ -121,7 +122,7 @@
}
while ((o = ao2_iterator_next(i))) {
- struct parking_lot *lot = o;
+ struct parking_lot_state *lot = o;
ast_cli(fd, "\n");
ast_cli(fd, "Parking lot: %s\n", lot->name);
ast_cli(fd, "------------\n");
@@ -133,12 +134,12 @@
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->disabled ? "no" : "yes");
+ ast_cli(fd, "Enabled : %s\n", lot->parking_disabled ? "no" : "yes");
ast_cli(fd, "\n");
ao2_ref(o, -1);
}
- parking_lot_iterator_destroy(i);
+ parking_lot_state_iterator_destroy(i);
}
/* \brief Parkinglots command show <name> */
@@ -147,7 +148,7 @@
int length;
int which;
struct ao2_iterator *i;
- struct parking_lot *lot;
+ struct parking_lot_state *lot;
char *match = NULL;
switch (cmd) {
@@ -160,7 +161,7 @@
case CLI_GENERATE:
length = strlen(a->word);
which = 0;
- i = parking_lot_iterator_create();
+ i = parking_lot_state_iterator_create();
while ((lot = ao2_iterator_next(i))) {
if (!strncasecmp(a->word, lot->name, length) && ++which > a->n) {
match = ast_strdup(lot->name);
@@ -169,7 +170,7 @@
}
ao2_ref(lot, -1);
}
- parking_lot_iterator_destroy(i);
+ parking_lot_state_iterator_destroy(i);
return match;
return NULL;
}
@@ -192,13 +193,13 @@
const char *id = astman_get_header(m, "ActionID");
char id_text[256] = "";
struct ao2_iterator *iter;
- struct parking_lot *curlot;
+ struct parking_lot_state *curlot;
if (!ast_strlen_zero(id)) {
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
}
- iter = parking_lot_iterator_create();
+ iter = parking_lot_state_iterator_create();
if (!iter) {
ast_log(LOG_ERROR, "Failed to create parking lot iterator. Action canceled.\n");
@@ -209,11 +210,11 @@
astman_send_ack(s, m, "Parking lots will follow");
while ((curlot = ao2_iterator_next(iter))) {
- publish_parking_lot(curlot);
+ publish_parking_lot_state(curlot);
ao2_ref(curlot, -1);
}
- parking_lot_iterator_destroy(iter);
+ parking_lot_state_iterator_destroy(iter);
return RESULT_SUCCESS;
}
@@ -225,13 +226,13 @@
char id_text[256] = "";
struct ao2_iterator *iter_lots;
struct ao2_iterator iter_users;
- struct parking_lot *curlot;
+ 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_iterator_create();
+ iter_lots = parking_lot_state_iterator_create();
if (!iter_lots) {
ast_log(LOG_ERROR, "Failed to create parking lot iterator. Action canceled.\n");
@@ -251,7 +252,7 @@
ao2_ref(curlot, -1);
}
- parking_lot_iterator_destroy(iter_lots);
+ parking_lot_state_iterator_destroy(iter_lots);
return RESULT_SUCCESS;
}
@@ -260,7 +261,7 @@
AST_CLI_DEFINE(handle_show_parking_lot_cmd, "Show a parking lot or a list of all parking lots."),
};
-int load_tools(void)
+int load_parking_ui(void)
{
int res;
@@ -271,7 +272,7 @@
return res ? -1 : 0;
}
-void unload_tools(void)
+void unload_parking_ui(void)
{
ast_cli_unregister_multiple(cli_parking_lot, ARRAY_LEN(cli_parking_lot));
ast_manager_unregister("Parkinglots");
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=383612&r1=383611&r2=383612
==============================================================================
--- team/jrose/bridge_projects/res/parking/res_parking.h (original)
+++ team/jrose/bridge_projects/res/parking/res_parking.h Fri Mar 22 14:28:49 2013
@@ -47,36 +47,34 @@
OPT_PARKEDRECORDING,
};
-struct parking_lot {
+struct parking_lot_state {
int parking_start;
int parking_stop;
+ int next_space;
unsigned int parkingtime;
unsigned int comebackdialtime;
-
unsigned int parkfindnext;
unsigned int parkext_exclusive;
unsigned int parkaddhints;
unsigned int comebacktoorigin;
-
- /* These all need to be handled by a special configuration handler */
int parkedplay;
int parkedcalltransfers;
int parkedcallreparking;
int parkedcallhangup;
int parkedcallrecording;
- /*! Next space should be... */
- int next_space;
-
- /*! Was this parking space created dynamically? (break down the parking lot once it empties) */
- int dynamic;
+ /* When a parking lot becomes unconfigured, this flag is raised to keep new calls from entering */
+ int parking_disabled;
/*! Which holding bridge the parking lot uses for placing calls */
struct ast_bridge *parking_bridge;
/*! Ordered list of active parkings in this parkinglot */
struct ao2_container *parked_user_list;
+
+ /*! Does this parking lot have a configuration that owns it? Used to determine if we should unlink ourselves from the global state list */
+ int has_owner;
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(name);
@@ -86,26 +84,85 @@
AST_STRING_FIELD(comebackcontext);
AST_STRING_FIELD(courtesytone);
);
-
- /*! Destroy unused parking lot on deletion marker */
- unsigned int the_mark:1;
- /*! TRUE if the parking lot is disabled */
- unsigned int disabled:1;
+};
+
+struct parking_lot_cfg {
+ int parking_start;
+ int parking_stop;
+
+ unsigned int parkingtime;
+ unsigned int comebackdialtime;
+
+ unsigned int parkfindnext;
+ unsigned int parkext_exclusive;
+ unsigned int parkaddhints;
+ unsigned int comebacktoorigin;
+
+ /* These all need to be handled by a special configuration handler */
+ int parkedplay;
+ int parkedcalltransfers;
+ int parkedcallreparking;
+ int parkedcallhangup;
+ int parkedcallrecording;
+
+ /*!
+ * State of the parkinglot
+ * Generated on creation of the parking lot
+ * Unlinked (and destroyed) when the parking lot is destroyed if and only if the parked call list is empty
+ * If not referenced by a parking lot, this will be destroyed when the last call is unparked
+ */
+ struct parking_lot_state *state;
+
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(name);
+ AST_STRING_FIELD(mohclass);
+ AST_STRING_FIELD(parkext);
+ AST_STRING_FIELD(parking_con);
+ AST_STRING_FIELD(comebackcontext);
+ AST_STRING_FIELD(courtesytone);
+ );
};
struct parked_user {
- struct ast_channel *chan; /*!< Parked channel */
- struct ast_channel_snapshot *parker; /*!< Snapshot of the channel that parked the call at the time of parking */
- struct timeval start; /*!< When the call was parked */
- int parking_space; /*!< Which parking space is used */
- char context[AST_MAX_CONTEXT]; /*!< Where to go on parking timeout (context) */
- char exten[AST_MAX_CONTEXT]; /*!< Where to go on parking timeout (extension) */
- unsigned int time_limit; /*!< How long this specific channel may remain in the parking lot before timing out */
- struct parking_lot *lot; /*!< Which parking lot the user is parked to */
- enum park_call_resolution resolution; /*!< How did the parking session end? */
-};
-
-/*!
+ struct ast_channel *chan; /*!< Parked channel */
+ struct ast_channel_snapshot *parker; /*!< Snapshot of the channel that parked the call at the time of parking */
+ struct timeval start; /*!< When the call was parked */
+ int parking_space; /*!< Which parking space is used */
+ char context[AST_MAX_CONTEXT]; /*!< Where to go on parking timeout (context) */
+ char exten[AST_MAX_CONTEXT]; /*!< Where to go on parking timeout (extension) */
+ unsigned int time_limit; /*!< How long this specific channel may remain in the parking lot before timing out */
+ struct parking_lot_state *lot_state; /*!< Which parking lot the user is parked to */
+ enum park_call_resolution resolution; /*!< How did the parking session end? */
+};
+
+/*!
+ * \since 12
+ * \brief If a parking lot state exists in the state list already, return a reference to it. Otherwise,
+ * create a parking lot state struct based on a parking lot configuration and return a reference
+ *
+ * \param lot The lot being used as a reference to build the parking lot state from.
+ *
+ * \retval A reference to the new parking lot state
+ * \retval NULL if it couldn't be allocated
+ *
+ * \note The state will need to be unreffed if it ever falls out of scope
+ * \note The state will automatically be added to the state container if needed as part of this process
+ */
+struct parking_lot_state *parking_lot_state_build_or_find(struct parking_lot_cfg *lot);
+
+/*!
+ * \since 12
+ * \brief Remove a parking lot from the usable lists if it is no longer involved in any calls and no configuration currently claims it
+ *
+ * \param lot Which parking lot state is being checked for elimination
+ *
+ * \note This should generally be called when something is happening that could cause a parking lot to die such as a call being unparked or
+ * a parking lot no longer existing in configurations.
+ */
+void parking_lot_remove_if_unused(struct parking_lot_state *lot);
+
+/*!
+ * \since 12
* \brief Get a reference to a parking lot's bridge. If it doesn't exist, create it and get a reference.
*
* \param lot Which parking lot we need the bridge from. This parking lot must be locked before calling this function.
@@ -115,32 +172,35 @@
*
* \note This bridge will need to be unreffed if it ever falls out of scope.
*/
-struct ast_bridge *get_parkinglot_bridge(struct parking_lot *lot);
-
-/*!
+struct ast_bridge *get_parkinglot_bridge(struct parking_lot_state *state);
+
+/*!
+ * \since 12
* \brief Get an available parking space within a parking lot.
*
* \param lot Which parking lot we are getting a space from
* \param target_override If there is a specific slot we want, provide it here and we'll start from that position
*
- * retval -1 if No slot can be found
- * retval integer value of parking space selected
+ * \retval -1 if No slot can be found
+ * \retval integer value of parking space selected
*
* \note lot should be locked before this is called and unlocked only after a parked_user with the space
* returned has been added to the parking lot.
*/
-int parking_lot_get_space(struct parking_lot *lot, int target_override);
-
-/*!
+int parking_lot_get_space(struct parking_lot_state *lot, int target_override);
+
+/*!
+ * \since 12
* \brief Set necessary bridge roles on a channel that is about to enter a parking lot
*
* \param chan Entering channel
- * \param lot The parking lot the channel will be entering
+ * \param lot_state The parking lot state the channel will be entering
* \param force_ringing Use ringing instead of music on hold
*/
-void parking_channel_set_roles(struct ast_channel *chan, struct parking_lot *lot, int force_ringing);
-
-/*!
+void parking_channel_set_roles(struct ast_channel *chan, struct parking_lot_state *lot_state, int force_ringing);
+
+/*!
+ * \since 12
* \brief Setup timeout interval feature on an ast_bridge_features for parking
*
* \param features The ast_bridge_features we are establishing the interval hook on
@@ -150,49 +210,54 @@
void parking_set_duration(struct ast_bridge_features *features, struct parked_user *user, int override_time);
/*!
- * \brief Create an iterator which will iterate through all configured parking_lot structs
- *
- * \retval iterator for parking lots if successful
+ * \since 12
+ * \brief Create an iterator which will iterate through all parking_lot_state structs
+ *
+ * \retval iterator for parking lot states if successful
* \retval NULL if the iterator could not be initialized
*
* \note If this succeeds, the iterator should be destroyed using parking_lot_iterator_destroy when it is no longer needed.
*/
-struct ao2_iterator *parking_lot_iterator_create(void);
-
-/*!
- * \brief Call this to free an iterator created by parking_lot_iterator_create
- */
-void parking_lot_iterator_destroy(struct ao2_iterator *iter);
-
-/*!
- * \brief Find a parking lot based on its name
- *
- * \param lot_name Name of the parking lot sought
- *
- * \retval The parking lot if found
- * \retval NULL if no parking lot with the name specified exists
- *
- * \note This reference will need to be free'd when you are done using it.
- */
-struct parking_lot *parking_lot_get(const char *lot_name);
-
-/*!
- * \brief Get the parkinglot that a channel should be parked in
- *
- * \param chan Channel which a parkinglot is sought for
- *
- * \retval The parking lot that the channel should go into
- * \retval NULL if the parking lot that the channel is designated to
- * enter does not exist.
- *
- * \note This reference will need to be free'd when you are done using it.
- */
-struct parking_lot *channel_find_parkinglot(struct ast_channel *chan);
-
-/*!
+struct ao2_iterator *parking_lot_state_iterator_create(void);
+
+/*!
+ * \since 12
+ * \brief Call this to free an iterator created by parking_lot_state_iterator_create
+ */
+void parking_lot_state_iterator_destroy(struct ao2_iterator *iter);
+
+/*!
+ * \since 12
+ * \brief Find a parking lot state based on its name
+ *
+ * \param lot_name Name of the parking lot state sought
+ *
+ * \retval The parking lot state if found
+ * \retval NULL if no parking lot state with the name specified exists
+ *
+ * \note ao2_cleanup this reference when you are done using it or you'll cause leaks.
+ */
+struct parking_lot_state *parking_lot_find_by_name(const char *lot_name);
+
+/*!
+ * \since 12
+ * \brief Get the parkinglot state that a channel should be parked in
+ *
+ * \param chan Channel which a parkinglot state is sought for
+ *
+ * \retval The parking lot state that the channel should go into
+ * \retval NULL if the parking lot state that the channel is designated to
+ * enter does not exist or can not accept parking lots
+ *
+ * \note ao2_cleanup this reference when you are done using it or you'll cause leaks.
+ */
+struct parking_lot_state *channel_find_parkinglot(struct ast_channel *chan);
+
+/*!
+ * \since 12
* \brief Create a parked user within the specified parking lot and get a reference to it.
*
- * \param lot The parking lot we are assigning the user to
+ * \param lot_state The parking lot state we are assigning the user to
* \param parkee The channel being parked
* \param parker The channel performing the park operation (may be the same channel)
* \param use_random_space if true, prioritize using a random parking space instead
@@ -204,11 +269,12 @@
* \retval NULL on failure
* \retval reference to the parked user
*
- * \note This reference will need to be free'd when you are done using it.
- */
-struct parked_user *generate_parked_user(struct parking_lot *lot, struct ast_channel *parkee, struct ast_channel *parker, int use_random_space, int time_limit);
-
-/*!
+ * \note ao2_cleanup this reference when you are done using it or you'll cause leaks.
+ */
+struct parked_user *generate_parked_user(struct parking_lot_state *lot_state, struct ast_channel *parkee, struct ast_channel *parker, int use_random_space, int time_limit);
+
+/*!
+ * \since 12
* \brief Reset the start time of a parked user to now
*
* \param pu Parked user having the time reset
@@ -221,17 +287,19 @@
void reset_parked_time(struct parked_user *pu);
/*!
+ * \since 12
* \brief Set a channel's position in the PBX after timeout using the parking lot settings
*
* \param pu Parked user who is entering/reentering the PBX
- * \param lot Parking lot the user was removed from.
+ * \param lot_state Parking lot state the user was removed from.
*
* \retval 0 Position set successfully
* \retval -1 Failed to set the position
*/
-int comeback_goto(struct parked_user *pu, struct parking_lot *lot);
-
-/*!
+int comeback_goto(struct parked_user *pu, struct parking_lot_state *lot_state);
+
+/*!
+ * \since 12
* \brief Pull a parked user out of its parking lot.
* \param user The parked user being pulled.
*
@@ -241,6 +309,7 @@
int unpark_parked_user(struct parked_user *user);
/*!
+ * \since 12
* \brief Publish a stasis parked call message for a given parked user
*
* \param pu pointer to a parked_user that we are generating the message for
@@ -249,27 +318,38 @@
void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type event_type);
/*!
- * \brief Publish a stasis parking lot message for a given parking lot
- *
- * \param lot pointer to a parking lot that we are generating the message for
- */
-void publish_parking_lot(struct parking_lot *lot);
-
-/*!
- * \brief Get a pointer to the Park application function.
- *
- * \retval Pointer to the Park application function
- */
-void *parking_get_park_app_cb(void);
-
-/*!
+ * \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);
+
+/*!
+ * \since 12
+ * \brief Execution function for the parking 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 parking application and not generally to park calls.
+ */
+int park_app_exec(struct ast_channel *chan, const char *data);
+
+/*!
+ * \since 12
* \brief Register CLI commands and manager actions
+ *
* \retval 0 if successful
* \retval -1 on failure
*/
-int load_tools(void);
-
-/*!
+int load_parking_ui(void);
+
+/*!
+ * \since 12
* \brief Unregister CLI commands and manager actions
*/
-void unload_tools(void);
+void unload_parking_ui(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=383612&r1=383611&r2=383612
==============================================================================
--- team/jrose/bridge_projects/res/res_parking.c (original)
+++ team/jrose/bridge_projects/res/res_parking.c Fri Mar 22 14:28:49 2013
@@ -50,6 +50,9 @@
</configOption>
<configOption name="parkingtime" default="45">
<synopsis>Amount of time a call will remain parked before giving up (in seconds).</synopsis>
+ </configOption>
+ <configOption name="parkedmusicclass">
+ <synopsis>Which music class to use for parked calls. They will use the default if unspecified.</synopsis>
</configOption>
<configOption name="comebacktoorigin" default="yes">
<synopsis>Determines what should be done with the parked channel if no one picks it up before it times out.</synopsis>
@@ -113,40 +116,36 @@
<synopsis>Who we should play the courtesytone to on the pickup of a parked call from this lot</synopsis>
<description>
<enumlist>
+ <enum name="no"><para>Apply to neither side.</para></enum>
<enum name="caller"><para>Apply to only to the caller picking up the parked call.</para></enum>
<enum name="callee"><para>Apply to only to the parked call being picked up.</para></enum>
<enum name="both"><para>Apply to both the caller and the callee.</para></enum>
</enumlist>
- <note><para>If courtesy tone is not specified then this option will be ignored. If any value not listed above
- is used then the coutesy tone will not be played to either side.</para></note>
- </description>
- </configOption>
- <configOption name="parkedcalltransfers" default="none">
+ <note><para>If courtesy tone is not specified then this option will be ignored.</para></note>
+ </description>
+ </configOption>
+ <configOption name="parkedcalltransfers" default="no">
<synopsis>Apply the DTMF transfer features to the caller and/or callee when parked calls are picked up.</synopsis>
<description>
<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedplay']/description/enumlist)" />
- <note><para>If any value not listed above is used, this feature is applied to neither side</para></note>
- </description>
- </configOption>
- <configOption name="parkedcallreparking" default="none">
+ </description>
+ </configOption>
+ <configOption name="parkedcallreparking" default="no">
<synopsis>Apply the DTMF parking feature to the caller and/or callee when parked calls are picked up.</synopsis>
<description>
<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedplay']/description/enumlist)" />
- <xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedcalltransfers']/description/note)" />
- </description>
- </configOption>
- <configOption name="parkedcallhangup" default="none">
+ </description>
+ </configOption>
+ <configOption name="parkedcallhangup" default="no">
<synopsis>Apply the DTMF Hangup feature to the caller and/or callee when parked calls are picked up.</synopsis>
<description>
<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedplay']/description/enumlist)" />
- <xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedcalltransfers']/description/note)" />
- </description>
- </configOption>
- <configOption name="parkedcallrecording" default="none">
+ </description>
+ </configOption>
+ <configOption name="parkedcallrecording" default="no">
<synopsis>Apply the DTMF recording features to the caller and/or callee when parked calls are picked up</synopsis>
<description>
<xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedplay']/description/enumlist)" />
- <xi:include xpointer="xpointer(/docs/configInfo[@name='res_parking']/configFile[@name='res_parking.conf']/configObject[@name='parking_lot']/configOption[@name='parkedcalltransfers']/description/note)" />
</description>
</configOption>
<configOption name="findslot" default="first">
@@ -182,55 +181,12 @@
#include "asterisk/features.h"
#include "asterisk/manager.h"
-static void *parking_lot_config_alloc(void);
-static void *parking_lot_alloc(const char *cat);
-static void *parking_lot_find(struct ao2_container *container, const char *cat);
-
-struct parking_global_config {
- int parkeddynamic; /* XXX This feature still needs to be implemented. Entirely. */
-};
-
-struct parking_lot_config {
- struct parking_global_config *global;
- struct ao2_container *parking_lot_list;
-};
-
-static struct aco_type global_option = {
- .type = ACO_GLOBAL,
- .name = "globals",
- .item_offset = offsetof(struct parking_lot_config, global),
- .category_match = ACO_WHITELIST,
- .category = "^general$",
-};
-
-struct aco_type *global_options[] = ACO_TYPES(&global_option);
-
-static struct aco_type parking_lot_type = {
- .type = ACO_ITEM,
- .name = "parking_lot",
- .category_match = ACO_BLACKLIST,
- .category = "^(general)$",
- .item_alloc = parking_lot_alloc,
- .item_find = parking_lot_find,
- .item_offset = offsetof(struct parking_lot_config, parking_lot_list),
-};
-
-struct aco_type *parking_lot_types[] = ACO_TYPES(&parking_lot_type);
-
-struct aco_file parking_lot_conf = {
- .filename = "res_parking.conf",
- .types = ACO_TYPES(&global_option, &parking_lot_type),
-};
-
-static AO2_GLOBAL_OBJ_STATIC(globals);
-
-CONFIG_INFO_STANDARD(cfg_info, globals, parking_lot_config_alloc,
- .files = ACO_FILES(&parking_lot_conf),
-);
-
-static int parking_lot_hash_fn(const void *obj, const int flags)
-{
- const struct parking_lot *entry;
+#define app_park "Park"
+#define app_parkedcall "ParkedCall"
+
[... 731 lines stripped ...]
More information about the asterisk-commits
mailing list