Asterisk - The Open Source Telephony Project  18.5.0
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_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)
}
 

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)
 
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 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 }, }
 

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"

Enumeration Type Documentation

◆ park_args

enum park_args
Enumerator
OPT_ARG_COMEBACK 
OPT_ARG_TIMEOUT 
OPT_ARG_ARRAY_SIZE 

Definition at line 241 of file parking_applications.c.

241  {
244  OPT_ARG_ARRAY_SIZE /* Always the last element of the enum */
245 };

◆ park_flags

enum park_flags
Enumerator
MUXFLAG_RINGING 
MUXFLAG_RANDOMIZE 
MUXFLAG_NOANNOUNCE 
MUXFLAG_COMEBACK_OVERRIDE 
MUXFLAG_TIMEOUT_OVERRIDE 

Definition at line 247 of file parking_applications.c.

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 800 of file parking_applications.c.

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().

801 {
802  struct ast_channel *dchan;
803  struct outgoing_helper oh = { 0, };
804  int outstate;
806  char buf[13];
807  char *dial_tech;
808  char *cur_announce;
809 
810  dial_tech = strsep(&dial_string, "/");
811  ast_verb(3, "Dial Tech,String: (%s,%s)\n", dial_tech, dial_string);
812 
813  if (!cap_slin) {
814  ast_log(LOG_WARNING, "PARK: Failed to announce park.\n");
815  goto announce_cleanup;
816  }
818 
819  snprintf(buf, sizeof(buf), "%d", parkingspace);
820  oh.vars = ast_variable_new("_PARKEDAT", buf, "");
821 
822  inherit_channel_vars_from_id(&oh, parkee_snapshot->base->uniqueid);
823 
824  dchan = __ast_request_and_dial(dial_tech, cap_slin, NULL, NULL, dial_string, 30000,
825  &outstate,
826  parkee_snapshot->caller->number,
827  parkee_snapshot->caller->name,
828  &oh);
829 
831  if (!dchan) {
832  ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
833  goto announce_cleanup;
834  }
835 
836  ast_verb(4, "Announce Template: %s\n", announce_string);
837 
838  for (cur_announce = strsep(&announce_string, ":"); cur_announce; cur_announce = strsep(&announce_string, ":")) {
839  ast_verb(4, "Announce:%s\n", cur_announce);
840  if (!strcmp(cur_announce, "PARKED")) {
841  ast_say_digits(dchan, parkingspace, "", ast_channel_language(dchan));
842  } else {
843  int dres = ast_streamfile(dchan, cur_announce, ast_channel_language(dchan));
844  if (!dres) {
845  dres = ast_waitstream(dchan, "");
846  } else {
847  ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", cur_announce, ast_channel_name(dchan));
848  }
849  }
850  }
851 
852  ast_stopstream(dchan);
853  ast_hangup(dchan);
854 
855 announce_cleanup:
856  ao2_cleanup(cap_slin);
857 }
Main Channel structure associated with a channel.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
struct ast_channel_snapshot_base * base
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
const ast_string_field name
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8349
const ast_string_field uniqueid
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_variable * vars
Definition: channel.h:1113
#define ast_log
Definition: astobj2.c:42
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_variable_new(name, value, filename)
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
struct ast_channel_snapshot_caller * caller
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
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:6066
char * strsep(char **str, const char *delims)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const ast_string_field number
const char * ast_channel_name(const struct ast_channel *chan)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
static void inherit_channel_vars_from_id(struct outgoing_helper *oh, const char *channel_id)

◆ apply_option_timeout()

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

Definition at line 263 of file parking_applications.c.

References ast_log, ast_strlen_zero, and LOG_ERROR.

Referenced by park_app_parse_data().

