Asterisk - The Open Source Telephony Project  21.4.1
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"

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...
 
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...
 
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.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file res_parking.h.

Enumeration Type Documentation

Enumerator
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 };
Enumerator
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

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
Returns
Newly created parking bridge

Definition at line 450 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, bridge_base_init(), bridge_register(), and parking_lot::name.

Referenced by parking_lot_get_bridge().

451 {
452  void *bridge;
453 
454  bridge = bridge_alloc(sizeof(struct ast_bridge_parking), &ast_bridge_parking_v_table);
457  | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, "Parking", bridge_lot->name, NULL);
458  bridge = ast_bridge_parking_init(bridge, bridge_lot);
459  bridge = bridge_register(bridge);
460  return bridge;
461 }
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:691
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:742
const ast_string_field name
Definition: res_parking.h:100
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 263 of file parking_controller.c.

References ast_async_goto(), ast_exists_extension(), ast_strdupa, parking_lot::cfg, parked_user::chan, parking_lot_cfg::comebackcontext, parking_lot_cfg::comebacktoorigin, flatten_dial_string(), and parked_user::parker_dial_string.

264 {
265  struct ast_channel *chan = pu->chan;
266  char *peername_flat = ast_strdupa(pu->parker_dial_string);
267 
268  /* Flatten the peername so that it can be used for performing the timeout PBX operations */
269  flatten_dial_string(peername_flat);
270 
271  if (lot->cfg->comebacktoorigin) {
272  if (ast_exists_extension(chan, PARK_DIAL_CONTEXT, peername_flat, 1, NULL)) {
273  ast_async_goto(chan, PARK_DIAL_CONTEXT, peername_flat, 1);
274  return 0;
275  } else {
276  ast_log(LOG_ERROR, "Can not start %s at %s,%s,1 because extension does not exist. Terminating call.\n",
277  ast_channel_name(chan), PARK_DIAL_CONTEXT, peername_flat);
278  return -1;
279  }
280  }
281 
282  if (ast_exists_extension(chan, lot->cfg->comebackcontext, peername_flat, 1, NULL)) {
283  ast_async_goto(chan, lot->cfg->comebackcontext, peername_flat, 1);
284  return 0;
285  }
286 
287  if (ast_exists_extension(chan, lot->cfg->comebackcontext, "s", 1, NULL)) {
288  ast_verb(2, "Could not start %s at %s,%s,1. Using 's@%s' instead.\n", ast_channel_name(chan),
289  lot->cfg->comebackcontext, peername_flat, lot->cfg->comebackcontext);
290  ast_async_goto(chan, lot->cfg->comebackcontext, "s", 1);
291  return 0;
292  }
293 
294  ast_verb(2, "Can not start %s at %s,%s,1 and exten 's@%s' does not exist. Using 's@default'\n",
295  ast_channel_name(chan),
296  lot->cfg->comebackcontext, peername_flat, lot->cfg->comebackcontext);
297  ast_async_goto(chan, "default", "s", 1);
298 
299  return 0;
300 }
Main Channel structure associated with a channel.
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.
char * parker_dial_string
Definition: res_parking.h:109
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
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:4175
unsigned int comebacktoorigin
Definition: res_parking.h:74
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:6969
struct ast_channel * chan
Definition: res_parking.h:104
struct parking_lot_cfg * cfg
Definition: res_parking.h:96
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.

234 {
235  return create_parked_subscription_full(chan, parkee_uuid, hangup_after, NULL);
236 }
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 608 of file res_parking.c.

References parking_lot::name, and pbx_builtin_getvar_helper().

609 {
610  const char *name;
611 
612  /* The channel variable overrides everything */
613  name = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
614  if (ast_strlen_zero(name)) {
615  /* Try the channel's parking lot. */
616  name = ast_channel_parkinglot(chan);
617  if (ast_strlen_zero(name)) {
618  /* Fall back to the default parking lot. */
619  name = DEFAULT_PARKING_LOT;
620  }
621  }
622 
623  return name;
624 }
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
const ast_string_field name
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
dialstringunflattened dial string. This will be flattened in place.

Definition at line 251 of file parking_controller.c.

Referenced by comeback_goto().

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

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

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

Definition at line 441 of file parking_applications.c.

