Asterisk - The Open Source Telephony Project GIT-master-a358458
Data Structures | Macros | Enumerations | Functions | Variables
parking_applications.c File Reference

Call Parking Applications. More...

#include "asterisk.h"
#include "res_parking.h"
#include "asterisk/config.h"
#include "asterisk/config_options.h"
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
#include "asterisk/features.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/say.h"
#include "asterisk/bridge_basic.h"
#include "asterisk/format_cache.h"
Include dependency graph for parking_applications.c:

Go to the source code of this file.

Data Structures

struct  park_announce_subscription_data
 

Macros

#define PARK_AND_ANNOUNCE_APPLICATION   "ParkAndAnnounce"
 

Enumerations

enum  park_args { OPT_ARG_COMEBACK , OPT_ARG_TIMEOUT , OPT_ARG_MUSICONHOLD , OPT_ARG_ARRAY_SIZE }
 
enum  park_flags {
  MUXFLAG_RINGING = (1 << 0) , MUXFLAG_RANDOMIZE = (1 << 1) , MUXFLAG_NOANNOUNCE = (1 << 2) , MUXFLAG_COMEBACK_OVERRIDE = (1 << 3) ,
  MUXFLAG_TIMEOUT_OVERRIDE = (1 << 4) , MUXFLAG_MUSICONHOLD = (1 << 5)
}
 

Functions

static void announce_to_dial (char *dial_string, char *announce_string, int parkingspace, struct ast_channel_snapshot *parkee_snapshot)
 
static int apply_option_timeout (int *var, char *timeout_arg)
 
struct park_common_datastoreget_park_common_datastore_copy (struct ast_channel *parkee)
 Get a copy of the park_common_datastore from a channel that is being parked. More...
 
static void inherit_channel_vars_from_id (struct outgoing_helper *oh, const char *channel_id)
 
int load_parking_applications (void)
 Register parking applications. More...
 
static int park_and_announce_app_exec (struct ast_channel *chan, const char *data)
 
static struct park_announce_subscription_datapark_announce_subscription_data_create (const char *parkee_uuid, const char *dial_string, const char *announce_string)
 
static void park_announce_subscription_data_destroy (void *data)
 
static void park_announce_update_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int park_app_exec (struct ast_channel *chan, const char *data)
 
static int park_app_parse_data (const char *data, int *disable_announce, int *use_ringing, int *randomize, int *time_limit, char **comeback_override, char **lot_name, char **musicclass)
 
struct ast_bridgepark_application_setup (struct ast_channel *parkee, struct ast_channel *parker, const char *app_data, int *silence_announcements)
 Function to prepare a channel for parking by determining which parking bridge should be used, setting up a park common datastore so that the parking bridge will have access to necessary parking information when joining, and applying various bridge roles to the channel. More...
 
static void park_common_datastore_destroy (void *data)
 
void park_common_datastore_free (struct park_common_datastore *datastore)
 Free a park common datastore struct. More...
 
struct ast_bridgepark_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. More...
 
static struct ast_bridgepark_common_setup2 (struct ast_channel *parkee, struct ast_channel *parker, const char *lot_name, const char *comeback_override, const char *musicclass, int use_ringing, int randomize, int time_limit, int silence_announcements)
 
static int parked_call_app_exec (struct ast_channel *chan, const char *data)
 
static int setup_park_common_datastore (struct ast_channel *parkee, const char *parker_uuid, const char *comeback_override, int randomize, int time_limit, int silence_announce)
 
void unload_parking_applications (void)
 Unregister parking applications. More...
 
static void wipe_park_common_datastore (struct ast_channel *chan)
 

Variables

static const struct ast_datastore_info park_common_info
 
static const struct ast_app_option park_opts [128] = { [ 'r' ] = { .flag = MUXFLAG_RINGING }, [ 'R' ] = { .flag = MUXFLAG_RANDOMIZE }, [ 's' ] = { .flag = MUXFLAG_NOANNOUNCE }, [ 'c' ] = { .flag = MUXFLAG_COMEBACK_OVERRIDE , .arg_index = OPT_ARG_COMEBACK + 1 }, [ 't' ] = { .flag = MUXFLAG_TIMEOUT_OVERRIDE , .arg_index = OPT_ARG_TIMEOUT + 1 }, [ 'm' ] = { .flag = MUXFLAG_MUSICONHOLD , .arg_index = OPT_ARG_MUSICONHOLD + 1 }, }
 

Detailed Description

Call Parking Applications.

Author
Jonathan Rose jrose.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file parking_applications.c.

Macro Definition Documentation

◆ PARK_AND_ANNOUNCE_APPLICATION

#define PARK_AND_ANNOUNCE_APPLICATION   "ParkAndAnnounce"

Definition at line 237 of file parking_applications.c.

Enumeration Type Documentation

◆ park_args

enum park_args
Enumerator
OPT_ARG_COMEBACK 
OPT_ARG_TIMEOUT 
OPT_ARG_MUSICONHOLD 
OPT_ARG_ARRAY_SIZE 

Definition at line 241 of file parking_applications.c.

241 {
245 OPT_ARG_ARRAY_SIZE /* Always the last element of the enum */
246};
@ OPT_ARG_TIMEOUT
@ OPT_ARG_MUSICONHOLD
@ OPT_ARG_COMEBACK
@ OPT_ARG_ARRAY_SIZE

◆ park_flags

enum park_flags
Enumerator
MUXFLAG_RINGING 
MUXFLAG_RANDOMIZE 
MUXFLAG_NOANNOUNCE 
MUXFLAG_COMEBACK_OVERRIDE 
MUXFLAG_TIMEOUT_OVERRIDE 
MUXFLAG_MUSICONHOLD 