264 {
265  if (ast_strlen_zero(timeout_arg)) {
266  ast_log(LOG_ERROR, "No duration value provided for the timeout ('t') option.\n");
267  return -1;
268  }
269 
270  if (sscanf(timeout_arg, "%d", var) != 1 || *var < 0) {
271  ast_log(LOG_ERROR, "Duration value provided for timeout ('t') option must be 0 or greater.\n");
272  return -1;
273  }
274 
275  return 0;
276 }
#define var
Definition: ast_expr2f.c:614
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285

◆ 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
Return values
Pointerto 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.
NULLif the park_common_datastore could not be copied off of the channel.

Definition at line 433 of file parking_applications.c.

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_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().

434 {
435  struct ast_datastore *datastore;
436  struct park_common_datastore *data;
437  struct park_common_datastore *data_copy;
438 
439  SCOPED_CHANNELLOCK(lock, parkee);
440 
441  if (!(datastore = ast_channel_datastore_find(parkee, &park_common_info, NULL))) {
442  return NULL;
443  }
444 
445  data = datastore->data;
446 
447  /* This data should always be populated if this datastore was appended to the channel */
448  ast_assert(data != NULL);
449 
450  data_copy = ast_calloc(1, sizeof(*data_copy));
451  if (!data_copy) {
452  return NULL;
453  }
454 
455  data_copy->parker_uuid = ast_strdup(data->parker_uuid);
456  if (!data_copy->parker_uuid) {
457  park_common_datastore_free(data_copy);
458  return NULL;
459  }
460 
461  data_copy->randomize = data->randomize;
462  data_copy->time_limit = data->time_limit;
463  data_copy->silence_announce = data->silence_announce;
464 
465  if (data->comeback_override) {
466  data_copy->comeback_override = ast_strdup(data->comeback_override);
467  if (!data_copy->comeback_override) {
468  park_common_datastore_free(data_copy);
469  return NULL;
470  }
471  }
472 
473  if (data->parker_dial_string) {
475  if (!data_copy->parker_dial_string) {
476  park_common_datastore_free(data_copy);
477  return NULL;
478  }
479  }
480 
481  return data_copy;
482 }
void park_common_datastore_free(struct park_common_datastore *datastore)
Free a park common datastore struct.
#define ast_assert(a)
Definition: utils.h:695
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
static const struct ast_datastore_info park_common_info
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void * data
Definition: datastore.h:70

◆ inherit_channel_vars_from_id()

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

Definition at line 746 of file parking_applications.c.

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, ast_variable::name, ast_variable::next, and outgoing_helper::vars.

Referenced by announce_to_dial().

747 {
748  struct ast_channel *chan = ast_channel_get_by_name(channel_id);
749  struct ast_var_t *current;
750  struct ast_variable *newvar;
751  const char *varname;
752  int vartype;
753 
754 
755  if (!chan) {
756  /* Already gone */
757  return;
758  }
759 
760  ast_channel_lock(chan);
761 
762  AST_LIST_TRAVERSE(ast_channel_varshead((struct ast_channel *) chan), current, entries) {
763  varname = ast_var_full_name(current);
764  if (!varname) {
765  continue;
766  }
767 
768  vartype = 0;
769  if (varname[0] == '_') {
770  vartype = 1;
771  if (varname[1] == '_') {
772  vartype = 2;
773  }
774  }
775 
776  switch (vartype) {
777  case 1:
778  newvar = ast_variable_new(&varname[1], ast_var_value(current), "");
779  break;
780  case 2:
781  newvar = ast_variable_new(varname, ast_var_value(current), "");
782  break;
783  default:
784  continue;
785  }
786  if (newvar) {
787  ast_debug(1, "Inheriting variable %s from %s.\n",
788  newvar->name, ast_channel_name(chan));
789  if (oh->vars) {
790  newvar->next = oh->vars;
791  oh->vars = newvar;
792  }
793  }
794  }
795 
796  ast_channel_unlock(chan);
797  ast_channel_cleanup(chan);
798 }
struct ast_variable * next
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
Structure for variables, used for configurations and for channel variables.
struct varshead * ast_channel_varshead(struct ast_channel *chan)
struct ast_variable * vars
Definition: channel.h:1113
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ast_variable_new(name, value, filename)
const char * ast_var_full_name(const struct ast_var_t *var)
Definition: chanvars.c:75
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454