References ast_calloc, ast_channel_datastore_find(), ast_strdup, park_common_datastore::comeback_override, ast_datastore::data, lock, 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.

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

Definition at line 597 of file res_parking.c.

References parking_lot_container.

598 {
599  return parking_lot_container;
600 }
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
int load_parking_applications ( void  )

Register parking applications.

Since
12.0.0
Return values
0if successful
-1on failure

Definition at line 1008 of file parking_applications.c.

References ast_register_application_xml, and PARK_APPLICATION.

1009 {
1010  if (ast_register_application_xml(PARK_APPLICATION, park_app_exec)) {
1011  return -1;
1012  }
1013 
1014  if (ast_register_application_xml(PARKED_CALL_APPLICATION, parked_call_app_exec)) {
1015  return -1;
1016  }
1017 
1018  if (ast_register_application_xml(PARK_AND_ANNOUNCE_APPLICATION, park_and_announce_app_exec)) {
1019  return -1;
1020  }
1021 
1022  return 0;
1023 }
#define PARK_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
int load_parking_bridge_features ( void  )

Register bridge features for parking.

Since
12.0.0
Return values
0on success
-1on failure

Definition at line 800 of file parking_bridge_features.c.

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

801 {
802  parking_provider.module = AST_MODULE_SELF;
803 
804  ast_custom_function_register(&getparkingslotchannel_function);
805 
806  if (ast_parking_register_bridge_features(&parking_provider)) {
807  return -1;
808  }
809 
810  if (ast_bridge_features_register(AST_BRIDGE_BUILTIN_PARKCALL, feature_park_call, NULL)) {
811  return -1;
812  }
813 
814  return 0;
815 }
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
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:3062
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
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().

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

Register manager actions and setup subscriptions for stasis events.

Since
12.0.0

Definition at line 704 of file parking_manager.c.

References ast_manager_register_xml.

705 {
706  int res;
707 
708  res = ast_manager_register_xml("Parkinglots", EVENT_FLAG_CALL, manager_parking_lot_list);
709  res |= ast_manager_register_xml("ParkedCalls", EVENT_FLAG_CALL, manager_parking_status);
710  res |= ast_manager_register_xml("Park", EVENT_FLAG_CALL, manager_park);
711  parking_manager_enable_stasis();
712  return res ? -1 : 0;
713 }
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
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.

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 }
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 ast_cli_register_multiple.

199 {
200  return ast_cli_register_multiple(cli_parking_lot, ARRAY_LEN(cli_parking_lot));
201 }
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
struct ast_bridge* park_application_setup ( struct ast_channel parkee,
struct ast_channel parker,
const char *  app_data,
int *  silence_announcements 
)

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

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

Definition at line 545 of file parking_applications.c.

References RAII_VAR.

547 {
548  int use_ringing = 0;
549  int randomize = 0;
550  int time_limit = -1;
551 
552  RAII_VAR(char *, comeback_override, NULL, ast_free);
553  RAII_VAR(char *, lot_name_app_arg, NULL, ast_free);
554  RAII_VAR(char *, musicclass, NULL, ast_free);
555 
556  if (app_data) {
557  park_app_parse_data(app_data, silence_announcements, &use_ringing, &randomize, &time_limit, &comeback_override, &lot_name_app_arg, &musicclass);
558  }
559 
560  return park_common_setup2(parkee, parker, lot_name_app_arg, comeback_override, musicclass, use_ringing,
561  randomize, time_limit, silence_announcements ? *silence_announcements : 0);
562 
563 }
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void park_common_datastore_free ( struct park_common_datastore datastore)

Free a park common datastore struct.

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

Definition at line 335 of file parking_applications.c.

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

Referenced by get_park_common_datastore_copy().

336 {
337  if (!datastore) {
338  return;
339  }
340 
341  ast_free(datastore->parker_uuid);
342  ast_free(datastore->parker_dial_string);
343  ast_free(datastore->comeback_override);
344  ast_free(datastore);
345 }
struct ast_bridge* park_common_setup ( struct ast_channel parkee,
struct ast_channel parker,
const char *  lot_name,
const char *  comeback_override,
int  use_ringing,
int  randomize,
int  time_limit,
int  silence_announcements 
)