Definition at line 248 of file parking_applications.c.

248 {
249 MUXFLAG_RINGING = (1 << 0),
250 MUXFLAG_RANDOMIZE = (1 << 1),
251 MUXFLAG_NOANNOUNCE = (1 << 2),
252 MUXFLAG_COMEBACK_OVERRIDE = (1 << 3),
253 MUXFLAG_TIMEOUT_OVERRIDE = (1 << 4),
254 MUXFLAG_MUSICONHOLD = (1 << 5),
255};
@ MUXFLAG_RINGING
@ MUXFLAG_MUSICONHOLD
@ MUXFLAG_COMEBACK_OVERRIDE
@ MUXFLAG_TIMEOUT_OVERRIDE
@ MUXFLAG_RANDOMIZE
@ MUXFLAG_NOANNOUNCE

Function Documentation

◆ announce_to_dial()

static void announce_to_dial ( char *  dial_string,
char *  announce_string,
int  parkingspace,
struct ast_channel_snapshot parkee_snapshot 
)
static

Definition at line 819 of file parking_applications.c.

820{
821 struct ast_channel *dchan;
822 struct outgoing_helper oh = { 0, };
823 int outstate;
825 char buf[13];
826 char *dial_tech;
827 char *cur_announce;
828
829 dial_tech = strsep(&dial_string, "/");
830 ast_verb(3, "Dial Tech,String: (%s,%s)\n", dial_tech, dial_string);
831
832 if (!cap_slin) {
833 ast_log(LOG_WARNING, "PARK: Failed to announce park.\n");
834 goto announce_cleanup;
835 }
837
838 snprintf(buf, sizeof(buf), "%d", parkingspace);
839 oh.vars = ast_variable_new("_PARKEDAT", buf, "");
840
841 inherit_channel_vars_from_id(&oh, parkee_snapshot->base->uniqueid);
842
843 dchan = __ast_request_and_dial(dial_tech, cap_slin, NULL, NULL, dial_string, 30000,
844 &outstate,
845 parkee_snapshot->caller->number,
846 parkee_snapshot->caller->name,
847 &oh);
848
850 if (!dchan) {
851 ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
852 goto announce_cleanup;
853 }
854
855 ast_verb(4, "Announce Template: %s\n", announce_string);
856
857 for (cur_announce = strsep(&announce_string, ":"); cur_announce; cur_announce = strsep(&announce_string, ":")) {
858 ast_verb(4, "Announce:%s\n", cur_announce);
859 if (!strcmp(cur_announce, "PARKED")) {
860 ast_say_digits(dchan, parkingspace, "", ast_channel_language(dchan));
861 } else {
862 int dres = ast_streamfile(dchan, cur_announce, ast_channel_language(dchan));
863 if (!dres) {
864 dres = ast_waitstream(dchan, "");
865 } else {
866 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", cur_announce, ast_channel_name(dchan));
867 }
868 }
869 }
870
871 ast_stopstream(dchan);
872 ast_hangup(dchan);
873
874announce_cleanup:
875 ao2_cleanup(cap_slin);
876}
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
struct ast_channel * __ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int timeout, int *reason, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
Request a channel of a given type, with data as optional information used by the low level module and...
Definition: channel.c:5976
const char * ast_channel_language(const struct ast_channel *chan)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
char * strsep(char **str, const char *delims)
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define ast_verb(level,...)
#define LOG_WARNING
static void inherit_channel_vars_from_id(struct outgoing_helper *oh, const char *channel_id)
#define NULL
Definition: resample.c:96
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8253
const ast_string_field uniqueid
const ast_string_field number
const ast_string_field name
struct ast_channel_snapshot_base * base
struct ast_channel_snapshot_caller * caller
Main Channel structure associated with a channel.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct ast_variable * vars
Definition: channel.h:1112