◆ load_parking_applications()

int load_parking_applications ( void  )

Register parking applications.

Since
12.0.0
Return values
0if successful
-1on failure

Definition at line 989 of file parking_applications.c.

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().

990 {
992  return -1;
993  }
994 
996  return -1;
997  }
998 
1000  return -1;
1001  }
1002 
1003  return 0;
1004 }
#define PARK_AND_ANNOUNCE_APPLICATION
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_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
#define PARKED_CALL_APPLICATION
Definition: res_parking.h:38
static int park_app_exec(struct ast_channel *chan, const char *data)
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ park_and_announce_app_exec()

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

Definition at line 892 of file parking_applications.c.

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, parse(), 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().

893 {
894  struct ast_bridge_features chan_features;
895  char *parse;
896  int res;
897  int silence_announcements = 1;
898 
900  struct park_announce_subscription_data *pa_data;
901 
902  RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
903 
905  AST_APP_ARG(lot_name);
907  AST_APP_ARG(announce_template);
908  AST_APP_ARG(dial);
909  AST_APP_ARG(others);/* Any remaining unused arguments */
910  );
911 
912  if (ast_strlen_zero(data)) {
913  ast_log(LOG_ERROR, "ParkAndAnnounce has required arguments. No arguments were provided.\n");
914  return -1;
915  }
916 
917  parse = ast_strdupa(data);
918  AST_STANDARD_APP_ARGS(args, parse);
919 
920  if (ast_strlen_zero(args.announce_template)) {
921  /* improperly configured arguments for the application */
922  ast_log(LOG_ERROR, "ParkAndAnnounce requires the announce_template argument.\n");
923  return -1;
924  }
925 
926  if (ast_strlen_zero(args.dial)) {
927  /* improperly configured arguments */
928  ast_log(LOG_ERROR, "ParkAndAnnounce requires the dial argument.\n");
929  return -1;
930  }
931 
932  if (!strchr(args.dial, '/')) {
933  ast_log(LOG_ERROR, "ParkAndAnnounce dial string '%s' is improperly formed.\n", args.dial);
934  return -1;
935  }
936 
937  /* Handle the common parking setup stuff */
938  if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
939  return 0;
940  }
941 
942  /* Initialize bridge features for the channel. */
943  res = ast_bridge_features_init(&chan_features);
944  if (res) {
945  ast_bridge_features_cleanup(&chan_features);
946  return -1;
947  }
948 
949  /* subscribe to the parking message so that we can announce once it is parked */
950  pa_data = park_announce_subscription_data_create(ast_channel_uniqueid(chan), args.dial, args.announce_template);
951  if (!pa_data) {
952  return -1;
953  }
954 
955  if (!(parking_subscription = stasis_subscribe_pool(ast_parking_topic(), park_announce_update_cb, pa_data))) {
956  /* Failed to create subscription */
958  return -1;
959  }
960 
964 
965  /* Now for the fun part... park it! */
966  ast_bridge_join(parking_bridge, chan, NULL, &chan_features, NULL, 0);
967 
968  /* Toss the subscription since we aren't bridged at this point. */
969  stasis_unsubscribe(parking_subscription);
970 
971  /*
972  * If the bridge was broken for a hangup that isn't real, then
973  * don't run the h extension, because the channel isn't really
974  * hung up. This should only happen with AST_SOFTHANGUP_ASYNCGOTO.
975  */
976  res = -1;
977 
978  ast_channel_lock(chan);
980  res = 0;
981  }
982  ast_channel_unlock(chan);
983 
984  ast_bridge_features_cleanup(&chan_features);
985 
986  return res;
987 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3720
Structure that contains features information.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3687
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:1079
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
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...
#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:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_uniqueid(const struct ast_channel *chan)
Structure that contains information about a bridge.
Definition: bridge.h:357
#define LOG_ERROR
Definition: logger.h:285
#define stasis_subscribe_pool(topic, callback, data)
Definition: stasis.h:682
struct stasis_subscription * stasis_unsubscribe(struct stasis_subscription *subscription)
Cancel a subscription.
Definition: stasis.c:973
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static void park_announce_subscription_data_destroy(void *data)
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:1667
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
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:1025
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
static void park_announce_update_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static struct test_options options
static struct stasis_forward * parking_subscription
Our subscription for parking.
Definition: cdr.c:380
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ 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

