Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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...
 
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.

Macro Definition Documentation

◆ BASE_REGISTRAR

#define BASE_REGISTRAR   "res_parking"

Definition at line 36 of file res_parking.h.

◆ DEFAULT_PARKING_EXTEN

#define DEFAULT_PARKING_EXTEN   "700"

Definition at line 35 of file res_parking.h.

◆ DEFAULT_PARKING_LOT

#define DEFAULT_PARKING_LOT   "default"

Definition at line 34 of file res_parking.h.

◆ PARK_DIAL_CONTEXT

#define PARK_DIAL_CONTEXT   "park-dial"

Definition at line 37 of file res_parking.h.

◆ PARKED_CALL_APPLICATION

#define PARKED_CALL_APPLICATION   "ParkedCall"

Definition at line 38 of file res_parking.h.

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};
@ PARK_ANSWERED
Definition: res_parking.h:45
@ PARK_TIMEOUT
Definition: res_parking.h:43
@ PARK_FORCED
Definition: res_parking.h:44
@ PARK_UNSET
Definition: res_parking.h:41
@ PARK_ABANDON
Definition: res_parking.h:42

◆ parked_call_feature_options

Enumerator
OPT_PARKEDPLAY 
OPT_PARKEDTRANSFERS 
OPT_PARKEDREPARKING 
OPT_PARKEDHANGUP 
OPT_PARKEDRECORDING 

Definition at line 48 of file res_parking.h.

48 {
54};
@ OPT_PARKEDREPARKING
Definition: res_parking.h:51
@ OPT_PARKEDTRANSFERS
Definition: res_parking.h:50
@ OPT_PARKEDPLAY
Definition: res_parking.h:49
@ OPT_PARKEDRECORDING
Definition: res_parking.h:53
@ OPT_PARKEDHANGUP
Definition: res_parking.h:52

◆ 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};
@ PARKINGLOT_DISABLED
Definition: res_parking.h:61
@ PARKINGLOT_NORMAL
Definition: res_parking.h:57
@ PARKINGLOT_DYNAMIC
Definition: res_parking.h:59

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

Definition at line 450 of file parking_bridge.c.

451{
452 void *bridge;
453
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}
@ AST_BRIDGE_CAPABILITY_HOLDING
Definition: bridge.h:90
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:713
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:783
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:747
struct ast_bridge_methods ast_bridge_parking_v_table
static struct ast_bridge * ast_bridge_parking_init(struct ast_bridge_parking *self, struct parking_lot *bridge_lot)
#define NULL
Definition: resample.c:96
const ast_string_field name
Definition: res_parking.h:102

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(), ast_bridge_parking_v_table, bridge_alloc(), bridge_base_init(), bridge_register(), parking_lot::name, and NULL.

Referenced by parking_lot_get_bridge().

◆ 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 263 of file parking_controller.c.

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}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
const char * ast_channel_name(const struct ast_channel *chan)
#define LOG_ERROR
#define ast_verb(level,...)
void flatten_dial_string(char *dialstring)
Flattens a dial string so that it can be written to/found from PBX extensions.
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:4190
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:6984
#define PARK_DIAL_CONTEXT
Definition: res_parking.h:37
Main Channel structure associated with a channel.
char * parker_dial_string
Definition: res_parking.h:111
struct ast_channel * chan
Definition: res_parking.h:106
unsigned int comebacktoorigin
Definition: res_parking.h:74
const ast_string_field comebackcontext
Definition: res_parking.h:89
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

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

◆ 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 236 of file parking_bridge_features.c.

237{
238 return create_parked_subscription_full(chan, parkee_uuid, hangup_after, NULL);
239}
static int create_parked_subscription_full(struct ast_channel *chan, const char *parkee_uuid, int hangup_after, struct transfer_channel_data *parked_channel_data)

References create_parked_subscription_full(), parked_subscription_data::hangup_after, NULL, and parked_subscription_data::parkee_uuid.

Referenced by manager_park(), and manager_park_bridged().

◆ 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 668 of file res_parking.c.

669{
670 const char *name;
671
672 /* The channel variable overrides everything */
673 name = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
674 if (ast_strlen_zero(name)) {
675 /* Try the channel's parking lot. */
677 if (ast_strlen_zero(name)) {
678 /* Fall back to the default parking lot. */
680 }
681 }
682
683 return name;
684}
const char * ast_channel_parkinglot(const struct ast_channel *chan)
static const char name[]
Definition: format_mp3.c:68
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define DEFAULT_PARKING_LOT
Definition: res_parking.h:34
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

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

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