References __ast_request_and_dial(), ao2_cleanup, ast_channel_language(), ast_channel_name(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_hangup(), ast_log, ast_say_digits(), ast_stopstream(), ast_streamfile(), ast_variable_new, ast_variables_destroy(), ast_verb, ast_waitstream(), ast_channel_snapshot::base, buf, ast_channel_snapshot::caller, inherit_channel_vars_from_id(), LOG_WARNING, ast_channel_snapshot_caller::name, NULL, ast_channel_snapshot_caller::number, strsep(), ast_channel_snapshot_base::uniqueid, and outgoing_helper::vars.

Referenced by park_announce_update_cb().

◆ apply_option_timeout()

static int apply_option_timeout ( int *  var,
char *  timeout_arg 
)
static

Definition at line 266 of file parking_applications.c.

267{
268 if (ast_strlen_zero(timeout_arg)) {
269 ast_log(LOG_ERROR, "No duration value provided for the timeout ('t') option.\n");
270 return -1;
271 }
272
273 if (sscanf(timeout_arg, "%d", var) != 1 || *var < 0) {
274 ast_log(LOG_ERROR, "Duration value provided for timeout ('t') option must be 0 or greater.\n");
275 return -1;
276 }
277
278 return 0;
279}
#define var
Definition: ast_expr2f.c:605
#define LOG_ERROR
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_log, ast_strlen_zero(), LOG_ERROR, and var.

Referenced by park_app_parse_data().

◆ get_park_common_datastore_copy()

struct park_common_datastore * get_park_common_datastore_copy ( struct ast_channel parkee)

Get a copy of the park_common_datastore from a channel that is being parked.

Since
12.0.0
Parameters
parkeeThe channel entering parking with the datastore we are checking
Returns
Pointer to a copy of the park common datastore for parkee if it could be cloned. This needs to be free'd with park_common_datastore free.
Return values
NULLif the park_common_datastore could not be copied off of the channel.

Definition at line 441 of file parking_applications.c.

442{
443 struct ast_datastore *datastore;
444 struct park_common_datastore *data;
445 struct park_common_datastore *data_copy;
446
447 SCOPED_CHANNELLOCK(lock, parkee);
448
449 if (!(datastore = ast_channel_datastore_find(parkee, &park_common_info, NULL))) {
450 return NULL;
451 }
452
453 data = datastore->data;
454
455 /* This data should always be populated if this datastore was appended to the channel */
456 ast_assert(data != NULL);
457
458 data_copy = ast_calloc(1, sizeof(*data_copy));
459 if (!data_copy) {
460 return NULL;
461 }
462
463 data_copy->parker_uuid = ast_strdup(data->parker_uuid);
464 if (!data_copy->parker_uuid) {
466 return NULL;
467 }
468
469 data_copy->randomize = data->randomize;
470 data_copy->time_limit = data->time_limit;
471 data_copy->silence_announce = data->silence_announce;
472
473 if (data->comeback_override) {
475 if (!data_copy->comeback_override) {
477 return NULL;
478 }
479 }
480
481 if (data->parker_dial_string) {
483 if (!data_copy->parker_dial_string) {
485 return NULL;
486 }
487 }
488
489 return data_copy;
490}
ast_mutex_t lock
Definition: app_sla.c:331
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:619
void park_common_datastore_free(struct park_common_datastore *datastore)
Free a park common datastore struct.
static const struct ast_datastore_info park_common_info
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
#define ast_assert(a)
Definition: utils.h:739

References ast_assert, ast_calloc, ast_channel_datastore_find(), ast_strdup, park_common_datastore::comeback_override, ast_datastore::data, lock, NULL, park_common_datastore_free(), park_common_info, park_common_datastore::parker_dial_string, park_common_datastore::parker_uuid, park_common_datastore::randomize, SCOPED_CHANNELLOCK, park_common_datastore::silence_announce, and park_common_datastore::time_limit.

Referenced by bridge_parking_push().

◆ inherit_channel_vars_from_id()

static void inherit_channel_vars_from_id ( struct outgoing_helper oh,
const char *  channel_id 
)
static

Definition at line 765 of file parking_applications.c.

766{
767 struct ast_channel *chan = ast_channel_get_by_name(channel_id);
768 struct ast_var_t *current;
769 struct ast_variable *newvar;
770 const char *varname;
771 int vartype;
772
773
774 if (!chan) {
775 /* Already gone */
776 return;
777 }
778
779 ast_channel_lock(chan);
780
781 AST_LIST_TRAVERSE(ast_channel_varshead((struct ast_channel *) chan), current, entries) {
782 varname = ast_var_full_name(current);
783 if (!varname) {
784 continue;
785 }
786
787 vartype = 0;
788 if (varname[0] == '_') {
789 vartype = 1;
790 if (varname[1] == '_') {
791 vartype = 2;
792 }
793 }
794
795 switch (vartype) {
796 case 1:
797 newvar = ast_variable_new(&varname[1], ast_var_value(current), "");
798 break;
799 case 2:
800 newvar = ast_variable_new(varname, ast_var_value(current), "");
801 break;
802 default:
803 continue;
804 }
805 if (newvar) {
806 ast_debug(1, "Inheriting variable %s from %s.\n",
807 newvar->name, ast_channel_name(chan));
808 if (oh->vars) {
809 newvar->next = oh->vars;
810 oh->vars = newvar;
811 }
812 }
813 }
814
815 ast_channel_unlock(chan);
817}
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define ast_channel_unlock(chan)
Definition: channel.h:2923
const char * ast_var_full_name(const struct ast_var_t *var)
Definition: chanvars.c:75
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
size_t current
Definition: main/cli.c:113
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

References ast_channel_cleanup, ast_channel_get_by_name(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_channel_varshead(), ast_debug, AST_LIST_TRAVERSE, ast_var_full_name(), ast_var_value(), ast_variable_new, current, ast_variable::name, ast_variable::next, and outgoing_helper::vars.

Referenced by announce_to_dial().

◆ load_parking_applications()

int load_parking_applications ( void  )

Register parking applications.

Since
12.0.0
Return values
0if successful
-1on failure

Definition at line 1008 of file parking_applications.c.

1009{
1011 return -1;
1012 }
1013
1015 return -1;
1016 }
1017
1019 return -1;
1020 }
1021
1022 return 0;
1023}
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
#define PARK_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
static int park_app_exec(struct ast_channel *chan, const char *data)
static int park_and_announce_app_exec(struct ast_channel *chan, const char *data)
static int parked_call_app_exec(struct ast_channel *chan, const char *data)
#define PARK_AND_ANNOUNCE_APPLICATION
#define PARKED_CALL_APPLICATION
Definition: res_parking.h:38

References ast_register_application_xml, park_and_announce_app_exec(), PARK_AND_ANNOUNCE_APPLICATION, park_app_exec(), PARK_APPLICATION, parked_call_app_exec(), and PARKED_CALL_APPLICATION.

Referenced by load_module().

◆ park_and_announce_app_exec()

static int park_and_announce_app_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 911 of file parking_applications.c.