Definition at line 718 of file parking_applications.c.

References park_announce_subscription_data::announce_string, ast_calloc, ast_strdup, park_announce_subscription_data::dial_string, NULL, park_announce_subscription_data_destroy(), and park_announce_subscription_data::parkee_uuid.

Referenced by park_and_announce_app_exec().

721 {
722  struct park_announce_subscription_data *pa_data;
723 
724  if (!(pa_data = ast_calloc(1, sizeof(*pa_data)))) {
725  return NULL;
726  }
727 
728  if (!(pa_data->parkee_uuid = ast_strdup(parkee_uuid))
729  || !(pa_data->dial_string = ast_strdup(dial_string))
730  || !(pa_data->announce_string = ast_strdup(announce_string))) {
732  return NULL;
733  }
734 
735  return pa_data;
736 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static void park_announce_subscription_data_destroy(void *data)

◆ 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 859 of file parking_applications.c.

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(), and ast_channel_snapshot_base::uniqueid.

Referenced by park_and_announce_app_exec().

860 {
861  struct park_announce_subscription_data *pa_data = data;
862  char *dial_string = pa_data->dial_string;
863 
864  struct ast_parked_call_payload *payload = stasis_message_data(message);
865 
866  if (stasis_subscription_final_message(sub, message)) {
868  return;
869  }
870 
871  if (ast_parked_call_type() != stasis_message_type(message)) {
872  return;
873  }
874 
875  if (payload->event_type != PARKED_CALL) {
876  /* We are only concerned with calls parked */
877  return;
878  }
879 
880  if (strcmp(payload->parkee->base->uniqueid, pa_data->parkee_uuid)) {
881  /* We are only concerned with the parkee we are subscribed for. */
882  return;
883  }
884 
885  if (!ast_strlen_zero(dial_string)) {
886  announce_to_dial(dial_string, pa_data->announce_string, payload->parkingspace, payload->parkee);
887  }
888 
889  *dial_string = '\0'; /* If we observe this dial string on a second pass, we don't want to do anything with it. */
890 }
struct ast_channel_snapshot_base * base
static void announce_to_dial(char *dial_string, char *announce_string, int parkingspace, struct ast_channel_snapshot *parkee_snapshot)
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
const ast_string_field uniqueid
A parked call message payload.
Definition: parking.h:59
enum ast_parked_call_event_type event_type
Definition: parking.h:62
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_channel_snapshot * parkee
Definition: parking.h:60
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
unsigned int parkingspace
Definition: parking.h:65
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:1176
static void park_announce_subscription_data_destroy(void *data)

◆ park_app_exec()

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

Definition at line 545 of file parking_applications.c.

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().

546 {
547  RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
548 
549  struct ast_bridge_features chan_features;
550  int res;
551  int silence_announcements = 0;
552  int blind_transfer;
553 
554  /* Answer the channel if needed */
555  if (ast_channel_state(chan) != AST_STATE_UP) {
556  ast_answer(chan);
557  }
558 
559  ast_channel_lock(chan);
560  blind_transfer = !ast_strlen_zero(pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"));
561  ast_channel_unlock(chan);
562 
563  /* Handle the common parking setup stuff */
564  if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
565  if (!silence_announcements && !blind_transfer) {
566  ast_stream_and_wait(chan, "pbx-parkingfailed", "");
567  }
569  return 0;
570  }
571 
572  /* Initialize bridge features for the channel. */
573  res = ast_bridge_features_init(&chan_features);
574  if (res) {
575  ast_bridge_features_cleanup(&chan_features);
577  return -1;
578  }
579 
580  /* Now for the fun part... park it! */
581  ast_bridge_join(parking_bridge, chan, NULL, &chan_features, NULL, 0);
582 
583  /*
584  * If the bridge was broken for a hangup that isn't real, then
585  * don't run the h extension, because the channel isn't really
586  * hung up. This should only happen with AST_SOFTHANGUP_ASYNCGOTO.
587  */
588  res = -1;
589 
590  ast_channel_lock(chan);
592  res = 0;
593  }
594  ast_channel_unlock(chan);
595 
596  ast_bridge_features_cleanup(&chan_features);
597 
598  return res;
599 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3720
Structure that contains features information.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3687
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define NULL
Definition: resample.c:96
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
void publish_parked_call_failure(struct ast_channel *parkee)
Publish a stasis parked call message for the channel indicating failure to park.
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...
#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:911
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_channel_unlock(chan)
Definition: channel.h:2946
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:1814
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:1667
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814

◆ 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 
)
static

