[asterisk-commits] jrose: branch jrose/bridge_projects r383481 - in /team/jrose/bridge_projects:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 20 16:22:06 CDT 2013
Author: jrose
Date: Wed Mar 20 16:22:03 2013
New Revision: 383481
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383481
Log:
Getting ready to split parking lots and parking lot state
Modified:
team/jrose/bridge_projects/include/asterisk/parking.h
team/jrose/bridge_projects/main/manager.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/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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/parking.h (original)
+++ team/jrose/bridge_projects/include/asterisk/parking.h Wed Mar 20 16:22:03 2013
@@ -26,7 +26,7 @@
#include "asterisk/stringfields.h"
/*! \brief Defines the type of parked call message */
-enum parked_call_event_type {
+enum ast_parked_call_event_type {
PARKED_CALL = 0,
PARKED_CALL_TIMEOUT,
PARKED_CALL_GIVEUP,
@@ -37,18 +37,15 @@
* \brief A parked call message payload
* \since 12
*/
-struct parked_call_payload {
+struct ast_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;
+ 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);
- AST_STRING_FIELD(list);
);
};
@@ -56,37 +53,56 @@
* \brief A parking lot message payload
* \since 12
*/
-struct parking_lot_payload {
- int list_item;
- int list_size;
+struct ast_parking_lot_payload {
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(name);
AST_STRING_FIELD(starting_space);
AST_STRING_FIELD(ending_space);
AST_STRING_FIELD(timeout);
- AST_STRING_FIELD(list);
);
};
/*!
+ * \brief Create a blank parked call payload and get a reference to it
* \since 12
+ *
+ * \retval NULL if the payload could not be allocated
+ * \retval reference to the payload object
+ *
+ * \note This reference should be free'd when it is no longer in use.
+ */
+struct ast_parked_call_payload *ast_parked_call_payload_create(void);
+
+/*!
+ * \brief Create a blank parking lot payload and get a reference to it
+ * \since 12
+ *
+ * \retval NULL if the payload could not be allocated
+ * \retval reference to the payload object
+ *
+ * \note This reference should be free'd when it is no longer in use.
+ */
+struct ast_parking_lot_payload *ast_parking_lot_payload_create(void);
+
+/*!
* \brief Message type for \ref ast_parked_call
+ * \since 12
*
* \retval Message type for \ref ast_parked_call
*/
struct stasis_message_type *ast_parked_call(void);
/*!
+ * \brief Message type for \ref ast_parking_lot
* \since 12
- * \brief Message type for \ref ast_parking_lot
*
* \retval Message type for \ref ast_parking_lot
*/
struct stasis_message_type *ast_parking_lot(void);
/*!
+ * \brief A topic which publishes events pertaining generally to parking lots.
* \since 12
- * \brief A topic which publishes events pertaining generally to parking lots.
*
* \retval Topic for parking lot events.
*/
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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/main/manager.c (original)
+++ team/jrose/bridge_projects/main/manager.c Wed Mar 20 16:22:03 2013
@@ -7541,7 +7541,7 @@
channel_name, name, value, uniqueid);
}
-static void parked_call(struct parked_call_payload *parked_call)
+static void parked_call(struct ast_parked_call_payload *parked_call)
{
char *event_type;
@@ -7562,59 +7562,42 @@
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",
-
+ "Duration: %s\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
+ parked_call->duration
);
}
-static void parking_lot(struct parking_lot_payload *parking_lot)
+static void parking_lot(struct ast_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);
+ "Name: %s\r\n"
+ "StartSpace: %s\r\n"
+ "EndSpace: %s\r\n"
+ "Timeout: %s\r\n",
+ parking_lot->name,
+ parking_lot->starting_space,
+ parking_lot->ending_space,
+ parking_lot->timeout
+ );
}
static void channel_event_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
@@ -7634,7 +7617,7 @@
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);
+ struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
parked_call(parked_call_message);
}
}
@@ -7642,7 +7625,7 @@
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);
+ struct ast_parking_lot_payload *parking_lot_message = stasis_message_data(message);
parking_lot(parking_lot_message);
}
}
@@ -7672,8 +7655,7 @@
channel_state_sub = stasis_unsubscribe(channel_state_sub);
- stasis_unsubscribe(parking_lot_sub);
- parking_lot_sub = NULL;
+ parking_lot_sub = stasis_unsubscribe(parking_lot_sub);
if (registered) {
ast_manager_unregister("Ping");
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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/main/parking.c (original)
+++ team/jrose/bridge_projects/main/parking.c Wed Mar 20 16:22:03 2013
@@ -42,28 +42,80 @@
* res_parking.
*/
+/*! \brief Destructor for parked_call_payload objects */
+static void parked_call_payload_destructor(void *obj)
+{
+ struct ast_parked_call_payload *park_obj = obj;
+
+ ao2_cleanup(park_obj->parkee);
+ ao2_cleanup(park_obj->parker);
+ ast_string_field_free_memory(park_obj);
+}
+
+struct ast_parked_call_payload *ast_parked_call_payload_create()
+{
+ struct ast_parked_call_payload *payload;
+
+ payload = ao2_alloc(sizeof(*payload), parked_call_payload_destructor);
+ if (!payload) {
+ return NULL;
+ }
+
+ if (ast_string_field_init(payload, 32)) {
+ ao2_cleanup(payload);
+ return NULL;
+ }
+
+ return payload;
+}
+
+/*! \brief destructor for parking_lot_payload objects */
+static void parking_lot_payload_destructor(void *obj)
+{
+ struct ast_parking_lot_payload *park_obj = obj;
+
+ ast_string_field_free_memory(park_obj);
+}
+
+struct ast_parking_lot_payload *ast_parking_lot_payload_create()
+{
+ struct ast_parking_lot_payload *payload;
+
+ payload = ao2_alloc(sizeof(*payload), parking_lot_payload_destructor);
+ if (!payload) {
+ return NULL;
+ }
+
+ if (ast_string_field_init(payload, 32)) {
+ ao2_cleanup(payload);
+ return NULL;
+ }
+
+ return payload;
+}
+
/*! \brief Message type for parked calls */
-static struct stasis_message_type *__parked_call;
+static struct stasis_message_type *parked_call;
/*! \brief Message type for parking lots */
-static struct stasis_message_type *__parking_lot;
+static struct stasis_message_type *parking_lot;
/*! \brief Topic for parking lots */
-static struct stasis_topic *__parking_lot_topic;
+static struct stasis_topic *parking_lot_topic;
struct stasis_message_type *ast_parked_call(void)
{
- return __parked_call;
+ return parked_call;
}
struct stasis_message_type *ast_parking_lot(void)
{
- return __parking_lot;
+ return parking_lot;
}
struct stasis_topic *ast_parking_lot_topic(void)
{
- return __parking_lot_topic;
+ return parking_lot_topic;
}
/*! \internal
@@ -71,17 +123,17 @@
*/
static void parking_shutdown(void)
{
- ao2_cleanup(__parked_call);
- ao2_cleanup(__parking_lot);
- ao2_cleanup(__parking_lot_topic);
- __parked_call = NULL;
+ 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");
+ 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");
+ parking_lot_topic = stasis_topic_create("ast_parking_lot_topic");
ast_register_atexit(parking_shutdown);
}
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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_applications.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_applications.c Wed Mar 20 16:22:03 2013
@@ -77,17 +77,18 @@
<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
+ <para>Used to park yourself (typically in combination with an attended
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 in use then execution
+ will continue at the next priority.
+ </para>
</description>
<see-also>
<ref type="application">ParkedCall</ref>
@@ -101,7 +102,7 @@
enum park_args {
OPT_ARG_COMEBACK,
OPT_ARG_TIMEOUT,
- OPT_ARG_ARRAY_SIZE, /* Always the last element of the enum */
+ OPT_ARG_ARRAY_SIZE /* Always the last element of the enum */
};
enum park_flags {
@@ -138,9 +139,9 @@
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;
+ RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
+
struct ast_bridge_features chan_features;
struct ast_flags flags = { 0 };
char *parse;
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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Wed Mar 20 16:22:03 2013
@@ -31,28 +31,15 @@
#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);
+void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type event_type)
+{
+ RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
struct timeval now = ast_tvnow();
char timeout_text[32] = "";
- payload = ao2_alloc(sizeof(*payload), parked_call_payload_destructor);
+ payload = ast_parked_call_payload_create();
if (!payload) {
- return;
- }
-
- if (ast_string_field_init(payload, 32)) {
return;
}
@@ -84,12 +71,6 @@
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;
- }
-
msg = stasis_message_create(ast_parked_call(), payload);
if (!msg) {
return;
@@ -100,24 +81,13 @@
}
}
-static void parking_lot_payload_destructor(void *obj)
-{
- struct parking_lot_payload *park_obj = obj;
-
- ast_string_field_free_memory(park_obj);
-}
-
-void publish_parking_lot(struct parking_lot *lot, const char *list, int list_item, int list_size)
-{
- RAII_VAR(struct parking_lot_payload *, payload, NULL, ao2_cleanup);
+void publish_parking_lot(struct parking_lot *lot)
+{
+ RAII_VAR(struct ast_parking_lot_payload *, payload, NULL, ao2_cleanup);
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
- payload = ao2_alloc(sizeof(*payload), parking_lot_payload_destructor);
+ payload = ast_parking_lot_payload_create();
if (!payload) {
- return;
- }
-
- if (ast_string_field_init(payload, 32)) {
return;
}
@@ -125,9 +95,6 @@
ast_string_field_build(payload, starting_space, "%d", lot->parking_start);
ast_string_field_build(payload, ending_space, "%d", lot->parking_stop);
ast_string_field_build(payload, timeout, "%u", lot->parkingtime);
- ast_string_field_set(payload, list, list);
- payload->list_item = list_item;
- payload->list_size = list_size;
msg = stasis_message_create(ast_parking_lot(), payload);
if (!msg) {
@@ -137,17 +104,24 @@
stasis_publish(ast_parking_lot_topic(), msg);
}
-/*! This should only be called while holding an ao2 lock on the parking_lot */
struct ast_bridge *get_parkinglot_bridge(struct parking_lot *lot)
{
struct ast_bridge *lot_bridge;
if (lot->parking_bridge) {
+ ao2_ref(lot->parking_bridge, +1);
return lot->parking_bridge;
}
/* XXX Richard is going to change some things here. Name will be an argument */
lot_bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_HOLDING, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM);
+ if (!lot_bridge) {
+ return NULL;
+ }
+
+ /* The parking lot needs a reference to the bridge as well. */
+ lot->parking_bridge = lot_bridge;
+ ao2_ref(lot->parking_bridge, +1);
return lot_bridge;
}
@@ -166,7 +140,7 @@
}
struct parking_limits_pvt {
- struct parkeduser *user;
+ struct parked_user *user;
};
/*! \internal
@@ -174,11 +148,11 @@
*
* \param bridge Which bridge the channel was parked in
* \param bridge_channel bridge channel this interval hook is being executed on
- * \param hook_pvt A pointer to the parkeduser struct associated with the channel is stuffed in here
+ * \param hook_pvt A pointer to the parked_user struct associated with the channel is stuffed in here
*/
static int parking_duration_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
{
- struct parkeduser *user = hook_pvt;
+ struct parked_user *user = hook_pvt;
ao2_lock(bridge_channel);
switch (bridge_channel->state) {
@@ -195,18 +169,18 @@
/* Set the resolution for the user to timeout */
user->resolution = PARK_TIMEOUT;
- publish_parked_call(user, NULL, 0, 0, PARKED_CALL_TIMEOUT);
+ publish_parked_call(user, PARKED_CALL_TIMEOUT);
return -1;
}
static void parking_duration_cb_destroyer(void *hook_pvt)
{
- struct parkeduser *user = hook_pvt;
+ struct parked_user *user = hook_pvt;
ao2_ref(user, -1);
}
-int unpark_parked_user(struct parkeduser *pu)
+int unpark_parked_user(struct parked_user *pu)
{
if (pu->lot) {
ao2_unlink(pu->lot->parked_user_list, pu);
@@ -217,7 +191,7 @@
return -1;
}
-void parking_set_duration(struct ast_bridge_features *features, struct parkeduser *user, int override_time)
+void parking_set_duration(struct ast_bridge_features *features, struct parked_user *user, int override_time)
{
unsigned int time_limit;
@@ -232,7 +206,7 @@
return;
}
- /* The interval hook is going to need a reference to the parkeduser */
+ /* The interval hook is going to need a reference to the parked_user */
ao2_ref(user, +1);
if (ast_bridge_interval_hook(features, time_limit,
@@ -241,14 +215,12 @@
}
}
-/* Returns -1 if no slot is available, call it with a read lock taken? */
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 current_target;
struct ao2_iterator i;
- struct parkeduser *user;
- int found_mode = 0;
+ struct parked_user *user;
int wrap;
if (target_override != -1 && target_override >= lot->parking_start && target_override <= lot->parking_stop) {
@@ -267,25 +239,20 @@
}
if (user->parking_space < current_target) {
+ /* It's lower than the anticipated target, so we haven't reached the target yet. */
ao2_ref(user, -1);
continue;
}
- switch (found_mode) {
- case 0:
- if (user->parking_space > current_target) {
- /* The current target is usable. */
- ao2_ref(user, -1);
- break;
- }
-
- found_mode = 1;
- /* We want to fall through here */
- case 1:
- /* We found one already parked here. Bump the target by 1 and try again. */
- current_target += 1;
- found_mode = 0;
- }
+ if (user->parking_space > current_target) {
+ /* The current target is usable because all items below have been read and the next target is higher than the one we want. */
+ ao2_ref(user, -1);
+ break;
+ }
+
+ /* We found one already parked here. Bump the target by 1 and try again. */
+ current_target += 1;
+ ao2_ref(user, -1);
}
ao2_iterator_destroy(&i);
@@ -300,9 +267,9 @@
return -1;
}
-static void destroy_parkeduser(void *obj)
-{
- struct parkeduser *pu = obj;
+static void destroy_parked_user(void *obj)
+{
+ struct parked_user *pu = obj;
ao2_cleanup(pu->parker);
}
@@ -333,7 +300,7 @@
ast_channel_priority_set(chan, priority);
}
-int comeback_goto(struct parkeduser *pu, struct parking_lot *lot)
+int comeback_goto(struct parked_user *pu, struct parking_lot *lot)
{
struct ast_channel *chan = pu->chan;
char *peername = ast_strdupa(pu->parker->name);
@@ -369,19 +336,19 @@
return 0;
}
-void reset_parked_time(struct parkeduser *pu)
+void reset_parked_time(struct parked_user *pu)
{
pu->start = ast_tvnow();
}
-struct parkeduser *generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, struct ast_channel *parker, int use_random_space, int time_limit)
-{
- struct parkeduser *new_parked_user;
+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 *new_parked_user;
int preferred_space = -1; /* Initialize to use parking lot defaults */
int parking_space;
const char *parkingexten;
- new_parked_user = ao2_alloc(sizeof(*new_parked_user), destroy_parkeduser);
+ new_parked_user = ao2_alloc(sizeof(*new_parked_user), destroy_parked_user);
if (!new_parked_user) {
return NULL;
}
@@ -399,10 +366,14 @@
}
}
+ /* 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);
if (parking_space == -1) {
ast_log(LOG_NOTICE, "Failed to get parking space in lot '%s'. All full.\n", lot->name);
ao2_ref(new_parked_user, -1);
+ ao2_unlock(lot);
return NULL;
}
lot->next_space = ((parking_space + 1) - lot->parking_start) % (lot->parking_stop - lot->parking_start + 1) + lot->parking_start;
@@ -415,14 +386,16 @@
if (!new_parked_user->parker) {
ast_log(LOG_ERROR, "Allocation error\n");
ao2_ref(new_parked_user, -1);
+ ao2_unlock(lot);
return NULL;
}
/* Generate ParkedCall Stasis Message */
- publish_parked_call(new_parked_user, NULL, 0, 0, PARKED_CALL);
-
- /* Insert into the parking lot's parked user list */
+ 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);
return new_parked_user;
}
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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/res/parking/res_parking.h (original)
+++ team/jrose/bridge_projects/res/parking/res_parking.h Wed Mar 20 16:22:03 2013
@@ -48,15 +48,6 @@
};
struct parking_lot {
- /*! Name of the parking lot */
- char name[AST_MAX_CONTEXT];
-
- char mohclass[MAX_MUSICCLASS];
- char parkext[AST_MAX_EXTENSION];
- char parking_con[AST_MAX_CONTEXT];
- char comebackcontext[AST_MAX_CONTEXT];
- char courtesytone[256];
-
int parking_start;
int parking_stop;
@@ -67,8 +58,6 @@
unsigned int parkext_exclusive;
unsigned int parkaddhints;
unsigned int comebacktoorigin;
-
- unsigned int is_invalid; /* XXX Is this necessary? Probably not. */
/* These all need to be handled by a special configuration handler */
int parkedplay;
@@ -83,19 +72,28 @@
/*! Was this parking space created dynamically? (break down the parking lot once it empties) */
int dynamic;
+ /*! 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;
+
+ 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);
+ );
+
/*! Destroy unused parking lot on deletion marker */
unsigned int the_mark:1;
/*! TRUE if the parking lot is disabled */
unsigned int disabled:1;
-
- /*! 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;
-};
-
-struct parkeduser {
+};
+
+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 */
@@ -107,6 +105,16 @@
enum park_call_resolution resolution; /*!< How did the parking session end? */
};
+/*!
+ * \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.
+ *
+ * \retval A reference to the ast_bridge associated with the parking lot
+ * \retval NULL if it didn't already have a bridge and one couldn't be created
+ *
+ * \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);
/*!
@@ -118,7 +126,7 @@
* 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 parkeduser with the space
+ * \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);
@@ -136,10 +144,10 @@
* \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
- * \param user The parkeduser receiving the timeout duration limits
+ * \param user The parked_user receiving the timeout duration limits
* \param override_time If >= 0, use this instead of the user's timeout inherited from its lot
*/
-void parking_set_duration(struct ast_bridge_features *features, struct parkeduser *user, int override_time);
+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
@@ -190,7 +198,7 @@
* \param use_random_space if true, prioritize using a random parking space instead
* of ${PARKINGEXTEN} and/or automatic assignment from the parking lot
* \param time_limit If using a custom timeout, this should be supplied so that the
- * parkeduser struct can provide this information for manager events. If <0,
+ * parked_user struct can provide this information for manager events. If <0,
* use the parking lot limit instead.
*
* \retval NULL on failure
@@ -198,7 +206,7 @@
*
* \note This reference will need to be free'd when you are done using it.
*/
-struct parkeduser *generate_parked_user(struct parking_lot *lot, struct ast_channel *parkee, struct ast_channel *parker, int use_random_space, int time_limit);
+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);
/*!
* \brief Reset the start time of a parked user to now
@@ -210,7 +218,7 @@
* channel is placed into the parking bridge then there will likely be some discrepencies
* between real timeouts and expected timeouts when reporting for manager events.
*/
-void reset_parked_time(struct parkeduser *pu);
+void reset_parked_time(struct parked_user *pu);
/*!
* \brief Set a channel's position in the PBX after timeout using the parking lot settings
@@ -221,7 +229,7 @@
* \retval 0 Position set successfully
* \retval -1 Failed to set the position
*/
-int comeback_goto(struct parkeduser *pu, struct parking_lot *lot);
+int comeback_goto(struct parked_user *pu, struct parking_lot *lot);
/*!
* \brief Pull a parked user out of its parking lot.
@@ -230,27 +238,22 @@
* \retval 0 on success
* \retval -1 if the user didn't have its parking lot set
*/
-int unpark_parked_user(struct parkeduser *user);
+int unpark_parked_user(struct parked_user *user);
/*!
* \brief Publish a stasis parked call message for a given parked user
*
- * \param pu pointer to a parkeduser that we are generating the message for
- * \param list If the item is part of a list, the name of the list
- * \param list_item If the item is part of a list, which entry it is (1 to n where n is the number of items)
- * \param list_size If the item is part of a list, how many total entries there are in the list to expect
- */
-void publish_parked_call(struct parkeduser *pu, const char *list, int list_item, int list_size, enum parked_call_event_type event_type);
+ * \param pu pointer to a parked_user that we are generating the message for
+ * \param event_type What parked call event type is provoking this message
+ */
+void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type event_type);
/*!
* \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
- * \param list If the item is part of a list, the name of the list.
- * \param list_item If the item is part of a list, which entry it is (1 to n where n is number of items)
- * \param list_size If the item is part of a list, how many total entries there are in the list to expect
- */
-void publish_parking_lot(struct parking_lot *lot, const char *list, int list_item, int list_size);
+ */
+void publish_parking_lot(struct parking_lot *lot);
/*!
* \brief Get a pointer to the Park application function.
@@ -261,12 +264,12 @@
/*!
* \brief Register CLI commands and manager actions
- */
-void load_tools(void);
+ * \retval 0 if successful
+ * \retval -1 on failure
+ */
+int load_tools(void);
/*!
* \brief Unregister CLI commands and manager actions
- *
- * \note Not implemented yet. Currently a No-Op.
*/
void unload_tools(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=383481&r1=383480&r2=383481
==============================================================================
--- team/jrose/bridge_projects/res/res_parking.c (original)
+++ team/jrose/bridge_projects/res/res_parking.c Wed Mar 20 16:22:03 2013
@@ -113,9 +113,10 @@
<synopsis>Who we should play the courtesytone to on the pickup of a parked call from this lot</synopsis>
<description>
<enumlist>
- <enum name="caller"><para>Play the courtesy tone only to the caller picking up the parked call.</para></enum>
- <enum name="callee"><para>Play the courtesy tone only to the parked call being picked up.</para></enum>
- <enum name="both"><para>Play the courtesy tone to both the caller and the callee.</para></enum></enumlist>
+ <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>
@@ -123,53 +124,29 @@
<configOption name="parkedcalltransfers" default="none">
<synopsis>Apply the DTMF transfer features to the caller and/or callee when parked calls are picked up.</synopsis>
<description>
- <enumlist>
- <enum name="caller"><para>The Caller may use the <literal>blindxfer</literal> and <literal>atxfer</literal>
- features</para></enum>
- <enum name="callee"><para>The Callee (parked call that is picked up) may use the <literal>blindxfer</literal>
- and <literal>atxfer</literal> features</para></enum>
- <enum name="both"><para>Both Caller and Callee may use the <literal>blindxfer</literal> and
- <literal>atxfer</literal> features</para></enum>
- </enumlist>
- <note><para>If any value not listed above is used, these features are applied to neither side.</para></note>
+ <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">
<synopsis>Apply the DTMF parking feature to the caller and/or callee when parked calls are picked up.</synopsis>
<description>
- <enumlist>
- <enum name="caller"><para>The Caller may use the <literal>parkcall</literal> feature</para></enum>
- <enum name="callee"><para>The Callee (parked call that is picked up) may use the <literal>parkcall</literal>
- feature</para></enum>
- <enum name="both"><para>Both Caller and Callee may use the <literal>parkcall</literal> feature</para></enum>
- </enumlist>
- <note><para>If any value not listed above is used, this feature is applied to neither side.</para></note>
+ <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">
<synopsis>Apply the DTMF Hangup feature to the caller and/or callee when parked calls are picked up.</synopsis>
<description>
- <enumlist>
- <enum name="caller"><para>The Caller may use the <literal>disconnect</literal> feature</para></enum>
- <enum name="callee"><para>The Callee (parked call that is picked up) may use the <literal>disconnect</literal>
- feature</para></enum>
- <enum name="both"><para>Both Caller and Callee may use the <literal>disconnect</literal> feature</para></enum>
- </enumlist>
- <note><para>If any value not listed above is used, this feature is applied to neither side.</para></note>
+ <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">
<synopsis>Apply the DTMF recording features to the caller and/or callee when parked calls are picked up</synopsis>
<description>
- <enumlist>
- <enum name="caller"><para>The Caller may use the <literal>automon</literal> and <literal>automixmon</literal>
- features</para></enum>
- <enum name="callee"><para>The Callee (parked call that is picked up) may use the <literal>automon</literal> and
- <literal>automixmon</literal> features</para></enum>
- <enum name="both"><para>Both Caller and Callee may use use the <literal>automon</literal> and
- <literal>automixmon</literal> features</para></enum>
- </enumlist>
- <note><para>If any value not listed above is used, these features are applied to neither side.</para></note>
+ <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">
@@ -253,16 +230,44 @@
static int parking_lot_hash_fn(const void *obj, const int flags)
{
- const struct parking_lot *entry = obj;
- return ast_str_hash(entry->name);
+ const struct parking_lot *entry;
+ const char *key;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY)) {
+ case OBJ_KEY:
+ key = obj;
+ return ast_str_hash(key);
+ case OBJ_POINTER:
+ entry = obj;
+ return ast_str_hash(entry->name);
+ }
+
+ /* It should be impossible to reach this point */
+ return 0;
}
static int parking_lot_cmp_fn(void *obj, void *arg, const int flags)
{
struct parking_lot *entry1 = obj;
- struct parking_lot *entry2 = arg;
-
- return (!strcmp(entry1->name, entry2->name)) ? (CMP_MATCH | CMP_STOP) : 0;
+
+ char *key;
+ size_t key_size;
+ struct parking_lot *entry2;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_KEY:
+ key = arg;
+ return (!strcmp(entry1->name, key)) ? (CMP_MATCH | CMP_STOP) : 0;
+ case OBJ_PARTIAL_KEY:
+ key = arg;
+ key_size = strlen(key);
+ return (!strncmp(entry1->name, key, key_size)) ? (CMP_MATCH | CMP_STOP) : 0;
+ case OBJ_POINTER:
+ entry2 = arg;
+ return (!strcmp(entry1->name, entry2->name)) ? (CMP_MATCH | CMP_STOP) : 0;
+ }
+
+ return CMP_STOP;
}
/*! \brief destructor for parking_lot_config */
@@ -270,6 +275,7 @@
{
struct parking_lot_config *cfg = obj;
ao2_cleanup(cfg->parking_lot_list);
+ ao2_cleanup(cfg->global);
}
/*! \brief destructor for parking_global_config */
@@ -303,17 +309,19 @@
}
/*! \brief Destroy a parking lot object */
-static void destroy_parking_lot(void *obj)
+static void parking_lot_destructor(void *obj)
{
struct parking_lot *lot = obj;
ao2_cleanup(lot->parking_bridge);
+ ao2_cleanup(lot->parked_user_list);
+ ast_string_field_free_memory(lot);
}
/* The arg just needs to have the parking space with it */
static int parked_user_cmp_fn(void *obj, void *arg, int flags)
{
int *search_space = arg;
- struct parkeduser *user = obj;
+ struct parked_user *user = obj;
int object_space = user->parking_space;
if (*search_space == object_space) {
@@ -324,16 +332,10 @@
static int parked_user_sort_fn(const void *obj_left, const void *obj_right, int flags)
{
- const struct parkeduser *left = obj_left;
- const struct parkeduser *right = obj_right;
-
- if (left->parking_space < right->parking_space) {
- return -1;
- } else if (left->parking_space > right->parking_space) {
- return 1;
- } else {
- return 0;
- }
+ const struct parked_user *left = obj_left;
+ const struct parked_user *right = obj_right;
+
+ return left->parking_space - right->parking_space;
}
/*!
@@ -346,8 +348,13 @@
{
struct parking_lot *lot;
- lot = ao2_alloc(sizeof(*lot), destroy_parking_lot);
+ lot = ao2_alloc(sizeof(*lot), parking_lot_destructor);
if (!lot) {
+ return NULL;
+ }
+
+ if (ast_string_field_init(lot, 32)) {
+ ao2_cleanup(lot);
return NULL;
}
@@ -362,7 +369,7 @@
return NULL;
}
- ast_copy_string(lot->name, cat, sizeof(lot->name));
+ ast_string_field_set(lot, name, cat);
return lot;
}
@@ -377,9 +384,8 @@
*/
static void *parking_lot_find(struct ao2_container *container, const char *cat)
{
- struct parking_lot tmp;
- ast_copy_string(tmp.name, cat, sizeof(tmp.name));
- return ao2_find(container, &tmp, OBJ_POINTER);
+ char *search_key = ast_strdupa(cat);
[... 49 lines stripped ...]
More information about the asterisk-commits
mailing list