912{
913 struct ast_bridge_features chan_features;
914 char *parse;
915 int res;
916 int silence_announcements = 1;
917
919 struct park_announce_subscription_data *pa_data;
920
921 RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
922
924 AST_APP_ARG(lot_name);
926 AST_APP_ARG(announce_template);
927 AST_APP_ARG(dial);
928 AST_APP_ARG(others);/* Any remaining unused arguments */
929 );
930
931 if (ast_strlen_zero(data)) {
932 ast_log(LOG_ERROR, "ParkAndAnnounce has required arguments. No arguments were provided.\n");
933 return -1;
934 }
935
936 parse = ast_strdupa(data);
938
939 if (ast_strlen_zero(args.announce_template)) {
940 /* improperly configured arguments for the application */
941 ast_log(LOG_ERROR, "ParkAndAnnounce requires the announce_template argument.\n");
942 return -1;
943 }
944
945 if (ast_strlen_zero(args.dial)) {
946 /* improperly configured arguments */
947 ast_log(LOG_ERROR, "ParkAndAnnounce requires the dial argument.\n");
948 return -1;
949 }
950
951 if (!strchr(args.dial, '/')) {
952 ast_log(LOG_ERROR, "ParkAndAnnounce dial string '%s' is improperly formed.\n", args.dial);
953 return -1;
954 }
955
956 /* Handle the common parking setup stuff */
957 if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
958 return 0;
959 }
960
961 /* Initialize bridge features for the channel. */
962 res = ast_bridge_features_init(&chan_features);
963 if (res) {
964 ast_bridge_features_cleanup(&chan_features);
965 return -1;
966 }
967
968 /* subscribe to the parking message so that we can announce once it is parked */
969 pa_data = park_announce_subscription_data_create(ast_channel_uniqueid(chan), args.dial, args.announce_template);
970 if (!pa_data) {
971 return -1;
972 }
973
975 /* Failed to create subscription */
977 return -1;
978 }
979
983
984 /* Now for the fun part... park it! */
985 ast_bridge_join(parking_bridge, chan, NULL, &chan_features, NULL, 0);
986
987 /* Toss the subscription since we aren't bridged at this point. */
989
990 /*
991 * If the bridge was broken for a hangup that isn't real, then
992 * don't run the h extension, because the channel isn't really
993 * hung up. This should only happen with AST_SOFTHANGUP_ASYNCGOTO.
994 */
995 res = -1;
996
997 ast_channel_lock(chan);
999 res = 0;
1000 }
1001 ast_channel_unlock(chan);
1002
1003 ast_bridge_features_cleanup(&chan_features);
1004
1005 return res;
1006}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
Join a channel to a bridge (blocking)
Definition: bridge.c:1621
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3620
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3653
static struct stasis_forward * parking_subscription
Our subscription for parking.
Definition: cdr.c:422
const char * ast_channel_uniqueid(const struct ast_channel *chan)
@ AST_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1126
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static void park_announce_update_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void park_announce_subscription_data_destroy(void *data)
static struct park_announce_subscription_data * park_announce_subscription_data_create(const char *parkee_uuid, const char *dial_string, const char *announce_string)
struct ast_bridge * park_application_setup(struct ast_channel *parkee, struct ast_channel *parker, const char *app_data, int *silence_announcements)
Function to prepare a channel for parking by determining which parking bridge should be used,...
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
Definition: stasis.h:297
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.
Definition: stasis.c:1023
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1077
#define stasis_subscribe_pool(topic, callback, data)
Definition: stasis.h:680
struct stasis_subscription * stasis_unsubscribe(struct stasis_subscription *subscription)
Cancel a subscription.
Definition: stasis.c:971
Structure that contains features information.
Structure that contains information about a bridge.
Definition: bridge.h:349
const char * args
static struct test_options options
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ao2_cleanup, args, AST_APP_ARG, ast_bridge_features_cleanup(), ast_bridge_features_init(), ast_bridge_join(), ast_channel_lock, ast_channel_softhangup_internal_flag(), ast_channel_uniqueid(), ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log, ast_parked_call_type(), ast_parking_topic(), AST_SOFTHANGUP_ASYNCGOTO, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_ERROR, NULL, options, park_announce_subscription_data_create(), park_announce_subscription_data_destroy(), park_announce_update_cb(), park_application_setup(), parking_subscription, RAII_VAR, stasis_subscribe_pool, stasis_subscription_accept_message_type(), stasis_subscription_change_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), and stasis_unsubscribe().

Referenced by load_parking_applications().

◆ park_announce_subscription_data_create()

static struct park_announce_subscription_data * park_announce_subscription_data_create ( const char *  parkee_uuid,
const char *  dial_string,
const char *  announce_string 
)
static

◆ park_announce_subscription_data_destroy()

static void park_announce_subscription_data_destroy ( void *  data)
static

◆ park_announce_update_cb()

static void park_announce_update_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 878 of file parking_applications.c.

879{
880 struct park_announce_subscription_data *pa_data = data;
881 char *dial_string = pa_data->dial_string;
882
884
887 return;
888 }
889
891 return;
892 }
893
894 if (payload->event_type != PARKED_CALL) {
895 /* We are only concerned with calls parked */
896 return;
897 }
898
899 if (strcmp(payload->parkee->base->uniqueid, pa_data->parkee_uuid)) {
900 /* We are only concerned with the parkee we are subscribed for. */
901 return;
902 }
903
904 if (!ast_strlen_zero(dial_string)) {
905 announce_to_dial(dial_string, pa_data->announce_string, payload->parkingspace, payload->parkee);
906 }
907
908 *dial_string = '\0'; /* If we observe this dial string on a second pass, we don't want to do anything with it. */
909}
@ PARKED_CALL
Definition: parking.h:47
static void announce_to_dial(char *dial_string, char *announce_string, int parkingspace, struct ast_channel_snapshot *parkee_snapshot)
struct stasis_forward * sub
Definition: res_corosync.c:240
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
Definition: stasis.c:1174
A parked call message payload.
Definition: parking.h:59
unsigned int parkingspace
Definition: parking.h:65
struct ast_channel_snapshot * parkee
Definition: parking.h:60
enum ast_parked_call_event_type event_type
Definition: parking.h:62

