187 ast_channel_lock(chan);
189 ast_channel_unlock(chan);
190 if (!parkee_snapshot) {
203 const char *lot_name = pu->
lot->
name;
205 ast_channel_lock(pu->
chan);
207 ast_channel_unlock(pu->
chan);
208 if (!parkee_snapshot) {
213 duration = now.tv_sec - pu->
start.tv_sec;
231 if (!parkee_string) {
238 if (!retriever_string) {
247 "ParkerDialString: %s\r\n"
249 "ParkingSpace: %u\r\n"
250 "ParkingTimeout: %lu\r\n"
251 "ParkingDuration: %lu\r\n",
264 static void manager_parking_status_single_lot(
struct mansession *s,
const struct message *m,
const char *id_text,
const char *lot_name)
280 while ((curuser = ao2_iterator_next(&iter_users))) {
284 payload = parked_call_payload_from_parked_user(curuser, PARKED_CALL);
291 if (!parked_call_string) {
314 static void manager_parking_status_all_lots(
struct mansession *s,
const struct message *m,
const char *id_text)
324 if (!lot_container) {
325 ast_log(LOG_ERROR,
"Failed to obtain parking lot list. Action canceled.\n");
333 while ((curlot = ao2_iterator_next(&iter_lots))) {
335 while ((curuser = ao2_iterator_next(&iter_users))) {
339 payload = parked_call_payload_from_parked_user(curuser, PARKED_CALL);
348 if (!parked_call_string) {
384 if (!ast_strlen_zero(
id)) {
385 snprintf(id_text,
sizeof(id_text),
"ActionID: %s\r\n",
id);
388 if (!ast_strlen_zero(lot_name)) {
389 manager_parking_status_single_lot(s, m, id_text, lot_name);
391 manager_parking_status_all_lots(s, m, id_text);
402 static int manager_append_event_parking_lot_data_cb(
void *obj,
void *arg,
void *data,
int flags)
425 static int manager_parking_lot_list(
struct mansession *s,
const struct message *m)
433 if (!ast_strlen_zero(
id)) {
434 snprintf(id_text,
sizeof(id_text),
"ActionID: %s\r\n",
id);
438 if (!lot_container) {
439 ast_log(LOG_ERROR,
"Failed to obtain parking lot list. Action canceled.\n");
446 list_data.id_text = id_text;
449 manager_append_event_parking_lot_data_cb, s, &list_data);
457 static void manager_park_unbridged(
struct mansession *s,
const struct message *m,
458 struct ast_channel *chan,
const char *parkinglot,
int timeout_override)
461 chan, parkinglot, NULL, 0, 0, timeout_override, 1);
463 if (!parking_bridge) {
470 ao2_cleanup(parking_bridge);
475 ao2_cleanup(parking_bridge);
480 const char *parkinglot,
int timeout_override)
485 if (timeout_override != -1) {
486 if (
ast_asprintf(&app_data,
"%s,t(%d)", parkinglot, timeout_override) == -1) {
497 ast_channel_lock(parker_chan);
499 ast_channel_unlock(parker_chan);
501 if (!bridge_channel) {
511 ao2_cleanup(bridge_channel);
516 ast_channel_uniqueid(parker_chan), app_data);
521 ao2_cleanup(bridge_channel);
533 int timeout_override = -1;
538 if (ast_strlen_zero(channel)) {
543 if (!ast_strlen_zero(timeout)) {
544 if (sscanf(timeout,
"%30d", &timeout_override) != 1 || timeout_override < 0) {
549 if (timeout_override) {
551 timeout_override = MAX(1, timeout_override / 1000);
556 snprintf(buf,
sizeof(buf),
"Channel does not exist: %s", channel);
561 if (!ast_strlen_zero(timeout_channel)) {
562 ast_channel_lock(chan);
564 ast_channel_unlock(chan);
567 if (!ast_strlen_zero(parkingspace)) {
572 if (!parker_chan || strcmp(ast_channel_name(parker_chan), timeout_channel)) {
573 if (!ast_strlen_zero(announce_channel)) {
575 if (!announce_channel) {
584 manager_park_unbridged(s, m, chan, parkinglot, timeout_override);
588 if (!ast_strlen_zero(announce_channel) && strcmp(announce_channel, timeout_channel)) {
592 if (!announce_channel) {
601 manager_park_bridged(s, m, chan, parker_chan, parkinglot, timeout_override);
614 payload = parked_call_payload_from_failure(parkee);
636 payload = parked_call_payload_from_parked_user(pu, event_type);
651 char *event_type =
"";
656 event_type =
"ParkedCall";
658 case PARKED_CALL_TIMEOUT:
659 event_type =
"ParkedCallTimeOut";
661 case PARKED_CALL_GIVEUP:
662 event_type =
"ParkedCallGiveUp";
664 case PARKED_CALL_UNPARKED:
665 event_type =
"UnParkedCall";
667 case PARKED_CALL_SWAP:
668 event_type =
"ParkedCallSwap";
670 case PARKED_CALL_FAILED:
676 if (!parked_call_string) {
677 ast_log(LOG_ERROR,
"Failed to issue an AMI event of '%s' in response to a stasis message.\n", event_type);
691 parked_call_message_response(parked_call_message);
695 static void parking_manager_enable_stasis(
void)
711 parking_manager_enable_stasis();
715 static void parking_manager_disable_stasis(
void)
725 parking_manager_disable_stasis();
Main Channel structure associated with a channel.
void astman_append(struct mansession *s, const char *fmt,...)
int load_parking_manager(void)
Register manager actions and setup subscriptions for stasis events.
Asterisk main include file. File version handling, generic pbx functions.
struct ast_parked_call_payload * ast_parked_call_payload_create(enum ast_parked_call_event_type event_type, struct ast_channel_snapshot *parkee_snapshot, const char *parker_dial_string, struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot, unsigned int parkingspace, unsigned long int timeout, unsigned long int duration)
Constructor for parked_call_payload objects.
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
struct ao2_container * parked_users
int ast_bridge_channel_write_park(struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
Have a bridge channel park a channel in the bridge.
Structure representing a snapshot of channel state.
struct ast_str * ast_manager_build_channel_state_string_prefix(const struct ast_channel_snapshot *snapshot, const char *prefix)
Generate the AMI message body from a channel snapshot.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
A parked call message payload.
enum ast_parked_call_event_type event_type
void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type event_type)
Publish a stasis parked call message for a given parked user.
long unsigned int duration
struct ast_channel_snapshot * ast_channel_snapshot_create(struct ast_channel *chan)
Generate a snapshot of the channel state. This is an ao2 object, so ao2_cleanup() to deallocate...
struct ao2_container * get_parking_lot_container(void)
Get a pointer to the parking lot container for purposes such as iteration.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
void publish_parked_call_failure(struct ast_channel *parkee)
Publish a stasis parked call message for the channel indicating failure to park.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Configuration File Parser.
struct ast_channel_snapshot * parkee
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
char * parker_dial_string
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ast_channel_cleanup(c)
Cleanup a channel reference.
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Configuration option-handling.
Structure that contains information about a bridge.
int ast_bridge_add_channel(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_bridge_features *features, int play_tone, const char *xfersound)
Add an arbitrary channel to a bridge.
Support for dynamic strings.
static struct ast_str * manager_build_parked_call_string(const struct ast_parked_call_payload *payload)
Builds a manager string based on the contents of a parked call payload.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
unsigned int parkingspace
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
long unsigned int timeout
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
ast_parked_call_event_type
Defines the type of parked call message being published.
void unload_parking_manager(void)
Unregister manager actions and remove subscriptions for stasis events.
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
void ast_bridge_set_transfer_variables(struct ast_channel *chan, const char *value, int is_attended)
Set the relevant transfer variables for a single channel.
const ast_string_field name
const ast_string_field parkinglot
static struct stasis_subscription * parking_sub
subscription to the parking lot topic
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Structure that contains information regarding a channel in a bridge.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
const ast_string_field parker_dial_string
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
Call Parking Resource Internal API.
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
struct ast_channel_snapshot * retriever
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Asterisk module definitions.
struct ast_channel_snapshot * retriever
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
struct ast_channel * chan
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct ast_bridge * park_common_setup(struct ast_channel *parkee, struct ast_channel *parker, const char *lot_name, const char *comeback_override, int use_ringing, int randomize, int time_limit, int silence_announcements)
Setup a parked call on a parking bridge without needing to parse appdata.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int create_parked_subscription(struct ast_channel *chan, const char *parkee_uuid, int hangup_after)
Create a parking announcement subscription.
struct parking_lot_cfg * cfg
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.