Asterisk - The Open Source Telephony Project  18.5.0
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"
Include dependency graph for res_parking.c:

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. More...
 
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. More...
 
static int option_handler_parkpos (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom field handler for parking positions. More...
 
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 More...
 
static void parking_config_destructor (void *obj)
 destructor for parking_config More...
 
struct parking_lotparking_create_dynamic_lot (const char *name, struct ast_channel *chan)
 Create a dynamic parking lot. More...
 
struct parking_lotparking_create_dynamic_lot_forced (const char *name, struct ast_channel *chan)
 Create a dynamic parking lot without respect to whether they are enabled by configuration. More...
 
int parking_dynamic_lots_enabled (void)
 Check global configuration to see if dynamic parking is enabled. More...
 
static int parking_feature_flag_cfg (int *param, const char *var)
 Maps string values for option_handler_parkedfeature to their ENUM values. More...
 
static void parking_global_config_destructor (void *obj)
 destructor for parking_global_config More...
 
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)
 
struct parking_lot_cfgparking_lot_cfg_create (const char *cat)
 Create an empty parking lot configuration structure useful for unit tests. More...
 
int parking_lot_cfg_create_extensions (struct parking_lot_cfg *lot_cfg)
 Add extensions for a parking lot configuration. More...
 
static void parking_lot_cfg_destructor (void *obj)
 Destroy a parking lot cfg object. More...
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1295 of file res_parking.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1295 of file res_parking.c.

◆ alloc_new_parking_lot()

static struct parking_lot* alloc_new_parking_lot ( struct parking_lot_cfg lot_cfg)
static

Definition at line 637 of file res_parking.c.

References ao2_alloc, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_cleanup, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ast_string_field_init, ast_string_field_set, name, parking_lot_cfg::name, NULL, parked_user_cmp_fn(), parked_user_sort_fn(), parking_lot::parked_users, and parking_lot_destructor().

Referenced by parking_lot_build_or_update().

638 {
639  struct parking_lot *lot;
640  if (!(lot = ao2_alloc(sizeof(*lot), parking_lot_destructor))) {
641  return NULL;
642  }
643 
644  if (ast_string_field_init(lot, 32)) {
645  return NULL;
646  }
647 
648  /* Create parked user ordered list */
653 
654  if (!lot->parked_users) {
655  ao2_cleanup(lot);
656  return NULL;
657  }
658 
659  ast_string_field_set(lot, name, lot_cfg->name);
660  return lot;
661 }
struct ao2_container * parked_users
Definition: res_parking.h:95
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define NULL
Definition: resample.c:96
static int parked_user_sort_fn(const void *obj_left, const void *obj_right, int flags)
Definition: res_parking.c:447
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:353
static int parked_user_cmp_fn(void *obj, void *arg, int flags)
Definition: res_parking.c:435
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Reject objects with duplicate keys in container.
Definition: astobj2.h:1192
static void parking_lot_destructor(void *obj)
Definition: res_parking.c:625
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ AO2_GLOBAL_OBJ_STATIC()

static AO2_GLOBAL_OBJ_STATIC ( globals  )
static

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1295 of file res_parking.c.

◆ clone_parkinglot_cfg()

static struct parking_lot_cfg* clone_parkinglot_cfg ( struct parking_lot_cfg source,
const char *  name 
)
static

Definition at line 939 of file res_parking.c.

References ast_string_field_set, ast_string_fields_copy, parking_lot_cfg::comebackdialtime, parking_lot_cfg::comebacktoorigin, NULL, parking_lot_cfg::parkaddhints, parking_lot_cfg::parkedcallhangup, parking_lot_cfg::parkedcallrecording, parking_lot_cfg::parkedcallreparking, parking_lot_cfg::parkedcalltransfers, parking_lot_cfg::parkedplay, parking_lot_cfg::parkext_exclusive, parking_lot_cfg::parkfindnext, parking_lot_cfg_alloc(), parking_lot_cfg::parking_start, parking_lot_cfg::parking_stop, and parking_lot_cfg::parkingtime.

Referenced by create_dynamic_lot_full().

940 {
942 
943  if (!cfg) {
944  return NULL;
945  }
946 
947  ast_string_fields_copy(cfg, source);
948 
949  /* Needs to be reset after being copied */
951 
952  /* Stuff that should be cloned that isn't hit by string field copy */
953  cfg->parking_start = source->parking_start;
954  cfg->parking_stop = source->parking_stop;
955  cfg->parkingtime = source->parkingtime;
956  cfg->comebackdialtime = source->comebackdialtime;
957  cfg->parkfindnext = source->parkfindnext;
958  cfg->parkext_exclusive = source->parkext_exclusive;
959  cfg->parkaddhints = source->parkaddhints;
960  cfg->comebacktoorigin = source->comebacktoorigin;
961  cfg->parkedplay = source->parkedplay;
964  cfg->parkedcallhangup = source->parkedcallhangup;
966 
967  return cfg;
968 }
unsigned int comebackdialtime
Definition: res_parking.h:70
int parkedcallreparking
Definition: res_parking.h:77
unsigned int parkingtime
Definition: res_parking.h:69
#define NULL
Definition: resample.c:96
unsigned int parkaddhints
Definition: res_parking.h:73
unsigned int comebacktoorigin
Definition: res_parking.h:74
static void * parking_lot_cfg_alloc(const char *cat)
create a parking lot structure
Definition: res_parking.c:461
#define ast_string_fields_copy(copy, orig)
Copy all string fields from one instance to another of the same structure.
Definition: stringfields.h:627
static const char name[]
Definition: cdr_mysql.c:74
unsigned int parkfindnext
Definition: res_parking.h:71
int parkedcalltransfers
Definition: res_parking.h:76
int parkedcallrecording
Definition: res_parking.h:79
unsigned int parkext_exclusive
Definition: res_parking.h:72
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ CONFIG_INFO_STANDARD()

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 
)

◆ config_parking_preapply()

static int config_parking_preapply ( void  )
static

Definition at line 1155 of file res_parking.c.

References configure_parking_extensions(), mark_lots_as_disabled(), and verify_default_parking_lot().

