Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Enumerations | Functions
res_parking.h File Reference

Call Parking Resource Internal API. More...

#include "asterisk/pbx.h"
#include "asterisk/bridge.h"
#include "asterisk/parking.h"
#include "asterisk/stasis_channels.h"
Include dependency graph for res_parking.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  park_common_datastore
 
struct  parked_user
 
struct  parking_lot
 
struct  parking_lot_cfg
 

Macros

#define BASE_REGISTRAR   "res_parking"
 
#define DEFAULT_PARKING_EXTEN   "700"
 
#define DEFAULT_PARKING_LOT   "default"
 
#define PARK_DIAL_CONTEXT   "park-dial"
 
#define PARKED_CALL_APPLICATION   "ParkedCall"
 

Enumerations

enum  park_call_resolution {
  PARK_UNSET = 0, PARK_ABANDON, PARK_TIMEOUT, PARK_FORCED,
  PARK_ANSWERED
}
 
enum  parked_call_feature_options {
  OPT_PARKEDPLAY = 0, OPT_PARKEDTRANSFERS, OPT_PARKEDREPARKING, OPT_PARKEDHANGUP,
  OPT_PARKEDRECORDING
}
 
enum  parking_lot_modes { PARKINGLOT_NORMAL = 0, PARKINGLOT_DYNAMIC, PARKINGLOT_DISABLED }
 

Functions

struct ast_bridgebridge_parking_new (struct parking_lot *bridge_lot)
 Create a new parking bridge. More...
 
int comeback_goto (struct parked_user *pu, struct parking_lot *lot)
 Set a channel's position in the PBX after timeout using the parking lot settings. More...
 
int create_parked_subscription (struct ast_channel *chan, const char *parkee_uuid, int hangup_after)
 Create a parking announcement subscription. More...
 
const char * find_channel_parking_lot_name (struct ast_channel *chan)
 Find parking lot name from channel. More...
 
void flatten_dial_string (char *dialstring)
 Flattens a dial string so that it can be written to/found from PBX extensions. More...
 
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...
 
struct ao2_containerget_parking_lot_container (void)
 Get a pointer to the parking lot container for purposes such as iteration. More...
 
int load_parking_applications (void)
 Register parking applications. More...
 
int load_parking_bridge_features (void)
 Register bridge features for parking. More...
 
int load_parking_devstate (void)
 Register Parking devstate handler. More...
 
int load_parking_manager (void)
 Register manager actions and setup subscriptions for stasis events. More...
 
int load_parking_tests (void)
 Register parking unit tests. More...
 
int load_parking_ui (void)
 Register CLI commands. More...
 
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...
 
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...
 
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. More...
 
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. More...
 
struct parking_lotparking_create_dynamic_lot (const char *name, struct ast_channel *chan)
 Create a dynamic parking lot. More...
 
struct parking_lotparking_create_dynamic_lot_forced (const char *name, struct ast_channel *chan)
 Create a dynamic parking lot without respect to whether they are enabled by configuration. More...
 
int parking_dynamic_lots_enabled (void)
 Check global configuration to see if dynamic parking is enabled. More...
 
struct parking_lotparking_lot_build_or_update (struct parking_lot_cfg *cfg, int dynamic)
 If a parking lot exists in the parking lot list already, update its status to match the provided configuration and return a reference return a reference to it. Otherwise, create a parking lot struct based on a parking lot configuration and return a reference to the new one. More...
 
struct parking_lot_cfgparking_lot_cfg_create (const char *cat)
 Create an empty parking lot configuration structure useful for unit tests. More...
 
int parking_lot_cfg_create_extensions (struct parking_lot_cfg *lot_cfg)
 Add extensions for a parking lot configuration. More...
 
void parking_lot_cfg_remove_extensions (struct parking_lot_cfg *lot_cfg)
 Remove extensions belonging to a parking lot configuration. More...
 
struct parking_lotparking_lot_find_by_name (const char *lot_name)
 Find a parking lot based on its name. More...
 
struct ast_bridgeparking_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. More...
 
int parking_lot_get_space (struct parking_lot *lot, int target_override)
 Get an available parking space within a parking lot. More...
 
struct parked_userparking_lot_inspect_parked_user (struct parking_lot *lot, int target)
 Determine if there is a parked user in a parking space and return it if there is. More...
 
int parking_lot_remove_if_unused (struct parking_lot *lot)
 Remove a parking lot from the usable lists if it is no longer involved in any calls and no configuration currently claims it. More...
 
struct parked_userparking_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. More...
 
void parking_notify_metermaids (int exten, const char *context, enum ast_device_state state)
 Notify metermaids that we've changed an extension. More...
 
void parking_set_duration (struct ast_bridge_features *features, struct parked_user *user)
 Setup timeout interval feature on an ast_bridge_features for parking. More...
 
void publish_parked_call (struct parked_user *pu, enum ast_parked_call_event_type event_type)
 Publish a stasis parked call message for a given parked user. More...
 
void publish_parked_call_failure (struct ast_channel *parkee)
 Publish a stasis parked call message for the channel indicating failure to park. More...
 
void say_parking_space (struct ast_bridge_channel *bridge_channel, const char *payload)
 custom callback function for ast_bridge_channel_queue_playfile which plays a parking space and optionally hangs up the call afterwards based on the payload in playfile. More...
 
void unload_parking_applications (void)
 Unregister parking applications. More...
 
void unload_parking_bridge_features (void)
 Unregister features registered by load_parking_bridge_features. More...
 
void unload_parking_devstate (void)
 Unregister Parking devstate handler. More...
 
void unload_parking_manager (void)
 Unregister manager actions and remove subscriptions for stasis events. More...
 
void unload_parking_tests (void)
 Unregister parking unit tests. More...
 
void unload_parking_ui (void)
 Unregister CLI commands. More...
 
int unpark_parked_user (struct parked_user *user)
 Pull a parked user out of its parking lot. Use this when you don't want to use the parked user afterwards. More...
 

Detailed Description

Call Parking Resource Internal API.

Author
Jonathan Rose jrose[email protected]@dig[email protected]ium.c[email protected]om

Definition in file res_parking.h.

Macro Definition Documentation

◆ BASE_REGISTRAR

#define BASE_REGISTRAR   "res_parking"

◆ DEFAULT_PARKING_EXTEN

#define DEFAULT_PARKING_EXTEN   "700"

Definition at line 35 of file res_parking.h.

Referenced by verify_default_parking_lot().

◆ DEFAULT_PARKING_LOT

#define DEFAULT_PARKING_LOT   "default"

◆ PARK_DIAL_CONTEXT

#define PARK_DIAL_CONTEXT   "park-dial"

Definition at line 37 of file res_parking.h.

Referenced by comeback_goto(), and parking_duration_callback().

◆ PARKED_CALL_APPLICATION

#define PARKED_CALL_APPLICATION   "ParkedCall"

Enumeration Type Documentation

◆ park_call_resolution

Enumerator
PARK_UNSET 
PARK_ABANDON 

Nothing set a resolution. This should never be observed in practice.

PARK_TIMEOUT 

The channel for the parked call hung up

PARK_FORCED 

The parked call stayed parked until the parking lot timeout was reached and was removed

PARK_ANSWERED 

The parked call was forcibly terminated by an unusual means in Asterisk

Definition at line 40 of file res_parking.h.