Setup a parked call on a parking bridge without needing to parse appdata.

Since
12.0.0

Definition at line 538 of file parking_applications.c.

541 {
542  return park_common_setup2(parkee, parker, lot_name, comeback_override, NULL, use_ringing, randomize, time_limit, silence_announcements);
543 }
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 217 of file parking_controller.c.

References ast_bridge_features_ds_get(), ast_bridge_features_ds_set(), parking_lot::cfg, parking_lot_cfg::parkedcallhangup, parking_lot_cfg::parkedcallrecording, parking_lot_cfg::parkedcallreparking, and parking_lot_cfg::parkedcalltransfers.

218 {
219  /* Enabling features here should be additive to features that are already on the channel. */
220  struct ast_flags feature_flags = { 0 };
221  struct ast_flags *existing_features;
222 
223  ast_channel_lock(chan);
224  existing_features = ast_bridge_features_ds_get(chan);
225  if (existing_features) {
226  feature_flags = *existing_features;
227  }
228 
229  if (lot->cfg->parkedcalltransfers & recipient_mode) {
230  ast_set_flag(&feature_flags, AST_FEATURE_REDIRECT);
231  }
232 
233  if (lot->cfg->parkedcallreparking & recipient_mode) {
234  ast_set_flag(&feature_flags, AST_FEATURE_PARKCALL);
235  }
236 
237  if (lot->cfg->parkedcallhangup & recipient_mode) {
238  ast_set_flag(&feature_flags, AST_FEATURE_DISCONNECT);
239  }
240 
241  if (lot->cfg->parkedcallrecording & recipient_mode) {
242  ast_set_flag(&feature_flags, AST_FEATURE_AUTOMIXMON);
243  }
244 
245  ast_bridge_features_ds_set(chan, &feature_flags);
246  ast_channel_unlock(chan);
247 
248  return;
249 }
int parkedcallreparking
Definition: res_parking.h:77
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
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
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(), parking_lot::cfg, and parking_lot_cfg::mohclass.

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:313
int ast_channel_set_bridge_role_option(struct ast_channel *channel, const char *role_name, const char *option, const char *value)
Set a role option on a channel.
Definition: bridge_roles.c:375
const ast_string_field mohclass
Definition: res_parking.h:89
struct parking_lot_cfg * cfg
Definition: res_parking.h:96
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
Returns
dynamically created parking lot on success
Return values
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 1060 of file res_parking.c.

1060  {
1061  return create_dynamic_lot_full(name, chan, 0);
1062 }
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 929 of file res_parking.c.

References ao2_global_obj_ref, and RAII_VAR.

930 {
931  RAII_VAR(struct parking_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
932 
933  if (!cfg) {
934  return 0;
935  }
936 
937  return cfg->global->parkeddynamic;
938 }
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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.
Returns
A reference to the new parking lot
Return values
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 869 of file res_parking.c.

References ao2_link, ao2_ref, parking_lot::cfg, parking_lot::disable_mark, parking_lot::mode, parking_lot_cfg::name, named_item_find(), and PARKINGLOT_DYNAMIC.

870 {
871  struct parking_lot *lot;
872  struct parking_lot_cfg *replaced_cfg = NULL;
873  int found = 0;
874 
875  /* Start by trying to find it. If that works we can skip the rest. */
876  lot = named_item_find(parking_lot_container, lot_cfg->name);
877  if (!lot) {
878  lot = alloc_new_parking_lot(lot_cfg);
879 
880  /* If we still don't have a lot, we failed to alloc one. */
881  if (!lot) {
882  return NULL;
883  }
884  } else {
885  found = 1;
886 
887  if (dynamic) {
888  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);
889  ao2_cleanup(lot);
890  return NULL;
891  }
892  }
893 
894  /* Set the configuration reference. Unref the one currently in the lot if it's there. */
895  if (lot->cfg) {
896  replaced_cfg = lot->cfg;
897  }
898 
899  ao2_ref(lot_cfg, +1);
900  lot->cfg = lot_cfg;
901 
902  ao2_cleanup(replaced_cfg);
903 
904  /* Set the operating mode to normal since the parking lot has a configuration. */
905  lot->disable_mark = 0;
906  lot->mode = dynamic ? PARKINGLOT_DYNAMIC : PARKINGLOT_NORMAL;
907 
908  if (!found) {
909  /* Link after configuration is set since a lot without configuration will cause all kinds of trouble. */
911  };
912 
913  return lot;
914 }
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:497
int disable_mark
Definition: res_parking.h:98
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
enum parking_lot_modes mode
Definition: res_parking.h:97
struct parking_lot_cfg * cfg
Definition: res_parking.h:96
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
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 759 of file res_parking.c.