1156 {
1158 
1160  return -1;
1161  }
1162 
1164  return -1;
1165  }
1166 
1167  return 0;
1168 }
static int verify_default_parking_lot(void)
Definition: res_parking.c:1071
static int configure_parking_extensions(void)
Definition: res_parking.c:1110
static void mark_lots_as_disabled(void)
Definition: res_parking.c:1143

◆ configure_parking_extensions()

static int configure_parking_extensions ( void  )
static

Definition at line 1110 of file res_parking.c.

References aco_pending_config(), ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_log, LOG_ERROR, NULL, parking_lot_cfg_create_extensions(), parking_config::parking_lots, RAII_VAR, remove_all_configured_parking_lot_extensions(), and remove_pending_parking_lot_extensions().

Referenced by config_parking_preapply().

1111 {
1112  struct parking_config *cfg = aco_pending_config(&cfg_info);
1113  struct ao2_iterator iter;
1114  RAII_VAR(struct parking_lot_cfg *, lot_cfg, NULL, ao2_cleanup);
1115  int res = 0;
1116 
1117  if (!cfg) {
1118  return 0;
1119  }
1120 
1121  /* Clear existing extensions */
1123 
1124  /* Attempt to build new extensions for each lot */
1125  for (iter = ao2_iterator_init(cfg->parking_lots, 0); (lot_cfg = ao2_iterator_next(&iter)); ao2_ref(lot_cfg, -1)) {
1126  if (parking_lot_cfg_create_extensions(lot_cfg)) {
1127  ao2_cleanup(lot_cfg);
1128  lot_cfg = NULL;
1129  res = -1;
1130  break;
1131  }
1132  }
1133  ao2_iterator_destroy(&iter);
1134 
1135  if (res) {
1137  ast_log(LOG_ERROR, "Extension registration failed. Previously configured lot extensions were removed and can not be safely restored.\n");
1138  }
1139 
1140  return res;
1141 }
static void remove_pending_parking_lot_extensions(struct parking_config *cfg_pending)
Definition: res_parking.c:1095
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * parking_lots
Definition: res_parking.c:282
#define LOG_ERROR
Definition: logger.h:285
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void remove_all_configured_parking_lot_extensions(void)
Definition: res_parking.c:678
int parking_lot_cfg_create_extensions(struct parking_lot_cfg *lot_cfg)
Add extensions for a parking lot configuration.
Definition: res_parking.c:758
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ create_dynamic_lot_full()

static struct parking_lot* create_dynamic_lot_full ( const char *  name,
struct ast_channel chan,
int  forced 
)
static

Definition at line 970 of file res_parking.c.

References ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, ast_channel_lock, ast_channel_unlock, ast_log, ast_strdupa, ast_string_field_set, ast_strlen_zero, parking_lot::cfg, clone_parkinglot_cfg(), DEFAULT_PARKING_LOT, LOG_ERROR, LOG_NOTICE, NULL, parking_dynamic_lots_enabled(), parking_lot_build_or_update(), parking_lot_cfg_create_extensions(), parking_lot_find_by_name(), parking_lot_cfg::parking_start, parking_lot_cfg::parking_stop, pbx_builtin_getvar_helper(), RAII_VAR, and S_OR.

Referenced by parking_create_dynamic_lot(), and parking_create_dynamic_lot_forced().

971 {
972  RAII_VAR(struct parking_lot_cfg *, cfg, NULL, ao2_cleanup);
973  RAII_VAR(struct parking_lot *, template_lot, NULL, ao2_cleanup);
974 
975  struct parking_lot *lot;
976  const char *dyn_context;
977  const char *dyn_exten;
978  const char *dyn_range;
979  const char *template_name;
980  const char *chan_template_name;
981  int dyn_start;
982  int dyn_end;
983 
984  if (!forced && !parking_dynamic_lots_enabled()) {
985  return NULL;
986  }
987 
988  ast_channel_lock(chan);
989  chan_template_name = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
990  dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
991  dyn_exten = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNEXTEN"), ""));
992  dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
993  ast_channel_unlock(chan);
994 
995  template_name = S_OR(chan_template_name, DEFAULT_PARKING_LOT);
996 
997  template_lot = parking_lot_find_by_name(template_name);
998  if (!template_lot) {
999  ast_log(LOG_ERROR, "Lot %s does not exist. Can not use it as a dynamic parking lot template.\n",
1000  template_name);
1001  return NULL;
1002  }
1003 
1004  cfg = clone_parkinglot_cfg(template_lot->cfg, name);
1005 
1006  if (!cfg) {
1007  ast_log(LOG_ERROR, "Failed to allocate dynamic parking lot configuration.\n");
1008  return NULL;
1009  }
1010 
1011  if (!ast_strlen_zero(dyn_exten)) {
1012  ast_string_field_set(cfg, parkext, dyn_exten);
1013  }
1014 
1015  if (!ast_strlen_zero(dyn_context)) {
1016  ast_string_field_set(cfg, parking_con, dyn_context);
1017  }
1018 
1019  if (!ast_strlen_zero(dyn_range)) {
1020  if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
1022  "Invalid parking range %s specified in PARKINGDYNPOS: could not parse minimum/maximum parking space range\n", dyn_range);
1023  return NULL;
1024  }
1025  if (dyn_end < dyn_start || dyn_start < 0) {
1027  "Invalid parking range %s specified for PARKINGDYNPOS: end parking space must be greater than starting parking space.\n", dyn_range);
1028  return NULL;
1029  }
1030 
1031  cfg->parking_start = dyn_start;
1032  cfg->parking_stop = dyn_end;
1033  }
1034 
1036  ast_log(LOG_ERROR, "Extensions for dynamic parking lot '%s' could not be registered. Dynamic lot creation failed.\n", name);
1037  return NULL;
1038  }
1039 
1041 
1042  if ((lot = parking_lot_find_by_name(name))) {
1044  ast_log(LOG_ERROR, "Started creating dynamic parking lot '%s', but a parking lot with that name already exists.\n", name);
1045  ao2_ref(lot, -1);
1046  return NULL;
1047  }
1048 
1049  lot = parking_lot_build_or_update(cfg, 1);
1051 
1052  if (!lot) {
1053  ast_log(LOG_NOTICE, "Failed to build dynamic parking lot '%s'\n", name);
1054  }
1055 
1056  return lot;
1057 }
#define DEFAULT_PARKING_LOT
Definition: res_parking.h:34
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
int parking_dynamic_lots_enabled(void)
Check global configuration to see if dynamic parking is enabled.
Definition: res_parking.c:928
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
Definition: res_parking.c:601
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_ERROR
Definition: logger.h:285
static struct parking_lot_cfg * clone_parkinglot_cfg(struct parking_lot_cfg *source, const char *name)
Definition: res_parking.c:939
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct parking_lot * parking_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 conf...
Definition: res_parking.c:868
int parking_lot_cfg_create_extensions(struct parking_lot_cfg *lot_cfg)
Add extensions for a parking lot configuration.
Definition: res_parking.c:758
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