40  {
41  PARK_UNSET = 0, /*! Nothing set a resolution. This should never be observed in practice. */
42  PARK_ABANDON, /*! The channel for the parked call hung up */
43  PARK_TIMEOUT, /*! The parked call stayed parked until the parking lot timeout was reached and was removed */
44  PARK_FORCED, /*! The parked call was forcibly terminated by an unusual means in Asterisk */
45  PARK_ANSWERED, /*! The parked call was retrieved successfully */
46 };

◆ parked_call_feature_options

Enumerator
OPT_PARKEDPLAY 
OPT_PARKEDTRANSFERS 
OPT_PARKEDREPARKING 
OPT_PARKEDHANGUP 
OPT_PARKEDRECORDING 

Definition at line 48 of file res_parking.h.

◆ parking_lot_modes

Enumerator
PARKINGLOT_NORMAL 
PARKINGLOT_DYNAMIC 

The parking lot is configured normally and can accept new calls. Disable on reload if the config isn't replaced. valid transitions: PARKINGLOT_DISABLED

PARKINGLOT_DISABLED 

The parking lot is a dynamically created parking lot. It can be parked to at any time. Disabled on last parked call leaving. valid transitions: PARKINGLOT_DISABLED

Definition at line 56 of file res_parking.h.

56  {
57  PARKINGLOT_NORMAL = 0, /*! The parking lot is configured normally and can accept new calls. Disable on reload if the config isn't replaced.
58  * valid transitions: PARKINGLOT_DISABLED */
59  PARKINGLOT_DYNAMIC, /*! The parking lot is a dynamically created parking lot. It can be parked to at any time. Disabled on last parked call leaving.
60  * valid transitions: PARKINGLOT_DISABLED */
61  PARKINGLOT_DISABLED, /*! The parking lot is no longer linked to a parking lot in configuration. It can no longer be parked to.
62  * and it can not be parked to. This mode has no transitions. */
63 };

Function Documentation

◆ bridge_parking_new()

struct ast_bridge* bridge_parking_new ( struct parking_lot bridge_lot)

Create a new parking bridge.

Since
12.0.0
Parameters
bridge_lotParking lot which the new bridge should be based on
Return values
NULLif the bridge can not be created
Newlycreated parking bridge

Definition at line 456 of file parking_bridge.c.

References AST_BRIDGE_CAPABILITY_HOLDING, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO, AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, ast_bridge_parking_init(), bridge_alloc(), bridge_base_init(), bridge_register(), parking_lot::name, and NULL.

Referenced by parking_lot_get_bridge().

457 {
458  void *bridge;
459 
463  | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, "Parking", bridge_lot->name, NULL);
464  bridge = ast_bridge_parking_init(bridge, bridge_lot);
465  bridge = bridge_register(bridge);
466  return bridge;
467 }
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:709
#define NULL
Definition: resample.c:96
static struct ast_bridge * ast_bridge_parking_init(struct ast_bridge_parking *self, struct parking_lot *bridge_lot)
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:724
struct ast_bridge * bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Initialize the base class of the bridge.
Definition: bridge.c:760
const ast_string_field name
Definition: res_parking.h:100
struct ast_bridge_methods ast_bridge_parking_v_table

◆ comeback_goto()

int comeback_goto ( struct parked_user pu,
struct parking_lot lot 
)

Set a channel's position in the PBX after timeout using the parking lot settings.

Since
12.0.0
Parameters
puParked user who is entering/reentering the PBX
lotParking lot the user was removed from.
Return values
0Position set successfully
-1Failed to set the position

Definition at line 261 of file parking_controller.c.

References ast_async_goto(), ast_channel_name(), ast_exists_extension(), ast_log, ast_strdupa, ast_verb, parking_lot::cfg, parked_user::chan, parking_lot_cfg::comebackcontext, parking_lot_cfg::comebacktoorigin, flatten_dial_string(), LOG_ERROR, NULL, PARK_DIAL_CONTEXT, and parked_user::parker_dial_string.

Referenced by parking_duration_callback().

262 {
263  struct ast_channel *chan = pu->chan;
264  char *peername_flat = ast_strdupa(pu->parker_dial_string);
265 
266  /* Flatten the peername so that it can be used for performing the timeout PBX operations */
267  flatten_dial_string(peername_flat);
268 
269  if (lot->cfg->comebacktoorigin) {
270  if (ast_exists_extension(chan, PARK_DIAL_CONTEXT, peername_flat, 1, NULL)) {
271  ast_async_goto(chan, PARK_DIAL_CONTEXT, peername_flat, 1);
272  return 0;
273  } else {
274  ast_log(LOG_ERROR, "Can not start %s at %s,%s,1 because extension does not exist. Terminating call.\n",
275  ast_channel_name(chan), PARK_DIAL_CONTEXT, peername_flat);
276  return -1;
277  }
278  }
279 
280  if (ast_exists_extension(chan, lot->cfg->comebackcontext, peername_flat, 1, NULL)) {
281  ast_async_goto(chan, lot->cfg->comebackcontext, peername_flat, 1);
282  return 0;
283  }
284 
285  if (ast_exists_extension(chan, lot->cfg->comebackcontext, "s", 1, NULL)) {
286  ast_verb(2, "Could not start %s at %s,%s,1. Using '[email protected]%s' instead.\n", ast_channel_name(chan),
287  lot->cfg->comebackcontext, peername_flat, lot->cfg->comebackcontext);
288  ast_async_goto(chan, lot->cfg->comebackcontext, "s", 1);
289  return 0;
290  }
291 
292  ast_verb(2, "Can not start %s at %s,%s,1 and exten '[email protected]%s' does not exist. Using '[email protected]'\n",
293  ast_channel_name(chan),
294  lot->cfg->comebackcontext, peername_flat, lot->cfg->comebackcontext);
295  ast_async_goto(chan, "default", "s", 1);
296 
297  return 0;
298 }
Main Channel structure associated with a channel.
#define PARK_DIAL_CONTEXT
Definition: res_parking.h:37
const ast_string_field comebackcontext
Definition: res_parking.h:89
void flatten_dial_string(char *dialstring)
Flattens a dial string so that it can be written to/found from PBX extensions.
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
char * parker_dial_string
Definition: res_parking.h:109
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
unsigned int comebacktoorigin
Definition: res_parking.h:74
#define LOG_ERROR
Definition: logger.h:285
const char * ast_channel_name(const struct ast_channel *chan)
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:7011
struct ast_channel * chan
Definition: res_parking.h:104
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

◆ create_parked_subscription()

int create_parked_subscription ( struct ast_channel chan,
const char *  parkee_uuid,
int  hangup_after 
)

Create a parking announcement subscription.

Since
12.3.0
Parameters
chanChannel that will receive the announcement
parkee_uuidUnique ID of the channel being parked
hangup_afterif non-zero, have the channel hangup after hearing the announcement
Return values
0on success
-1on failure

Definition at line 233 of file parking_bridge_features.c.

References create_parked_subscription_full(), and NULL.

Referenced by manager_park(), and manager_park_bridged().

234 {
235  return create_parked_subscription_full(chan, parkee_uuid, hangup_after, NULL);
236 }
#define NULL
Definition: resample.c:96
static int create_parked_subscription_full(struct ast_channel *chan, const char *parkee_uuid, int hangup_after, struct transfer_channel_data *parked_channel_data)

◆ find_channel_parking_lot_name()

const char* find_channel_parking_lot_name ( struct ast_channel chan)