References ast_context_find_or_create(), AST_MAX_EXTENSION, ast_str_buffer(), ast_str_create, ast_str_set(), ast_string_field_build, ast_unlock_context(), ast_unlock_contexts(), ast_wrlock_context(), ast_wrlock_contexts(), parking_lot_cfg::name, PARK_APPLICATION, parking_lot_cfg::parkaddhints, parking_lot_cfg::parkext, parking_lot_cfg::parkext_exclusive, parking_lot_cfg::parking_con, parking_lot_cfg::parking_start, PRIORITY_HINT, RAII_VAR, and parking_lot_cfg::registrar.

760 {
761  int parkingspace;
762  struct ast_exten *existing_exten;
763  struct ast_context *lot_context;
764  struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
765  const char *parkext_registrar_pointer; /* Used for park extension */
766  const char *parkedcall_registrar_pointer; /* Used for parkedcall extensions/hints */
767 
768  if (ast_strlen_zero(lot_cfg->parkext)) {
769  return 0;
770  }
771 
772  ast_string_field_build(lot_cfg, registrar, "%s/%s", BASE_REGISTRAR, lot_cfg->name);
773  parkedcall_registrar_pointer = lot_cfg->registrar;
774 
775  if (lot_cfg->parkext_exclusive) {
776  parkext_registrar_pointer = lot_cfg->registrar;
777  } else {
778  parkext_registrar_pointer = BASE_REGISTRAR;
779  }
780 
781  /* We need the contexts list locked to safely be able to both read and lock the specific context within */
783 
784  if (!(lot_context = ast_context_find_or_create(NULL, NULL, lot_cfg->parking_con, parkext_registrar_pointer))) {
785  ast_log(LOG_ERROR, "Parking lot '%s' -- Needs a context '%s' which does not exist and Asterisk was unable to create\n",
786  lot_cfg->name, lot_cfg->parking_con);
788  return -1;
789  }
790 
791  /* Once we know what context we will be modifying, we need to write lock it because we will be reading extensions
792  * and we don't want something else to destroy them while we are looking at them.
793  */
794  ast_wrlock_context(lot_context);
795 
797 
798  /* Handle generation/confirmation for the Park extension */
799  if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, lot_cfg->parkext, 1, NULL, NULL, E_MATCH))) {
800  if (lot_cfg->parkext_exclusive || !extension_is_compatible(lot_cfg, PARK_APPLICATION, existing_exten)) {
801  ast_unlock_context(lot_context);
802  return -1;
803  }
804  } else if (parking_add_extension(lot_context, 0, lot_cfg->parkext, 1, PARK_APPLICATION,
805  lot_cfg->parkext_exclusive ? lot_cfg->name : "", parkext_registrar_pointer)) {
806  ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add %s extension '%s@%s' to the PBX.\n",
807  lot_cfg->name, PARK_APPLICATION, lot_cfg->parkext, lot_cfg->parking_con);
808  ast_unlock_context(lot_context);
809  return -1;
810  }
811 
812  /* Handle generation/confirmation for the ParkedCall extensions and hints */
813  for (parkingspace = lot_cfg->parking_start; parkingspace <= lot_cfg->parking_stop; parkingspace++) {
814  char space[AST_MAX_EXTENSION];
815  RAII_VAR(struct ast_str *, arguments_string, NULL, ast_free);
816  find_info.stacklen = 0; /* reset for pbx_find_exten */
817 
818  snprintf(space, sizeof(space), "%d", parkingspace);
819 
820  /* Unlike the Park extensions, ParkedCall extensions and their hints may never be shared for any reason. */
821  if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, space, 1, NULL, NULL, E_MATCH))) {
822  ast_unlock_context(lot_context);
823  return -1;
824  }
825 
826  arguments_string = ast_str_create(32);
827  if (!arguments_string) {
828  ast_unlock_context(lot_context);
829  return -1;
830  }
831 
832  ast_str_set(&arguments_string, 0, "%s,%s", lot_cfg->name, space);
833  if (parking_add_extension(lot_context, 0, space, 1, PARKED_CALL_APPLICATION,
834  ast_str_buffer(arguments_string), parkedcall_registrar_pointer)) {
835  ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add %s extension '%s@%s' to the PBX.\n",
836  lot_cfg->name, PARKED_CALL_APPLICATION, space, lot_cfg->parking_con);
837  ast_unlock_context(lot_context);
838  return -1;
839  }
840 
841  find_info.stacklen = 0; /* reset for pbx_find_exten */
842 
843  if (lot_cfg->parkaddhints) {
844  char hint_device[AST_MAX_EXTENSION];
845 
846  snprintf(hint_device, sizeof(hint_device), "park:%s@%s", space, lot_cfg->parking_con);
847 
848  if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, space, PRIORITY_HINT, NULL, NULL, E_MATCH))) {
849  ast_log(LOG_ERROR, "Parking lot '%s' -- Needs to add a hint '%s' at '%s@%s' but one already exists owned by %s\n",
850  lot_cfg->name, hint_device, space, lot_cfg->parking_con, ast_get_extension_registrar(existing_exten));
851  ast_unlock_context(lot_context);
852  return -1;
853  }
854 
855  if (parking_add_extension(lot_context, 0, space, PRIORITY_HINT, hint_device, "", parkedcall_registrar_pointer)) {
856  ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add hint '%s@%s' to the PBX.\n",
857  lot_cfg->name, space, lot_cfg->parking_con);
858  ast_unlock_context(lot_context);
859  return -1;
860  }
861  }
862  }
863 
864  ast_unlock_context(lot_context);
865 
866  return 0;
867 }
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8491
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Definition: pbx.c:237
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8463
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:1113
const ast_string_field name
Definition: res_parking.h:89
const ast_string_field parking_con
Definition: res_parking.h:89
unsigned int parkaddhints
Definition: res_parking.h:73
#define AST_MAX_EXTENSION
Definition: channel.h:134
#define PRIORITY_HINT
Definition: pbx.h:54
Support for dynamic strings.
Definition: strings.h:623
const ast_string_field registrar
Definition: res_parking.h:89
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8473
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:8481
#define PARK_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
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:6149
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
ast_context: An extension context
Definition: pbx.c:284
unsigned int parkext_exclusive
Definition: res_parking.h:72
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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 664 of file res_parking.c.

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

