Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Functions | Variables
res_parking.c File Reference

Call Parking Resource. More...

#include "asterisk.h"
#include "parking/res_parking.h"
#include "asterisk/config.h"
#include "asterisk/config_options.h"
#include "asterisk/utils.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/astobj2.h"
#include "asterisk/features.h"
#include "asterisk/manager.h"
#include "asterisk/pbx.h"

Go to the source code of this file.

Data Structures

struct  parking_config
 
struct  parking_global_config
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static struct parking_lotalloc_new_parking_lot (struct parking_lot_cfg *lot_cfg)
 
static AO2_GLOBAL_OBJ_STATIC (globals)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct parking_lot_cfgclone_parkinglot_cfg (struct parking_lot_cfg *source, const char *name)
 
 CONFIG_INFO_STANDARD (cfg_info, globals, parking_config_alloc,.files=ACO_FILES(&parking_lot_conf),.pre_apply_config=config_parking_preapply,.post_apply_config=link_configured_disable_marked_lots,)
 
static int config_parking_preapply (void)
 
static int configure_parking_extensions (void)
 
static struct parking_lotcreate_dynamic_lot_full (const char *name, struct ast_channel *chan, int forced)
 
static void disable_marked_lots (void)
 
static int extension_is_compatible (struct parking_lot_cfg *lot_cfg, const char *app_type, struct ast_exten *extension)
 
const char * find_channel_parking_lot_name (struct ast_channel *chan)
 Find parking lot name from channel. More...
 
static void generate_or_link_lots_to_configs (void)
 
struct ao2_containerget_parking_lot_container (void)
 Get a pointer to the parking lot container for purposes such as iteration. More...
 
static void link_configured_disable_marked_lots (void)
 
static int load_module (void)
 
static void mark_lots_as_disabled (void)
 
static void * named_item_find (struct ao2_container *container, const char *name)
 find an item in a container by its name More...
 
static int option_handler_findslot (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom field handler for the findslot option.
 
static int option_handler_parkedfeature (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom field handler for feature mapping on parked call pickup options.
 
static int option_handler_parkpos (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom field handler for parking positions.
 
static int parked_user_cmp_fn (void *obj, void *arg, int flags)
 
static int parked_user_sort_fn (const void *obj_left, const void *obj_right, int flags)
 
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)
 
static void * parking_config_alloc (void)
 allocator callback for parking_config. Notice it returns void * since it is only used by the backend config code
 
static void parking_config_destructor (void *obj)
 destructor for parking_config
 
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...
 
static int parking_feature_flag_cfg (int *param, const char *var)
 Maps string values for option_handler_parkedfeature to their ENUM values.
 
static void parking_global_config_destructor (void *obj)
 destructor for parking_global_config
 
struct parking_lotparking_lot_build_or_update (struct parking_lot_cfg *lot_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...
 
static void * parking_lot_cfg_alloc (const char *cat)
 create a parking lot structure More...
 
static int parking_lot_cfg_cmp_fn (void *obj, void *arg, const int flags)
 
int parking_lot_cfg_create_extensions (struct parking_lot_cfg *lot_cfg)
 Add extensions for a parking lot configuration. More...
 
static void parking_lot_cfg_destructor (void *obj)
 Destroy a parking lot cfg object.
 
static int parking_lot_cfg_hash_fn (const void *obj, const int flags)
 
void parking_lot_cfg_remove_extensions (struct parking_lot_cfg *lot_cfg)
 Remove extensions belonging to a parking lot configuration. More...
 
static void parking_lot_destructor (void *obj)
 
static void parking_lot_disable (struct parking_lot *lot)
 
struct parking_lotparking_lot_find_by_name (const char *lot_name)
 Find a parking lot based on its name. 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...
 
static int parking_lot_sort_fn (const void *obj_left, const void *obj_right, int flags)
 
static int reload_module (void)
 
static void remove_all_configured_parking_lot_extensions (void)
 
static void remove_pending_parking_lot_extensions (struct parking_config *cfg_pending)
 
static int unload_module (void)
 
static int verify_default_parking_lot (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Call Parking Resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "da6642af068ee5e6490c5b1d2cc1d238" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct aco_type global_option
 
struct aco_typeglobal_options [] = ACO_TYPES(&global_option)
 
struct aco_file parking_lot_conf
 
static struct ao2_containerparking_lot_container
 
static struct aco_type parking_lot_type
 
struct aco_typeparking_lot_types [] = ACO_TYPES(&parking_lot_type)
 

Detailed Description

Call Parking Resource.

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

Definition in file res_parking.c.

Function Documentation

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.
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
static void * named_item_find ( struct ao2_container container,
const char *  name 
)
static

find an item in a container by its name

XXX This is actually incredibly generic and might be better placed in something like astobj2 if there isn't already an equivalent

Parameters
containerao2container where we want the item from
namename of the item wanted to be found
Returns
pointer to the parking lot if available.
Return values
NULLif not found.

Definition at line 497 of file res_parking.c.

References OBJ_KEY.

Referenced by parking_lot_build_or_update(), and parking_lot_find_by_name().

498 {
499  return ao2_find(container, name, OBJ_KEY);
500 }
#define OBJ_KEY
Definition: astobj2.h:1151
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
const ast_string_field name
Definition: res_parking.h:89
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
static void * parking_lot_cfg_alloc ( const char *  cat)
static

create a parking lot structure

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

Definition at line 461 of file res_parking.c.

References ast_string_field_init, ast_string_field_set, parking_lot_cfg::name, and parking_lot_cfg_destructor().

462 {
463  struct parking_lot_cfg *lot_cfg;
464 
465  lot_cfg = ao2_alloc(sizeof(*lot_cfg), parking_lot_cfg_destructor);
466  if (!lot_cfg) {
467  return NULL;
468  }
469 
470  if (ast_string_field_init(lot_cfg, 32)) {
471  ao2_cleanup(lot_cfg);
472  return NULL;
473  }
474 
475  ast_string_field_set(lot_cfg, name, cat);
476 
477  return lot_cfg;
478 }
const ast_string_field name
Definition: res_parking.h:89
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
static void parking_lot_cfg_destructor(void *obj)
Destroy a parking lot cfg object.
Definition: res_parking.c:427
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
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
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

Variable Documentation

struct aco_file parking_lot_conf
Initial value:
= {
.filename = "res_parking.conf",
.types = ACO_TYPES(&global_option, &parking_lot_type),
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static struct aco_type global_option
An aco_type structure to link the "general" category to the skel_global_config type.
Definition: app_skel.c:241

Definition at line 307 of file res_parking.c.

struct ao2_container* parking_lot_container
static

All parking lots that are currently alive in some fashion can be obtained from here

Definition at line 266 of file res_parking.c.

Referenced by get_parking_lot_container().