Find parking lot name from channel.

Since
12.0.0
Parameters
chanThe channel we want the parking lot name for
Returns
name of the parking lot to use for the channel.
Note
Always returns a parking lot name.
Channel needs to be locked while the returned string is in use.

Definition at line 607 of file res_parking.c.

References ast_channel_parkinglot(), ast_strlen_zero, DEFAULT_PARKING_LOT, name, and pbx_builtin_getvar_helper().

Referenced by park_common_setup(), parked_call_app_exec(), and parking_park_call().

608 {
609  const char *name;
610 
611  /* The channel variable overrides everything */
612  name = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
613  if (ast_strlen_zero(name)) {
614  /* Try the channel's parking lot. */
615  name = ast_channel_parkinglot(chan);
616  if (ast_strlen_zero(name)) {
617  /* Fall back to the default parking lot. */
618  name = DEFAULT_PARKING_LOT;
619  }
620  }
621 
622  return name;
623 }
#define DEFAULT_PARKING_LOT
Definition: res_parking.h:34
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 char name[]
Definition: cdr_mysql.c:74
const char * ast_channel_parkinglot(const struct ast_channel *chan)

◆ flatten_dial_string()

void flatten_dial_string ( char *  dialstring)

Flattens a dial string so that it can be written to/found from PBX extensions.

Since
12.0.0
Parameters
peernameunflattened dial string. This will be flattened in place.

Definition at line 249 of file parking_controller.c.

Referenced by comeback_goto(), and parking_duration_callback().

250 {
251  int i;
252 
253  for (i = 0; dialstring[i]; i++) {
254  if (dialstring[i] == '/') {
255  /* The underscore is the flattest character of all. */
256  dialstring[i] = '_';
257  }
258  }
259 }

◆ 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

◆ get_parking_lot_container()

struct ao2_container* get_parking_lot_container ( void  )

Get a pointer to the parking lot container for purposes such as iteration.

Since
12.0.0
Return values
pointerto the parking lot container.

Definition at line 596 of file res_parking.c.

References parking_lot_container.

Referenced by cli_display_parking_lot_list(), complete_parking_lot(), manager_parking_lot_list(), manager_parking_status_all_lots(), and metermaidstate().

597 {
598  return parking_lot_container;
599 }
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266

◆ 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

◆ load_parking_bridge_features()

int load_parking_bridge_features ( void  )

Register bridge features for parking.

Since
12.0.0
Return values
0on success
-1on failure

Definition at line 802 of file parking_bridge_features.c.

References AST_BRIDGE_BUILTIN_PARKCALL, ast_bridge_features_register(), ast_custom_function_register, ast_parking_register_bridge_features(), feature_park_call(), ast_parking_bridge_feature_fn_table::module, and NULL.

Referenced by load_module().

803 {
804  parking_provider.module = AST_MODULE_SELF;
805 
807 
809  return -1;
810  }
811 
813  return -1;
814  }
815 
816  return 0;
817 }
#define NULL
Definition: resample.c:96
int ast_parking_register_bridge_features(struct ast_parking_bridge_feature_fn_table *fn_table)
Register a parking provider.
Definition: parking.c:196
struct ast_module * module
The module info for the module registering this parking provider.
Definition: parking.h:202
struct ast_parking_bridge_feature_fn_table parking_provider
int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf)
Register a handler for a built in feature.
Definition: bridge.c:3123
static struct ast_custom_function getparkingslotchannel_function
static int feature_park_call(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508

◆ load_parking_devstate()

int load_parking_devstate ( void  )

Register Parking devstate handler.

Since
12.0.0

Definition at line 121 of file parking_devicestate.c.

References ast_devstate_prov_add(), and metermaidstate().

Referenced by load_module().

122 {
123  return ast_devstate_prov_add("Park", metermaidstate);
124 }
static enum ast_device_state metermaidstate(const char *data)
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
Definition: devicestate.c:391

◆ load_parking_manager()

int load_parking_manager ( void  )

Register manager actions and setup subscriptions for stasis events.

Since
12.0.0

Definition at line 694 of file parking_manager.c.

References ast_manager_register_xml, EVENT_FLAG_CALL, manager_park(), manager_parking_lot_list(), manager_parking_status(), and parking_manager_enable_stasis().

Referenced by load_module().

695 {
696  int res;
697 
702  return res ? -1 : 0;
703 }
static int manager_park(struct mansession *s, const struct message *m)
static void parking_manager_enable_stasis(void)
static int manager_parking_status(struct mansession *s, const struct message *m)
static int manager_parking_lot_list(struct mansession *s, const struct message *m)
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:186

◆ load_parking_tests()

int load_parking_tests ( void  )

Register parking unit tests.

Since
12.0.0
Return values
0on success
nonzeroon failure

Definition at line 851 of file parking_tests.c.

References AST_TEST_REGISTER.

Referenced by load_module().

852 {
853  int res = 0;
854 
855 /* NOOP without test framework */
856 #if defined(TEST_FRAMEWORK)
857  res |= AST_TEST_REGISTER(create_lot);
858  res |= AST_TEST_REGISTER(park_call);
859  res |= AST_TEST_REGISTER(retrieve_call);
860  res |= AST_TEST_REGISTER(park_extensions);
861  res |= AST_TEST_REGISTER(extension_conflicts);
862  res |= AST_TEST_REGISTER(dynamic_parking_variables);
863 #endif
864 
865  return res;
866 }
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

◆ load_parking_ui()

int load_parking_ui ( void  )

Register CLI commands.

Since
12.0.0
Return values
0if successful
-1on failure

Definition at line 198 of file parking_ui.c.

References ARRAY_LEN, and ast_cli_register_multiple.

Referenced by load_module().

199 {
201 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct ast_cli_entry cli_parking_lot[]
Definition: parking_ui.c:194

◆ 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 
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_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's bridge. If it doesn't exist, create it and get a reference...

◆ parked_call_retrieve_enable_features()

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.

Since
12.0.0
Parameters
chanWhich channel's feature set is being modified
lotparking lot which establishes the features used
recipient_modeAST_FEATURE_FLAG_BYCALLER if the user is the retriever AST_FEATURE_FLAG_BYCALLEE if the user is the parkee

Definition at line 215 of file parking_controller.c.

References ast_bridge_features_ds_get(), ast_bridge_features_ds_set(), ast_channel_lock, ast_channel_unlock, AST_FEATURE_AUTOMIXMON, AST_FEATURE_DISCONNECT, AST_FEATURE_PARKCALL, AST_FEATURE_REDIRECT, ast_set_flag, parking_lot::cfg, parking_lot_cfg::parkedcallhangup, parking_lot_cfg::parkedcallrecording, parking_lot_cfg::parkedcallreparking, and parking_lot_cfg::parkedcalltransfers.

Referenced by bridge_parking_pull(), and parked_call_app_exec().

216 {
217  /* Enabling features here should be additive to features that are already on the channel. */
218  struct ast_flags feature_flags = { 0 };
219  struct ast_flags *existing_features;
220 
221  ast_channel_lock(chan);
222  existing_features = ast_bridge_features_ds_get(chan);
223  if (existing_features) {
224  feature_flags = *existing_features;
225  }
226 
227  if (lot->cfg->parkedcalltransfers & recipient_mode) {
228  ast_set_flag(&feature_flags, AST_FEATURE_REDIRECT);
229  }
230 
231  if (lot->cfg->parkedcallreparking & recipient_mode) {
232  ast_set_flag(&feature_flags, AST_FEATURE_PARKCALL);
233  }
234 
235  if (lot->cfg->parkedcallhangup & recipient_mode) {
236  ast_set_flag(&feature_flags, AST_FEATURE_DISCONNECT);
237  }
238 
239  if (lot->cfg->parkedcallrecording & recipient_mode) {
240  ast_set_flag(&feature_flags, AST_FEATURE_AUTOMIXMON);
241  }
242 
243  ast_bridge_features_ds_set(chan, &feature_flags);
244  ast_channel_unlock(chan);
245 
246  return;
247 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
int parkedcallreparking
Definition: res_parking.h:77
#define ast_set_flag(p, flag)
Definition: utils.h:70
int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags)
Set basic bridge DTMF feature flags datastore on the channel.
Definition: bridge_basic.c:258
struct ast_flags * ast_bridge_features_ds_get(struct ast_channel *chan)
Get DTMF feature flags from the channel.
Definition: bridge_basic.c:268
#define ast_channel_unlock(chan)
Definition: channel.h:2946
Structure used to handle boolean flags.
Definition: utils.h:199
int parkedcalltransfers
Definition: res_parking.h:76
int parkedcallrecording
Definition: res_parking.h:79
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

◆ parking_channel_set_roles()

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.

Since
12.0.0
Parameters
chanEntering channel
lotThe parking lot the channel will be entering
force_ringingUse ringing instead of music on hold
Return values
0on success
non-zeroon failure

Definition at line 57 of file parking_controller.c.

References ast_channel_add_bridge_role(), ast_channel_set_bridge_role_option(), ast_strlen_zero, parking_lot::cfg, and parking_lot_cfg::mohclass.

Referenced by bridge_parking_push(), and park_common_setup().

58 {
59  if (ast_channel_add_bridge_role(chan, "holding_participant")) {
60  return -1;
61  }
62 
63  if (force_ringing) {
64  if (ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "ringing")) {
65  return -1;
66  }
67  } else {
68  if (ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "musiconhold")) {
69  return -1;
70  }
71  if (!ast_strlen_zero(lot->cfg->mohclass)) {
72  if (ast_channel_set_bridge_role_option(chan, "holding_participant", "moh_class", lot->cfg->mohclass)) {
73  return -1;
74  }
75  }
76  }
77 
78  return 0;
79 }
int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name)
Adds a bridge role to a channel.
Definition: bridge_roles.c:317
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:379
const ast_string_field mohclass
Definition: res_parking.h:89
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

