[asterisk-commits] jrose: branch jrose/bridge_projects r384114 - in /team/jrose/bridge_projects:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 27 13:35:28 CDT 2013
Author: jrose
Date: Wed Mar 27 13:35:24 2013
New Revision: 384114
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=384114
Log:
One army of findings later
Modified:
team/jrose/bridge_projects/include/asterisk/parking.h
team/jrose/bridge_projects/main/manager_channels.c
team/jrose/bridge_projects/main/parking.c
team/jrose/bridge_projects/res/parking/parking_applications.c
team/jrose/bridge_projects/res/parking/parking_controller.c
team/jrose/bridge_projects/res/parking/parking_manager.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/parking.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/parking.h?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/parking.h (original)
+++ team/jrose/bridge_projects/include/asterisk/parking.h Wed Mar 27 13:35:24 2013
@@ -22,3 +22,40 @@
*
* \author Jonathan Rose <jrose at digium.com>
*/
+
+#include "asterisk/stringfields.h"
+
+/*!
+ * \brief Defines the type of parked call message being published
+ * \since 12
+ */
+enum ast_parked_call_event_type {
+ PARKED_CALL = 0,
+ PARKED_CALL_TIMEOUT,
+ PARKED_CALL_GIVEUP,
+ PARKED_CALL_UNPARKED,
+};
+
+/*!
+ * \brief A parked call message payload
+ * \since 12
+ */
+struct ast_parked_call_payload {
+ struct ast_channel_snapshot *parkee;
+ struct ast_channel_snapshot *parker;
+ enum ast_parked_call_event_type event_type;
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(parkinglot);
+ AST_STRING_FIELD(parkingspace);
+ AST_STRING_FIELD(timeout);
+ AST_STRING_FIELD(duration);
+ );
+};
+
+/*! \brief Constructor for parked_call_payload objects */
+struct ast_parked_call_payload *ast_parked_call_payload_create(enum ast_parked_call_event_type event_type, struct ast_channel_snapshot *parkee_snapshot, struct ast_channel_snapshot *parker_snapshot, const char *parkinglot, int parkingspace, long int timeout, long int duration);
+
+void ast_parking_stasis_init(void);
+void ast_parking_stasis_disable(void);
+struct stasis_topic *ast_parking_topic(void);
+struct stasis_message_type *ast_parked_call_type(void);
Modified: team/jrose/bridge_projects/main/manager_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/manager_channels.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/main/manager_channels.c (original)
+++ team/jrose/bridge_projects/main/manager_channels.c Wed Mar 27 13:35:24 2013
@@ -182,9 +182,7 @@
"Context%s: %s\r\n"
"Exten%s: %s\r\n"
"Priority%s: %d\r\n"
- "Uniqueid%s: %s\r\n"
- "Cause%s: %d\r\n"
- "Cause-txt%s: %s\r\n",
+ "Uniqueid%s: %s\r\n",
suffix, snapshot->name,
suffix, snapshot->state,
suffix, ast_state2str(snapshot->state),
@@ -196,9 +194,8 @@
suffix, snapshot->context,
suffix, snapshot->exten,
suffix, snapshot->priority,
- suffix, snapshot->uniqueid,
- suffix, snapshot->hangupcause,
- suffix, ast_cause2str(snapshot->hangupcause));
+ suffix, snapshot->uniqueid
+ );
if (!res) {
return NULL;
Modified: team/jrose/bridge_projects/main/parking.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/parking.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/main/parking.c (original)
+++ team/jrose/bridge_projects/main/parking.c Wed Mar 27 13:35:24 2013
@@ -30,3 +30,74 @@
#include "asterisk/_private.h"
#include "asterisk/parking.h"
#include "asterisk/channel.h"
+
+/*! \brief Message type for parked calls */
+static struct stasis_message_type *parked_call_type;
+
+/*! \brief Topic for parking lots */
+static struct stasis_topic *parking_topic;
+
+void ast_parking_stasis_init(void)
+{
+ parked_call_type = stasis_message_type_create("ast_parked_call");
+ parking_topic = stasis_topic_create("ast_parking");
+}
+
+void ast_parking_stasis_disable(void)
+{
+ ao2_cleanup(parked_call_type);
+ ao2_cleanup(parking_topic);
+ parked_call_type = NULL;
+ parking_topic = NULL;
+}
+
+struct stasis_topic *ast_parking_topic(void)
+{
+ return parking_topic;
+}
+
+struct stasis_message_type *ast_parked_call_type(void)
+{
+ return parked_call_type;
+}
+
+/*! \brief Destructor for parked_call_payload objects */
+static void parked_call_payload_destructor(void *obj)
+{
+ struct ast_parked_call_payload *park_obj = obj;
+
+ ao2_cleanup(park_obj->parkee);
+ ao2_cleanup(park_obj->parker);
+ ast_string_field_free_memory(park_obj);
+}
+
+struct ast_parked_call_payload *ast_parked_call_payload_create(enum ast_parked_call_event_type event_type, struct ast_channel_snapshot *parkee_snapshot, struct ast_channel_snapshot *parker_snapshot, const char *parkinglot, int parkingspace, long int timeout, long int duration)
+{
+ RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
+
+ payload = ao2_alloc(sizeof(*payload), parked_call_payload_destructor);
+ if (!payload) {
+ return NULL;
+ }
+
+ if (ast_string_field_init(payload, 32)) {
+ return NULL;
+ }
+
+ payload->event_type = event_type;
+
+ ao2_ref(parkee_snapshot, +1);
+ payload->parkee = parkee_snapshot;
+
+ ao2_ref(parker_snapshot, +1);
+ payload->parker = parker_snapshot;
+
+ ast_string_field_set(payload, parkinglot, parkinglot);
+ ast_string_field_build(payload, parkingspace, "%d", parkingspace);
+ ast_string_field_build(payload, timeout, "%ld", timeout);
+ ast_string_field_build(payload, duration, "%ld", duration);
+
+ /* Bump the ref count by one since RAII_VAR is going to eat one when we leave. */
+ ao2_ref(payload, +1);
+ return payload;
+}
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=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_applications.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_applications.c Wed Mar 27 13:35:24 2013
@@ -171,9 +171,9 @@
}
if (ast_strlen_zero(args.lot_name)) {
- lot = channel_find_parkinglot(chan);
+ lot = channel_find_parking_lot_state(chan);
} else {
- lot = parking_lot_find_by_name(args.lot_name);
+ lot = parking_lot_state_find_by_name(args.lot_name);
}
if (!lot) {
@@ -182,7 +182,7 @@
}
ao2_lock(lot);
- parking_bridge = get_parkinglot_bridge(lot);
+ parking_bridge = parking_lot_state_get_bridge(lot);
ao2_unlock(lot);
if (!parking_bridge) {
@@ -220,10 +220,12 @@
/* At this point the channel is no longer in the bridge. Start breaking things down. */
ast_bridge_features_cleanup(&chan_features);
- /* If the parked channel exits without a resolution set, it gave up. Issue a ParkedCallGiveUp message. */
+ /* If the parked channel exits without a resolution set, it gave up. Issue a ParkedCallGiveUp message and exit early. */
if (pu->resolution == PARK_UNSET) {
pu->resolution = PARK_ABANDON;
publish_parked_call(pu, PARKED_CALL_GIVEUP);
+ unpark_parked_user(pu);
+ return -1;
}
unpark_parked_user(pu);
@@ -239,7 +241,7 @@
}
}
- /* 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. */
+ /* Since this is executed from pbx, it'll automatically bump the priority when we return. We can address that by reducing it by 1 before returning. Smooth. */
ast_channel_priority_set(chan, ast_channel_priority(chan) - 1);
return ast_check_hangup_locked(chan) ? -1 : 0;
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=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Wed Mar 27 13:35:24 2013
@@ -18,7 +18,7 @@
/*! \file
*
- * \brief Parking Entry, Exit, Events, and other assorted controls.
+ * \brief Parking Entry, Exit, and other assorted controls.
*
* \author Jonathan Rose <jrose at digium.com>
*/
@@ -31,7 +31,7 @@
#include "asterisk/manager.h"
#include "asterisk/test.h"
-struct ast_bridge *get_parkinglot_bridge(struct parking_lot_state *state)
+struct ast_bridge *parking_lot_state_get_bridge(struct parking_lot_state *state)
{
struct ast_bridge *lot_bridge;
@@ -41,7 +41,7 @@
}
/* XXX Richard has changed some things here. Need to implement subclass of bridge as part of the next phase */
- lot_bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM);
+ lot_bridge = bridge_parking_new(state);
if (!lot_bridge) {
return NULL;
}
@@ -137,7 +137,7 @@
{
if (pu->lot_state) {
ao2_unlink(pu->lot_state->parked_user_list, pu);
- parking_lot_remove_if_unused(pu->lot_state);
+ parking_lot_state_remove_if_unused(pu->lot_state);
pu->lot_state = NULL;
return 0;
}
@@ -169,7 +169,7 @@
}
}
-int parking_lot_get_space(struct parking_lot_state *lot, int target_override)
+int parking_lot_state_get_space(struct parking_lot_state *lot, int target_override)
{
int original_target;
int current_target;
@@ -335,10 +335,10 @@
}
}
- /* 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. */
+ /* We need to keep the lot state locked between parking_lot_state_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);
+ parking_space = parking_lot_state_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_state->name);
ao2_ref(new_parked_user, -1);
Modified: team/jrose/bridge_projects/res/parking/parking_manager.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_manager.c?view=diff&rev=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_manager.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_manager.c Wed Mar 27 13:35:24 2013
@@ -63,88 +63,37 @@
</manager>
***/
-/*! \brief Message type for parked calls */
-static struct stasis_message_type *parked_call_message_type;
-
-/*! \brief Topic for parking lots */
-static struct stasis_topic *parking_topic;
-
/*! \brief subscription to the parking lot topic */
static struct stasis_subscription *parking_sub;
-/*!
- * \brief A parked call message payload
- * \since 12
- */
-struct parked_call_payload {
- struct ast_channel_snapshot *parkee;
- struct ast_channel_snapshot *parker;
- enum parked_call_event_type event_type;
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(parkinglot);
- AST_STRING_FIELD(parkingspace);
- AST_STRING_FIELD(timeout);
- AST_STRING_FIELD(duration);
- );
-};
-
-/*! \brief Destructor for parked_call_payload objects */
-static void parked_call_payload_destructor(void *obj)
-{
- struct parked_call_payload *park_obj = obj;
-
- ao2_cleanup(park_obj->parkee);
- ao2_cleanup(park_obj->parker);
- ast_string_field_free_memory(park_obj);
-}
-
-/*! \brief Constructor for parked_call_payload objects */
-static struct parked_call_payload *parked_call_payload_create(struct parked_user *pu, enum parked_call_event_type event_type)
-{
- struct parked_call_payload *payload;
- char timeout_text[32] = "";
+static struct ast_parked_call_payload *parked_call_payload_from_parked_user(struct parked_user *pu, enum ast_parked_call_event_type event_type)
+{
+ RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_channel_snapshot *, parkee_snapshot, NULL, ao2_cleanup);
+ long int timeout;
+ long int duration;
struct timeval now = ast_tvnow();
-
- payload = ao2_alloc(sizeof(*payload), parked_call_payload_destructor);
- if (!payload) {
- return NULL;
- }
-
- if (ast_string_field_init(payload, 32)) {
- ao2_cleanup(payload);
- return NULL;
- }
-
- payload->parkee = ast_channel_snapshot_create(pu->chan);
- if (!payload->parkee) {
- ao2_cleanup(payload);
- return NULL;
- }
-
- payload->event_type = event_type;
+ const char *lot_name = pu->lot_state->name;
if (!pu->parker) {
return NULL;
}
- ao2_ref(pu->parker, +1);
- payload->parker = pu->parker;
-
- if (!pu->time_limit) {
- snprintf(timeout_text, sizeof(timeout_text), "(no time limit)");
- } else {
- snprintf(timeout_text, sizeof(timeout_text), "%ld", pu->start.tv_sec + (long) pu->time_limit - now.tv_sec);
- }
-
- ast_string_field_set(payload, parkinglot, pu->lot_state->name);
- ast_string_field_build(payload, parkingspace, "%d", pu->parking_space);
- ast_string_field_set(payload, timeout, timeout_text);
- ast_string_field_build(payload, duration, "%ld", now.tv_sec - pu->start.tv_sec);
-
- return payload;
+
+ parkee_snapshot = ast_channel_snapshot_create(pu->chan);
+
+ if (!parkee_snapshot) {
+ return NULL;
+ }
+
+ timeout = pu->start.tv_sec + (long) pu->time_limit - now.tv_sec;
+ duration = now.tv_sec - pu->start.tv_sec;
+
+ return ast_parked_call_payload_create(event_type, parkee_snapshot, pu->parker, lot_name, pu->parking_space, timeout, duration);
+
}
/*! \brief Builds a manager string based on the contents of a parked call payload */
-static struct ast_str *manager_build_parked_call_string(const struct parked_call_payload *payload)
+static struct ast_str *manager_build_parked_call_string(const struct ast_parked_call_payload *payload)
{
struct ast_str *out = ast_str_create(1024);
int res = 0;
@@ -185,7 +134,8 @@
struct parked_user *curuser;
const char *id = astman_get_header(m, "ActionID");
char id_text[256] = "";
- struct ao2_iterator *iter_lots;
+ struct ao2_container *lot_container;
+ struct ao2_iterator iter_lots;
struct ao2_iterator iter_users;
struct parking_lot_state *curlot;
int total = 0;
@@ -194,22 +144,24 @@
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
}
- iter_lots = parking_lot_state_iterator_create();
-
- if (!iter_lots) {
- ast_log(LOG_ERROR, "Failed to create parking lot iterator. Action canceled.\n");
+ lot_container = get_parking_lot_state_container();
+
+ if (!lot_container) {
+ ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
astman_send_error(s, m, "Could not create parking lot list");
return -1;
}
+ iter_lots = ao2_iterator_init(lot_container, 0);
+
astman_send_ack(s, m, "Parked calls will follow");
- while ((curlot = ao2_iterator_next(iter_lots))) {
+ while ((curlot = ao2_iterator_next(&iter_lots))) {
iter_users = ao2_iterator_init(curlot->parked_user_list, 0);
while ((curuser = ao2_iterator_next(&iter_users))) {
- RAII_VAR(struct parked_call_payload *, payload, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
- payload = parked_call_payload_create(curuser, PARKED_CALL);
+ payload = parked_call_payload_from_parked_user(curuser, PARKED_CALL);
parked_call_string = manager_build_parked_call_string(payload);
total++;
@@ -226,7 +178,7 @@
ao2_ref(curlot, -1);
}
- parking_lot_state_iterator_destroy(iter_lots);
+ ao2_iterator_destroy(&iter_lots);
astman_append(s,
"Event: ParkedCallsComplete\r\n"
@@ -238,43 +190,62 @@
return RESULT_SUCCESS;
}
-static int manager_parkinglot_list(struct mansession *s, const struct message *m)
+static void manager_append_event_parking_lot(struct mansession *s, struct parking_lot_state *curlot, char *id_text)
+{
+ astman_append(s, "Event: Parkinglot\r\n"
+ "Name: %s\r\n"
+ "StartSpace: %d\r\n"
+ "StopSpace: %d\r\n"
+ "Timeout: %d\r\n"
+ "%s" /* The Action ID */
+ "\r\n",
+ curlot->name,
+ curlot->parking_start,
+ curlot->parking_stop,
+ curlot->parkingtime,
+ id_text);
+}
+
+struct manager_append_event_cb_data {
+ struct mansession *s;
+ char *id_text;
+};
+
+static int manager_append_event_parking_lot_cb(void *obj, void *arg, int flags)
+{
+ struct parking_lot_state *lot = obj;
+ struct manager_append_event_cb_data *data = arg;
+ struct mansession *s = data->s;
+ char *id_text = data->id_text;
+ manager_append_event_parking_lot(s, lot, id_text);
+ return 0;
+}
+
+static int manager_parking_lot_list(struct mansession *s, const struct message *m)
{
const char *id = astman_get_header(m, "ActionID");
char id_text[256] = "";
- struct ao2_iterator *iter;
- struct parking_lot_state *curlot;
+ struct ao2_container *lot_container;
+ struct manager_append_event_cb_data cb_data = {
+ .s = s,
+ .id_text = id_text,
+ };
if (!ast_strlen_zero(id)) {
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
}
- iter = parking_lot_state_iterator_create();
-
- if (!iter) {
- ast_log(LOG_ERROR, "Failed to create parking lot iterator. Action canceled.\n");
+ lot_container = get_parking_lot_state_container();
+
+ if (!lot_container) {
+ ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
astman_send_error(s, m, "Could not create parking lot list");
return -1;
}
astman_send_ack(s, m, "Parking lots will follow");
- while ((curlot = ao2_iterator_next(iter))) {
- astman_append(s, "Event: Parkinglot\r\n"
- "Name: %s\r\n"
- "StartSpace: %d\r\n"
- "StopSpace: %d\r\n"
- "Timeout: %d\r\n"
- "\r\n",
- curlot->name,
- curlot->parking_start,
- curlot->parking_stop,
- curlot->parkingtime);
-
- ao2_ref(curlot, -1);
- }
-
- parking_lot_state_iterator_destroy(iter);
+ ao2_callback(lot_container, OBJ_MULTIPLE | OBJ_NODATA, manager_append_event_parking_lot_cb, &cb_data);
astman_append(s,
"Event: ParkinglotsComplete\r\n"
@@ -284,27 +255,27 @@
return RESULT_SUCCESS;
}
-void publish_parked_call(struct parked_user *pu, enum parked_call_event_type event_type)
-{
- RAII_VAR(struct parked_call_payload *, payload, NULL, ao2_cleanup);
+void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type event_type)
+{
+ RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
- payload = parked_call_payload_create(pu, event_type);
+ payload = parked_call_payload_from_parked_user(pu, event_type);
if (!payload) {
return;
}
- msg = stasis_message_create(parked_call_message_type, payload);
+ msg = stasis_message_create(ast_parked_call_type(), payload);
if (!msg) {
return;
}
if (pu->chan) {
- stasis_publish(parking_topic, msg);
- }
-}
-
-static void parked_call_message_response(struct parked_call_payload *parked_call)
+ stasis_publish(ast_parking_topic(), msg);
+ }
+}
+
+static void parked_call_message_response(struct ast_parked_call_payload *parked_call)
{
char *event_type;
RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
@@ -334,8 +305,8 @@
static void parking_event_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
{
- if (stasis_message_type(message) == parked_call_message_type) {
- struct parked_call_payload *parked_call_message = stasis_message_data(message);
+ if (stasis_message_type(message) == ast_parked_call_type()) {
+ struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
parked_call_message_response(parked_call_message);
}
}
@@ -343,24 +314,20 @@
static void parking_manager_disable_stasis(void)
{
parking_sub = stasis_unsubscribe(parking_sub);
- ao2_cleanup(parked_call_message_type);
- ao2_cleanup(parking_topic);
- parked_call_message_type = NULL;
- parking_topic = NULL;
+ ast_parking_stasis_disable();
}
int load_parking_manager(void)
{
int res;
- res = ast_manager_register_xml_core("Parkinglots", 0, manager_parkinglot_list);
+ res = ast_manager_register_xml_core("Parkinglots", 0, manager_parking_lot_list);
res |= ast_manager_register_xml_core("ParkedCalls", 0, manager_parking_status);
- parked_call_message_type = stasis_message_type_create("parked_call");
- parking_topic = stasis_topic_create("ast_parking_topic");
+ ast_parking_stasis_init();
if (!parking_sub) {
- parking_sub = stasis_subscribe(parking_topic, parking_event_cb, NULL);
+ parking_sub = stasis_subscribe(ast_parking_topic(), parking_event_cb, NULL);
}
return res ? -1 : 0;
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=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_ui.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_ui.c Wed Mar 27 13:35:24 2013
@@ -38,14 +38,48 @@
#include "asterisk/features.h"
#include "asterisk/manager.h"
+static void display_parked_call(struct parked_user *user, int fd)
+{
+ ast_cli(fd, " Space: %d\n", user->parking_space);
+ ast_cli(fd, " Channel: %s\n", ast_channel_name(user->chan));
+ ast_cli(fd, "\n");
+}
+
+static int display_parked_users_cb(void *obj, void *arg, int flags)
+{
+ int *fd = arg;
+ struct parked_user *user = obj;
+ display_parked_call(user, *fd);
+ return 0;
+}
+
+static void display_parking_lot_state(struct parking_lot_state *lot, int fd)
+{
+ ast_cli(fd, "Parking Lot: %s\n--------------------------------------------------------------------------\n", lot->name);
+ ast_cli(fd, "Parking Extension : %s\n", lot->parkext);
+ ast_cli(fd, "Parking Context : %s\n", lot->parking_con);
+ ast_cli(fd, "Parking Spaces : %d-%d\n", lot->parking_start, lot->parking_stop);
+ ast_cli(fd, "Parking Time : %u sec\n", lot->parkingtime);
+ ast_cli(fd, "Comeback to Origin : %s\n", lot->comebacktoorigin ? "yes" : "no");
+ ast_cli(fd, "Comeback Context : %s%s\n", lot->comebackcontext, lot->comebacktoorigin ? " (comebacktoorigin=yes, not used)" : "");
+ ast_cli(fd, "Comeback Dial Time : %u sec\n", lot->comebackdialtime);
+ ast_cli(fd, "MusicOnHold Class : %s\n", lot->mohclass);
+ ast_cli(fd, "Enabled : %s\n", lot->parking_disabled ? "no" : "yes");
+ ast_cli(fd, "\n");
+}
+
+static int display_parking_lot_state_cb(void *obj, void *arg, int flags)
+{
+ int *fd = arg;
+ struct parking_lot_state *lot = obj;
+ display_parking_lot_state(lot, *fd);
+ return 0;
+}
+
static void cli_display_parking_lot(int fd, const char *name)
{
RAII_VAR(struct parking_lot_state *, lot, NULL, ao2_cleanup);
- struct ao2_iterator i;
- struct parked_user *user;
- int total = 0;
-
- lot = parking_lot_find_by_name(name);
+ lot = parking_lot_state_find_by_name(name);
/* If the parking lot couldn't be found with the search, also abort. */
if (!lot) {
@@ -53,68 +87,33 @@
return;
}
- ast_cli(fd, "\nParking Lot: %s\n------------------------------------------------------------------------\n", name);
- ast_cli(fd, "Parking Extension : %s\n", lot->parkext);
- ast_cli(fd, "Parking Context : %s\n", lot->parking_con);
- ast_cli(fd, "Parking Spaces : %d-%d\n", lot->parking_start, lot->parking_stop);
- ast_cli(fd, "Parking Time : %u sec\n", lot->parkingtime);
- ast_cli(fd, "Comeback to Origin : %s\n", lot->comebacktoorigin ? "yes" : "no");
- ast_cli(fd, "Comeback Context : %s%s\n", lot->comebackcontext, lot->comebacktoorigin ? " (comebacktoorigin=yes, not used)" : "");
- ast_cli(fd, "Comeback Dial Time : %u sec\n", lot->comebackdialtime);
- ast_cli(fd, "MusicOnHold Class : %s\n", lot->mohclass);
- ast_cli(fd, "Enabled : %s\n", lot->parking_disabled ? "no" : "yes");
- ast_cli(fd, "\n");
+ display_parking_lot_state(lot, fd);
+
ast_cli(fd, "Parked Calls\n------------\n");
- i = ao2_iterator_init(lot->parked_user_list, 0);
- while ((user = ao2_iterator_next(&i))) {
- ast_cli(fd, " Space: %d\n", user->parking_space);
- ast_cli(fd, " Channel: %s\n", ast_channel_name(user->chan));
- ast_cli(fd, "\n");
- ao2_ref(user, -1);
- total++;
- }
- ao2_iterator_destroy(&i);
-
- if (!total) {
+ if (!ao2_container_count(lot->parked_user_list)) {
ast_cli(fd, " (none)\n");
- ast_cli(fd, "\n");
+ ast_cli(fd, "\n\n");
+ return;
}
+ ao2_callback(lot->parked_user_list, OBJ_MULTIPLE | OBJ_NODATA, display_parked_users_cb, &fd);
ast_cli(fd, "\n");
}
static void cli_display_parking_lot_list(int fd)
{
- struct ao2_iterator *i;
- void *o;
+ struct ao2_container *lot_container;
- i = parking_lot_state_iterator_create();
+ lot_container = get_parking_lot_state_container();
- if (!i) {
- ast_cli(fd, "Parking Lot configuration is unavailable.\n");
+ if (!lot_container) {
+ ast_cli(fd, "Failed to obtain parking lot list.\n\n");
return;
}
- while ((o = ao2_iterator_next(i))) {
- struct parking_lot_state *lot = o;
- ast_cli(fd, "\n");
- ast_cli(fd, "Parking lot: %s\n", lot->name);
- ast_cli(fd, "------------\n");
- ast_cli(fd, "Parking Extension : %s\n", lot->parkext);
- ast_cli(fd, "Parking Context : %s\n", lot->parking_con);
- ast_cli(fd, "Parking Spaces : %d-%d\n", lot->parking_start, lot->parking_stop);
- ast_cli(fd, "Parking Time : %u sec\n", lot->parkingtime);
- ast_cli(fd, "Comeback to Origin : %s\n", lot->comebacktoorigin ? "yes" : "no");
- ast_cli(fd, "Comeback Context : %s%s\n", lot->comebackcontext, lot->comebacktoorigin ? " (comebacktoorigin=yes, not used)" : "");
- ast_cli(fd, "Comeback Dial Time : %u sec\n", lot->comebackdialtime);
- ast_cli(fd, "MusicOnHold Class : %s\n", lot->mohclass);
- ast_cli(fd, "Enabled : %s\n", lot->parking_disabled ? "no" : "yes");
- ast_cli(fd, "\n");
- ao2_ref(o, -1);
- }
-
- parking_lot_state_iterator_destroy(i);
+ ao2_callback(lot_container, OBJ_MULTIPLE | OBJ_NODATA, display_parking_lot_state_cb, &fd);
+ ast_cli(fd, "\n");
}
/* \brief Parkinglots command show <name> */
@@ -122,7 +121,8 @@
{
int length;
int which;
- struct ao2_iterator *i;
+ struct ao2_container *lot_container;
+ struct ao2_iterator iter;
struct parking_lot_state *lot;
char *match = NULL;
@@ -136,8 +136,16 @@
case CLI_GENERATE:
length = strlen(a->word);
which = 0;
- i = parking_lot_state_iterator_create();
- while ((lot = ao2_iterator_next(i))) {
+
+ lot_container = get_parking_lot_state_container();
+
+ if (!lot_container) {
+ /* This should never be possible, but if it is, there certainly aren't any parking lots to look at */
+ return NULL;
+ }
+
+ iter = ao2_iterator_init(lot_container, 0);
+ while ((lot = ao2_iterator_next(&iter))) {
if (!strncasecmp(a->word, lot->name, length) && ++which > a->n) {
match = ast_strdup(lot->name);
ao2_ref(lot, -1);
@@ -145,10 +153,12 @@
}
ao2_ref(lot, -1);
}
- parking_lot_state_iterator_destroy(i);
+ ao2_iterator_destroy(&iter);
+
return match;
- return NULL;
}
+
+ ast_cli(a->fd, "\n");
if (a->argc == 2) {
cli_display_parking_lot_list(a->fd);
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=384114&r1=384113&r2=384114
==============================================================================
--- team/jrose/bridge_projects/res/parking/res_parking.h (original)
+++ team/jrose/bridge_projects/res/parking/res_parking.h Wed Mar 27 13:35:24 2013
@@ -34,7 +34,7 @@
enum park_call_resolution {
PARK_UNSET = 0, /*! Nothing set a resolution. This should never be observed in practice. */
PARK_ABANDON, /*! The channel for the parked call hung up */
- PARK_TIMEOUT, /*! The parked call stayed parked until the parkinglot timeout was reached and was removed */
+ PARK_TIMEOUT, /*! The parked call stayed parked until the parking lot timeout was reached and was removed */
PARK_FORCED, /*! The parked call was forcibly terminated by an unusual means in Asterisk */
PARK_ANSWERED, /*! The parked call was retrieved successfully */
};
@@ -48,90 +48,69 @@
};
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;
- int parkedplay;
- int parkedcalltransfers;
- int parkedcallreparking;
- int parkedcallhangup;
- int parkedcallrecording;
-
- /* 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;
+ int parking_start; /*!< First space in the parking lot */
+ int parking_stop; /*!< Last space in the parking lot */
+ int next_space; /*!< When using parkfindnext, which space we should start searching from next time we park */
+
+ unsigned int parkingtime; /*!< Analogous to parkingtime config option */
+ unsigned int comebackdialtime; /*!< Analogous to comebackdialtime config option */
+ unsigned int parkfindnext; /*!< Analogous to parkfindnext config option */
+ unsigned int parkext_exclusive; /*!< Analogous to parkext_exclusive config option */
+ unsigned int parkaddhints; /*!< Analogous to parkaddhints config option */
+ unsigned int comebacktoorigin; /*!< Analogous to comebacktoorigin config option */
+ int parkedplay; /*!< Analogous to parkedplay config option */
+ int parkedcalltransfers; /*!< Analogous to parkedcalltransfers config option */
+ int parkedcallreparking; /*!< Analogous to parkedcallreparking config option */
+ int parkedcallhangup; /*!< Analogous to parkedcallhangup config option */
+ int parkedcallrecording; /*!< Analogous to parkedcallrecording config option */
+
+ int parking_disabled; /*!< Used for reloading, keeps calls from being parked to a parking lot removed from configs */
+ struct ast_bridge *parking_bridge; /*!< Bridged where parked calls will rest until they are answered or otherwise leave */
+ struct ao2_container *parked_user_list; /*!< List of parked users rigidly ordered by their parking space */
+
+ int has_owner; /*!< Used for reloading, marks a parking lot to be removed from the list of parking lots when
+ * its last parked call has departed the parking_brige.
+ */
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);
+ AST_STRING_FIELD(name); /*!< Name of the parking lot state object */
+ AST_STRING_FIELD(mohclass); /*!< Analogous to mohclass config option */
+ AST_STRING_FIELD(parkext); /*!< Analogous to parkext config option */
+ AST_STRING_FIELD(parking_con); /*!< Analogous to context config option */
+ AST_STRING_FIELD(comebackcontext); /*!< Analogous to comebackcontext config option */
+ AST_STRING_FIELD(courtesytone); /*!< Analogous to courtesytone config option */
);
};
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;
+ int parking_start; /*!< First space in the parking lot */
+ int parking_stop; /*!< Last space in the parking lot */
+
+ unsigned int parkingtime; /*!< Analogous to parkingtime config option */
+ unsigned int comebackdialtime; /*!< Analogous to comebackdialtime config option */
+ unsigned int parkfindnext; /*!< Analogous to parkfindnext config option */
+ unsigned int parkext_exclusive; /*!< Analogous to parkext_exclusive config option */
+ unsigned int parkaddhints; /*!< Analogous to parkaddhints config option */
+ unsigned int comebacktoorigin; /*!< Analogous to comebacktoorigin config option */
+ int parkedplay; /*!< Analogous to parkedplay config option */
+ int parkedcalltransfers; /*!< Analogous to parkedcalltransfers config option */
+ int parkedcallreparking; /*!< Analogous to parkedcallreparking config option */
+ int parkedcallhangup; /*!< Analogous to parkedcallhangup config option */
+ int parkedcallrecording; /*!< Analogous to parkedcallrecording config option */
+
+ struct parking_lot_state *state; /*!< State of the parking lot, generated on creation of the parking lot and
+ * unlinked from the parking lot and destroyed if and only if its call list
+ * is empty and it is removed from configuration.
+ */
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);
+ AST_STRING_FIELD(name); /*!< Name of the parking lot configuration object */
+ AST_STRING_FIELD(mohclass); /*!< Analogous to mohclass config option */
+ AST_STRING_FIELD(parkext); /*!< Analogous to parkext config option */
+ AST_STRING_FIELD(parking_con); /*!< Analogous to context config option */
+ AST_STRING_FIELD(comebackcontext); /*!< Analogous to comebackcontext config option */
+ AST_STRING_FIELD(courtesytone); /*!< Analogous to courtesytone config option */
);
-};
-
-/*!
- * \brief Defines the type of parked call message being published
- * \since 12
- */
-enum parked_call_event_type {
- PARKED_CALL = 0,
- PARKED_CALL_TIMEOUT,
- PARKED_CALL_GIVEUP,
- PARKED_CALL_UNPARKED,
};
struct parked_user {
@@ -148,18 +127,19 @@
/*!
* \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
+ * \brief If a parking lot state exists in the state list already, update its status to match the provided
+ * configuration and return a reference return a reference to it. Otherwise, create a parking lot
+ * state struct based on a parking lot configuration and return a reference to the new one.
*
* \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
+ * \retval NULL if it was not found and could not be 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);
+struct parking_lot_state *parking_lot_state_build_or_update(struct parking_lot_cfg *lot);
/*!
* \since 12
@@ -170,7 +150,18 @@
* \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);
+void parking_lot_state_remove_if_unused(struct parking_lot_state *lot);
+
+/*!
+ * \since 12
+ * \brief Create a new parking bridge
+ *
+ * \param bridge_lot Parking lot which the new bridge should be based on
+ *
+ * \retval NULL if the bridge can not be created
+ * \retval Newly created parking bridge
+ */
+struct ast_bridge *bridge_parking_new(struct parking_lot_state *bridge_lot);
/*!
* \since 12
@@ -183,7 +174,7 @@
*
* \note This bridge will need to be unreffed if it ever falls out of scope.
*/
-struct ast_bridge *get_parkinglot_bridge(struct parking_lot_state *state);
+struct ast_bridge *parking_lot_state_get_bridge(struct parking_lot_state *state);
/*!
* \since 12
@@ -198,7 +189,7 @@
* \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_state *lot, int target_override);
+int parking_lot_state_get_space(struct parking_lot_state *lot, int target_override);
/*!
* \since 12
@@ -222,21 +213,11 @@
/*!
* \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_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);
-
+ * \brief Get a pointer to the parking lot state container for purposes such as iteration
+ *
+ * \retval pointer to the parking lot state container.
+ */
+struct ao2_container *get_parking_lot_state_container(void);
/*!
* \since 12
* \brief Find a parking lot state based on its name
@@ -248,13 +229,13 @@
*
* \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
+struct parking_lot_state *parking_lot_state_find_by_name(const char *lot_name);
+
+/*!
+ * \since 12
+ * \brief Get the parking lot state that a channel should be parked in
+ *
+ * \param chan Channel which a parking lot state is sought for
*
* \retval The parking lot state that the channel should go into
[... 169 lines stripped ...]
More information about the asterisk-commits
mailing list