References park_announce_subscription_data::announce_string, announce_to_dial(), ast_parked_call_type(), ast_strlen_zero(), ast_channel_snapshot::base, park_announce_subscription_data::dial_string, ast_parked_call_payload::event_type, park_announce_subscription_data_destroy(), PARKED_CALL, ast_parked_call_payload::parkee, park_announce_subscription_data::parkee_uuid, ast_parked_call_payload::parkingspace, stasis_message_data(), stasis_message_type(), stasis_subscription_final_message(), sub, and ast_channel_snapshot_base::uniqueid.

Referenced by park_and_announce_app_exec().

◆ park_app_exec()

static int park_app_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 565 of file parking_applications.c.

566{
567 RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
568
569 struct ast_bridge_features chan_features;
570 int res = 0;
571 int silence_announcements = 0;
572 int blind_transfer;
573
574 /* Answer the channel if needed */
575 if (ast_channel_state(chan) != AST_STATE_UP) {
576 ast_answer(chan);
577 }
578
579 ast_channel_lock(chan);
580 blind_transfer = !ast_strlen_zero(pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"));
581 ast_channel_unlock(chan);
582
583 /* Handle the common parking setup stuff */
584 if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
585 if (!silence_announcements && !blind_transfer) {
586 ast_stream_and_wait(chan, "pbx-parkingfailed", "");
587 }
589 return 0;
590 }
591
592 /* Initialize bridge features for the channel. */
593 res = ast_bridge_features_init(&chan_features);
594 /* Now for the fun part... park it! */
595 if (res || ast_bridge_join(parking_bridge, chan, NULL, &chan_features, NULL, 0)) {
596 if (!silence_announcements && !blind_transfer) {
597 ast_stream_and_wait(chan, "pbx-parkingfailed", "");
598 }
599 ast_bridge_features_cleanup(&chan_features);
601 return res;
602 }
603
604 /*
605 * If the bridge was broken for a hangup that isn't real, then
606 * don't run the h extension, because the channel isn't really
607 * hung up. This should only happen with AST_SOFTHANGUP_ASYNCGOTO.
608 */
609 res = -1;
610
611 ast_channel_lock(chan);
613 res = 0;
614 }
615 ast_channel_unlock(chan);
616
617 ast_bridge_features_cleanup(&chan_features);
618
619 return res;
620}
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2805
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1878
void publish_parked_call_failure(struct ast_channel *parkee)
Publish a stasis parked call message for the channel indicating failure to park.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.

References ao2_cleanup, ast_answer(), ast_bridge_features_cleanup(), ast_bridge_features_init(), ast_bridge_join(), ast_channel_lock, ast_channel_softhangup_internal_flag(), ast_channel_unlock, AST_SOFTHANGUP_ASYNCGOTO, AST_STATE_UP, ast_stream_and_wait(), ast_strlen_zero(), NULL, park_application_setup(), pbx_builtin_getvar_helper(), publish_parked_call_failure(), and RAII_VAR.

Referenced by load_parking_applications().

◆ park_app_parse_data()

static int park_app_parse_data ( const char *  data,
int *  disable_announce,
int *  use_ringing,
int *  randomize,
int *  time_limit,
char **  comeback_override,
char **  lot_name,
char **  musicclass 
)
static

Definition at line 281 of file parking_applications.c.

283{
284 char *parse;
285 struct ast_flags flags = { 0 };
286
288 AST_APP_ARG(lot_name);
290 AST_APP_ARG(other); /* Any remaining unused arguments */
291 );
292
293 parse = ast_strdupa(data);
295
296 if (args.options) {
297 char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
298 ast_app_parse_options(park_opts, &flags, opts, args.options);
300 if (apply_option_timeout(time_limit, opts[OPT_ARG_TIMEOUT])) {
301 return -1;
302 }
303 }
304
306 *comeback_override = ast_strdup(opts[OPT_ARG_COMEBACK]);
307 }
308
310 if (disable_announce) {
311 *disable_announce = 1;
312 }
313 }
314
316 *musicclass = ast_strdup(opts[OPT_ARG_MUSICONHOLD]);
317 }
318
320 *use_ringing = 1;
321 }
322
324 *randomize = 1;
325 }
326 }
327
328 if (!ast_strlen_zero(args.lot_name)) {
329 *lot_name = ast_strdup(args.lot_name);
330 }
331
332 return 0;
333}
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3056
static const struct ast_app_option park_opts[128]
static int apply_option_timeout(int *var, char *timeout_arg)
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
#define ast_test_flag(p, flag)
Definition: utils.h:63

References apply_option_timeout(), args, AST_APP_ARG, ast_app_parse_options(), AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_flags::flags, MUXFLAG_COMEBACK_OVERRIDE, MUXFLAG_MUSICONHOLD, MUXFLAG_NOANNOUNCE, MUXFLAG_RANDOMIZE, MUXFLAG_RINGING, MUXFLAG_TIMEOUT_OVERRIDE, NULL, OPT_ARG_ARRAY_SIZE, OPT_ARG_COMEBACK, OPT_ARG_MUSICONHOLD, OPT_ARG_TIMEOUT, options, and park_opts.

Referenced by park_application_setup().

◆ park_application_setup()

struct ast_bridge * park_application_setup ( struct ast_channel parkee,
struct ast_channel parker,
const char *  app_data,
int *  silence_announcements 
)