◆ parking_create_dynamic_lot()

struct parking_lot* parking_create_dynamic_lot ( const char *  name,
struct ast_channel chan 
)

Create a dynamic parking lot.

Since
12.0.0
Parameters
nameDynamic parking lot name to create
chanChannel parkee to get dynamic parking lot parameters from
Return values
dynamicallycreated parking lot on success
NULLon error
Note
This should be called only after verifying that the named parking lot doesn't already exist in a non-dynamic way.

Definition at line 1059 of file res_parking.c.

References create_dynamic_lot_full().

Referenced by park_common_setup(), and parking_park_call().

1059  {
1060  return create_dynamic_lot_full(name, chan, 0);
1061 }
static struct parking_lot * create_dynamic_lot_full(const char *name, struct ast_channel *chan, int forced)
Definition: res_parking.c:970
static const char name[]
Definition: cdr_mysql.c:74

◆ parking_create_dynamic_lot_forced()

struct parking_lot* parking_create_dynamic_lot_forced ( const char *  name,
struct ast_channel chan 
)

Create a dynamic parking lot without respect to whether they are enabled by configuration.

Since
12.0.0
Parameters
nameDynamic parking lot name to create
chanChannel parkee to get the dynamic parking lot parameters from
Return values
dynamicallycreated parking lot on success
NULLon error
Note
This should be called only after verifying that the named parking lot doesn't already exist in a non-dynamic way.

Definition at line 1064 of file res_parking.c.

References create_dynamic_lot_full().

Referenced by AST_TEST_DEFINE().

1064  {
1065  return create_dynamic_lot_full(name, chan, 1);
1066 }
static struct parking_lot * create_dynamic_lot_full(const char *name, struct ast_channel *chan, int forced)
Definition: res_parking.c:970
static const char name[]
Definition: cdr_mysql.c:74

◆ parking_dynamic_lots_enabled()

int parking_dynamic_lots_enabled ( void  )

Check global configuration to see if dynamic parking is enabled.

Since
12.0.0
Return values
1if dynamic parking is enabled
0if dynamic parking is disabled

Definition at line 928 of file res_parking.c.

References ao2_cleanup, ao2_global_obj_ref, globals, and RAII_VAR.

Referenced by cli_display_parking_global(), and create_dynamic_lot_full().