◆ 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
dialstringunflattened dial string. This will be flattened in place.

Definition at line 251 of file parking_controller.c.

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}

Referenced by comeback_goto(), and parking_duration_callback().

◆ get_park_common_datastore_copy()

struct park_common_datastore * get_park_common_datastore_copy ( struct ast_channel parkee)

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

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

Definition at line 450 of file parking_applications.c.

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

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

Referenced by bridge_parking_push().

◆ 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
Returns
pointer to the parking lot container.

Definition at line 657 of file res_parking.c.

658{
660}
static struct ao2_container * parking_lot_container
Definition: res_parking.c:326

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

◆ load_parking_applications()

int load_parking_applications ( void  )

Register parking applications.

Since
12.0.0
Return values
0if successful
-1on failure

Definition at line 1017 of file parking_applications.c.

1018{
1020 return -1;
1021 }
1022
1024 return -1;
1025 }
1026
1028 return -1;
1029 }
1030
1031 return 0;
1032}
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
#define PARK_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
static int park_app_exec(struct ast_channel *chan, const char *data)
static int park_and_announce_app_exec(struct ast_channel *chan, const char *data)
static int parked_call_app_exec(struct ast_channel *chan, const char *data)
#define PARK_AND_ANNOUNCE_APPLICATION
#define PARKED_CALL_APPLICATION
Definition: res_parking.h:38

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

Referenced by load_module().

◆ 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 803 of file parking_bridge_features.c.

804{
805 parking_provider.module = AST_MODULE_SELF;
806
808
810 return -1;
811 }
812
814 return -1;
815 }
816
817 return 0;
818}
@ AST_BRIDGE_BUILTIN_PARKCALL
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:3131
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_parking_bridge_feature_fn_table parking_provider
static int feature_park_call(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
static struct ast_custom_function getparkingslotchannel_function
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1559
struct ast_module * module
The module info for the module registering this parking provider.
Definition: parking.h:202

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

Referenced by load_module().

◆ 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.

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

References ast_devstate_prov_add(), and metermaidstate().

Referenced by load_module().

◆ load_parking_manager()

int load_parking_manager ( void  )

Register manager actions and setup subscriptions for stasis events.

Since
12.0.0

Definition at line 728 of file parking_manager.c.

729{
730 int res;
731
736 return res ? -1 : 0;
737}
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:192
#define EVENT_FLAG_CALL
Definition: manager.h:76
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)

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

◆ 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.

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

References AST_TEST_REGISTER.

Referenced by load_module().

◆ 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.

199{
201}
#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
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, ast_cli_register_multiple, and cli_parking_lot.

Referenced by load_module().

◆ park_application_setup()

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

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

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

Definition at line 554 of file parking_applications.c.

556{
557 int use_ringing = 0;
558 int randomize = 0;
559 int time_limit = -1;
560
561 RAII_VAR(char *, comeback_override, NULL, ast_free);
562 RAII_VAR(char *, lot_name_app_arg, NULL, ast_free);
563 RAII_VAR(char *, musicclass, NULL, ast_free);
564
565 if (app_data) {
566 park_app_parse_data(app_data, silence_announcements, &use_ringing, &randomize, &time_limit, &comeback_override, &lot_name_app_arg, &musicclass);
567 }
568
569 return park_common_setup2(parkee, parker, lot_name_app_arg, comeback_override, musicclass, use_ringing,
570 randomize, time_limit, silence_announcements ? *silence_announcements : 0);
571
572}
#define ast_free(a)
Definition: astmm.h:180
static int park_app_parse_data(const char *data, int *disable_announce, int *use_ringing, int *randomize, int *time_limit, char **comeback_override, char **lot_name, char **musicclass)
static struct ast_bridge * park_common_setup2(struct ast_channel *parkee, struct ast_channel *parker, const char *lot_name, const char *comeback_override, const char *musicclass, int use_ringing, int randomize, int time_limit, int silence_announcements)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

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

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

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

345{
346 if (!datastore) {
347 return;
348 }
349
350 ast_free(datastore->parker_uuid);
351 ast_free(datastore->parker_dial_string);
352 ast_free(datastore->comeback_override);
353 ast_free(datastore);
354}

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

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