◆ disable_marked_lots()

static void disable_marked_lots ( void  )
static

Definition at line 1170 of file res_parking.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, parking_lot::disable_mark, and parking_lot_disable().

Referenced by link_configured_disable_marked_lots().

1171 {
1172  struct ao2_iterator iter;
1173  struct parking_lot *lot;
1174 
1175  for (iter = ao2_iterator_init(parking_lot_container, 0); (lot = ao2_iterator_next(&iter)); ao2_ref(lot, -1)) {
1176  if (lot->disable_mark) {
1177  parking_lot_disable(lot);
1178  }
1179  }
1180 
1181  ao2_iterator_destroy(&iter);
1182 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int disable_mark
Definition: res_parking.h:98
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void parking_lot_disable(struct parking_lot *lot)
Definition: res_parking.c:414
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ extension_is_compatible()

static int extension_is_compatible ( struct parking_lot_cfg lot_cfg,
const char *  app_type,
struct ast_exten extension 
)
static

Definition at line 730 of file res_parking.c.

References ast_assert, ast_debug, ast_get_context_name(), ast_get_extension_app(), ast_get_extension_context(), ast_get_extension_name(), ast_get_extension_registrar(), ast_log, BASE_REGISTRAR, LOG_ERROR, and parking_lot_cfg::name.

Referenced by parking_lot_cfg_create_extensions().

731 {
732  const char *extension_registrar = ast_get_extension_registrar(extension);
733  const char *extension_context = ast_get_context_name(ast_get_extension_context(extension));
734  const char *extension_name = ast_get_extension_name(extension);
735  const char *extension_application = ast_get_extension_app(extension);
736 
737  ast_assert(extension_registrar && extension_context && extension_name && extension_application);
738 
739  if (strcmp(extension_registrar, BASE_REGISTRAR)) {
740  ast_log(LOG_ERROR, "Parking lot '%s' -- Needs an extension '%s@%s', but that extension is already owned by %s.\n",
741  lot_cfg->name, extension_name, extension_context, extension_registrar);
742  return 0;
743  }
744 
745  if (strcmp(extension_application, app_type)) {
746  ast_log(LOG_ERROR, "Parking lot '%s' -- Needs an extension '%s@%s' with a non-exclusive %s application, "
747  "but a/an %s application is already registered to that extension by %s.\n",
748  lot_cfg->name, extension_name, extension_context, app_type,
749  extension_application, BASE_REGISTRAR);
750  return 0;
751  }
752 
753  ast_debug(3, "Parking lot '%s' -- extension '%s@%s' with application %s is compatible.\n",
754  lot_cfg->name, extension_name, extension_context, app_type);
755  return 1;
756 }
const char * ast_get_extension_registrar(struct ast_exten *e)
Definition: pbx.c:8571
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
#define BASE_REGISTRAR
Definition: res_parking.h:36
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:8596
#define ast_assert(a)
Definition: utils.h:695
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const ast_string_field name
Definition: res_parking.h:89
#define LOG_ERROR
Definition: logger.h:285
const char * ast_get_extension_name(struct ast_exten *exten)
Definition: pbx.c:8548
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
Definition: pbx.c:8543

◆ find_channel_parking_lot_name()

const char* find_channel_parking_lot_name ( struct ast_channel chan)

Find parking lot name from channel.

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

Definition at line 607 of file res_parking.c.

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

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

608 {
609  const char *name;
610 
611  /* The channel variable overrides everything */
612  name = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
613  if (ast_strlen_zero(name)) {
614  /* Try the channel's parking lot. */
615  name = ast_channel_parkinglot(chan);
616  if (ast_strlen_zero(name)) {
617  /* Fall back to the default parking lot. */
618  name = DEFAULT_PARKING_LOT;
619  }
620  }
621 
622  return name;
623 }
#define DEFAULT_PARKING_LOT
Definition: res_parking.h:34
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
static const char name[]
Definition: cdr_mysql.c:74
const char * ast_channel_parkinglot(const struct ast_channel *chan)

◆ generate_or_link_lots_to_configs()

static void generate_or_link_lots_to_configs ( void  )
static

Definition at line 915 of file res_parking.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, globals, parking_lot_build_or_update(), and RAII_VAR.

Referenced by link_configured_disable_marked_lots().

916 {
918  struct parking_lot_cfg *lot_cfg;
919  struct ao2_iterator iter;
920 
921  iter = ao2_iterator_init(cfg->parking_lots, 0);
922  for (; (lot_cfg = ao2_iterator_next(&iter)); ao2_ref(lot_cfg, -1)) {
924  }
925  ao2_iterator_destroy(&iter);
926 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct console_pvt globals
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct parking_lot * parking_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 conf...
Definition: res_parking.c:868
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

◆ get_parking_lot_container()

struct ao2_container* get_parking_lot_container ( void  )

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

Since
12.0.0
Return values
pointerto the parking lot container.

Definition at line 596 of file res_parking.c.

References parking_lot_container.

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

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

◆ link_configured_disable_marked_lots()

static void link_configured_disable_marked_lots ( void  )
static

Definition at line 1184 of file res_parking.c.

References disable_marked_lots(), and generate_or_link_lots_to_configs().

1185 {
1188 }
static void disable_marked_lots(void)
Definition: res_parking.c:1170
static void generate_or_link_lots_to_configs(void)
Definition: res_parking.c:915

◆ load_module()

static int load_module ( void  )
static

Definition at line 1207 of file res_parking.c.

References ACO_EXACT, aco_info_init(), aco_option_register, aco_option_register_custom, aco_process_config(), ACO_PROCESS_ERROR, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, error(), FLDSET, load_parking_applications(), load_parking_bridge_features(), load_parking_devstate(), load_parking_manager(), load_parking_tests(), load_parking_ui(), NULL, OPT_BOOL_T, OPT_PARKEDHANGUP, OPT_PARKEDPLAY, OPT_PARKEDRECORDING, OPT_PARKEDREPARKING, OPT_PARKEDTRANSFERS, OPT_STRINGFIELD_T, OPT_UINT_T, option_handler_findslot(), option_handler_parkedfeature(), option_handler_parkpos(), parking_global_config::parkeddynamic, parking_lot_sort_fn(), STRFLDSET, and unload_module().

Referenced by reload_module().

1208 {
1212  NULL);
1213  if (!parking_lot_container) {
1214  goto error;
1215  }
1216 
1217  if (aco_info_init(&cfg_info)) {
1218  goto error;
1219  }
1220 
1221  /* Global options */
1222  aco_option_register(&cfg_info, "parkeddynamic", ACO_EXACT, global_options, "no", OPT_BOOL_T, 1, FLDSET(struct parking_global_config, parkeddynamic));
1223 
1224  /* Register the per parking lot options. */
1225  aco_option_register(&cfg_info, "parkext", ACO_EXACT, parking_lot_types, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct parking_lot_cfg, parkext));
1226  aco_option_register(&cfg_info, "context", ACO_EXACT, parking_lot_types, "parkedcalls", OPT_STRINGFIELD_T, 0, STRFLDSET(struct parking_lot_cfg, parking_con));
1227  aco_option_register(&cfg_info, "parkingtime", ACO_EXACT, parking_lot_types, "45", OPT_UINT_T, 0, FLDSET(struct parking_lot_cfg, parkingtime));
1228  aco_option_register(&cfg_info, "comebacktoorigin", ACO_EXACT, parking_lot_types, "yes", OPT_BOOL_T, 1, FLDSET(struct parking_lot_cfg, comebacktoorigin));
1229  aco_option_register(&cfg_info, "comebackcontext", ACO_EXACT, parking_lot_types, "parkedcallstimeout", OPT_STRINGFIELD_T, 0, STRFLDSET(struct parking_lot_cfg, comebackcontext));
1230  aco_option_register(&cfg_info, "comebackdialtime", ACO_EXACT, parking_lot_types, "30", OPT_UINT_T, 0, FLDSET(struct parking_lot_cfg, comebackdialtime));
1231  aco_option_register(&cfg_info, "parkedmusicclass", ACO_EXACT, parking_lot_types, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct parking_lot_cfg, mohclass));
1232  aco_option_register(&cfg_info, "parkext_exclusive", ACO_EXACT, parking_lot_types, "no", OPT_BOOL_T, 1, FLDSET(struct parking_lot_cfg, parkext_exclusive));
1233  aco_option_register(&cfg_info, "parkinghints", ACO_EXACT, parking_lot_types, "no", OPT_BOOL_T, 1, FLDSET(struct parking_lot_cfg, parkaddhints));
1234  aco_option_register(&cfg_info, "courtesytone", ACO_EXACT, parking_lot_types, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct parking_lot_cfg, courtesytone));
1235 
1236  /* More complicated parking lot options that require special handling */
1237  aco_option_register_custom(&cfg_info, "parkpos", ACO_EXACT, parking_lot_types, "701-750", option_handler_parkpos, 0);
1238  aco_option_register_custom(&cfg_info, "findslot", ACO_EXACT, parking_lot_types, "first", option_handler_findslot, 0);
1244 
1245  if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
1246  goto error;
1247  }
1248 
1249  if (load_parking_applications()) {
1250  goto error;
1251  }
1252 
1253  if (load_parking_ui()) {
1254  goto error;
1255  }
1256 
1257  if (load_parking_manager()) {
1258  goto error;
1259  }
1260 
1262  goto error;
1263  }
1264 
1265  if (load_parking_devstate()) {
1266  goto error;
1267  }
1268 
1269  if (load_parking_tests()) {
1270  goto error;
1271  }
1272 
1273  return AST_MODULE_LOAD_SUCCESS;
1274 
1275 error:
1276  unload_module();
1277  return AST_MODULE_LOAD_DECLINE;
1278 }
static int unload_module(void)
Definition: res_parking.c:1190
int load_parking_manager(void)
Register manager actions and setup subscriptions for stasis events.
struct aco_type * global_options[]
Definition: res_parking.c:293
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
static int parking_lot_sort_fn(const void *obj_left, const void *obj_right, int flags)
Definition: res_parking.c:244
int load_parking_tests(void)
Register parking unit tests.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
int load_parking_ui(void)
Register CLI commands.
Definition: parking_ui.c:198
#define NULL
Definition: resample.c:96
static int option_handler_findslot(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom field handler for the findslot option.
Definition: res_parking.c:525
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
int load_parking_bridge_features(void)
Register bridge features for parking.
Type for default option handler for unsigned integers.
struct aco_type * parking_lot_types[]
Definition: res_parking.c:305
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
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.
Definition: res_parking.c:564
Their was an error and no changes were applied.
int load_parking_applications(void)
Register parking applications.
Type for default option handler for bools (ast_true/ast_false)
static int option_handler_parkpos(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom field handler for parking positions.
Definition: res_parking.c:504
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
Type for default option handler for stringfields.
int load_parking_devstate(void)
Register Parking devstate handler.
int error(const char *format,...)
Definition: utils/frame.c:999
Reject objects with duplicate keys in container.
Definition: astobj2.h:1192

◆ mark_lots_as_disabled()

static void mark_lots_as_disabled ( void  )
static

Definition at line 1143 of file res_parking.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, and parking_lot::disable_mark.

Referenced by config_parking_preapply().

1144 {
1145  struct ao2_iterator iter;
1146  struct parking_lot *lot;
1147 
1148  for (iter = ao2_iterator_init(parking_lot_container, 0); (lot = ao2_iterator_next(&iter)); ao2_ref(lot, -1)) {
1149  lot->disable_mark = 1;
1150  }
1151 
1152  ao2_iterator_destroy(&iter);
1153 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int disable_mark
Definition: res_parking.h:98
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ named_item_find()

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
keyname of the item wanted to be found
Return values
pointerto the parking lot if available. NULL if not found.

Definition at line 496 of file res_parking.c.

References ao2_find, and OBJ_KEY.

Referenced by parking_lot_build_or_update(), and parking_lot_find_by_name().

497 {
498  return ao2_find(container, name, OBJ_KEY);
499 }
#define OBJ_KEY
Definition: astobj2.h:1155
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ option_handler_findslot()

static int option_handler_findslot ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Custom field handler for the findslot option.

Definition at line 525 of file res_parking.c.

References ast_log, LOG_WARNING, parking_lot_cfg::parkfindnext, and ast_variable::value.

Referenced by load_module().

526 {
527  struct parking_lot_cfg *lot_cfg = obj;
528 
529  if (!strcmp(var->value, "first")) {
530  lot_cfg->parkfindnext = 0;
531  } else if (!strcmp(var->value, "next")) {
532  lot_cfg->parkfindnext = 1;
533  } else {
534  ast_log(LOG_WARNING, "value '%s' is not valid for findslot option.\n", var->value);
535  return -1;
536  }
537 
538  return 0;
539 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
unsigned int parkfindnext
Definition: res_parking.h:71

◆ option_handler_parkedfeature()

static int option_handler_parkedfeature ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Custom field handler for feature mapping on parked call pickup options.

Definition at line 564 of file res_parking.c.

References aco_option_get_flags(), ast_assert, NULL, OPT_PARKEDHANGUP, OPT_PARKEDPLAY, OPT_PARKEDRECORDING, OPT_PARKEDREPARKING, OPT_PARKEDTRANSFERS, parking_lot_cfg::parkedcallhangup, parking_lot_cfg::parkedcallrecording, parking_lot_cfg::parkedcallreparking, parking_lot_cfg::parkedcalltransfers, parking_lot_cfg::parkedplay, parking_feature_flag_cfg(), and ast_variable::value.

Referenced by load_module().

565 {
566  struct parking_lot_cfg *cfg = obj;
568  int *parameter = NULL;
569 
570  switch (option) {
571  case OPT_PARKEDPLAY:
572  parameter = &cfg->parkedplay;
573  break;
574  case OPT_PARKEDTRANSFERS:
575  parameter = &cfg->parkedcalltransfers;
576  break;
577  case OPT_PARKEDREPARKING:
578  parameter = &cfg->parkedcallreparking;
579  break;
580  case OPT_PARKEDHANGUP:
581  parameter = &cfg->parkedcallhangup;
582  break;
583  case OPT_PARKEDRECORDING:
584  parameter = &cfg->parkedcallrecording;
585  break;
586  }
587 
588  ast_assert(parameter != NULL);
589  if (!parameter || parking_feature_flag_cfg(parameter, var->value)) {
590  return -1;
591  }
592 
593  return 0;
594 }
parked_call_feature_options
Definition: res_parking.h:48
int parkedcallreparking
Definition: res_parking.h:77
unsigned int aco_option_get_flags(const struct aco_option *option)
Read the flags of a config option - useful when using a custom callback for a config option...
#define ast_assert(a)
Definition: utils.h:695
static int parking_feature_flag_cfg(int *param, const char *var)
Maps string values for option_handler_parkedfeature to their ENUM values.
Definition: res_parking.c:544
#define NULL
Definition: resample.c:96
int parkedcalltransfers
Definition: res_parking.h:76
int parkedcallrecording
Definition: res_parking.h:79

◆ option_handler_parkpos()

static int option_handler_parkpos ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Custom field handler for parking positions.

Definition at line 504 of file res_parking.c.

References ast_log, LOG_WARNING, parking_lot_cfg::parking_start, parking_lot_cfg::parking_stop, and ast_variable::value.

Referenced by load_module().

505 {
506  struct parking_lot_cfg *lot_cfg = obj;
507  int low;
508  int high;
509 
510  if (sscanf(var->value, "%30d-%30d", &low, &high) != 2) {
511  ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers\n");
512  } else if (high < low || low <= 0 || high <= 0) {
513  ast_log(LOG_WARNING, "Format for parking positions is a-b, where a <= b\n");
514  } else {
515  lot_cfg->parking_start = low;
516  lot_cfg->parking_stop = high;
517  return 0;
518  }
519  return -1;
520 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42

◆ parked_user_cmp_fn()

static int parked_user_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 435 of file res_parking.c.

References CMP_MATCH, and parked_user::parking_space.

Referenced by alloc_new_parking_lot().

436 {
437  int *search_space = arg;
438  struct parked_user *user = obj;
439  int object_space = user->parking_space;
440 
441  if (*search_space == object_space) {
442  return CMP_MATCH;
443  }
444  return 0;
445 }
int parking_space
Definition: res_parking.h:107
structure to hold users read from users.conf

◆ parked_user_sort_fn()

static int parked_user_sort_fn ( const void *  obj_left,
const void *  obj_right,
int  flags 
)
static

Definition at line 447 of file res_parking.c.

References parked_user::parking_space.

Referenced by alloc_new_parking_lot().

448 {
449  const struct parked_user *left = obj_left;
450  const struct parked_user *right = obj_right;
451 
452  return left->parking_space - right->parking_space;
453 }
int parking_space
Definition: res_parking.h:107

◆ parking_add_extension()

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

Definition at line 713 of file res_parking.c.

References ast_add_extension2_nolock(), ast_free_ptr(), ast_strdup, and NULL.

Referenced by parking_lot_cfg_create_extensions().

715 {
716  char *data_duplicate = ast_strdup(data);
717 
718  if (!data_duplicate) {
719  return -1;
720  }
721 
723  application, data_duplicate, ast_free_ptr, registrar, NULL, 0)) {
724  return -1;
725  }
726 
727  return 0;
728 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int priority
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
structure to hold extensions
static char * registrar
Definition: pbx_ael.c:78
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:790
int ast_add_extension2_nolock(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line)
Same as ast_add_extension2, but assumes you have already locked context.
Definition: pbx.c:7308

◆ parking_config_alloc()

static void * parking_config_alloc ( void  )
static

allocator callback for parking_config. Notice it returns void * since it is only used by the backend config code

Definition at line 377 of file res_parking.c.

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_cleanup, ao2_container_alloc_hash, ao2_ref, NULL, parking_config_destructor(), parking_global_config_destructor(), parking_lot_cfg_cmp_fn(), parking_lot_cfg_hash_fn(), and RAII_VAR.

378 {
379  RAII_VAR(struct parking_config *, cfg, NULL, ao2_cleanup);
380 
381  if (!(cfg = ao2_alloc(sizeof(*cfg), parking_config_destructor))) {
382  return NULL;
383  }
384 
385  cfg->parking_lots = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, 37,
387  if (!cfg->parking_lots) {
388  return NULL;
389  }
390 
391  if (!(cfg->global = ao2_alloc(sizeof(*cfg->global), parking_global_config_destructor))) {
392  return NULL;
393  }
394 
395  /* Bump the ref count since RAII_VAR is going to eat one */
396  ao2_ref(cfg, +1);
397  return cfg;
398 }
static void parking_global_config_destructor(void *obj)
destructor for parking_global_config
Definition: res_parking.c:371
static int parking_lot_cfg_cmp_fn(void *obj, void *arg, const int flags)
Definition: res_parking.c:338
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void parking_config_destructor(void *obj)
destructor for parking_config
Definition: res_parking.c:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int parking_lot_cfg_hash_fn(const void *obj, const int flags)
Definition: res_parking.c:320

◆ parking_config_destructor()

static void parking_config_destructor ( void *  obj)
static

destructor for parking_config

Definition at line 363 of file res_parking.c.

References ao2_cleanup, parking_config::global, and parking_config::parking_lots.

Referenced by parking_config_alloc().

364 {
365  struct parking_config *cfg = obj;
367  ao2_cleanup(cfg->global);
368 }
struct parking_global_config * global
Definition: res_parking.c:281
struct ao2_container * parking_lots
Definition: res_parking.c:282
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ parking_create_dynamic_lot()

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

Create a dynamic parking lot.

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

Definition at line 1059 of file res_parking.c.

References create_dynamic_lot_full().

Referenced by park_common_setup(), and parking_park_call().

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

◆ parking_create_dynamic_lot_forced()

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

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

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

Definition at line 1064 of file res_parking.c.

References create_dynamic_lot_full().

Referenced by AST_TEST_DEFINE().

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

◆ parking_dynamic_lots_enabled()

int parking_dynamic_lots_enabled ( void  )

Check global configuration to see if dynamic parking is enabled.

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

Definition at line 928 of file res_parking.c.

References ao2_cleanup, ao2_global_obj_ref, globals, and RAII_VAR.

Referenced by cli_display_parking_global(), and create_dynamic_lot_full().

929 {
931 
932  if (!cfg) {
933  return 0;
934  }
935 
936  return cfg->global->parkeddynamic;
937 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct console_pvt globals
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ parking_feature_flag_cfg()

static int parking_feature_flag_cfg ( int *  param,
const char *  var 
)
static

Maps string values for option_handler_parkedfeature to their ENUM values.

Definition at line 544 of file res_parking.c.

References ast_false(), AST_FEATURE_FLAG_BYBOTH, AST_FEATURE_FLAG_BYCALLEE, and AST_FEATURE_FLAG_BYCALLER.

Referenced by option_handler_parkedfeature().

545 {
546  if (ast_false(var)) {
547  *param = 0;
548  } else if (!strcasecmp(var, "both")) {
549  *param = AST_FEATURE_FLAG_BYBOTH;
550  } else if (!strcasecmp(var, "caller")) {
551  *param = AST_FEATURE_FLAG_BYCALLER;
552  } else if (!strcasecmp(var, "callee")) {
553  *param = AST_FEATURE_FLAG_BYCALLEE;
554  } else {
555  return -1;
556  }
557 
558  return 0;
559 }
#define var
Definition: ast_expr2f.c:614
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968

◆ parking_global_config_destructor()

static void parking_global_config_destructor ( void *  obj)
static

destructor for parking_global_config

Definition at line 371 of file res_parking.c.

Referenced by parking_config_alloc().

372 {
373  /* For now, do nothing. */
374 }

◆ parking_lot_build_or_update()

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

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

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

Definition at line 868 of file res_parking.c.

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

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

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

◆ parking_lot_cfg_alloc()

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 ao2_alloc, ao2_cleanup, ast_string_field_init, ast_string_field_set, name, NULL, and parking_lot_cfg_destructor().

Referenced by clone_parkinglot_cfg(), parking_lot_cfg_create(), and verify_default_parking_lot().

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 }
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:514

◆ parking_lot_cfg_cmp_fn()

static int parking_lot_cfg_cmp_fn ( void *  obj,
void *  arg,
const int  flags 
)
static

Definition at line 338 of file res_parking.c.

References CMP_MATCH, CMP_STOP, parking_lot_cfg::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by parking_config_alloc().

339 {
340  struct parking_lot_cfg *entry1 = obj;
341 
342  char *key;
343  size_t key_size;
344  struct parking_lot_cfg *entry2;
345 
346  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
347  case OBJ_KEY:
348  key = arg;
349  return (!strcmp(entry1->name, key)) ? CMP_MATCH : 0;
350  case OBJ_PARTIAL_KEY:
351  key = arg;
352  key_size = strlen(key);
353  return (!strncmp(entry1->name, key, key_size)) ? CMP_MATCH : 0;
354  case OBJ_POINTER:
355  entry2 = arg;
356  return (!strcmp(entry1->name, entry2->name)) ? CMP_MATCH : 0;
357  default:
358  return CMP_STOP;
359  }
360 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
const ast_string_field name
Definition: res_parking.h:89

◆ parking_lot_cfg_create()

struct parking_lot_cfg* parking_lot_cfg_create ( const char *  cat)

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

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

Definition at line 481 of file res_parking.c.

References parking_lot_cfg_alloc().

Referenced by AST_TEST_DEFINE(), and generate_test_parking_lot().

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

◆ parking_lot_cfg_create_extensions()

int parking_lot_cfg_create_extensions ( struct parking_lot_cfg lot_cfg)

Add extensions for a parking lot configuration.

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

Definition at line 758 of file res_parking.c.

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

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

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

◆ parking_lot_cfg_destructor()

static void parking_lot_cfg_destructor ( void *  obj)
static

Destroy a parking lot cfg object.

Definition at line 427 of file res_parking.c.

References ast_string_field_free_memory, and parking_lot_cfg_remove_extensions().

Referenced by parking_lot_cfg_alloc().

428 {
429  struct parking_lot_cfg *lot_cfg = obj;
432 }
void parking_lot_cfg_remove_extensions(struct parking_lot_cfg *lot_cfg)
Remove extensions belonging to a parking lot configuration.
Definition: res_parking.c:663
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ parking_lot_cfg_hash_fn()

static int parking_lot_cfg_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 320 of file res_parking.c.

References ast_assert, ast_str_hash(), parking_lot_cfg::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by parking_config_alloc().

321 {
322  const struct parking_lot_cfg *entry;
323  const char *key;
324 
325  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
326  case OBJ_KEY:
327  key = obj;
328  return ast_str_hash(key);
329  case OBJ_PARTIAL_KEY:
330  ast_assert(0);
331  return 0;
332  default:
333  entry = obj;
334  return ast_str_hash(entry->name);
335  }
336 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define ast_assert(a)
Definition: utils.h:695
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
const ast_string_field name
Definition: res_parking.h:89
Definition: search.h:40
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ parking_lot_cfg_remove_extensions()

void parking_lot_cfg_remove_extensions ( struct parking_lot_cfg lot_cfg)

Remove extensions belonging to a parking lot configuration.

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

Definition at line 663 of file res_parking.c.

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

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

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

◆ parking_lot_destructor()

static void parking_lot_destructor ( void *  obj)
static

Definition at line 625 of file res_parking.c.

References ao2_cleanup, ast_bridge_destroy(), ast_string_field_free_memory, parking_lot::cfg, parking_lot::parked_users, and parking_lot::parking_bridge.

Referenced by alloc_new_parking_lot().

626 {
627  struct parking_lot *lot = obj;
628 
629  if (lot->parking_bridge) {
631  }
633  ao2_cleanup(lot->cfg);
635 }
struct ast_bridge * parking_bridge
Definition: res_parking.h:94
struct ao2_container * parked_users
Definition: res_parking.h:95
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

◆ parking_lot_disable()

static void parking_lot_disable ( struct parking_lot lot)
static

Definition at line 414 of file res_parking.c.

References parking_lot::disable_mark, parking_lot::mode, parking_lot_remove_if_unused(), PARKINGLOT_DISABLED, and PARKINGLOT_DYNAMIC.

Referenced by disable_marked_lots().

415 {
416  /* If a dynamic lot wasn't removed, we need to restore it to full functionality afterwards. */
417  int was_dynamic = (lot->mode == PARKINGLOT_DYNAMIC);
418 
419  lot->mode = PARKINGLOT_DISABLED;
420  if (parking_lot_remove_if_unused(lot) && was_dynamic) {
421  lot->mode = PARKINGLOT_DYNAMIC;
422  lot->disable_mark = 0;
423  }
424 }
int parking_lot_remove_if_unused(struct parking_lot *lot)
Remove a parking lot from the usable lists if it is no longer involved in any calls and no configurat...
Definition: res_parking.c:400
int disable_mark
Definition: res_parking.h:98
enum parking_lot_modes mode
Definition: res_parking.h:97

◆ parking_lot_find_by_name()

struct parking_lot* parking_lot_find_by_name ( const char *  lot_name)

Find a parking lot based on its name.

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

Definition at line 601 of file res_parking.c.

References named_item_find().

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

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

◆ parking_lot_remove_if_unused()

int parking_lot_remove_if_unused ( struct parking_lot lot)

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

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

Definition at line 400 of file res_parking.c.

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

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

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

◆ parking_lot_sort_fn()

static int parking_lot_sort_fn ( const void *  obj_left,
const void *  obj_right,
int  flags 
)
static

Definition at line 244 of file res_parking.c.

References parking_lot::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by load_module().

245 {
246  const struct parking_lot *left = obj_left;
247  const struct parking_lot *right = obj_right;
248  const char *right_key = obj_right;
249  int cmp;
250 
251  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
252  default:
253  case OBJ_POINTER:
254  right_key = right->name;
255  /* Fall through */
256  case OBJ_KEY:
257  cmp = strcmp(left->name, right_key);
258  break;
259  case OBJ_PARTIAL_KEY:
260  cmp = strncmp(left->name, right_key, strlen(right_key));
261  }
262  return cmp;
263 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
const ast_string_field name
Definition: res_parking.h:100

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1280 of file res_parking.c.

References aco_process_config(), ACO_PROCESS_ERROR, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_DEVSTATE_PROVIDER, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, load_module(), reload(), and unload_module().

1281 {
1282  if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
1283  return AST_MODULE_LOAD_DECLINE;
1284  }
1285 
1286  return 0;
1287 }
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
Their was an error and no changes were applied.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78

◆ remove_all_configured_parking_lot_extensions()

static void remove_all_configured_parking_lot_extensions ( void  )
static

Definition at line 678 of file res_parking.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_context_destroy(), BASE_REGISTRAR, parking_lot::cfg, globals, NULL, parking_lot_cfg_remove_extensions(), and RAII_VAR.

Referenced by configure_parking_extensions(), and unload_module().

679 {
681  struct parking_lot_cfg *lot_cfg;
682  struct ao2_iterator iter;
683 
684  if (!cfg) {
685  return;
686  }
687 
688  for (iter = ao2_iterator_init(cfg->parking_lots, 0); (lot_cfg = ao2_iterator_next(&iter)); ao2_ref(lot_cfg, -1)) {
690  }
691 
693 
694  ao2_iterator_destroy(&iter);
695 }
#define BASE_REGISTRAR
Definition: res_parking.h:36
void parking_lot_cfg_remove_extensions(struct parking_lot_cfg *lot_cfg)
Remove extensions belonging to a parking lot configuration.
Definition: res_parking.c:663
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct console_pvt globals
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Definition: conf2ael.c:625
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

◆ remove_pending_parking_lot_extensions()

static void remove_pending_parking_lot_extensions ( struct parking_config cfg_pending)
static

Definition at line 1095 of file res_parking.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_context_destroy(), BASE_REGISTRAR, NULL, parking_lot_cfg_remove_extensions(), and parking_config::parking_lots.

Referenced by configure_parking_extensions().

1096 {
1097  struct parking_lot_cfg *lot_cfg;
1098  struct ao2_iterator iter;
1099 
1100  for (iter = ao2_iterator_init(cfg_pending->parking_lots, 0); (lot_cfg = ao2_iterator_next(&iter)); ao2_ref(lot_cfg, -1)) {
1102  }
1103 
1104  ao2_iterator_destroy(&iter);
1105 
1107 
1108 }
#define BASE_REGISTRAR
Definition: res_parking.h:36
void parking_lot_cfg_remove_extensions(struct parking_lot_cfg *lot_cfg)
Remove extensions belonging to a parking lot configuration.
Definition: res_parking.c:663
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * parking_lots
Definition: res_parking.c:282
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Definition: conf2ael.c:625
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1190 of file res_parking.c.

References aco_info_destroy(), ao2_cleanup, ao2_global_obj_release, globals, NULL, remove_all_configured_parking_lot_extensions(), unload_parking_applications(), unload_parking_bridge_features(), unload_parking_devstate(), unload_parking_manager(), unload_parking_tests(), and unload_parking_ui().

Referenced by load_module(), and reload_module().

1191 {
1201  aco_info_destroy(&cfg_info);
1203 
1204  return 0;
1205 }
void unload_parking_ui(void)
Unregister CLI commands.
Definition: parking_ui.c:203
void unload_parking_applications(void)
Unregister parking applications.
#define NULL
Definition: resample.c:96
void unload_parking_bridge_features(void)
Unregister features registered by load_parking_bridge_features.
void unload_parking_devstate(void)
Unregister Parking devstate handler.
static struct ao2_container * parking_lot_container
Definition: res_parking.c:266
static struct console_pvt globals
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
void unload_parking_tests(void)
Unregister parking unit tests.
void unload_parking_manager(void)
Unregister manager actions and remove subscriptions for stasis events.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void remove_all_configured_parking_lot_extensions(void)
Definition: res_parking.c:678

◆ verify_default_parking_lot()

static int verify_default_parking_lot ( void  )
static

Definition at line 1071 of file res_parking.c.

References aco_pending_config(), aco_set_defaults(), ao2_cleanup, ao2_find, ao2_link, ast_log, AST_LOG_NOTICE, ast_string_field_set, DEFAULT_PARKING_EXTEN, DEFAULT_PARKING_LOT, NULL, OBJ_KEY, parking_lot_cfg_alloc(), parking_config::parking_lots, and RAII_VAR.

Referenced by config_parking_preapply().

1072 {
1073  struct parking_config *cfg = aco_pending_config(&cfg_info);
1074  RAII_VAR(struct parking_lot_cfg *, lot_cfg, NULL, ao2_cleanup);
1075 
1076  if (!cfg) {
1077  return 0;
1078  }
1079 
1081  if (!lot_cfg) {
1083  if (!lot_cfg) {
1084  return -1;
1085  }
1086  ast_log(AST_LOG_NOTICE, "Adding %s profile to res_parking\n", DEFAULT_PARKING_LOT);
1088  ast_string_field_set(lot_cfg, parkext, DEFAULT_PARKING_EXTEN);
1089  ao2_link(cfg->parking_lots, lot_cfg);
1090  }
1091 
1092  return 0;
1093 }
#define DEFAULT_PARKING_LOT
Definition: res_parking.h:34
#define OBJ_KEY
Definition: astobj2.h:1155
#define NULL
Definition: resample.c:96
#define AST_LOG_NOTICE
Definition: logger.h:268
#define ast_log
Definition: astobj2.c:42
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ao2_container * parking_lots
Definition: res_parking.c:282
static void * parking_lot_cfg_alloc(const char *cat)
create a parking lot structure
Definition: res_parking.c:461
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define DEFAULT_PARKING_EXTEN
Definition: res_parking.h:35
static struct aco_type parking_lot_type
Definition: res_parking.c:295
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define ao2_link(container, obj)
Definition: astobj2.h:1549

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
static

Definition at line 1295 of file res_parking.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1295 of file res_parking.c.

◆ global_option

struct aco_type global_option
static

Definition at line 285 of file res_parking.c.

◆ global_options

struct aco_type* global_options[] = ACO_TYPES(&global_option)

Definition at line 293 of file res_parking.c.

◆ parking_lot_conf

struct aco_file parking_lot_conf
Initial value:
= {
.filename = "res_parking.conf",
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static struct aco_type global_option
Definition: res_parking.c:285
static struct aco_type parking_lot_type
Definition: res_parking.c:295

Definition at line 307 of file res_parking.c.

◆ parking_lot_container

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

◆ parking_lot_type

struct aco_type parking_lot_type
static

Definition at line 295 of file res_parking.c.

◆ parking_lot_types

struct aco_type* parking_lot_types[] = ACO_TYPES(&parking_lot_type)

Definition at line 305 of file res_parking.c.