929 {
931 
932  if (!cfg) {
933  return 0;
934  }
935 
936  return cfg->global->parkeddynamic;
937 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#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
static struct console_pvt globals
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ parking_lot_build_or_update()

struct parking_lot* parking_lot_build_or_update ( struct parking_lot_cfg cfg,
int  dynamic 
)

If a parking lot exists in the parking lot list already, update its status to match the provided configuration and return a reference return a reference to it. Otherwise, create a parking lot struct based on a parking lot configuration and return a reference to the new one.

Since
12.0.0
Parameters
cfgThe configuration being used as a reference to build the parking lot from.
dynamicnon-zero if creating a dynamic parking lot with this. Don't replace existing parking lots. Ever.
Return values
Areference to the new parking lot
NULLif it was not found and could not be allocated
Note
The parking lot will need to be unreffed if it ever falls out of scope
The parking lot will automatically be added to the parking lot container if needed as part of this process

Definition at line 868 of file res_parking.c.

References alloc_new_parking_lot(), ao2_cleanup, ao2_link, ao2_ref, ast_log, parking_lot::cfg, parking_lot::disable_mark, LOG_ERROR, parking_lot::mode, parking_lot_cfg::name, named_item_find(), NULL, PARKINGLOT_DYNAMIC, and PARKINGLOT_NORMAL.

Referenced by create_dynamic_lot_full(), generate_or_link_lots_to_configs(), and generate_test_parking_lot().

869 {
870  struct parking_lot *lot;
871  struct parking_lot_cfg *replaced_cfg = NULL;
872  int found = 0;
873 
874  /* Start by trying to find it. If that works we can skip the rest. */
875  lot = named_item_find(parking_lot_container, lot_cfg->name);
876  if (!lot) {
877  lot = alloc_new_parking_lot(lot_cfg);
878 
879  /* If we still don't have a lot, we failed to alloc one. */
880  if (!lot) {
881  return NULL;
882  }
883  } else {
884  found = 1;
885 
886  if (dynamic) {
887  ast_log(LOG_ERROR, "Tried to create dynamic parking lot with name '%s' but a lot with that name already exists.\n", lot_cfg->name);
888  ao2_cleanup(lot);
889  return NULL;
890  }
891  }
892 
893  /* Set the configuration reference. Unref the one currently in the lot if it's there. */
894  if (lot->cfg) {
895  replaced_cfg = lot->cfg;
896  }
897 
898  ao2_ref(lot_cfg, +1);
899  lot->cfg = lot_cfg;
900 
901  ao2_cleanup(replaced_cfg);
902 
903  /* Set the operating mode to normal since the parking lot has a configuration. */
904  lot->disable_mark = 0;
905  lot->mode = dynamic ? PARKINGLOT_DYNAMIC : PARKINGLOT_NORMAL;
906 
907  if (!found) {
908  /* Link after configuration is set since a lot without configuration will cause all kinds of trouble. */
910  };
911 
912  return lot;
913 }
static void * named_item_find(struct ao2_container *container, const char *name)
find an item in a container by its name
Definition: res_parking.c:496
int disable_mark
Definition: res_parking.h:98
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
enum parking_lot_modes mode
Definition: res_parking.h:97
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct parking_lot * alloc_new_parking_lot(struct parking_lot_cfg *lot_cfg)
Definition: res_parking.c:637
struct parking_lot_cfg * cfg
Definition: res_parking.h:96
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ parking_lot_cfg_create()

struct parking_lot_cfg* parking_lot_cfg_create ( const char *  cat)

Create an empty parking lot configuration structure useful for unit tests.

Since
12.0.0
Parameters
catname given to the parking lot
Return values
NULLfailure
non-NULLsuccessfully allocated parking lot

Definition at line 481 of file res_parking.c.

References parking_lot_cfg_alloc().

Referenced by AST_TEST_DEFINE(), and generate_test_parking_lot().

482 {
483  return parking_lot_cfg_alloc(cat);
484 }
static void * parking_lot_cfg_alloc(const char *cat)
create a parking lot structure
Definition: res_parking.c:461

◆ parking_lot_cfg_create_extensions()

int parking_lot_cfg_create_extensions ( struct parking_lot_cfg lot_cfg)

Add extensions for a parking lot configuration.

Since
12.0.0
Parameters
lot_cfgparking lot configuration to generate extensions for
Return values
0on success
non-zeroon failure

Definition at line 758 of file res_parking.c.

References ast_context_find_or_create(), ast_free, ast_get_extension_registrar(), ast_log, AST_MAX_EXTENSION, ast_str_buffer(), ast_str_create, ast_str_set(), ast_string_field_build, ast_strlen_zero, ast_unlock_context(), ast_unlock_contexts(), ast_wrlock_context(), ast_wrlock_contexts(), BASE_REGISTRAR, E_MATCH, extension_is_compatible(), LOG_ERROR, parking_lot_cfg::name, NULL, PARK_APPLICATION, parking_lot_cfg::parkaddhints, PARKED_CALL_APPLICATION, parking_lot_cfg::parkext, parking_lot_cfg::parkext_exclusive, parking_add_extension(), parking_lot_cfg::parking_con, parking_lot_cfg::parking_start, pbx_find_extension(), PRIORITY_HINT, RAII_VAR, registrar, parking_lot_cfg::registrar, and pbx_find_info::stacklen.

Referenced by configure_parking_extensions(), create_dynamic_lot_full(), and generate_test_parking_lot().

759 {
760  int parkingspace;
761  struct ast_exten *existing_exten;
762  struct ast_context *lot_context;
763  struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
764  const char *parkext_registrar_pointer; /* Used for park extension */
765  const char *parkedcall_registrar_pointer; /* Used for parkedcall extensions/hints */
766 
767  if (ast_strlen_zero(lot_cfg->parkext)) {
768  return 0;
769  }
770 
771  ast_string_field_build(lot_cfg, registrar, "%s/%s", BASE_REGISTRAR, lot_cfg->name);
772  parkedcall_registrar_pointer = lot_cfg->registrar;
773 
774  if (lot_cfg->parkext_exclusive) {
775  parkext_registrar_pointer = lot_cfg->registrar;
776  } else {
777  parkext_registrar_pointer = BASE_REGISTRAR;
778  }
779 
780  /* We need the contexts list locked to safely be able to both read and lock the specific context within */
782 
783  if (!(lot_context = ast_context_find_or_create(NULL, NULL, lot_cfg->parking_con, parkext_registrar_pointer))) {
784  ast_log(LOG_ERROR, "Parking lot '%s' -- Needs a context '%s' which does not exist and Asterisk was unable to create\n",
785  lot_cfg->name, lot_cfg->parking_con);
787  return -1;
788  }
789 
790  /* Once we know what context we will be modifying, we need to write lock it because we will be reading extensions
791  * and we don't want something else to destroy them while we are looking at them.
792  */
793  ast_wrlock_context(lot_context);
794 
796 
797  /* Handle generation/confirmation for the Park extension */
798  if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, lot_cfg->parkext, 1, NULL, NULL, E_MATCH))) {
799  if (lot_cfg->parkext_exclusive || !extension_is_compatible(lot_cfg, PARK_APPLICATION, existing_exten)) {
800  ast_unlock_context(lot_context);
801  return -1;
802  }
803  } else if (parking_add_extension(lot_context, 0, lot_cfg->parkext, 1, PARK_APPLICATION,
804  lot_cfg->parkext_exclusive ? lot_cfg->name : "", parkext_registrar_pointer)) {
805  ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add %s extension '%[email protected]%s' to the PBX.\n",
806  lot_cfg->name, PARK_APPLICATION, lot_cfg->parkext, lot_cfg->parking_con);
807  ast_unlock_context(lot_context);
808  return -1;
809  }
810 
811  /* Handle generation/confirmation for the ParkedCall extensions and hints */
812  for (parkingspace = lot_cfg->parking_start; parkingspace <= lot_cfg->parking_stop; parkingspace++) {
813  char space[AST_MAX_EXTENSION];
814  RAII_VAR(struct ast_str *, arguments_string, NULL, ast_free);
815  find_info.stacklen = 0; /* reset for pbx_find_exten */
816 
817  snprintf(space, sizeof(space), "%d", parkingspace);
818 
819  /* Unlike the Park extensions, ParkedCall extensions and their hints may never be shared for any reason. */
820  if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, space, 1, NULL, NULL, E_MATCH))) {
821  ast_unlock_context(lot_context);
822  return -1;
823  }
824 
825  arguments_string = ast_str_create(32);
826  if (!arguments_string) {
827  ast_unlock_context(lot_context);
828  return -1;
829  }
830 
831  ast_str_set(&arguments_string, 0, "%s,%s", lot_cfg->name, space);
832  if (parking_add_extension(lot_context, 0, space, 1, PARKED_CALL_APPLICATION,
833  ast_str_buffer(arguments_string), parkedcall_registrar_pointer)) {
834  ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add %s extension '%[email protected]%s' to the PBX.\n",
835  lot_cfg->name, PARKED_CALL_APPLICATION, space, lot_cfg->parking_con);
836  ast_unlock_context(lot_context);
837  return -1;
838  }
839 
840  find_info.stacklen = 0; /* reset for pbx_find_exten */
841 
842  if (lot_cfg->parkaddhints) {
843  char hint_device[AST_MAX_EXTENSION];
844 
845  snprintf(hint_device, sizeof(hint_device), "park:%[email protected]%s", space, lot_cfg->parking_con);
846 
847  if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, space, PRIORITY_HINT, NULL, NULL, E_MATCH))) {
848  ast_log(LOG_ERROR, "Parking lot '%s' -- Needs to add a hint '%s' at '%[email protected]%s' but one already exists owned by %s\n",
849  lot_cfg->name, hint_device, space, lot_cfg->parking_con, ast_get_extension_registrar(existing_exten));
850  ast_unlock_context(lot_context);
851  return -1;
852  }
853 
854  if (parking_add_extension(lot_context, 0, space, PRIORITY_HINT, hint_device, "", parkedcall_registrar_pointer)) {
855  ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add hint '%[email protected]%s' to the PBX.\n",
856  lot_cfg->name, space, lot_cfg->parking_con);
857  ast_unlock_context(lot_context);
858  return -1;
859  }
860  }
861  }
862 
863  ast_unlock_context(lot_context);
864 
865  return 0;
866 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8530
ast_exten: An extension The dialplan is saved as a linked list with each context having it&#39;s own link...
Definition: pbx.c:237
const char * ast_get_extension_registrar(struct ast_exten *e)
Definition: pbx.c:8571
#define BASE_REGISTRAR
Definition: res_parking.h:36
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8502
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_log
Definition: astobj2.c:42
const ast_string_field name
Definition: res_parking.h:89
const ast_string_field parking_con
Definition: res_parking.h:89
#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
unsigned int parkaddhints
Definition: res_parking.h:73
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define PRIORITY_HINT
Definition: pbx.h:54
static int parking_add_extension(struct ast_context *context, int replace, const char *extension, int priority, const char *application, const char *data, const char *registrar)
Definition: res_parking.c:713
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const ast_string_field registrar
Definition: res_parking.h:89
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8512
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:8520
#define PARK_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
static char * registrar
Definition: pbx_ael.c:78
#define ast_free(a)
Definition: astmm.h:182
#define PARKED_CALL_APPLICATION
Definition: res_parking.h:38
static int extension_is_compatible(struct parking_lot_cfg *lot_cfg, const char *app_type, struct ast_exten *extension)
Definition: res_parking.c:730
int stacklen
Definition: extconf.h:238
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:550
const ast_string_field parkext
Definition: res_parking.h:89
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: ael_main.c:152
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284
unsigned int parkext_exclusive
Definition: res_parking.h:72
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ parking_lot_cfg_remove_extensions()