◆ park_common_setup()

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

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

Since
12.0.0

Definition at line 547 of file parking_applications.c.

550{
551 return park_common_setup2(parkee, parker, lot_name, comeback_override, NULL, use_ringing, randomize, time_limit, silence_announcements);
552}

References NULL, and park_common_setup2().

Referenced by manager_park_unbridged().

◆ 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 217 of file parking_controller.c.

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}
struct ast_flags * ast_bridge_features_ds_get(struct ast_channel *chan)
Get DTMF feature flags from the channel.
Definition: bridge_basic.c:268
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
@ AST_FEATURE_AUTOMIXMON
Definition: channel.h:1089
@ AST_FEATURE_REDIRECT
Definition: channel.h:1084
@ AST_FEATURE_PARKCALL
Definition: channel.h:1088
@ AST_FEATURE_DISCONNECT
Definition: channel.h:1085
#define ast_channel_lock(chan)
Definition: channel.h:2972
#define ast_channel_unlock(chan)
Definition: channel.h:2973
Structure used to handle boolean flags.
Definition: utils.h:199
int parkedcalltransfers
Definition: res_parking.h:76
int parkedcallreparking
Definition: res_parking.h:77
int parkedcallrecording
Definition: res_parking.h:79
#define ast_set_flag(p, flag)
Definition: utils.h:70

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

◆ 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.

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_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
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
const ast_string_field mohclass
Definition: res_parking.h:89

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

◆ 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
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 1120 of file res_parking.c.

1120 {
1121 return create_dynamic_lot_full(name, chan, 0);
1122}
static struct parking_lot * create_dynamic_lot_full(const char *name, struct ast_channel *chan, int forced)
Definition: res_parking.c:1031

References create_dynamic_lot_full(), and name.

Referenced by park_common_setup2(), and parking_park_call().

◆ 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 989 of file res_parking.c.

990{
992
993 if (!cfg) {
994 return 0;
995 }
996
997 return cfg->global->parkeddynamic;
998}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static struct console_pvt globals

References ao2_cleanup, ao2_global_obj_ref, globals, and RAII_VAR.

Referenced by cli_display_parking_global(), and create_dynamic_lot_full().

◆ 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.
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 929 of file res_parking.c.

930{
931 struct parking_lot *lot;
932 struct parking_lot_cfg *replaced_cfg = NULL;
933 int found = 0;
934
935 /* Start by trying to find it. If that works we can skip the rest. */
936 lot = named_item_find(parking_lot_container, lot_cfg->name);
937 if (!lot) {
938 lot = alloc_new_parking_lot(lot_cfg);
939
940 /* If we still don't have a lot, we failed to alloc one. */
941 if (!lot) {
942 return NULL;
943 }
944 } else {
945 found = 1;
946
947 if (dynamic) {
948 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);
949 ao2_cleanup(lot);
950 return NULL;
951 }
952 }
953
954 /* Set the configuration reference. Unref the one currently in the lot if it's there. */
955 if (lot->cfg) {
956 replaced_cfg = lot->cfg;
957 }
958
959 ao2_ref(lot_cfg, +1);
960 lot->cfg = lot_cfg;
961
962 ao2_cleanup(replaced_cfg);
963
964 /* Set the operating mode to normal since the parking lot has a configuration. */
965 lot->disable_mark = 0;
966 lot->mode = dynamic ? PARKINGLOT_DYNAMIC : PARKINGLOT_NORMAL;
967
968 if (!found) {
969 /* Link after configuration is set since a lot without configuration will cause all kinds of trouble. */
971 };
972
973 return lot;
974}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static struct parking_lot * alloc_new_parking_lot(struct parking_lot_cfg *lot_cfg)
Definition: res_parking.c:698
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:557
enum parking_lot_modes mode
Definition: res_parking.h:97
int disable_mark
Definition: res_parking.h:98

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, parking_lot_container, PARKINGLOT_DYNAMIC, and PARKINGLOT_NORMAL.

Referenced by create_dynamic_lot_full(), and generate_or_link_lots_to_configs().

◆ 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 819 of file res_parking.c.

