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",
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;
439 int object_space =
user->parking_space;
441 if (*search_space == object_space) {
480#if defined(TEST_FRAMEWORK)
511 if (sscanf(
var->value,
"%30d-%30d", &low, &high) != 2) {
512 ast_log(
LOG_WARNING,
"Format for parking positions is a-b, where a and b are numbers\n");
513 }
else if (high < low || low <= 0 || high <= 0) {
530 if (!strcmp(
var->value,
"first")) {
532 }
else if (!strcmp(
var->value,
"next")) {
549 }
else if (!strcasecmp(
var,
"both")) {
551 }
else if (!strcasecmp(
var,
"caller")) {
553 }
else if (!strcasecmp(
var,
"callee")) {
569 int *parameter =
NULL;
719 if (!data_duplicate) {
738 ast_assert(extension_registrar && extension_context && extension_name && extension_application);
741 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Needs an extension '%s@%s', but that extension is already owned by %s.\n",
742 lot_cfg->
name, extension_name, extension_context, extension_registrar);
746 if (strcmp(extension_application, app_type)) {
747 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Needs an extension '%s@%s' with a non-exclusive %s application, "
748 "but a/an %s application is already registered to that extension by %s.\n",
749 lot_cfg->
name, extension_name, extension_context, app_type,
754 ast_debug(3,
"Parking lot '%s' -- extension '%s@%s' with application %s is compatible.\n",
755 lot_cfg->
name, extension_name, extension_context, app_type);
765 const char *parkext_registrar_pointer;
766 const char *parkedcall_registrar_pointer;
773 parkedcall_registrar_pointer = lot_cfg->
registrar;
776 parkext_registrar_pointer = lot_cfg->
registrar;
785 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Needs a context '%s' which does not exist and Asterisk was unable to create\n",
806 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Failed to add %s extension '%s@%s' to the PBX.\n",
813 for (parkingspace = lot_cfg->
parking_start; parkingspace <= lot_cfg->parking_stop; parkingspace++) {
818 snprintf(space,
sizeof(space),
"%d", parkingspace);
827 if (!arguments_string) {
834 ast_str_buffer(arguments_string), parkedcall_registrar_pointer)) {
835 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Failed to add %s extension '%s@%s' to the PBX.\n",
846 snprintf(hint_device,
sizeof(hint_device),
"park:%s@%s", space, lot_cfg->
parking_con);
849 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Needs to add a hint '%s' at '%s@%s' but one already exists owned by %s\n",
856 ast_log(
LOG_ERROR,
"Parking lot '%s' -- Failed to add hint '%s@%s' to the PBX.\n",
888 ast_log(
LOG_ERROR,
"Tried to create dynamic parking lot with name '%s' but a lot with that name already exists.\n", lot_cfg->
name);
896 replaced_cfg = lot->
cfg;
937 return cfg->global->parkeddynamic;
977 const char *dyn_context;
978 const char *dyn_exten;
979 const char *dyn_range;
980 const char *template_name;
981 const char *chan_template_name;
1000 ast_log(
LOG_ERROR,
"Lot %s does not exist. Can not use it as a dynamic parking lot template.\n",
1008 ast_log(
LOG_ERROR,
"Failed to allocate dynamic parking lot configuration.\n");
1021 if (sscanf(dyn_range,
"%30d-%30d", &dyn_start, &dyn_end) != 2) {
1023 "Invalid parking range %s specified in PARKINGDYNPOS: could not parse minimum/maximum parking space range\n", dyn_range);
1026 if (dyn_end < dyn_start || dyn_start < 0) {
1028 "Invalid parking range %s specified for PARKINGDYNPOS: end parking space must be greater than starting parking space.\n", dyn_range);
1037 ast_log(
LOG_ERROR,
"Extensions for dynamic parking lot '%s' could not be registered. Dynamic lot creation failed.\n",
name);
1045 ast_log(
LOG_ERROR,
"Started creating dynamic parking lot '%s', but a parking lot with that name already exists.\n",
name);
1064#if defined(TEST_FRAMEWORK)
1138 ast_log(
LOG_ERROR,
"Extension registration failed. Previously configured lot extensions were removed and can not be safely restored.\n");
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_free_ptr(void *ptr)
free() wrapper
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_RWLOCK
@ AO2_ALLOC_OPT_LOCK_MUTEX
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_unlink(container, obj)
Remove an object from a container.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
static struct console_pvt globals
#define ast_channel_lock(chan)
const char * ast_channel_parkinglot(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
#define AST_MAX_EXTENSION
Standard Command Line Interface.
Configuration option-handling.
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
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 aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
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 ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
Call Parking and Pickup API Includes code and algorithms from the Zapata library.
@ AST_FEATURE_FLAG_BYBOTH
@ AST_FEATURE_FLAG_BYCALLER
@ AST_FEATURE_FLAG_BYCALLEE
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Configuration File Parser.
#define ast_debug(level,...)
Log a DEBUG message.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_DEVSTATE_PROVIDER
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
#define PARK_APPLICATION
The default parking application that Asterisk expects.
void unload_parking_applications(void)
Unregister parking applications.
int load_parking_applications(void)
Register parking applications.
void unload_parking_bridge_features(void)
Unregister features registered by load_parking_bridge_features.
int load_parking_bridge_features(void)
Register bridge features for parking.
int load_parking_devstate(void)
Register Parking devstate handler.
void unload_parking_devstate(void)
Unregister Parking devstate handler.
int load_parking_manager(void)
Register manager actions and setup subscriptions for stasis events.
void unload_parking_manager(void)
Unregister manager actions and remove subscriptions for stasis events.
void unload_parking_tests(void)
Unregister parking unit tests.
int load_parking_tests(void)
Register parking unit tests.
void unload_parking_ui(void)
Unregister CLI commands.
int load_parking_ui(void)
Register CLI commands.
Core PBX routines and definitions.
int ast_wrlock_contexts(void)
Write locks the context list.
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
const char * ast_get_extension_app(struct ast_exten *e)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct 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.
int ast_unlock_context(struct ast_context *con)
const char * ast_get_context_name(struct ast_context *con)
struct ast_context * ast_get_extension_context(struct ast_exten *exten)
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
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.
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)
int ast_unlock_contexts(void)
Unlocks contexts.
const char * ast_get_extension_name(struct ast_exten *exten)
const char * ast_get_extension_registrar(struct ast_exten *e)
struct ao2_container * container
void parking_lot_cfg_remove_extensions(struct parking_lot_cfg *lot_cfg)
Remove extensions belonging to a parking lot configuration.
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.
struct aco_type * global_options[]
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)
struct ao2_container * get_parking_lot_container(void)
Get a pointer to the parking lot container for purposes such as iteration.
struct aco_type * parking_lot_types[]
static int verify_default_parking_lot(void)
static int option_handler_findslot(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom field handler for the findslot option.
static struct parking_lot * create_dynamic_lot_full(const char *name, struct ast_channel *chan, int forced)
static void link_configured_disable_marked_lots(void)
static int option_handler_parkpos(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom field handler for parking positions.
static void parking_config_destructor(void *obj)
destructor for parking_config
static int parking_lot_sort_fn(const void *obj_left, const void *obj_right, int flags)
static struct aco_type parking_lot_type
static AO2_GLOBAL_OBJ_STATIC(globals)
static int parked_user_cmp_fn(void *obj, void *arg, int flags)
static void disable_marked_lots(void)
static struct parking_lot * alloc_new_parking_lot(struct parking_lot_cfg *lot_cfg)
static int reload_module(void)
static void remove_all_configured_parking_lot_extensions(void)
static void * parking_lot_cfg_alloc(const char *cat)
create a parking lot structure
struct aco_file parking_lot_conf
static struct parking_lot_cfg * clone_parkinglot_cfg(struct parking_lot_cfg *source, const char *name)
struct parking_lot * parking_create_dynamic_lot(const char *name, struct ast_channel *chan)
Create a dynamic parking lot.
static int parked_user_sort_fn(const void *obj_left, const void *obj_right, int flags)
static void mark_lots_as_disabled(void)
const char * find_channel_parking_lot_name(struct ast_channel *chan)
Find parking lot name from channel.
static void parking_global_config_destructor(void *obj)
destructor for parking_global_config
static struct ao2_container * parking_lot_container
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...
static int load_module(void)
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
static int config_parking_preapply(void)
int parking_dynamic_lots_enabled(void)
Check global configuration to see if dynamic parking is enabled.
static int parking_feature_flag_cfg(int *param, const char *var)
Maps string values for option_handler_parkedfeature to their ENUM values.
static int configure_parking_extensions(void)
static int unload_module(void)
static void parking_lot_destructor(void *obj)
static void parking_lot_cfg_destructor(void *obj)
Destroy a parking lot cfg object.
static void * parking_config_alloc(void)
allocator callback for parking_config. Notice it returns void * since it is only used by the backend ...
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...
static int parking_lot_cfg_cmp_fn(void *obj, void *arg, const int flags)
static struct aco_type global_option
static int extension_is_compatible(struct parking_lot_cfg *lot_cfg, const char *app_type, struct ast_exten *extension)
static void * named_item_find(struct ao2_container *container, const char *name)
find an item in a container by its name
static void parking_lot_disable(struct parking_lot *lot)
static void remove_pending_parking_lot_extensions(struct parking_config *cfg_pending)
static int parking_lot_cfg_hash_fn(const void *obj, const int flags)
static void generate_or_link_lots_to_configs(void)
int parking_lot_cfg_create_extensions(struct parking_lot_cfg *lot_cfg)
Add extensions for a parking lot configuration.
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,)
Call Parking Resource Internal API.
parked_call_feature_options
#define PARKED_CALL_APPLICATION
#define DEFAULT_PARKING_EXTEN
#define DEFAULT_PARKING_LOT
#define ast_string_fields_copy(copy, orig)
Copy all string fields from one instance to another of the same structure.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
The representation of a single configuration file to be processed.
Type information about a category-level configurable object.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Main Channel structure associated with a channel.
ast_context: An extension context
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
structure to hold extensions
struct ao2_container * parking_lots
struct parking_global_config * global
unsigned int comebacktoorigin
unsigned int parkfindnext
unsigned int parkext_exclusive
const ast_string_field registrar
const ast_string_field parkext
unsigned int parkaddhints
const ast_string_field name
unsigned int comebackdialtime
const ast_string_field parking_con
enum parking_lot_modes mode
struct ast_bridge * parking_bridge
struct parking_lot_cfg * cfg
const ast_string_field name
struct ao2_container * parked_users
structure to hold users read from users.conf
static struct aco_type global
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.