void parking_lot_cfg_remove_extensions ( struct parking_lot_cfg lot_cfg)

Remove extensions belonging to a parking lot configuration.

Since
12.0.0
Parameters
lot_cfgparking lot configuratin to remove extensions from
Note
This will not remove extensions registered non-exclusively even if those extensions were registered by lot_cfg. Those are only purged on a res_parking module reload.

Definition at line 663 of file res_parking.c.

References ast_context_destroy(), ast_string_field_set, ast_strlen_zero, NULL, registrar, and parking_lot_cfg::registrar.

Referenced by parking_lot_cfg_destructor(), remove_all_configured_parking_lot_extensions(), and remove_pending_parking_lot_extensions().

664 {
665  if (!ast_strlen_zero(lot_cfg->registrar)) {
666  /* Although the function is called ast_context_destroy, the use of this funtion is
667  * intended only to remove extensions, hints, etc registered by the parking lot's registrar.
668  * It won't actually destroy the context unless that context is empty afterwards and it is
669  * unreferenced.
670  */
672  }
673 
674  /* If we come back for a second pass, someone else has this registrar now. */
675  ast_string_field_set(lot_cfg, registrar, "");
676 }
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field registrar
Definition: res_parking.h:89
static char * registrar
Definition: pbx_ael.c:78
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Definition: conf2ael.c:625
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ parking_lot_find_by_name()

struct parking_lot* parking_lot_find_by_name ( const char *  lot_name)

Find a parking lot based on its name.

Since
12.0.0
Parameters
lot_nameName of the parking lot sought
Return values
Theparking lot if found
NULLif no parking lot with the name specified exists
Note
ao2_cleanup this reference when you are done using it or you'll cause leaks.

Definition at line 601 of file res_parking.c.

References named_item_find().

Referenced by AST_TEST_DEFINE(), cli_display_parking_lot(), create_dynamic_lot_full(), dispose_test_lot(), func_get_parkingslot_channel(), manager_parking_status_single_lot(), park_common_setup(), parked_call_app_exec(), and parking_park_call().

602 {
603  struct parking_lot *lot = named_item_find(parking_lot_container, lot_name);
604  return lot;
605 }
static void * named_item_find(struct ao2_container *container, const char *name)
find an item in a container by its name
Definition: res_parking.c:496
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266

◆ parking_lot_get_bridge()

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.

Since
12.0.0
Parameters
lotWhich parking lot we need the bridge from. This parking lot must be locked before calling this function.
Return values
Areference to the ast_bridge associated with the parking lot
NULLif it didn't already have a bridge and one couldn't be created
Note
This bridge will need to be unreffed if it ever falls out of scope.

Definition at line 36 of file parking_controller.c.

References ao2_ref, bridge_parking_new(), NULL, and parking_lot::parking_bridge.

Referenced by park_common_setup().

37 {
38  struct ast_bridge *lot_bridge;
39 
40  if (lot->parking_bridge) {
41  ao2_ref(lot->parking_bridge, +1);
42  return lot->parking_bridge;
43  }
44 
45  lot_bridge = bridge_parking_new(lot);
46  if (!lot_bridge) {
47  return NULL;
48  }
49 
50  /* The parking lot needs a reference to the bridge as well. */
51  lot->parking_bridge = lot_bridge;
52  ao2_ref(lot->parking_bridge, +1);
53 
54  return lot_bridge;
55 }
struct ast_bridge * parking_bridge
Definition: res_parking.h:94
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
struct ast_bridge * bridge_parking_new(struct parking_lot *bridge_lot)
Create a new parking bridge.

◆ parking_lot_get_space()

int parking_lot_get_space ( struct parking_lot lot,
int  target_override 
)

Get an available parking space within a parking lot.

Since
12.0.0
Parameters
lotWhich parking lot we are getting a space from
target_overrideIf there is a specific slot we want, provide it here and we'll start from that position
Return values
-1if No slot can be found
integervalue of parking space selected
Note
lot should be locked before this is called and unlocked only after a parked_user with the space returned has been added to the parking lot.

Definition at line 96 of file parking_controller.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, parking_lot::cfg, parking_lot::next_space, parking_lot::parked_users, parking_lot_cfg::parkfindnext, parked_user::parking_space, parking_lot_cfg::parking_start, and parking_limits_pvt::user.

Referenced by generate_parked_user().

97 {
98  int original_target;
99  int current_target;
100  struct ao2_iterator i;
101  struct parked_user *user;
102  int wrap;
103 
104  if (lot->cfg->parkfindnext) {
105  /* Use next_space if the lot already has next_space set; otherwise use lot start. */
106  original_target = lot->next_space ? lot->next_space : lot->cfg->parking_start;
107  } else {
108  original_target = lot->cfg->parking_start;
109  }
110 
111  if (target_override >= lot->cfg->parking_start && target_override <= lot->cfg->parking_stop) {
112  original_target = target_override;
113  }
114 
115  current_target = original_target;
116 
117  wrap = lot->cfg->parking_start;
118 
119  i = ao2_iterator_init(lot->parked_users, 0);
120  while ((user = ao2_iterator_next(&i))) {
121  /* Increment the wrap on each pass until we find an empty space */
122  if (wrap == user->parking_space) {
123  wrap += 1;
124  }
125 
126  if (user->parking_space < current_target) {
127  /* It's lower than the anticipated target, so we haven't reached the target yet. */
128  ao2_ref(user, -1);
129  continue;
130  }
131 
132  if (user->parking_space > current_target) {
133  /* The current target is usable because all items below have been read and the next target is higher than the one we want. */
134  ao2_ref(user, -1);
135  break;
136  }
137 
138  /* We found one already parked here. */
139  current_target += 1;
140  ao2_ref(user, -1);
141  }
143 
144  if (current_target <= lot->cfg->parking_stop) {
145  return current_target;
146  }
147 
148  if (wrap <= lot->cfg->parking_stop) {
149  return wrap;
150  }
151 
152  return -1;
153 }
static char user[512]
struct ao2_container * parked_users
Definition: res_parking.h:95
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int next_space
Definition: res_parking.h:93
int parking_space
Definition: res_parking.h:107
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
unsigned int parkfindnext
Definition: res_parking.h:71
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

