diff options
author | Richard Mudgett <rmudgett@digium.com> | 2013-05-21 18:00:22 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2013-05-21 18:00:22 +0000 |
commit | 3d63833bd6c869b7efa383e8dea14be1a6eff998 (patch) | |
tree | 34957dd051b8f67c7cc58a510e24ee3873a61ad4 /main/parking.c | |
parent | e1e1cc2deefb92f8b43825f1f34e619354737842 (diff) |
Merge in the bridge_construction branch to make the system use the Bridging API.
Breaks many things until they can be reworked. A partial list:
chan_agent
chan_dahdi, chan_misdn, chan_iax2 native bridging
app_queue
COLP updates
DTMF attended transfers
Protocol attended transfers
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389378 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/parking.c')
-rw-r--r-- | main/parking.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/main/parking.c b/main/parking.c new file mode 100644 index 000000000..2a5b72e61 --- /dev/null +++ b/main/parking.c @@ -0,0 +1,191 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013, Digium, Inc. + * + * Jonathan Rose <jrose@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Parking Core + * + * \author Jonathan Rose <jrose@digium.com> + */ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/_private.h" +#include "asterisk/astobj2.h" +#include "asterisk/pbx.h" +#include "asterisk/bridging.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; + +/*! \brief Function Callback for handling blind transfers to park applications */ +static ast_park_blind_xfer_fn ast_park_blind_xfer_func = NULL; + +/*! \brief Function Callback for handling a bridge channel trying to park itself */ +static ast_bridge_channel_park_fn ast_bridge_channel_park_func = NULL; + +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, + struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot, + unsigned int parkingspace, unsigned long int timeout, + unsigned 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; + + if (parker_snapshot) { + ao2_ref(parker_snapshot, +1); + payload->parker = parker_snapshot; + } + + if (retriever_snapshot) { + ao2_ref(retriever_snapshot, +1); + payload->retriever = retriever_snapshot; + } + + if (parkinglot) { + ast_string_field_set(payload, parkinglot, parkinglot); + } + + payload->parkingspace = parkingspace; + payload->timeout = timeout; + payload->duration = duration; + + /* Bump the ref count by one since RAII_VAR is going to eat one when we leave. */ + ao2_ref(payload, +1); + return payload; +} + +void ast_install_park_blind_xfer_func(ast_park_blind_xfer_fn park_blind_xfer_func) +{ + ast_park_blind_xfer_func = park_blind_xfer_func; +} + +void ast_install_bridge_channel_park_func(ast_bridge_channel_park_fn bridge_channel_park_func) +{ + ast_bridge_channel_park_func = bridge_channel_park_func; +} + +void ast_uninstall_park_blind_xfer_func(void) +{ + ast_park_blind_xfer_func = NULL; +} + +void ast_uninstall_bridge_channel_park_func(void) +{ + ast_bridge_channel_park_func = NULL; +} + +int ast_park_blind_xfer(struct ast_bridge *bridge, struct ast_bridge_channel *parker, + struct ast_exten *park_exten) +{ + static int warned = 0; + if (ast_park_blind_xfer_func) { + return ast_park_blind_xfer_func(bridge, parker, park_exten); + } + + if (warned++ % 10 == 0) { + ast_verb(3, "%s attempted to blind transfer to a parking extension, but no parking blind transfer function is loaded.\n", + ast_channel_name(parker->chan)); + } + + return -1; +} + +struct ast_exten *ast_get_parking_exten(const char *exten_str, struct ast_channel *chan, const char *context) +{ + struct ast_exten *exten; + struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */ + const char *app_at_exten; + + ast_debug(4, "Checking if %s@%s is a parking exten\n", exten_str, context); + exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL, + E_MATCH); + if (!exten) { + return NULL; + } + + app_at_exten = ast_get_extension_app(exten); + if (!app_at_exten || strcasecmp(PARK_APPLICATION, app_at_exten)) { + return NULL; + } + + return exten; +} + +void ast_bridge_channel_park(struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, const char *parker_uuid, const char *app_data) +{ + /* Run installable function */ + if (ast_bridge_channel_park_func) { + return ast_bridge_channel_park_func(bridge_channel, parkee_uuid, parker_uuid, app_data); + } +} |