Definition at line 278 of file parking_applications.c.

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, MUXFLAG_COMEBACK_OVERRIDE, MUXFLAG_NOANNOUNCE, MUXFLAG_RANDOMIZE, MUXFLAG_RINGING, MUXFLAG_TIMEOUT_OVERRIDE, NULL, OPT_ARG_ARRAY_SIZE, OPT_ARG_COMEBACK, OPT_ARG_TIMEOUT, options, park_opts, and parse().

Referenced by park_application_setup().

279 {
280  char *parse;
281  struct ast_flags flags = { 0 };
282 
284  AST_APP_ARG(lot_name);
286  AST_APP_ARG(other); /* Any remaining unused arguments */
287  );
288 
289  parse = ast_strdupa(data);
290  AST_STANDARD_APP_ARGS(args, parse);
291 
292  if (args.options) {
293  char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
294  ast_app_parse_options(park_opts, &flags, opts, args.options);
296  if (apply_option_timeout(time_limit, opts[OPT_ARG_TIMEOUT])) {
297  return -1;
298  }
299  }
300 
302  *comeback_override = ast_strdup(opts[OPT_ARG_COMEBACK]);
303  }
304 
305  if (ast_test_flag(&flags, MUXFLAG_NOANNOUNCE)) {
306  if (disable_announce) {
307  *disable_announce = 1;
308  }
309  }
310 
311  if (ast_test_flag(&flags, MUXFLAG_RINGING)) {
312  *use_ringing = 1;
313  }
314 
315  if (ast_test_flag(&flags, MUXFLAG_RANDOMIZE)) {
316  *randomize = 1;
317  }
318  }
319 
320  if (!ast_strlen_zero(args.lot_name)) {
321  *lot_name = ast_strdup(args.lot_name);
322  }
323 
324  return 0;
325 }
static int apply_option_timeout(int *var, char *timeout_arg)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
unsigned int flags
Definition: utils.h:200
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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:2906
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
Structure used to handle boolean flags.
Definition: utils.h:199
static struct test_options options
static const struct ast_app_option park_opts[128]
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ 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 preparred 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.
Return values
referenceto a parking bridge if successful
NULLon failure
Note
ao2_cleanup this reference when you are done using it or you'll cause leaks.

Definition at line 526 of file parking_applications.c.

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

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