◆ parking_lot_inspect_parked_user()

struct parked_user* parking_lot_inspect_parked_user ( struct parking_lot lot,
int  target 
)

Determine if there is a parked user in a parking space and return it if there is.

Parameters
lotParking lot being pulled from
targetIf < 0 search for the first occupied space in the parking lot If >= 0 Only pull from the indicated target
Return values
NULLif no parked user could be pulled from the requested parking lot at the requested parking space
referenceto the requested parked user

Definition at line 166 of file parking_controller.c.

References ao2_callback, NULL, parking_lot::parked_users, retrieve_parked_user_targeted(), and parking_limits_pvt::user.

Referenced by func_get_parkingslot_channel().

167 {
168  struct parked_user *user;
169 
170  if (target < 0) {
171  user = ao2_callback(lot->parked_users, 0, NULL, NULL);
172  } else {
173  user = ao2_callback(lot->parked_users, 0, retrieve_parked_user_targeted, &target);
174  }
175 
176  if (!user) {
177  return NULL;
178  }
179 
180  return user;
181 }
static char user[512]
struct ao2_container * parked_users
Definition: res_parking.h:95
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define NULL
Definition: resample.c:96
static int retrieve_parked_user_targeted(void *obj, void *arg, int flags)

◆ parking_lot_remove_if_unused()

int parking_lot_remove_if_unused ( struct parking_lot lot)

Remove a parking lot from the usable lists if it is no longer involved in any calls and no configuration currently claims it.

Since
12.0.0
Parameters
lotWhich parking lot is being checked for elimination
Return values
0if the parking lot was removed
-1if the parking lot wasn't removed.
Note
This should generally be called when something is happening that could cause a parking lot to die such as a call being unparked or a parking lot no longer existing in configurations.

Definition at line 400 of file res_parking.c.

References ao2_container_count(), ao2_unlink, parking_lot::mode, parking_lot::parked_users, and PARKINGLOT_DISABLED.

Referenced by dispose_test_lot(), parking_lot_disable(), parking_lot_retrieve_parked_user(), and unpark_parked_user().