820{
821 int parkingspace;
822 struct ast_exten *existing_exten;
823 struct ast_context *lot_context;
824 struct pbx_find_info find_info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
825 const char *parkext_registrar_pointer; /* Used for park extension */
826 const char *parkedcall_registrar_pointer; /* Used for parkedcall extensions/hints */
827
828 if (ast_strlen_zero(lot_cfg->parkext)) {
829 return 0;
830 }
831
832 ast_string_field_build(lot_cfg, registrar, "%s/%s", BASE_REGISTRAR, lot_cfg->name);
833 parkedcall_registrar_pointer = lot_cfg->registrar;
834
835 if (lot_cfg->parkext_exclusive) {
836 parkext_registrar_pointer = lot_cfg->registrar;
837 } else {
838 parkext_registrar_pointer = BASE_REGISTRAR;
839 }
840
841 /* We need the contexts list locked to safely be able to both read and lock the specific context within */
843
844 if (!(lot_context = ast_context_find_or_create(NULL, NULL, lot_cfg->parking_con, parkext_registrar_pointer))) {
845 ast_log(LOG_ERROR, "Parking lot '%s' -- Needs a context '%s' which does not exist and Asterisk was unable to create\n",
846 lot_cfg->name, lot_cfg->parking_con);
848 return -1;
849 }
850
851 /* Once we know what context we will be modifying, we need to write lock it because we will be reading extensions
852 * and we don't want something else to destroy them while we are looking at them.
853 */
854 ast_wrlock_context(lot_context);
855
857
858 /* Handle generation/confirmation for the Park extension */
859 if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, lot_cfg->parkext, 1, NULL, NULL, E_MATCH))) {
860 if (lot_cfg->parkext_exclusive || !extension_is_compatible(lot_cfg, PARK_APPLICATION, existing_exten)) {
861 ast_unlock_context(lot_context);
862 return -1;
863 }
864 } else if (parking_add_extension(lot_context, 0, lot_cfg->parkext, 1, PARK_APPLICATION,
865 lot_cfg->parkext_exclusive ? lot_cfg->name : "", parkext_registrar_pointer)) {
866 ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add %s extension '%s@%s' to the PBX.\n",
867 lot_cfg->name, PARK_APPLICATION, lot_cfg->parkext, lot_cfg->parking_con);
868 ast_unlock_context(lot_context);
869 return -1;
870 }
871
872 /* Handle generation/confirmation for the ParkedCall extensions and hints */
873 for (parkingspace = lot_cfg->parking_start; parkingspace <= lot_cfg->parking_stop; parkingspace++) {
874 char space[AST_MAX_EXTENSION];
875 RAII_VAR(struct ast_str *, arguments_string, NULL, ast_free);
876 find_info.stacklen = 0; /* reset for pbx_find_exten */
877
878 snprintf(space, sizeof(space), "%d", parkingspace);
879
880 /* Unlike the Park extensions, ParkedCall extensions and their hints may never be shared for any reason. */
881 if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, space, 1, NULL, NULL, E_MATCH))) {
882 ast_unlock_context(lot_context);
883 return -1;
884 }
885
886 arguments_string = ast_str_create(32);
887 if (!arguments_string) {
888 ast_unlock_context(lot_context);
889 return -1;
890 }
891
892 ast_str_set(&arguments_string, 0, "%s,%s", lot_cfg->name, space);
893 if (parking_add_extension(lot_context, 0, space, 1, PARKED_CALL_APPLICATION,
894 ast_str_buffer(arguments_string), parkedcall_registrar_pointer)) {
895 ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add %s extension '%s@%s' to the PBX.\n",
896 lot_cfg->name, PARKED_CALL_APPLICATION, space, lot_cfg->parking_con);
897 ast_unlock_context(lot_context);
898 return -1;
899 }
900
901 find_info.stacklen = 0; /* reset for pbx_find_exten */
902
903 if (lot_cfg->parkaddhints) {
904 char hint_device[AST_MAX_EXTENSION];
905
906 snprintf(hint_device, sizeof(hint_device), "park:%s@%s", space, lot_cfg->parking_con);
907
908 if ((existing_exten = pbx_find_extension(NULL, NULL, &find_info, lot_cfg->parking_con, space, PRIORITY_HINT, NULL, NULL, E_MATCH))) {
909 ast_log(LOG_ERROR, "Parking lot '%s' -- Needs to add a hint '%s' at '%s@%s' but one already exists owned by %s\n",
910 lot_cfg->name, hint_device, space, lot_cfg->parking_con, ast_get_extension_registrar(existing_exten));
911 ast_unlock_context(lot_context);
912 return -1;
913 }
914
915 if (parking_add_extension(lot_context, 0, space, PRIORITY_HINT, hint_device, "", parkedcall_registrar_pointer)) {
916 ast_log(LOG_ERROR, "Parking lot '%s' -- Failed to add hint '%s@%s' to the PBX.\n",
917 lot_cfg->name, space, lot_cfg->parking_con);
918 ast_unlock_context(lot_context);
919 return -1;
920 }
921 }
922 }
923
924 ast_unlock_context(lot_context);
925
926 return 0;
927}
#define AST_MAX_EXTENSION
Definition: channel.h:134
@ E_MATCH
Definition: extconf.h:217
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8478
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:8496
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:6164
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8506
#define PRIORITY_HINT
Definition: pbx.h:54
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
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8488
const char * ast_get_extension_registrar(struct ast_exten *e)
Definition: pbx.c:8547
static char * registrar
Definition: pbx_ael.c:81
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:774
static int extension_is_compatible(struct parking_lot_cfg *lot_cfg, const char *app_type, struct ast_exten *extension)
Definition: res_parking.c:791
#define BASE_REGISTRAR
Definition: res_parking.h:36
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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
ast_context: An extension context
Definition: pbx.c:299
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Definition: pbx.c:252
Support for dynamic strings.
Definition: strings.h:623
unsigned int parkext_exclusive
Definition: res_parking.h:72
const ast_string_field registrar
Definition: res_parking.h:89
const ast_string_field parkext
Definition: res_parking.h:89
unsigned int parkaddhints
Definition: res_parking.h:73
const ast_string_field name
Definition: res_parking.h:89
const ast_string_field parking_con
Definition: res_parking.h:89
int stacklen
Definition: extconf.h:237

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