Referenced by parking_lot_cfg_destructor().

665 {
666  if (!ast_strlen_zero(lot_cfg->registrar)) {
667  /* Although the function is called ast_context_destroy, the use of this funtion is
668  * intended only to remove extensions, hints, etc registered by the parking lot's registrar.
669  * It won't actually destroy the context unless that context is empty afterwards and it is
670  * unreferenced.
671  */
672  ast_context_destroy(NULL, lot_cfg->registrar);
673  }
674 
675  /* If we come back for a second pass, someone else has this registrar now. */
676  ast_string_field_set(lot_cfg, registrar, "");
677 }
const ast_string_field registrar
Definition: res_parking.h:89
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Definition: pbx.c:8221
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
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
Returns
The parking lot if found
Return values
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 602 of file res_parking.c.

References named_item_find().

Referenced by func_get_parkingslot_channel().

603 {
604  struct parking_lot *lot = named_item_find(parking_lot_container, lot_name);
605  return lot;
606 }
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:497
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
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.
Returns
A reference to the ast_bridge associated with the parking lot
Return values
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(), and parking_lot::parking_bridge.

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 ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Structure that contains information about a bridge.
Definition: bridge.h:349
struct ast_bridge * bridge_parking_new(struct parking_lot *bridge_lot)
Create a new parking bridge.
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
Returns
integer value 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_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_lot_cfg::parking_stop.

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  } else if (target_override > -1) {
114  ast_log(LOG_WARNING, "Preferred parking spot %d is out of bounds (%d-%d)\n", target_override, lot->cfg->parking_start, lot->cfg->parking_stop);
115  }
116 
117  current_target = original_target;
118 
119  wrap = lot->cfg->parking_start;
120 
121  i = ao2_iterator_init(lot->parked_users, 0);
122  while ((user = ao2_iterator_next(&i))) {
123  /* Increment the wrap on each pass until we find an empty space */
124  if (wrap == user->parking_space) {
125  wrap += 1;
126  }
127 
128  if (user->parking_space < current_target) {
129  /* It's lower than the anticipated target, so we haven't reached the target yet. */
130  ao2_ref(user, -1);
131  continue;
132  }
133 
134  if (user->parking_space > current_target) {
135  /* The current target is usable because all items below have been read and the next target is higher than the one we want. */
136  ao2_ref(user, -1);
137  break;
138  }
139 
140  /* We found one already parked here. */
141  current_target += 1;
142  ao2_ref(user, -1);
143  }
145 
146  if (current_target <= lot->cfg->parking_stop) {
147  return current_target;
148  }
149 
150  if (wrap <= lot->cfg->parking_stop) {
151  return wrap;
152  }
153 
154  return -1;
155 }
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
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
int parking_space
Definition: res_parking.h:107
unsigned int parkfindnext
Definition: res_parking.h:71
structure to hold users read from users.conf
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
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
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
Returns
reference to the requested parked user