401 {
402  if (lot->mode != PARKINGLOT_DISABLED) {
403  return -1;
404  }
405 
406  if (!ao2_container_count(lot->parked_users)) {
408  return 0;
409  }
410 
411  return -1;
412 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_container * parked_users
Definition: res_parking.h:95
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
enum parking_lot_modes mode
Definition: res_parking.h:97

◆ parking_lot_retrieve_parked_user()

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.

Since
12.0.0
Parameters
lotParking lot being pulled from
targetIf < 0 search for the first occupied space in the parking lot If >= 0 Only pull from the indicated target
Return values
NULLif no parked user could be pulled from the requested parking lot at the requested parking space
referenceto the requested parked user
Note
The parked user will be removed from parking lot as part of this process
Remove this reference with ao2_cleanup once it falls out of scope.

Definition at line 183 of file parking_controller.c.

References ao2_callback, ao2_cleanup, ao2_lock, ao2_ref, ao2_unlink, ao2_unlock, NULL, PARK_ANSWERED, PARK_UNSET, parking_lot::parked_users, parking_lot_remove_if_unused(), RAII_VAR, retrieve_parked_user_targeted(), and parking_limits_pvt::user.

Referenced by AST_TEST_DEFINE(), and parked_call_app_exec().

184 {
186 
187  if (target < 0) {
188  user = ao2_callback(lot->parked_users, 0, NULL, NULL);
189  } else {
191  }
192 
193  if (!user) {
194  return NULL;
195  }
196 
197  ao2_lock(user);
198  if (user->resolution != PARK_UNSET) {
199  /* Abandon. Something else has resolved the parked user before we got to it. */
200  ao2_unlock(user);
201  return NULL;
202  }
203 
205  user->resolution = PARK_ANSWERED;
206  ao2_unlock(user);
207 
209 
210  /* Bump the ref count by 1 since the RAII_VAR will eat the reference otherwise */
211  ao2_ref(user, +1);
212  return user;
213 }
static char user[512]
struct ao2_container * parked_users
Definition: res_parking.h:95
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define ao2_unlock(a)
Definition: astobj2.h:730
#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
int parking_lot_remove_if_unused(struct parking_lot *lot)
Remove a parking lot from the usable lists if it is no longer involved in any calls and no configurat...
Definition: res_parking.c:400
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static int retrieve_parked_user_targeted(void *obj, void *arg, int flags)
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
structure to hold users read from users.conf
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ parking_notify_metermaids()

void parking_notify_metermaids ( int  exten,
const char *  context,
enum ast_device_state  state 
)

Notify metermaids that we've changed an extension.

Since
12.0.0
Parameters
extenExtension of the call parked/unparked
contextContext of the call parked/unparked
statenew device state

Definition at line 108 of file parking_devicestate.c.

References ast_debug, ast_devstate2str(), AST_DEVSTATE_CACHABLE, and ast_devstate_changed().

Referenced by bridge_parking_pull(), and bridge_parking_push().

109 {
110  ast_debug(4, "Notification of state change to metermaids %[email protected]%s\n to state '%s'\n",
112 
114 }
const char * ast_devstate2str(enum ast_device_state devstate) attribute_pure
Convert device state to text string for output.
Definition: devicestate.c:237
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ parking_set_duration()

void parking_set_duration ( struct ast_bridge_features features,
struct parked_user user 
)

Setup timeout interval feature on an ast_bridge_features for parking.

Since
12.0.0
Parameters
featuresThe ast_bridge_features we are establishing the interval hook on
userThe parked_user receiving the timeout duration limits

Definition at line 705 of file parking_bridge_features.c.

References __ao2_cleanup(), ao2_ref, AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_bridge_interval_hook(), ast_log, ast_remaining_ms(), LOG_ERROR, parking_duration_callback(), parked_user::start, and parked_user::time_limit.

Referenced by bridge_parking_push().

706 {
707  unsigned int time_limit;
708 
709  time_limit = user->time_limit * 1000;
710 
711  if (!time_limit) {
712  /* There is no duration limit that we need to apply. */
713  return;
714  }
715 
716  /* If the time limit has already been passed, set a really low time limit so we can kick them out immediately. */
717  time_limit = ast_remaining_ms(user->start, time_limit);
718  if (time_limit <= 0) {
719  time_limit = 1;
720  }
721 
722  /* The interval hook is going to need a reference to the parked_user */
723  ao2_ref(user, +1);
724 
725  if (ast_bridge_interval_hook(features, 0, time_limit,
727  ast_log(LOG_ERROR, "Failed to apply duration limit to the parked call.\n");
728  ao2_ref(user, -1);
729  }
730 }
void __ao2_cleanup(void *obj)
Definition: astobj2.c:674
unsigned int time_limit
Definition: res_parking.h:110
struct timeval start
Definition: res_parking.h:106
static int parking_duration_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3382
#define LOG_ERROR
Definition: logger.h:285
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: main/utils.c:2033

◆ publish_parked_call()

void publish_parked_call ( struct parked_user pu,
enum ast_parked_call_event_type  event_type 
)

Publish a stasis parked call message for a given parked user.

Since
12.0.0
Parameters
pupointer to a parked_user that we are generating the message for
event_typeWhat parked call event type is provoking this message

Definition at line 617 of file parking_manager.c.

References ao2_cleanup, ast_parked_call_type(), ast_parking_topic(), NULL, parked_call_payload_from_parked_user(), RAII_VAR, stasis_message_create(), and stasis_publish().

Referenced by bridge_parking_pull(), and bridge_parking_push().

618 {
619  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
620  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
621 
622  if (!ast_parked_call_type()) {
623  return;
624  }
625 
626  payload = parked_call_payload_from_parked_user(pu, event_type);
627  if (!payload) {
628  return;
629  }
630 
632  if (!msg) {
633  return;
634  }
635 
637 }
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
A parked call message payload.
Definition: parking.h:59
#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
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
static struct ast_parked_call_payload * parked_call_payload_from_parked_user(struct parked_user *pu, enum ast_parked_call_event_type event_type)
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
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

◆ publish_parked_call_failure()

void publish_parked_call_failure ( struct ast_channel parkee)

Publish a stasis parked call message for the channel indicating failure to park.

Since
12.0.0
Parameters
parkeechannel belonging to the failed parkee

Definition at line 595 of file parking_manager.c.

References ao2_cleanup, ast_parked_call_type(), ast_parking_topic(), NULL, parked_call_payload_from_failure(), RAII_VAR, stasis_message_create(), and stasis_publish().

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

596 {
597  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
598  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
599 
600  if (!ast_parked_call_type()) {
601  return;
602  }
603 
604  payload = parked_call_payload_from_failure(parkee);
605  if (!payload) {
606  return;
607  }
608 
610  if (!msg) {
611  return;
612  }
613 
615 }
static struct ast_parked_call_payload * parked_call_payload_from_failure(struct ast_channel *chan)
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
A parked call message payload.
Definition: parking.h:59
#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
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
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

◆ say_parking_space()

void say_parking_space ( struct ast_bridge_channel bridge_channel,
const char *  payload 
)

custom callback function for ast_bridge_channel_queue_playfile which plays a parking space and optionally hangs up the call afterwards based on the payload in playfile.

Since
12.0.0

Definition at line 683 of file parking_bridge_features.c.

References ast_assert, ast_bridge_channel_leave_bridge(), AST_CAUSE_NORMAL_CLEARING, ast_channel_language(), ast_say_digits(), BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, and ast_bridge_channel::chan.

Referenced by bridge_parking_push(), and parker_parked_call_message_response().

684 {
685  unsigned int numeric_value;
686  unsigned int hangup_after;
687 
688  if (sscanf(payload, "%u %u", &hangup_after, &numeric_value) != 2) {
689  /* If say_parking_space is called with a non-numeric string, we have a problem. */
690  ast_assert(0);
691  ast_bridge_channel_leave_bridge(bridge_channel,
693  return;
694  }
695 
696  ast_say_digits(bridge_channel->chan, numeric_value, "",
697  ast_channel_language(bridge_channel->chan));
698 
699  if (hangup_after) {
700  ast_bridge_channel_leave_bridge(bridge_channel,
702  }
703 }
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8349
#define ast_assert(a)
Definition: utils.h:695
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
struct ast_channel * chan
const char * ast_channel_language(const struct ast_channel *chan)

◆ 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

◆ unload_parking_bridge_features()

void unload_parking_bridge_features ( void  )

Unregister features registered by load_parking_bridge_features.

Since
12.0.0

Definition at line 795 of file parking_bridge_features.c.

References AST_BRIDGE_BUILTIN_PARKCALL, ast_bridge_features_unregister(), ast_custom_function_unregister(), ast_parking_unregister_bridge_features(), and ast_parking_bridge_feature_fn_table::module_name.

Referenced by unload_module().

796 {
800 }
const char * module_name
The name of the module that provides this parking functionality.
Definition: parking.h:139
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
Unregister a handler for a built in feature.
Definition: bridge.c:3139
struct ast_parking_bridge_feature_fn_table parking_provider
static struct ast_custom_function getparkingslotchannel_function
int ast_parking_unregister_bridge_features(const char *module_name)
Unregister the current parking provider.
Definition: parking.c:223

◆ unload_parking_devstate()

void unload_parking_devstate ( void  )

Unregister Parking devstate handler.

Since
12.0.0

Definition at line 116 of file parking_devicestate.c.

References ast_devstate_prov_del().

Referenced by unload_module().

117 {
118  ast_devstate_prov_del("Park");
119 }
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:418

◆ unload_parking_manager()

void unload_parking_manager ( void  )

Unregister manager actions and remove subscriptions for stasis events.

Since
12.0.0

Definition at line 710 of file parking_manager.c.

References ast_manager_unregister(), and parking_manager_disable_stasis().

Referenced by unload_module().

711 {
712  ast_manager_unregister("Parkinglots");
713  ast_manager_unregister("ParkedCalls");
714  ast_manager_unregister("Park");
716 }
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static void parking_manager_disable_stasis(void)

◆ unload_parking_tests()

void unload_parking_tests ( void  )

Unregister parking unit tests.

Since
12.0.0
Returns
Nothing

Definition at line 838 of file parking_tests.c.

References AST_TEST_UNREGISTER.

Referenced by unload_module().

839 {
840 /* NOOP without test framework */
841 #if defined(TEST_FRAMEWORK)
842  AST_TEST_UNREGISTER(create_lot);
843  AST_TEST_UNREGISTER(park_call);
844  AST_TEST_UNREGISTER(retrieve_call);
845  AST_TEST_UNREGISTER(park_extensions);
846  AST_TEST_UNREGISTER(extension_conflicts);
847  AST_TEST_UNREGISTER(dynamic_parking_variables);
848 #endif
849 }
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

◆ unload_parking_ui()

void unload_parking_ui ( void  )

Unregister CLI commands.

Since
12.0.0

Definition at line 203 of file parking_ui.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by unload_module().

204 {
206 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct ast_cli_entry cli_parking_lot[]
Definition: parking_ui.c:194

◆ unpark_parked_user()

int unpark_parked_user ( struct parked_user user)

Pull a parked user out of its parking lot. Use this when you don't want to use the parked user afterwards.

Since
12.0.0
Parameters
userThe parked user being pulled.
Return values
0on success
-1if the user didn't have its parking lot set

Definition at line 85 of file parking_controller.c.

References ao2_unlink, parked_user::lot, parking_lot::parked_users, and parking_lot_remove_if_unused().

Referenced by bridge_parking_pull().

86 {
87  if (pu->lot) {
88  ao2_unlink(pu->lot->parked_users, pu);
90  return 0;
91  }
92 
93  return -1;
94 }
int parking_lot_remove_if_unused(struct parking_lot *lot)
Remove a parking lot from the usable lists if it is no longer involved in any calls and no configurat...
Definition: res_parking.c:400
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598