◆ 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 724 of file res_parking.c.

725{
726 if (!ast_strlen_zero(lot_cfg->registrar)) {
727 /* Although the function is called ast_context_destroy, the use of this funtion is
728 * intended only to remove extensions, hints, etc registered by the parking lot's registrar.
729 * It won't actually destroy the context unless that context is empty afterwards and it is
730 * unreferenced.
731 */
733 }
734
735 /* If we come back for a second pass, someone else has this registrar now. */
736 ast_string_field_set(lot_cfg, registrar, "");
737}
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:8236
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521

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

◆ 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
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 662 of file res_parking.c.

663{
664 struct parking_lot *lot = named_item_find(parking_lot_container, lot_name);
665 return lot;
666}

References named_item_find(), and parking_lot_container.

Referenced by cli_display_parking_lot(), create_dynamic_lot_full(), func_get_parkingslot_channel(), manager_parking_status_single_lot(), park_common_setup2(), parked_call_app_exec(), and parking_park_call().

◆ 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.
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.

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 * bridge_parking_new(struct parking_lot *bridge_lot)
Create a new parking bridge.
Structure that contains information about a bridge.
Definition: bridge.h:353
struct ast_bridge * parking_bridge
Definition: res_parking.h:94

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

Referenced by park_common_setup2().

◆ 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
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.

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
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}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define LOG_WARNING
static char user[512]
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 parking_lot * lot
Definition: res_parking.h:113
unsigned int parkfindnext
Definition: res_parking.h:71
int next_space
Definition: res_parking.h:93
struct ao2_container * parked_users
Definition: res_parking.h:95
structure to hold users read from users.conf

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_log, parking_lot::cfg, LOG_WARNING, parked_user::lot, parking_lot::next_space, parking_lot::parked_users, parking_lot_cfg::parkfindnext, parking_lot_cfg::parking_start, parking_lot_cfg::parking_stop, and user.

Referenced by generate_parked_user().

◆ 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
Returns
reference to the requested parked user

Definition at line 168 of file parking_controller.c.

169{
170 struct parked_user *user;
171
172 if (target < 0) {
174 } else {
176 }
177
178 if (!user) {
179 return NULL;
180 }
181
182 return user;
183}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
static int retrieve_parked_user_targeted(void *obj, void *arg, int flags)

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

Referenced by func_get_parkingslot_channel().

◆ 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 460 of file res_parking.c.