Definition at line 168 of file parking_controller.c.

References ao2_callback, and parking_lot::parked_users.

Referenced by func_get_parkingslot_channel().

169 {
170  struct parked_user *user;
171 
172  if (target < 0) {
173  user = ao2_callback(lot->parked_users, 0, NULL, NULL);
174  } else {
175  user = ao2_callback(lot->parked_users, 0, retrieve_parked_user_targeted, &target);
176  }
177 
178  if (!user) {
179  return NULL;
180  }
181 
182  return user;
183 }
struct ao2_container * parked_users
Definition: res_parking.h:95
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
structure to hold users read from users.conf
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 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)
Remove an object from a container.
Definition: astobj2.h:1578
enum parking_lot_modes mode
Definition: res_parking.h:97
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
Returns
reference to 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 185 of file parking_controller.c.

References ao2_callback, ao2_ref, ao2_unlink, parked_user::lot, PARK_ANSWERED, parking_lot::parked_users, parking_lot_remove_if_unused(), RAII_VAR, and parked_user::resolution.

186 {
187  RAII_VAR(struct parked_user *, user, NULL, ao2_cleanup);
188 
189  if (target < 0) {
190  user = ao2_callback(lot->parked_users, 0, NULL, NULL);
191  } else {
192  user = ao2_callback(lot->parked_users, 0, retrieve_parked_user_targeted, &target);
193  }
194 
195  if (!user) {
196  return NULL;
197  }
198 
199  ao2_lock(user);
200  if (user->resolution != PARK_UNSET) {
201  /* Abandon. Something else has resolved the parked user before we got to it. */
202  ao2_unlock(user);
203  return NULL;
204  }
205 
207  user->resolution = PARK_ANSWERED;
208  ao2_unlock(user);
209 
211 
212  /* Bump the ref count by 1 since the RAII_VAR will eat the reference otherwise */
213  ao2_ref(user, +1);
214  return user;
215 }
struct ao2_container * parked_users
Definition: res_parking.h:95
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
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)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
structure to hold users read from users.conf
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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().

109 {
110  ast_debug(4, "Notification of state change to metermaids %d@%s\n to state '%s'\n",
111  exten, context, ast_devstate2str(state));
112 
113  ast_devstate_changed(state, AST_DEVSTATE_CACHABLE, "park:%d@%s", exten, context);
114 }
const char * ast_devstate2str(enum ast_device_state devstate) attribute_pure
Convert device state to text string for output.
Definition: devicestate.c:237
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
#define ast_debug(level,...)
Log a DEBUG message.
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 703 of file parking_bridge_features.c.

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