528 {
529  int use_ringing = 0;
530  int randomize = 0;
531  int time_limit = -1;
532 
533  RAII_VAR(char *, comeback_override, NULL, ast_free);
534  RAII_VAR(char *, lot_name_app_arg, NULL, ast_free);
535 
536  if (app_data) {
537  park_app_parse_data(app_data, silence_announcements, &use_ringing, &randomize, &time_limit, &comeback_override, &lot_name_app_arg);
538  }
539 
540  return park_common_setup(parkee, parker, lot_name_app_arg, comeback_override, use_ringing,
541  randomize, time_limit, silence_announcements ? *silence_announcements : 0);
542 
543 }
#define NULL
Definition: resample.c:96
#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:911
#define ast_free(a)
Definition: astmm.h:182
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)
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.

◆ park_common_datastore_destroy()

static void park_common_datastore_destroy ( void *  data)
static

Definition at line 339 of file parking_applications.c.

References park_common_datastore_free().

340 {
341  struct park_common_datastore *datastore = data;
342  park_common_datastore_free(datastore);
343 }
void park_common_datastore_free(struct park_common_datastore *datastore)
Free a park common datastore struct.

◆ 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 327 of file parking_applications.c.

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().

328 {
329  if (!datastore) {
330  return;
331  }
332 
333  ast_free(datastore->parker_uuid);
334  ast_free(datastore->parker_dial_string);
335  ast_free(datastore->comeback_override);
336  ast_free(datastore);
337 }
#define ast_free(a)
Definition: astmm.h:182

◆ 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 484 of file parking_applications.c.

References ao2_cleanup, ao2_lock, ao2_unlock, ast_channel_lock, 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 manager_park_unbridged(), and park_application_setup().

487 {
488  struct ast_bridge *parking_bridge;
489  RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
490 
491  if (!parker) {
492  parker = parkee;
493  }
494 
495  /* If the name of the parking lot isn't specified in the arguments, find it based on the channel. */
496  if (ast_strlen_zero(lot_name)) {
497  ast_channel_lock(parker);
498  lot_name = ast_strdupa(find_channel_parking_lot_name(parker));
499  ast_channel_unlock(parker);
500  }
501 
502  lot = parking_lot_find_by_name(lot_name);
503  if (!lot) {
504  lot = parking_create_dynamic_lot(lot_name, parker);
505  }
506  if (!lot) {
507  ast_log(LOG_ERROR, "Could not find parking lot: '%s'\n", lot_name);
508  return NULL;
509  }
510 
511  ao2_lock(lot);
512  parking_bridge = parking_lot_get_bridge(lot);
513  ao2_unlock(lot);
514 
515  if (!parking_bridge) {
516  return NULL;
517  }
518 
519  /* Apply relevant bridge roles and such to the parking channel */
520  parking_channel_set_roles(parkee, lot, use_ringing);
521  setup_park_common_datastore(parkee, ast_channel_uniqueid(parker), comeback_override, randomize, time_limit,
522  silence_announcements);
523  return parking_bridge;
524 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
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)
struct parking_lot * parking_create_dynamic_lot(const char *name, struct ast_channel *chan)
Create a dynamic parking lot.
Definition: res_parking.c:1059
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
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.
#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:911
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_uniqueid(const struct ast_channel *chan)
Structure that contains information about a bridge.
Definition: bridge.h:357
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
Definition: res_parking.c:601
const char * find_channel_parking_lot_name(struct ast_channel *chan)
Find parking lot name from channel.
Definition: res_parking.c:607
struct ast_bridge * parking_lot_get_bridge(struct parking_lot *lot)
Get a reference to a parking lot&#39;s bridge. If it doesn&#39;t exist, create it and get a reference...

◆ parked_call_app_exec()

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

Definition at line 603 of file parking_applications.c.

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(), parse(), and RAII_VAR.

Referenced by load_parking_applications().