461{
462 if (lot->mode != PARKINGLOT_DISABLED) {
463 return -1;
464 }
465
468 return 0;
469 }
470
471 return -1;
472}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578

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

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

◆ 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
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.

186{
188
189 if (target < 0) {
191 } else {
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. */
203 return NULL;
204 }
205
207 user->resolution = PARK_ANSWERED;
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}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
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:460

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

Referenced by parked_call_app_exec().

◆ 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.

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

References ast_debug, ast_devstate2str(), AST_DEVSTATE_CACHABLE, ast_devstate_changed(), voicemailpwcheck::context, and parking_lot_extension_inuse_search::exten.

Referenced by bridge_parking_pull(), and bridge_parking_push().

◆ 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 706 of file parking_bridge_features.c.

707{
708 unsigned int time_limit;
709
710 time_limit = user->time_limit * 1000;
711
712 if (!time_limit) {
713 /* There is no duration limit that we need to apply. */
714 return;
715 }
716
717 /* If the time limit has already been passed, set a really low time limit so we can kick them out immediately. */
718 time_limit = ast_remaining_ms(user->start, time_limit);
719 if (time_limit <= 0) {
720 time_limit = 1;
721 }
722
723 /* The interval hook is going to need a reference to the parked_user */
724 ao2_ref(user, +1);
725
726 if (ast_bridge_interval_hook(features, 0, time_limit,
728 ast_log(LOG_ERROR, "Failed to apply duration limit to the parked call.\n");
729 ao2_ref(user, -1);
730 }
731}
void __ao2_cleanup(void *obj)
Definition: astobj2.c:677
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:3388
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL
static int parking_duration_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:2281

References __ao2_cleanup(), ao2_ref, AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_bridge_interval_hook(), ast_log, ast_remaining_ms(), LOG_ERROR, and parking_duration_callback().

Referenced by bridge_parking_push().

◆ 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 651 of file parking_manager.c.

652{
654 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
655
656 if (!ast_parked_call_type()) {
657 return;
658 }
659
660 payload = parked_call_payload_from_parked_user(pu, event_type);
661 if (!payload) {
662 return;
663 }
664
666 if (!msg) {
667 return;
668 }
669
671}
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
static struct ast_parked_call_payload * parked_call_payload_from_parked_user(struct parked_user *pu, enum ast_parked_call_event_type event_type)
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:1538
A parked call message payload.
Definition: parking.h:59

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

◆ 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 629 of file parking_manager.c.

630{
632 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
633
634 if (!ast_parked_call_type()) {
635 return;
636 }
637
638 payload = parked_call_payload_from_failure(parkee);
639 if (!payload) {
640 return;
641 }
642
644 if (!msg) {
645 return;
646 }
647
649}
static struct ast_parked_call_payload * parked_call_payload_from_failure(struct ast_channel *chan)

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

◆ 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 684 of file parking_bridge_features.c.

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

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

◆ unload_parking_applications()

void unload_parking_applications ( void  )

Unregister parking applications.

Since
12.0.0

Definition at line 1034 of file parking_applications.c.

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

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

Referenced by unload_module().

◆ 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 796 of file parking_bridge_features.c.

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

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

Referenced by unload_module().

◆ 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.

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

References ast_devstate_prov_del().

Referenced by unload_module().

◆ unload_parking_manager()

void unload_parking_manager ( void  )

Unregister manager actions and remove subscriptions for stasis events.

Since
12.0.0

Definition at line 744 of file parking_manager.c.

745{
746 ast_manager_unregister("Parkinglots");
747 ast_manager_unregister("ParkedCalls");
750}
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7697
static void parking_manager_disable_stasis(void)

References ast_manager_unregister(), and parking_manager_disable_stasis().

Referenced by unload_module().

◆ unload_parking_tests()

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}
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

References AST_TEST_UNREGISTER.

Referenced by unload_module().

◆ unload_parking_ui()

void unload_parking_ui ( void  )

Unregister CLI commands.

Since
12.0.0

Definition at line 203 of file parking_ui.c.

204{
206}
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30

References ARRAY_LEN, ast_cli_unregister_multiple(), and cli_parking_lot.

Referenced by unload_module().

◆ 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.

86{
87 if (pu->lot) {
88 ao2_unlink(pu->lot->parked_users, pu);
90 return 0;
91 }
92
93 return -1;
94}

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

Referenced by bridge_parking_pull().