Function to prepare a channel for parking by determining which parking bridge should be used, setting up a park common datastore so that the parking bridge will have access to necessary parking information when joining, and applying various bridge roles to the channel.

Since
12.0.0
Parameters
parkeeThe channel being prepared for parking
parkerThe channel initiating the park; may be the parkee as well. May be NULL.
app_dataarguments supplied to the Park application. May be NULL.
silence_announcementsoptional pointer to an integer where we want to store the silence option flag this value should be initialized to 0 prior to calling park_common_setup.
Returns
reference to a parking bridge if successful
Return values
NULLon failure
Note
ao2_cleanup this reference when you are done using it or you'll cause leaks.

Definition at line 545 of file parking_applications.c.

547{
548 int use_ringing = 0;
549 int randomize = 0;
550 int time_limit = -1;
551
552 RAII_VAR(char *, comeback_override, NULL, ast_free);
553 RAII_VAR(char *, lot_name_app_arg, NULL, ast_free);
554 RAII_VAR(char *, musicclass, NULL, ast_free);
555
556 if (app_data) {
557 park_app_parse_data(app_data, silence_announcements, &use_ringing, &randomize, &time_limit, &comeback_override, &lot_name_app_arg, &musicclass);
558 }
559
560 return park_common_setup2(parkee, parker, lot_name_app_arg, comeback_override, musicclass, use_ringing,
561 randomize, time_limit, silence_announcements ? *silence_announcements : 0);
562
563}
static int park_app_parse_data(const char *data, int *disable_announce, int *use_ringing, int *randomize, int *time_limit, char **comeback_override, char **lot_name, char **musicclass)
static struct ast_bridge * park_common_setup2(struct ast_channel *parkee, struct ast_channel *parker, const char *lot_name, const char *comeback_override, const char *musicclass, int use_ringing, int randomize, int time_limit, int silence_announcements)

References ast_free, NULL, park_app_parse_data(), park_common_setup2(), and RAII_VAR.

Referenced by park_and_announce_app_exec(), park_app_exec(), and parking_park_bridge_channel().

◆ park_common_datastore_destroy()

static void park_common_datastore_destroy ( void *  data)
static

Definition at line 347 of file parking_applications.c.

348{
349 struct park_common_datastore *datastore = data;
351}

References park_common_datastore_free().

◆ park_common_datastore_free()

void park_common_datastore_free ( struct park_common_datastore datastore)

Free a park common datastore struct.

Since
12.0.0
Parameters
datastoreThe park_common_datastore being free'd. (NULL tolerant)

Definition at line 335 of file parking_applications.c.

336{
337 if (!datastore) {
338 return;
339 }
340
341 ast_free(datastore->parker_uuid);
342 ast_free(datastore->parker_dial_string);
343 ast_free(datastore->comeback_override);
344 ast_free(datastore);
345}

References ast_free, park_common_datastore::comeback_override, park_common_datastore::parker_dial_string, and park_common_datastore::parker_uuid.

Referenced by bridge_parking_push(), get_park_common_datastore_copy(), and park_common_datastore_destroy().

◆ park_common_setup()

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.

Since
12.0.0

Definition at line 538 of file parking_applications.c.

541{
542 return park_common_setup2(parkee, parker, lot_name, comeback_override, NULL, use_ringing, randomize, time_limit, silence_announcements);
543}

References NULL, and park_common_setup2().

Referenced by manager_park_unbridged().

◆ park_common_setup2()

static struct ast_bridge * park_common_setup2 ( struct ast_channel parkee,
struct ast_channel parker,
const char *  lot_name,
const char *  comeback_override,
const char *  musicclass,
int  use_ringing,
int  randomize,
int  time_limit,
int  silence_announcements 
)
static

Definition at line 492 of file parking_applications.c.

495{
496 struct ast_bridge *parking_bridge;
497 RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
498
499 if (!parker) {
500 parker = parkee;
501 }
502
503 /* If the name of the parking lot isn't specified in the arguments, find it based on the channel. */
504 if (ast_strlen_zero(lot_name)) {
505 ast_channel_lock(parker);
506 lot_name = ast_strdupa(find_channel_parking_lot_name(parker));
507 ast_channel_unlock(parker);
508 }
509
510 lot = parking_lot_find_by_name(lot_name);
511 if (!lot) {
512 lot = parking_create_dynamic_lot(lot_name, parker);
513 }
514 if (!lot) {
515 ast_log(LOG_ERROR, "Could not find parking lot: '%s'\n", lot_name);
516 return NULL;
517 }
518
519 ao2_lock(lot);
520 parking_bridge = parking_lot_get_bridge(lot);
521 ao2_unlock(lot);
522
523 if (!parking_bridge) {
524 return NULL;
525 }
526
527 /* Apply relevant bridge roles and such to the parking channel */
528 parking_channel_set_roles(parkee, lot, use_ringing);
529 /* If requested, override the MOH class */
530 if (!ast_strlen_zero(musicclass)) {
531 ast_channel_set_bridge_role_option(parkee, "holding_participant", "moh_class", musicclass);
532 }
533 setup_park_common_datastore(parkee, ast_channel_uniqueid(parker), comeback_override, randomize, time_limit,
534 silence_announcements);
535 return parking_bridge;
536}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
int ast_channel_set_bridge_role_option(struct ast_channel *channel, const char *role_name, const char *option, const char *value)
Set a role option on a channel.
Definition: bridge_roles.c:375
static int setup_park_common_datastore(struct ast_channel *parkee, const char *parker_uuid, const char *comeback_override, int randomize, int time_limit, int silence_announce)
int parking_channel_set_roles(struct ast_channel *chan, struct parking_lot *lot, int force_ringing)
Set necessary bridge roles on a channel that is about to enter a parking lot.
struct ast_bridge * parking_lot_get_bridge(struct parking_lot *lot)
Get a reference to a parking lot's bridge. If it doesn't exist, create it and get a reference.
struct parking_lot * parking_create_dynamic_lot(const char *name, struct ast_channel *chan)
Create a dynamic parking lot.
Definition: res_parking.c:1060
const char * find_channel_parking_lot_name(struct ast_channel *chan)
Find parking lot name from channel.
Definition: res_parking.c:608
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
Definition: res_parking.c:602