704 {
705  unsigned int time_limit;
706 
707  time_limit = user->time_limit * 1000;
708 
709  if (!time_limit) {
710  /* There is no duration limit that we need to apply. */
711  return;
712  }
713 
714  /* If the time limit has already been passed, set a really low time limit so we can kick them out immediately. */
715  time_limit = ast_remaining_ms(user->start, time_limit);
716  if (time_limit <= 0) {
717  time_limit = 1;
718  }
719 
720  /* The interval hook is going to need a reference to the parked_user */
721  ao2_ref(user, +1);
722 
723  if (ast_bridge_interval_hook(features, 0, time_limit,
724  parking_duration_callback, user, __ao2_cleanup, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
725  ast_log(LOG_ERROR, "Failed to apply duration limit to the parked call.\n");
726  ao2_ref(user, -1);
727  }
728 }
void __ao2_cleanup(void *obj)
Definition: astobj2.c:677
unsigned int time_limit
Definition: res_parking.h:110
struct timeval start
Definition: res_parking.h:106
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
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:3319
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:2281
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 627 of file parking_manager.c.

References ast_parked_call_type(), ast_parking_topic(), RAII_VAR, stasis_message_create(), and stasis_publish().

628 {
629  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
630  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
631 
632  if (!ast_parked_call_type()) {
633  return;
634  }
635 
636  payload = parked_call_payload_from_parked_user(pu, event_type);
637  if (!payload) {
638  return;
639  }
640 
642  if (!msg) {
643  return;
644  }
645 
647 }
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
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's subscribers.
Definition: stasis.c:1511
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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 605 of file parking_manager.c.

References ast_parked_call_type(), ast_parking_topic(), RAII_VAR, stasis_message_create(), and stasis_publish().

606 {
607  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
608  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
609 
610  if (!ast_parked_call_type()) {
611  return;
612  }
613 
614  payload = parked_call_payload_from_failure(parkee);
615  if (!payload) {
616  return;
617  }
618 
620  if (!msg) {
621  return;
622  }
623 
625 }
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
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's subscribers.
Definition: stasis.c:1511
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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 681 of file parking_bridge_features.c.

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

682 {
683  unsigned int numeric_value;
684  unsigned int hangup_after;
685 
686  if (sscanf(payload, "%u %u", &hangup_after, &numeric_value) != 2) {
687  /* If say_parking_space is called with a non-numeric string, we have a problem. */
688  ast_assert(0);
689  ast_bridge_channel_leave_bridge(bridge_channel,
690  BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
691  return;
692  }
693 
694  ast_say_digits(bridge_channel->chan, numeric_value, "",
695  ast_channel_language(bridge_channel->chan));
696 
697  if (hangup_after) {
698  ast_bridge_channel_leave_bridge(bridge_channel,
699  BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
700  }
701 }
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8253
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
void unload_parking_applications ( void  )

Unregister parking applications.

Since
12.0.0

Definition at line 1025 of file parking_applications.c.

References ast_unregister_application(), and PARK_APPLICATION.

1026 {
1028  ast_unregister_application(PARKED_CALL_APPLICATION);
1029  ast_unregister_application(PARK_AND_ANNOUNCE_APPLICATION);
1030 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
#define PARK_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
void unload_parking_bridge_features ( void  )

Unregister features registered by load_parking_bridge_features.

Since
12.0.0

Definition at line 793 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.

794 {
797  ast_custom_function_unregister(&getparkingslotchannel_function);
798 }
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:3078
int ast_parking_unregister_bridge_features(const char *module_name)
Unregister the current parking provider.
Definition: parking.c:223
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().

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

Unregister manager actions and remove subscriptions for stasis events.

Since
12.0.0

Definition at line 720 of file parking_manager.c.

References ast_manager_unregister().

721 {
722  ast_manager_unregister("Parkinglots");
723  ast_manager_unregister("ParkedCalls");
724  ast_manager_unregister("Park");
725  parking_manager_disable_stasis();
726 }
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8057
void unload_parking_tests ( void  )

Unregister parking unit tests.

Since
12.0.0

Definition at line 838 of file parking_tests.c.

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 }
void unload_parking_ui ( void  )

Unregister CLI commands.

Since
12.0.0

Definition at line 203 of file parking_ui.c.

References ast_cli_unregister_multiple().

204 {
205  ast_cli_unregister_multiple(cli_parking_lot, ARRAY_LEN(cli_parking_lot));
206 }
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
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().

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)
Remove an object from a container.
Definition: astobj2.h:1578