604 {
605  RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
606  RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup); /* Parked user being retrieved */
607  struct ast_bridge *retrieval_bridge;
608  int res;
609  int target_space = -1;
610  struct ast_bridge_features chan_features;
611  char *parse;
612  const char *lot_name;
613 
615  AST_APP_ARG(lot_name);
616  AST_APP_ARG(parking_space);
617  AST_APP_ARG(other); /* Any remaining unused arguments */
618  );
619 
620  parse = ast_strdupa(data);
621  AST_STANDARD_APP_ARGS(args, parse);
622 
623  /* Answer the channel if needed */
624  if (ast_channel_state(chan) != AST_STATE_UP) {
625  ast_answer(chan);
626  }
627 
628  lot_name = args.lot_name;
629 
630  /* If the name of the parking lot isn't in the arguments, find it based on the channel. */
631  if (ast_strlen_zero(lot_name)) {
632  ast_channel_lock(chan);
633  lot_name = ast_strdupa(find_channel_parking_lot_name(chan));
634  ast_channel_unlock(chan);
635  }
636 
637  lot = parking_lot_find_by_name(lot_name);
638  if (!lot) {
639  ast_log(LOG_ERROR, "Could not find the requested parking lot\n");
640  ast_stream_and_wait(chan, "pbx-invalidpark", "");
641  return -1;
642  }
643 
644  if (!ast_strlen_zero(args.parking_space)) {
645  if (sscanf(args.parking_space, "%d", &target_space) != 1 || target_space < 0) {
646  ast_stream_and_wait(chan, "pbx-invalidpark", "");
647  ast_log(LOG_ERROR, "value '%s' for parking_space argument is invalid. Must be an integer greater than 0.\n", args.parking_space);
648  return -1;
649  }
650  }
651 
652  /* Attempt to get the parked user from the parking lot */
653  pu = parking_lot_retrieve_parked_user(lot, target_space);
654  if (!pu) {
655  ast_stream_and_wait(chan, "pbx-invalidpark", "");
656  return -1;
657  }
658 
659  /* The parked call needs to know who is retrieving it before we move it out of the parking bridge */
660  ast_assert(pu->retriever == NULL);
661  pu->retriever = ast_channel_snapshot_create(chan);
662 
663  /* Create bridge */
664  retrieval_bridge = ast_bridge_basic_new();
665  if (!retrieval_bridge) {
666  return -1;
667  }
668 
669  /* Move the parkee into the new bridge */
670  if (ast_bridge_move(retrieval_bridge, lot->parking_bridge, pu->chan, NULL, 0)) {
671  ast_bridge_destroy(retrieval_bridge, 0);
672  return -1;
673  }
674 
675  /* Initialize our bridge features */
676  res = ast_bridge_features_init(&chan_features);
677  if (res) {
678  ast_bridge_destroy(retrieval_bridge, 0);
679  ast_bridge_features_cleanup(&chan_features);
680  return -1;
681  }
682 
683  /* Set the features */
685 
686  /* If the parkedplay option is set for the caller to hear, play that tone now. */
687  if (lot->cfg->parkedplay & AST_FEATURE_FLAG_BYCALLER) {
688  ast_stream_and_wait(chan, lot->cfg->courtesytone, NULL);
689  }
690 
691  /* Now we should try to join the new bridge ourselves... */
692  ast_bridge_join(retrieval_bridge, chan, NULL, &chan_features, NULL,
694 
695  ast_bridge_features_cleanup(&chan_features);
696 
697  /* Return -1 so that call does not continue in the dialplan. This is to make
698  * behavior consistent with Asterisk versions prior to 12.
699  */
700  return -1;
701 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3720
Structure that contains features information.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3687
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.
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
#define ast_assert(a)
Definition: utils.h:695
const char * args
#define NULL
Definition: resample.c:96
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...
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...
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#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:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
Structure that contains information about a bridge.
Definition: bridge.h:357
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
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:1814
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:1667
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
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:2508
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
Definition: res_parking.c:601
const char * find_channel_parking_lot_name(struct ast_channel *chan)
Find parking lot name from channel.
Definition: res_parking.c:607
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ 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 363 of file parking_applications.c.

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_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_setup().

364 {
365  struct ast_datastore *datastore = NULL;
366  struct park_common_datastore *park_datastore;
367  const char *attended_transfer;
368  const char *blind_transfer;
369  char *parker_dial_string = NULL;
370 
372 
373  if (!(datastore = ast_datastore_alloc(&park_common_info, NULL))) {
374  return -1;
375  }
376 
377  if (!(park_datastore = ast_calloc(1, sizeof(*park_datastore)))) {
378  ast_datastore_free(datastore);
379  return -1;
380  }
381  datastore->data = park_datastore;
382 
383  park_datastore->parker_uuid = ast_strdup(parker_uuid);
384  if (!park_datastore->parker_uuid) {
385  ast_datastore_free(datastore);
386  return -1;
387  }
388 
389  ast_channel_lock(parkee);
390  attended_transfer = pbx_builtin_getvar_helper(parkee, "ATTENDEDTRANSFER");
391  blind_transfer = pbx_builtin_getvar_helper(parkee, "BLINDTRANSFER");
392  if (!ast_strlen_zero(attended_transfer)) {
393  parker_dial_string = ast_strdupa(attended_transfer);
394  } else if (!ast_strlen_zero(blind_transfer)) {
395  parker_dial_string = ast_strdupa(blind_transfer);
396  /* Ensure that attended_transfer is NULL and not an empty string. */
397  attended_transfer = NULL;
398  }
399  ast_channel_unlock(parkee);
400 
401  if (!ast_strlen_zero(parker_dial_string)) {
402  ast_channel_name_to_dial_string(parker_dial_string);
403  ast_verb(4, "Setting Parker dial string to %s from %s value\n",
404  parker_dial_string,
405  attended_transfer ? "ATTENDEDTRANSFER" : "BLINDTRANSFER");
406  park_datastore->parker_dial_string = ast_strdup(parker_dial_string);
407  if (!park_datastore->parker_dial_string) {
408  ast_datastore_free(datastore);
409  return -1;
410  }
411  }
412 
413  park_datastore->randomize = randomize;
414  park_datastore->time_limit = time_limit;
415  park_datastore->silence_announce = silence_announce;
416 
417  if (comeback_override) {
419  if (!park_datastore->comeback_override) {
420  ast_datastore_free(datastore);
421  return -1;
422  }
423  }
424 
425 
426  ast_channel_lock(parkee);
427  ast_channel_datastore_add(parkee, datastore);
428  ast_channel_unlock(parkee);
429 
430  return 0;
431 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
static const struct ast_datastore_info park_common_info
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
void ast_channel_name_to_dial_string(char *channel_name)
Removes the trailing identifiers from a channel name string.
Definition: channel.c:6934
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void * data
Definition: datastore.h:70
static void wipe_park_common_datastore(struct ast_channel *chan)
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390

◆ unload_parking_applications()

void unload_parking_applications ( void  )

Unregister parking applications.

Since
12.0.0

Definition at line 1006 of file parking_applications.c.

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

Referenced by unload_module().

1007 {
1011 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
#define PARK_AND_ANNOUNCE_APPLICATION
#define PARK_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
#define PARKED_CALL_APPLICATION
Definition: res_parking.h:38

◆ wipe_park_common_datastore()

static void wipe_park_common_datastore ( struct ast_channel chan)
static

Definition at line 350 of file parking_applications.c.

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

Referenced by setup_park_common_datastore().

351 {
352  struct ast_datastore *datastore;
353 
354  ast_channel_lock(chan);
355  datastore = ast_channel_datastore_find(chan, &park_common_info, NULL);
356  if (datastore) {
357  ast_channel_datastore_remove(chan, datastore);
358  ast_datastore_free(datastore);
359  }
360  ast_channel_unlock(chan);
361 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
static const struct ast_datastore_info park_common_info
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2399

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 345 of file parking_applications.c.

◆ 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 }, }
static

Definition at line 261 of file parking_applications.c.

Referenced by park_app_parse_data().