References ao2_cleanup, ao2_lock, ao2_unlock, ast_channel_lock, ast_channel_set_bridge_role_option(), ast_channel_uniqueid(), ast_channel_unlock, ast_log, ast_strdupa, ast_strlen_zero(), find_channel_parking_lot_name(), LOG_ERROR, NULL, parking_channel_set_roles(), parking_create_dynamic_lot(), parking_lot_find_by_name(), parking_lot_get_bridge(), RAII_VAR, and setup_park_common_datastore().

Referenced by park_application_setup(), and park_common_setup().

◆ parked_call_app_exec()

static int parked_call_app_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 624 of file parking_applications.c.

625{
626 RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
627 RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup); /* Parked user being retrieved */
628 struct ast_bridge *retrieval_bridge;
629 int res;
630 int target_space = -1;
631 struct ast_bridge_features chan_features;
632 char *parse;
633 const char *lot_name;
634
636 AST_APP_ARG(lot_name);
637 AST_APP_ARG(parking_space);
638 AST_APP_ARG(other); /* Any remaining unused arguments */
639 );
640
641 parse = ast_strdupa(data);
643
644 /* Answer the channel if needed */
645 if (ast_channel_state(chan) != AST_STATE_UP) {
646 ast_answer(chan);
647 }
648
649 lot_name = args.lot_name;
650
651 /* If the name of the parking lot isn't in the arguments, find it based on the channel. */
652 if (ast_strlen_zero(lot_name)) {
653 ast_channel_lock(chan);
655 ast_channel_unlock(chan);
656 }
657
658 lot = parking_lot_find_by_name(lot_name);
659 if (!lot) {
660 ast_log(LOG_ERROR, "Could not find the requested parking lot\n");
661 ast_stream_and_wait(chan, "pbx-invalidpark", "");
662 return -1;
663 }
664
665 if (!ast_strlen_zero(args.parking_space)) {
666 if (sscanf(args.parking_space, "%d", &target_space) != 1 || target_space < 0) {
667 ast_stream_and_wait(chan, "pbx-invalidpark", "");
668 ast_log(LOG_ERROR, "value '%s' for parking_space argument is invalid. Must be an integer greater than 0.\n", args.parking_space);
669 return -1;
670 }
671 }
672
673 /* Attempt to get the parked user from the parking lot */
674 pu = parking_lot_retrieve_parked_user(lot, target_space);
675 if (!pu) {
676 ast_stream_and_wait(chan, "pbx-invalidpark", "");
677 return -1;
678 }
679
680 /* The parked call needs to know who is retrieving it before we move it out of the parking bridge */
681 ast_assert(pu->retriever == NULL);
682 pu->retriever = ast_channel_snapshot_create(chan);
683
684 /* Create bridge */
685 retrieval_bridge = ast_bridge_basic_new();
686 if (!retrieval_bridge) {
687 return -1;
688 }
689
690 /* Move the parkee into the new bridge */
691 if (ast_bridge_move(retrieval_bridge, lot->parking_bridge, pu->chan, NULL, 0)) {
692 ast_bridge_destroy(retrieval_bridge, 0);
693 return -1;
694 }
695
696 /* Initialize our bridge features */
697 res = ast_bridge_features_init(&chan_features);
698 if (res) {
699 ast_bridge_destroy(retrieval_bridge, 0);
700 ast_bridge_features_cleanup(&chan_features);
701 return -1;
702 }
703
704 /* Set the features */
706
707 /* If the parkedplay option is set for the caller to hear, play that tone now. */
708 if (lot->cfg->parkedplay & AST_FEATURE_FLAG_BYCALLER) {
709 ast_stream_and_wait(chan, lot->cfg->courtesytone, NULL);
710 }
711
712 /* Now we should try to join the new bridge ourselves... */
713 ast_bridge_join(retrieval_bridge, chan, NULL, &chan_features, NULL,
715
716 ast_bridge_features_cleanup(&chan_features);
717
718 /* Return -1 so that call does not continue in the dialplan. This is to make
719 * behavior consistent with Asterisk versions prior to 12.
720 */
721 return -1;
722}
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
@ AST_BRIDGE_JOIN_PASS_REFERENCE
Definition: bridge.h:535
int ast_bridge_move(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
Move a channel from one bridge to another.
Definition: bridge.c:2460
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
@ AST_FEATURE_FLAG_BYCALLER
Definition: features.h:38
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.
void parked_call_retrieve_enable_features(struct ast_channel *chan, struct parking_lot *lot, int recipient_mode)
Apply features based on the parking lot feature options.
struct parked_user * parking_lot_retrieve_parked_user(struct parking_lot *lot, int target)
Determine if there is a parked user in a parking space and pull it from the parking lot if there is.

References ao2_cleanup, args, ast_answer(), AST_APP_ARG, ast_assert, ast_bridge_basic_new(), ast_bridge_destroy(), ast_bridge_features_cleanup(), ast_bridge_features_init(), ast_bridge_join(), AST_BRIDGE_JOIN_PASS_REFERENCE, ast_bridge_move(), ast_channel_lock, ast_channel_snapshot_create(), ast_channel_unlock, AST_DECLARE_APP_ARGS, AST_FEATURE_FLAG_BYCALLER, ast_log, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_stream_and_wait(), ast_strlen_zero(), find_channel_parking_lot_name(), LOG_ERROR, NULL, parked_call_retrieve_enable_features(), parking_lot_find_by_name(), parking_lot_retrieve_parked_user(), and RAII_VAR.

Referenced by load_parking_applications().

◆ setup_park_common_datastore()

static int setup_park_common_datastore ( struct ast_channel parkee,
const char *  parker_uuid,
const char *  comeback_override,
int  randomize,
int  time_limit,
int  silence_announce 
)
static

Definition at line 371 of file parking_applications.c.

372{
373 struct ast_datastore *datastore = NULL;
374 struct park_common_datastore *park_datastore;
375 const char *attended_transfer;
376 const char *blind_transfer;
377 char *parker_dial_string = NULL;
378
380
381 if (!(datastore = ast_datastore_alloc(&park_common_info, NULL))) {
382 return -1;
383 }
384
385 if (!(park_datastore = ast_calloc(1, sizeof(*park_datastore)))) {
386 ast_datastore_free(datastore);
387 return -1;
388 }
389 datastore->data = park_datastore;
390
391 park_datastore->parker_uuid = ast_strdup(parker_uuid);
392 if (!park_datastore->parker_uuid) {
393 ast_datastore_free(datastore);
394 return -1;
395 }
396
397 ast_channel_lock(parkee);
398 attended_transfer = pbx_builtin_getvar_helper(parkee, "ATTENDEDTRANSFER");
399 blind_transfer = pbx_builtin_getvar_helper(parkee, "BLINDTRANSFER");
400 if (!ast_strlen_zero(attended_transfer)) {
401 parker_dial_string = ast_strdupa(attended_transfer);
402 } else if (!ast_strlen_zero(blind_transfer)) {
403 parker_dial_string = ast_strdupa(blind_transfer);
404 /* Ensure that attended_transfer is NULL and not an empty string. */
405 attended_transfer = NULL;
406 }
407 ast_channel_unlock(parkee);
408
411 ast_verb(4, "Setting Parker dial string to %s from %s value\n",
413 attended_transfer ? "ATTENDEDTRANSFER" : "BLINDTRANSFER");
415 if (!park_datastore->parker_dial_string) {
416 ast_datastore_free(datastore);
417 return -1;
418 }
419 }
420
421 park_datastore->randomize = randomize;
422 park_datastore->time_limit = time_limit;
423 park_datastore->silence_announce = silence_announce;
424
425 if (comeback_override) {
427 if (!park_datastore->comeback_override) {
428 ast_datastore_free(datastore);
429 return -1;
430 }
431 }
432
433
434 ast_channel_lock(parkee);
435 ast_channel_datastore_add(parkee, datastore);
436 ast_channel_unlock(parkee);
437
438 return 0;
439}
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
void ast_channel_name_to_dial_string(char *channel_name)
Removes the trailing identifiers from a channel name string.
Definition: channel.c:6839
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
static void wipe_park_common_datastore(struct ast_channel *chan)

References ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_name_to_dial_string(), ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_verb, park_common_datastore::comeback_override, ast_datastore::data, NULL, park_common_info, park_common_datastore::parker_dial_string, park_common_datastore::parker_uuid, pbx_builtin_getvar_helper(), park_common_datastore::randomize, park_common_datastore::silence_announce, park_common_datastore::time_limit, and wipe_park_common_datastore().

Referenced by park_common_setup2().

◆ unload_parking_applications()

void unload_parking_applications ( void  )

Unregister parking applications.

Since
12.0.0

Definition at line 1025 of file parking_applications.c.

1026{
1030}
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References ast_unregister_application(), PARK_AND_ANNOUNCE_APPLICATION, PARK_APPLICATION, and PARKED_CALL_APPLICATION.

Referenced by unload_module().

◆ wipe_park_common_datastore()

static void wipe_park_common_datastore ( struct ast_channel chan)
static

Definition at line 358 of file parking_applications.c.

359{
360 struct ast_datastore *datastore;
361
362 ast_channel_lock(chan);
364 if (datastore) {
365 ast_channel_datastore_remove(chan, datastore);
366 ast_datastore_free(datastore);
367 }
368 ast_channel_unlock(chan);
369}
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2394

References ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_datastore_free(), NULL, and park_common_info.

Referenced by setup_park_common_datastore().

Variable Documentation

◆ park_common_info

const struct ast_datastore_info park_common_info
static
Initial value:
= {
.type = "park entry data",
}
static void park_common_datastore_destroy(void *data)

Definition at line 353 of file parking_applications.c.

Referenced by get_park_common_datastore_copy(), setup_park_common_datastore(), and wipe_park_common_datastore().

◆ park_opts

const struct ast_app_option park_opts[128] = { [ 'r' ] = { .flag = MUXFLAG_RINGING }, [ 'R' ] = { .flag = MUXFLAG_RANDOMIZE }, [ 's' ] = { .flag = MUXFLAG_NOANNOUNCE }, [ 'c' ] = { .flag = MUXFLAG_COMEBACK_OVERRIDE , .arg_index = OPT_ARG_COMEBACK + 1 }, [ 't' ] = { .flag = MUXFLAG_TIMEOUT_OVERRIDE , .arg_index = OPT_ARG_TIMEOUT + 1 }, [ 'm' ] = { .flag = MUXFLAG_MUSICONHOLD , .arg_index = OPT_ARG_MUSICONHOLD + 1 }, }
static

Definition at line 264 of file parking_applications.c.

Referenced by park_app_parse_data().