248 const char *right_key = obj_right;
254 right_key = right->
name;
257 cmp = strcmp(left->
name, right_key);
260 cmp = strncmp(left->
name, right_key, strlen(right_key));
290 .category =
"general",
297 .name =
"parking_lot",
299 .category =
"general",
309 .types =
ACO_TYPES(&global_option, &parking_lot_type),
352 key_size = strlen(key);
353 return (!strncmp(entry1->
name, key, key_size)) ?
CMP_MATCH : 0;
387 if (!cfg->parking_lots) {
437 int *search_space = arg;
441 if (*search_space == object_space) {
480 #if defined(TEST_FRAMEWORK) 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) {
529 if (!strcmp(var->
value,
"first")) {
531 }
else if (!strcmp(var->
value,
"next")) {
548 }
else if (!strcasecmp(var,
"both")) {
550 }
else if (!strcasecmp(var,
"caller")) {
552 }
else if (!strcasecmp(var,
"callee")) {
568 int *parameter =
NULL;
718 if (!data_duplicate) {
737 ast_assert(extension_registrar && extension_context && extension_name && extension_application);
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);
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,
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);
764 const char *parkext_registrar_pointer;
765 const char *parkedcall_registrar_pointer;
772 parkedcall_registrar_pointer = lot_cfg->
registrar;
775 parkext_registrar_pointer = lot_cfg->
registrar;
784 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Needs a context '%s' which does not exist and Asterisk was unable to create\n",
805 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Failed to add %s extension '%s@%s' to the PBX.\n",
812 for (parkingspace = lot_cfg->
parking_start; parkingspace <= lot_cfg->parking_stop; parkingspace++) {
817 snprintf(space,
sizeof(space),
"%d", parkingspace);
826 if (!arguments_string) {
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",
845 snprintf(hint_device,
sizeof(hint_device),
"park:%s@%s", space, lot_cfg->
parking_con);
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",
855 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Failed to add hint '%s@%s' to the PBX.\n",
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);
895 replaced_cfg = lot->
cfg;
909 ao2_link(parking_lot_container, lot);
936 return cfg->global->parkeddynamic;
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;
999 ast_log(
LOG_ERROR,
"Lot %s does not exist. Can not use it as a dynamic parking lot template.\n",
1007 ast_log(
LOG_ERROR,
"Failed to allocate dynamic parking lot configuration.\n");
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);
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);
1036 ast_log(
LOG_ERROR,
"Extensions for dynamic parking lot '%s' could not be registered. Dynamic lot creation failed.\n", name);
1044 ast_log(
LOG_ERROR,
"Started creating dynamic parking lot '%s', but a parking lot with that name already exists.\n", name);
1063 #if defined(TEST_FRAMEWORK) 1137 ast_log(
LOG_ERROR,
"Extension registration failed. Previously configured lot extensions were removed and can not be safely restored.\n");
1200 parking_lot_container =
NULL;
1213 if (!parking_lot_container) {
parked_call_feature_options
static void remove_pending_parking_lot_extensions(struct parking_config *cfg_pending)
static void disable_marked_lots(void)
#define DEFAULT_PARKING_LOT
int ast_unlock_context(struct ast_context *con)
static int unload_module(void)
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
int load_parking_manager(void)
Register manager actions and setup subscriptions for stasis events.
Asterisk main include file. File version handling, generic pbx functions.
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
unsigned int comebackdialtime
struct parking_lot_cfg * parking_lot_cfg_create(const char *cat)
Create an empty parking lot configuration structure useful for unit tests.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
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 void parking_global_config_destructor(void *obj)
destructor for parking_global_config
const char * ast_get_extension_registrar(struct ast_exten *e)
const char * ast_get_context_name(struct ast_context *con)
static struct aco_type global
struct aco_type * global_options[]
struct parking_lot * parking_create_dynamic_lot(const char *name, struct ast_channel *chan)
Create a dynamic parking lot.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
static int parking_lot_cfg_cmp_fn(void *obj, void *arg, const int flags)
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...
void unload_parking_ui(void)
Unregister CLI commands.
void unload_parking_applications(void)
Unregister parking applications.
static int verify_default_parking_lot(void)
static struct parking_lot * create_dynamic_lot_full(const char *name, struct ast_channel *chan, int forced)
struct parking_global_config * global
static int parking_lot_sort_fn(const void *obj_left, const void *obj_right, int flags)
struct ast_bridge * parking_bridge
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
struct ao2_container * parked_users
const char * ast_get_extension_app(struct ast_exten *e)
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)
Structure for variables, used for configurations and for channel variables.
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...
void parking_lot_cfg_remove_extensions(struct parking_lot_cfg *lot_cfg)
Remove extensions belonging to a parking lot configuration.
static int configure_parking_extensions(void)
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
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.
#define ao2_global_obj_ref(holder)
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int ast_wrlock_contexts(void)
Write locks the context list.
static int parking_feature_flag_cfg(int *param, const char *var)
Maps string values for option_handler_parkedfeature to their ENUM values.
int load_parking_ui(void)
Register CLI commands.
#define ast_strdup(str)
A wrapper for strdup()
static void * named_item_find(struct ao2_container *container, const char *name)
find an item in a container by its name
The representation of a single configuration file to be processed.
void ast_free_ptr(void *ptr)
free() wrapper
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.
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
void unload_parking_bridge_features(void)
Unregister features registered by load_parking_bridge_features.
static int parked_user_sort_fn(const void *obj_left, const void *obj_right, int flags)
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)
static int option_handler_findslot(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom field handler for the findslot option.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
struct ao2_container * get_parking_lot_container(void)
Get a pointer to the parking lot container for purposes such as iteration.
void unload_parking_devstate(void)
Unregister Parking devstate handler.
Configuration File Parser.
#define ast_debug(level,...)
Log a DEBUG message.
static AO2_GLOBAL_OBJ_STATIC(globals)
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
const ast_string_field name
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
const ast_string_field parking_con
int load_parking_bridge_features(void)
Register bridge features for parking.
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
int parking_dynamic_lots_enabled(void)
Check global configuration to see if dynamic parking is enabled.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Type for default option handler for unsigned integers.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
unsigned int parkaddhints
static int parked_user_cmp_fn(void *obj, void *arg, int flags)
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
struct aco_type * parking_lot_types[]
static struct ao2_container * parking_lot_container
#define AST_MAX_EXTENSION
const char * find_channel_parking_lot_name(struct ast_channel *chan)
Find parking lot name from channel.
structure to hold extensions
#define ao2_ref(o, delta)
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 void mark_lots_as_disabled(void)
#define ast_strdupa(s)
duplicate a string in memory from the stack
struct ao2_container * container
static struct console_pvt globals
static void parking_lot_disable(struct parking_lot *lot)
static struct aco_type global_option
Core PBX routines and definitions.
unsigned int comebacktoorigin
struct ao2_container * parking_lots
static void * parking_lot_cfg_alloc(const char *cat)
create a parking lot structure
static void parking_config_destructor(void *obj)
destructor for parking_config
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)
Their was an error and no changes were applied.
int load_parking_applications(void)
Register parking applications.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Configuration option-handling.
#define ast_string_fields_copy(copy, orig)
Copy all string fields from one instance to another of the same structure.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
static struct parking_lot_cfg * clone_parkinglot_cfg(struct parking_lot_cfg *source, const char *name)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
const ast_string_field registrar
#define ao2_unlink(container, obj)
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define ao2_global_obj_release(holder)
Type for default option handler for bools (ast_true/ast_false)
int ast_unlock_contexts(void)
Unlocks contexts.
static int reload_module(void)
void unload_parking_tests(void)
Unregister parking unit tests.
#define ao2_iterator_next(iter)
#define ao2_alloc(data_size, destructor_fn)
const char * ast_get_extension_name(struct ast_exten *exten)
static int config_parking_preapply(void)
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
static void generate_or_link_lots_to_configs(void)
#define PARK_APPLICATION
The default parking application that Asterisk expects.
static int option_handler_parkpos(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom field handler for parking positions.
#define ast_channel_unlock(chan)
unsigned int parkfindnext
#define PARKED_CALL_APPLICATION
static int extension_is_compatible(struct parking_lot_cfg *lot_cfg, const char *app_type, struct ast_exten *extension)
void unload_parking_manager(void)
Unregister manager actions and remove subscriptions for stasis events.
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
#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.
const ast_string_field name
static void * parking_config_alloc(void)
allocator callback for parking_config. Notice it returns void * since it is only used by the backend ...
#define ao2_find(container, arg, flags)
structure to hold users read from users.conf
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
struct aco_file parking_lot_conf
enum parking_lot_modes mode
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
static int load_module(void)
Type information about a category-level configurable object.
const ast_string_field parkext
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
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...
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Type for default option handler for stringfields.
int load_parking_devstate(void)
Register Parking devstate handler.
int error(const char *format,...)
Reject objects with duplicate keys in container.
Call Parking Resource Internal API.
static void remove_all_configured_parking_lot_extensions(void)
static int parking_lot_cfg_hash_fn(const void *obj, const int flags)
static char context[AST_MAX_CONTEXT]
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
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.
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define DEFAULT_PARKING_EXTEN
Asterisk module definitions.
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)
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
ast_context: An extension context - must remain in sync with fake_context
static void link_configured_disable_marked_lots(void)
int parking_lot_cfg_create_extensions(struct parking_lot_cfg *lot_cfg)
Add extensions for a parking lot configuration.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
unsigned int parkext_exclusive
static void parking_lot_destructor(void *obj)
const char * ast_channel_parkinglot(const struct ast_channel *chan)
static struct aco_type parking_lot_type
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.
static void parking_lot_cfg_destructor(void *obj)
Destroy a parking lot cfg object.
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
static struct parking_lot * alloc_new_parking_lot(struct parking_lot_cfg *lot_cfg)
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
struct parking_lot_cfg * cfg
#define ao2_link(container, obj)