Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
sorcery.h File Reference

Sorcery Data Access Layer API. More...

#include "asterisk/config_options.h"
#include "asterisk/uuid.h"
Include dependency graph for sorcery.h:

Go to the source code of this file.

Data Structures

struct  ast_sorcery_global_observer
 Interface for the global sorcery observer. More...
 
struct  ast_sorcery_instance_observer
 Interface for the sorcery instance observer. More...
 
struct  ast_sorcery_object_details
 Structure which contains details about a sorcery object. More...
 
struct  ast_sorcery_observer
 Interface for a sorcery object type observer. More...
 
struct  ast_sorcery_wizard
 Interface for a sorcery wizard. More...
 
struct  ast_sorcery_wizard_observer
 Interface for the sorcery wizard observer. More...
 

Macros

#define _sorcery_stringify(val)   #val
 
#define ast_sorcery_apply_config(sorcery, name)    __ast_sorcery_apply_config((sorcery), (name), AST_MODULE)
 
#define ast_sorcery_apply_default(sorcery, type, name, data)    __ast_sorcery_apply_default((sorcery), (type), AST_MODULE, (name), (data))
 
#define ast_sorcery_apply_wizard_mapping(sorcery, type, name, data, caching)    __ast_sorcery_apply_wizard_mapping((sorcery), (type), AST_MODULE, (name), (data), (caching));
 Apply additional object wizard mappings.
 
#define ast_sorcery_insert_wizard_mapping(sorcery, type, name, data, caching, position)
 Insert an additional object wizard mapping at a specific position in the wizard list.
 
#define ast_sorcery_internal_object_register(sorcery, type, alloc, transform, apply)    __ast_sorcery_object_register((sorcery), (type), 1, 1, (alloc), (transform), (apply))
 Register an internal, hidden object type.
 
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags, ...)    __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 0, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
 Register a field within an object.
 
#define ast_sorcery_object_field_register_alias(sorcery, type, name, default_val, opt_type, flags, ...)    __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 1, 1, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
 Register a field within an object as an alias.
 
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags, ...)    __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 0, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__);
 Register a field within an object with custom handlers.
 
#define ast_sorcery_object_field_register_custom_alias(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags, ...)    __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 1, 1, VA_NARGS(__VA_ARGS__), __VA_ARGS__);
 Register a field within an object with custom handlers as an alias.
 
#define ast_sorcery_object_field_register_custom_nodoc(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags, ...)    __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 1, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__);
 Register a field within an object with custom handlers without documentation.
 
#define ast_sorcery_object_field_register_nodoc(sorcery, type, name, default_val, opt_type, flags, ...)    __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 1, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
 Register a field within an object without documentation.
 
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)    __ast_sorcery_object_register((sorcery), (type), 0, 1, (alloc), (transform), (apply))
 Register an object type.
 
#define ast_sorcery_object_register_no_reload(sorcery, type, alloc, transform, apply)    __ast_sorcery_object_register((sorcery), (type), 0, 0, (alloc), (transform), (apply))
 Register an object type that is not reloadable.
 
#define ast_sorcery_object_type_apply_wizard(sorcery, object_type_name, wizard_type_name, wizard_args, flags, wizard, wizard_data)
 Apply additional object wizard mappings returning wizard information.
 
#define ast_sorcery_object_type_insert_wizard(sorcery, object_type_name, wizard_type_name, wizard_args, flags, position, wizard, wizard_data)
 Insert an additional object wizard mapping at a specific position in the wizard list returning wizard information.
 
#define ast_sorcery_object_type_remove_wizard(sorcery, object_type_name, wizard_type_name, wizard_args)
 Remove an object wizard mapping.
 
#define ast_sorcery_objectset_create(sorcery, object)    ast_sorcery_objectset_create2(sorcery, object, AST_HANDLER_PREFER_LIST)
 Create an object set (KVP list) for an object.
 
#define ast_sorcery_open()   __ast_sorcery_open(AST_MODULE, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Open a new sorcery structure.
 
#define ast_sorcery_register_bool(object, structure, option, field, def_value)
 Register a boolean field as type OPT_YESNO_T within an object.
 
#define ast_sorcery_register_cust(object, option, def_value)
 Register a custom field within an object.
 
#define ast_sorcery_register_int(object, structure, option, field, def_value)
 Register an int field as type OPT_INT_T within an object.
 
#define ast_sorcery_register_sf(object, structure, option, field, def_value)
 Register a stringfield field as type OPT_STRINGFIELD_T within an object.
 
#define ast_sorcery_register_uint(object, structure, option, field, def_value)
 Register an unsigned int field as type OPT_UINT_T within an object.
 
#define ast_sorcery_remove_wizard_mapping(sorcery, type, name)    __ast_sorcery_remove_wizard_mapping((sorcery), (type), AST_MODULE, (name))
 Remove an object wizard mapping.
 
#define ast_sorcery_unref(sorcery)    ao2_cleanup(sorcery)
 Decrease the reference count of a sorcery structure.
 
#define ast_sorcery_wizard_register(interface)   __ast_sorcery_wizard_register(interface, AST_MODULE_SELF)
 See __ast_sorcery_wizard_register()
 
#define MAX_OBJECT_FIELD   128
 Maximum length of an object field name.
 
#define MAX_OBJECT_TYPE   64
 Maximum size of an object type.
 
#define SORCERY_OBJECT(details)
 Macro which must be used at the beginning of each sorcery capable object.
 

Typedefs

typedef int(* sorcery_apply_handler) (const struct ast_sorcery *sorcery, void *obj)
 A callback function for when an object set is successfully applied to an object.
 
typedef int(* sorcery_copy_handler) (const void *src, void *dst)
 A callback function for copying the contents of one object to another.
 
typedef int(* sorcery_diff_handler) (const void *original, const void *modified, struct ast_variable **changes)
 A callback function for generating a changeset between two objects.
 
typedef int(* sorcery_field_handler) (const void *obj, const intptr_t *args, char **buf)
 A callback function for translating a value into a string.
 
typedef int(* sorcery_fields_handler) (const void *obj, struct ast_variable **fields)
 A callback function for translating multiple values into an ast_variable list.
 
typedef struct ast_variable *(* sorcery_transform_handler) (struct ast_variable *set)
 A callback function for performing a transformation on an object set.
 

Enumerations

enum  ast_sorcery_apply_result {
  AST_SORCERY_APPLY_FAIL = -1 , AST_SORCERY_APPLY_SUCCESS = 0 , AST_SORCERY_APPLY_DUPLICATE = 1 , AST_SORCERY_APPLY_DEFAULT_UNNECESSARY = 2 ,
  AST_SORCERY_APPLY_NO_CONFIGURATION = 3
}
 
enum  ast_sorcery_field_handler_flags { AST_HANDLER_PREFER_STRING , AST_HANDLER_PREFER_LIST , AST_HANDLER_ONLY_STRING , AST_HANDLER_ONLY_LIST }
 Field handler flags. More...
 
enum  ast_sorcery_retrieve_flags { AST_RETRIEVE_FLAG_DEFAULT = 0 , AST_RETRIEVE_FLAG_MULTIPLE = (1 << 0) , AST_RETRIEVE_FLAG_ALL = (1 << 1) }
 Retrieval flags. More...
 
enum  ast_sorcery_wizard_apply_flags { AST_SORCERY_WIZARD_APPLY_NONE = (0 << 0) , AST_SORCERY_WIZARD_APPLY_CACHING = (1 << 0) , AST_SORCERY_WIZARD_APPLY_READONLY = (1 << 1) , AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE = (1 << 2) }
 Wizard Apply Flags. More...
 
enum  ast_sorcery_wizard_position { AST_SORCERY_WIZARD_POSITION_LAST = -1 , AST_SORCERY_WIZARD_POSITION_FIRST = 0 }
 Pre-defined locations to insert at. More...
 

Functions

enum ast_sorcery_apply_result __ast_sorcery_apply_config (struct ast_sorcery *sorcery, const char *name, const char *module)
 Apply configured wizard mappings.
 
enum ast_sorcery_apply_result __ast_sorcery_apply_default (struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data)
 Apply default object wizard mappings.
 
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping (struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching)
 Apply additional object wizard mappings.
 
enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping (struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching, int position)
 Insert an additional object wizard mapping at a specific position in the wizard list.
 
int __ast_sorcery_object_field_register (struct ast_sorcery *sorcery, const char *type, const char *name, const char *default_val, enum aco_option_type opt_type, aco_option_handler config_handler, sorcery_field_handler sorcery_handler, sorcery_fields_handler multiple_handler, unsigned int flags, unsigned int no_doc, unsigned int alias, size_t argc,...)
 Register a field within an object.
 
int __ast_sorcery_object_register (struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply)
 Register an object type.
 
enum ast_sorcery_apply_result __ast_sorcery_object_type_insert_wizard (struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, enum ast_sorcery_wizard_apply_flags flags, int position, struct ast_sorcery_wizard **wizard, void **wizard_data)
 Insert an additional object wizard mapping at a specific position in the wizard list returning wizard information.
 
int __ast_sorcery_object_type_remove_wizard (struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args)
 Remove an object wizard mapping.
 
struct ast_sorcery__ast_sorcery_open (const char *module, const char *file, int line, const char *func)
 
int __ast_sorcery_remove_wizard_mapping (struct ast_sorcery *sorcery, const char *type, const char *module, const char *name)
 Remove an object wizard mapping.
 
int __ast_sorcery_wizard_register (const struct ast_sorcery_wizard *interface, struct ast_module *module)
 Register a sorcery wizard.
 
void * ast_sorcery_alloc (const struct ast_sorcery *sorcery, const char *type, const char *id)
 Allocate an object.
 
int ast_sorcery_changeset_create (const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
 Create a changeset given two object sets.
 
void * ast_sorcery_copy (const struct ast_sorcery *sorcery, const void *object)
 Create a copy of an object.
 
int ast_sorcery_create (const struct ast_sorcery *sorcery, void *object)
 Create and potentially persist an object using an available wizard.
 
int ast_sorcery_delete (const struct ast_sorcery *sorcery, void *object)
 Delete an object.
 
int ast_sorcery_diff (const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes)
 Create a changeset of two objects.
 
void ast_sorcery_force_reload (const struct ast_sorcery *sorcery)
 Inform any wizards to reload persistent objects, even if no changes determined.
 
void ast_sorcery_force_reload_object (const struct ast_sorcery *sorcery, const char *type)
 Inform any wizards of a specific object type to reload persistent objects even if no changes determined.
 
void * ast_sorcery_generic_alloc (size_t size, ao2_destructor_fn destructor)
 Allocate a generic sorcery capable object.
 
const char * ast_sorcery_get_module (const struct ast_sorcery *sorcery)
 Get the module that has opened the provided sorcery instance.
 
struct ast_sorcery_object_typeast_sorcery_get_object_type (const struct ast_sorcery *sorcery, const char *type)
 Get the sorcery object type given a type name.
 
int ast_sorcery_get_wizard_mapping (struct ast_sorcery *sorcery, const char *type, int index, struct ast_sorcery_wizard **wizard, void **data)
 By index, return a wizard mapped to an object type.
 
int ast_sorcery_get_wizard_mapping_count (struct ast_sorcery *sorcery, const char *type)
 Return the number of wizards mapped to an object type.
 
int ast_sorcery_global_observer_add (const struct ast_sorcery_global_observer *callbacks)
 Add a global observer to sorcery.
 
void ast_sorcery_global_observer_remove (const struct ast_sorcery_global_observer *callbacks)
 Remove a global observer from sorcery.
 
int ast_sorcery_init (void)
 Initialize the sorcery API.
 
int ast_sorcery_instance_observer_add (struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
 Add an observer to a sorcery instance.
 
void ast_sorcery_instance_observer_remove (struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
 Remove an observer from a sorcery instance.
 
int ast_sorcery_is_object_field_registered (const struct ast_sorcery_object_type *object_type, const char *field_name)
 Determine if a particular object field has been registered with sorcery.
 
int ast_sorcery_is_stale (const struct ast_sorcery *sorcery, void *object)
 Determine if a sorcery object is stale with respect to its backing datastore.
 
void ast_sorcery_load (const struct ast_sorcery *sorcery)
 Inform any wizards to load persistent objects.
 
void ast_sorcery_load_object (const struct ast_sorcery *sorcery, const char *type)
 Inform any wizards of a specific object type to load persistent objects.
 
void * ast_sorcery_lockable_alloc (size_t size, ao2_destructor_fn destructor, void *lockobj)
 Allocate a generic sorcery capable object with locking.
 
int ast_sorcery_object_fields_register (struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
 Register a regex for multiple fields within an object.
 
const struct timeval ast_sorcery_object_get_created (const void *object)
 Get when the sorcery object was created.
 
const char * ast_sorcery_object_get_extended (const void *object, const char *name)
 Get an extended field value from a sorcery object.
 
const char * ast_sorcery_object_get_id (const void *object)
 Get the unique identifier of a sorcery object.
 
const char * ast_sorcery_object_get_type (const void *object)
 Get the type of a sorcery object.
 
unsigned int ast_sorcery_object_has_dynamic_contents (const void *object)
 Get whether an object contains dynamic contents or not.
 
int ast_sorcery_object_id_compare (void *obj, void *arg, int flags)
 ao2 object comparator based on sorcery id.
 
int ast_sorcery_object_id_hash (const void *obj, int flags)
 ao2 object hasher based on sorcery id.
 
int ast_sorcery_object_id_sort (const void *obj, const void *arg, int flags)
 ao2 object sorter based on sorcery id.
 
int ast_sorcery_object_set_congestion_levels (struct ast_sorcery *sorcery, const char *type, long low_water, long high_water)
 Set the high and low alert water marks of the sorcery object type.
 
void ast_sorcery_object_set_copy_handler (struct ast_sorcery *sorcery, const char *type, sorcery_copy_handler copy)
 Set the copy handler for an object type.
 
void ast_sorcery_object_set_diff_handler (struct ast_sorcery *sorcery, const char *type, sorcery_diff_handler diff)
 Set the diff handler for an object type.
 
int ast_sorcery_object_set_extended (const void *object, const char *name, const char *value)
 Set an extended field value on a sorcery object.
 
void ast_sorcery_object_set_has_dynamic_contents (const void *object)
 Set the dynamic contents flag on a sorcery object.
 
int ast_sorcery_object_unregister (struct ast_sorcery *sorcery, const char *type)
 Unregister an object type.
 
int ast_sorcery_objectset_apply (const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
 Apply an object set (KVP list) to an object.
 
struct ast_variableast_sorcery_objectset_create2 (const struct ast_sorcery *sorcery, const void *object, enum ast_sorcery_field_handler_flags flags)
 Create an object set (KVP list) for an object.
 
struct ast_jsonast_sorcery_objectset_json_create (const struct ast_sorcery *sorcery, const void *object)
 Create an object set in JSON format for an object.
 
int ast_sorcery_observer_add (const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
 Add an observer to a specific object type.
 
void ast_sorcery_observer_remove (const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
 Remove an observer from a specific object type.
 
void ast_sorcery_ref (struct ast_sorcery *sorcery)
 Increase the reference count of a sorcery structure.
 
void ast_sorcery_reload (const struct ast_sorcery *sorcery)
 Inform any wizards to reload persistent objects.
 
void ast_sorcery_reload_object (const struct ast_sorcery *sorcery, const char *type)
 Inform any wizards of a specific object type to reload persistent objects.
 
void * ast_sorcery_retrieve_by_fields (const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
 Retrieve an object or multiple objects using specific fields.
 
void * ast_sorcery_retrieve_by_id (const struct ast_sorcery *sorcery, const char *type, const char *id)
 Retrieve an object using its unique identifier.
 
struct ast_sorceryast_sorcery_retrieve_by_module_name (const char *module_name)
 Retrieves an existing sorcery instance by module name.
 
struct ao2_containerast_sorcery_retrieve_by_prefix (const struct ast_sorcery *sorcery, const char *type, const char *prefix, const size_t prefix_len)
 Retrieve multiple objects whose id begins with the specified prefix.
 
struct ao2_containerast_sorcery_retrieve_by_regex (const struct ast_sorcery *sorcery, const char *type, const char *regex)
 Retrieve multiple objects using a regular expression on their id.
 
int ast_sorcery_update (const struct ast_sorcery *sorcery, void *object)
 Update an object.
 
int ast_sorcery_wizard_observer_add (struct ast_sorcery_wizard *wizard, const struct ast_sorcery_wizard_observer *callbacks)
 Add an observer to a sorcery wizard.
 
void ast_sorcery_wizard_observer_remove (struct ast_sorcery_wizard *interface, const struct ast_sorcery_wizard_observer *callbacks)
 Remove an observer from a sorcery wizard.
 
int ast_sorcery_wizard_unregister (const struct ast_sorcery_wizard *interface)
 Unregister a sorcery wizard.
 

Variables

int ast_sorcery_update_or_create_on_update_miss
 Global control for optional update->create fallback in backends.
 

Detailed Description

Sorcery Data Access Layer API.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om Data Access Layer API

Definition in file sorcery.h.

Macro Definition Documentation

◆ _sorcery_stringify

#define _sorcery_stringify (   val)    #val

Definition at line 1695 of file sorcery.h.

◆ ast_sorcery_apply_config

#define ast_sorcery_apply_config (   sorcery,
  name 
)     __ast_sorcery_apply_config((sorcery), (name), AST_MODULE)

Definition at line 455 of file sorcery.h.

516 {
519};
520
521/*!
522 * \brief Insert an additional object wizard mapping at a specific position
523 * in the wizard list
524 *
525 * \param sorcery Pointer to a sorcery structure
526 * \param type Type of object to apply to
527 * \param module The name of the module, typically AST_MODULE
528 * \param name Name of the wizard to use
529 * \param data Data to be passed to wizard
530 * \param caching Wizard should cache
531 * \param position An index to insert to or one of ast_sorcery_wizard_position
532 *
533 * \return What occurred when applying the mapping
534 *
535 * \note This should be called *after* applying default mappings
536 * \note Wizards can be retrieved by using ast_sorcery_get_wizard_mapping_count
537 * and iterating over them using ast_sorcery_get_wizard_mapping.
538 *
539 * \since 13.4.0
540 */
542 const char *type, const char *module, const char *name, const char *data,
543 unsigned int caching, int position);
544
545/*!
546 * \brief Insert an additional object wizard mapping at a specific position
547 * in the wizard list
548 *
549 * \param sorcery Pointer to a sorcery structure
550 * \param type Type of object to apply to
551 * \param name Name of the wizard to use
552 * \param data Data to be passed to wizard
553 * \param caching Wizard should cache
554 * \param position One of ast_sorcery_wizard_position
555 *
556 * \return What occurred when applying the mapping
557 *
558 * \note This should be called *after* applying default mappings
559 * \since 13.4.0
560 */
561#define ast_sorcery_insert_wizard_mapping(sorcery, type, name, data, caching, position) \
562 __ast_sorcery_insert_wizard_mapping((sorcery), (type), AST_MODULE, (name), (data), \
563 (caching), (position))
564
565/*!
566 * \brief Wizard Apply Flags
567 *
568 * These flags apply only to a wizard/object-type combination.
569 * The same wizard may be applied to a different object-type with
570 * different flags and behavior. If ALLOW_DUPLICATE is set
571 * the wizard could even be applied to the same object-type
572 * with different flags.
573 */
575 /*! Apply no special behavior */
577 /*! This wizard will cache this object type's entries */
579 /*! This wizard won't allow Create, Update or Delete operations on this object type */
581 /*! This wizard will allow other instances of itself on the same object type */
583};
584
585/*!
586 * \brief Insert an additional object wizard mapping at a specific position
587 * in the wizard list returning wizard information
588 * \since 13.26.0
589 * \since 16.3.0
590 *
591 * \param sorcery Pointer to a sorcery structure
592 * \param object_type_name Name of the object type to apply to
593 * \param module The name of the module, typically AST_MODULE
594 * \param wizard_type_name Name of the wizard type to use
595 * \param wizard_args Opaque string to be passed to the wizard
596 * May be NULL but see note below
597 * \param flags One or more of enum ast_sorcery_wizard_apply_flags
598 * \param position An index to insert to or one of ast_sorcery_wizard_position
599 * \param[out] wizard A variable to receive a pointer to the ast_sorcery_wizard structure.
600 * May be NULL if not needed.
601 * \param[out] wizard_data A variable to receive a pointer to the wizard's internal data.
602 * May be NULL if not needed.
603 *
604 * \return What occurred when applying the mapping
605 *
606 * \note This should be called *after* applying default mappings
607 *
608 * \note Although \p wizard_args is an optional parameter it is highly
609 * recommended to supply one. If you use the AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE
610 * flag, and you intend to ever remove a wizard mapping, you'll need \p wizard_args
611 * to remove specific instances of a wizard type.
612 */
614 const char *object_type_name, const char *module, const char *wizard_type_name,
615 const char *wizard_args, enum ast_sorcery_wizard_apply_flags flags, int position,
616 struct ast_sorcery_wizard **wizard, void **wizard_data);
617
618/*!
619 * \brief Insert an additional object wizard mapping at a specific position
620 * in the wizard list returning wizard information
621 * \since 13.26.0
622 * \since 16.3.0
623 *
624 * \param sorcery Pointer to a sorcery structure
625 * \param object_type_name Name of the object type to apply to
626 * \param wizard_type_name Name of the wizard type to use
627 * \param wizard_args Opaque string to be passed to the wizard
628 * May be NULL but see note below
629 * \param flags One or more of enum ast_sorcery_wizard_apply_flags
630 * \param position An index to insert to or one of ast_sorcery_wizard_position
631 * \param[out] wizard A variable to receive a pointer to the ast_sorcery_wizard structure.
632 * May be NULL if not needed.
633 * \param[out] wizard_data A variable to receive a pointer to the wizard's internal data.
634 * May be NULL if not needed.
635 *
636 * \return What occurred when applying the mapping
637 *
638 * \note This should be called *after* applying default mappings
639 *
640 * \note Although \p wizard_args is an optional parameter it is highly
641 * recommended to supply one. If you use the AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE
642 * flag, and you intend to ever remove a wizard mapping, you'll need \p wizard_args
643 * to remove specific instances.
644 */
645#define ast_sorcery_object_type_insert_wizard(sorcery, \
646 object_type_name, wizard_type_name, wizard_args, flags, \
647 position, wizard, wizard_data) \
648 __ast_sorcery_object_type_insert_wizard((sorcery), \
649 (object_type_name), AST_MODULE, (wizard_type_name), (wizard_args), (flags), \
650 position, (wizard), (wizard_data))
651
652/*!
653 * \brief Apply additional object wizard mappings returning wizard information
654 * \since 13.26.0
655 * \since 16.3.0
656 *
657 * \param sorcery Pointer to a sorcery structure
658 * \param object_type_name Name of the object type to apply to
659 * \param wizard_type_name Name of the wizard type to use
660 * \param wizard_args Opaque string to be passed to the wizard
661 * May be NULL but see note below
662 * \param flags One or more of enum ast_sorcery_wizard_apply_flags
663 * \param[out] wizard A variable to receive a pointer to the ast_sorcery_wizard structure.
664 * May be NULL if not needed.
665 * \param[out] wizard_data A variable to receive a pointer to the wizard's internal data.
666 * May be NULL if not needed.
667 *
668 * \return What occurred when applying the mapping
669 *
670 * \note This should be called *after* applying default mappings
671 *
672 * \note Although \p wizard_args is an optional parameter it is highly
673 * recommended to supply one. If you use the AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE
674 * flag, and you intend to ever remove a wizard mapping, you'll need \p wizard_args
675 * to remove specific instances.
676 */
677#define ast_sorcery_object_type_apply_wizard(sorcery, \
678 object_type_name, wizard_type_name, wizard_args, flags, \
679 wizard, wizard_data) \
680 __ast_sorcery_object_type_insert_wizard((sorcery), \
681 (object_type_name), AST_MODULE, (wizard_type_name), (wizard_args), (flags), \
682 AST_SORCERY_WIZARD_POSITION_LAST, (wizard), (wizard_data))
683
684/*!
685 * \brief Remove an object wizard mapping
686 * \since 13.26.0
687 * \since 16.3.0
688 *
689 * \param sorcery Pointer to a sorcery structure
690 * \param object_type_name Name of the object type to remove from
691 * \param module The name of the module, typically AST_MODULE
692 * \param wizard_type_name The name of the of the wizard type to remove
693 * \param wizard_args Opaque string originally passed to the wizard
694 *
695 * \retval 0 success
696 * \retval -1 failure
697 *
698 * \note If there were multiple instances of the same wizard type
699 * added to this object type without using \p wizard_args, then
700 * only the first wizard matching wizard_type will be removed.
701 */
703 const char *object_type_name, const char *module, const char *wizard_type_name,
704 const char *wizard_args);
705
706/*!
707 * \brief Remove an object wizard mapping
708 * \since 13.26.0
709 * \since 16.3.0
710 *
711 * \param sorcery Pointer to a sorcery structure
712 * \param object_type_name Name of the object type to remove from
713 * \param wizard_type_name The name of the of the wizard type to remove
714 * \param wizard_args Opaque string originally passed to the wizard
715 *
716 * \retval 0 success
717 * \retval -1 failure
718 *
719 * \note If there were multiple instances of the same wizard type
720 * added to this object type without using \p wizard_args, then
721 * only the first wizard matching wizard_type will be removed.
722 */
723#define ast_sorcery_object_type_remove_wizard(sorcery, object_type_name, \
724 wizard_type_name, wizard_args) \
725 __ast_sorcery_object_type_remove_wizard((sorcery), (object_type_name), \
726 AST_MODULE, (wizard_type_name), (wizard_args))
727
728/*!
729 * \brief Remove an object wizard mapping
730 *
731 * \param sorcery Pointer to a sorcery structure
732 * \param type Type of object to remove from
733 * \param module The name of the module, typically AST_MODULE
734 * \param name The name of the wizard to remove
735 *
736 * \retval 0 success
737 * \retval -1 failure
738 *
739 * \since 13.4.0
740 */
742 const char *type, const char *module, const char *name);
743
744/*!
745 * \brief Remove an object wizard mapping
746 *
747 * \param sorcery Pointer to a sorcery structure
748 * \param type Type of object to remove from
749 * \param name The name of the wizard to remove
750 *
751 * \retval 0 success
752 * \retval -1 failure
753 *
754 * \since 13.4.0
755 */
756#define ast_sorcery_remove_wizard_mapping(sorcery, type, name) \
757 __ast_sorcery_remove_wizard_mapping((sorcery), (type), AST_MODULE, (name))
758
759/*!
760 * \brief Return the number of wizards mapped to an object type
761 *
762 * \param sorcery Pointer to a sorcery structure
763 * \param type Type of object
764 *
765 * \return Number of wizards or -1 for error
766 * \since 13.4.0
767 */
769 const char *type);
770
771/*!
772 * \brief By index, return a wizard mapped to an object type
773 *
774 * \param sorcery Pointer to a sorcery structure
775 * \param type Type of object
776 * \param index Index of the wizard
777 * \param wizard A pointer to receive the wizard pointer
778 * \param data A pointer to receive the data pointer
779 *
780 * \retval 0 success
781 * \retval -1 failure
782 *
783 * \warning The wizard will have its reference count bumped so you must
784 * call ao2_cleanup when you're done with it.
785 *
786 * \note The wizard and data returned are valid only for this object type
787 * and only while the wizard is applied to the object type.
788 *
789 * \since 13.4.0
790 */
792 const char *type, int index, struct ast_sorcery_wizard **wizard, void **data);
793
794/*!
795 * \brief Unregister an object type
796 *
797 * \param sorcery Pointer to a sorcery structure
798 * \param type Type of object
799 *
800 * \retval 0 success
801 * \retval -1 failure
802 */
803int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type);
804
805/*!
806 * \brief Register an object type
807 *
808 * \param sorcery Pointer to a sorcery structure
809 * \param type Type of object
810 * \param hidden All objects of this type are internal and should not be manipulated by users
811 * \param reloadable All objects of this type are reloadable
812 * \param alloc Required object allocation callback
813 * \param transform Optional transformation callback
814 * \param apply Optional object set apply callback
815 *
816 * \note In general, this function should not be used directly. One of the various
817 * macro'd versions should be used instead.
818 *
819 * \retval 0 success
820 * \retval -1 failure
821 */
822int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply);
823
824/*!
825 * \brief Register an object type
826 *
827 * \param sorcery Pointer to a sorcery structure
828 * \param type Type of object
829 * \param alloc Required object allocation callback
830 * \param transform Optional transformation callback
831 * \param apply Optional object set apply callback
832 *
833 * \retval 0 success
834 * \retval -1 failure
835 */
836#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply) \
837 __ast_sorcery_object_register((sorcery), (type), 0, 1, (alloc), (transform), (apply))
838
839/*!
840 * \brief Register an object type that is not reloadable
841 *
842 * \param sorcery Pointer to a sorcery structure
843 * \param type Type of object
844 * \param alloc Required object allocation callback
845 * \param transform Optional transformation callback
846 * \param apply Optional object set apply callback
847 *
848 * \retval 0 success
849 * \retval -1 failure
850 */
851#define ast_sorcery_object_register_no_reload(sorcery, type, alloc, transform, apply) \
852 __ast_sorcery_object_register((sorcery), (type), 0, 0, (alloc), (transform), (apply))
853
854/*!
855 * \brief Register an internal, hidden object type
856 *
857 * \param sorcery Pointer to a sorcery structure
858 * \param type Type of object
859 * \param alloc Required object allocation callback
860 * \param transform Optional transformation callback
861 * \param apply Optional object set apply callback
862 *
863 * \retval 0 success
864 * \retval -1 failure
865 */
866#define ast_sorcery_internal_object_register(sorcery, type, alloc, transform, apply) \
867 __ast_sorcery_object_register((sorcery), (type), 1, 1, (alloc), (transform), (apply))
868
869/*!
870 * \brief Set the high and low alert water marks of the sorcery object type.
871 * \since 13.10.0
872 *
873 * \param sorcery Pointer to a sorcery structure
874 * \param type Type of object
875 * \param low_water New queue low water mark. (-1 to set as 90% of high_water)
876 * \param high_water New queue high water mark.
877 *
878 * \retval 0 on success.
879 * \retval -1 on error (water marks not changed).
880 */
881int ast_sorcery_object_set_congestion_levels(struct ast_sorcery *sorcery, const char *type, long low_water, long high_water);
882
883/*!
884 * \brief Set the copy handler for an object type
885 *
886 * \param sorcery Pointer to a sorcery structure
887 * \param type Type of object
888 * \param copy Copy handler
889 */
891
892/*!
893 * \brief Set the diff handler for an object type
894 *
895 * \param sorcery Pointer to a sorcery structure
896 * \param type Type of object
897 * \param diff Diff handler
898 */
900
901/*!
902 * \brief Register a regex for multiple fields within an object
903 *
904 * \param sorcery Pointer to a sorcery structure
905 * \param type Type of object
906 * \param regex A regular expression pattern for the fields
907 * \param config_handler A custom handler for translating the string representation of the fields
908 * \param sorcery_handler A custom handler for translating the native representation of the fields
909 *
910 * \retval 0 success
911 * \retval -1 failure
912 */
913int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler,
914 sorcery_fields_handler sorcery_handler);
915
916/*!
917 * \brief Register a field within an object
918 *
919 * \param sorcery Pointer to a sorcery structure
920 * \param type Type of object
921 * \param name Name of the field
922 * \param default_val Default value of the field
923 * \param config_handler A custom handler for translating the string representation of the fields
924 * \param sorcery_handler A custom handler for translating the native representation of the fields
925 * \param multiple_handler A custom handler for translating the native representation of the fields
926 * \param opt_type Option type
927 * \param flags Option type specific flags
928 * \param no_doc Field should not be documented
929 * \param alias Interpret and apply field value only
930 * \param argc
931 *
932 * \retval 0 success
933 * \retval -1 failure
934 */
936 const char *name, const char *default_val, enum aco_option_type opt_type,
937 aco_option_handler config_handler, sorcery_field_handler sorcery_handler,
938 sorcery_fields_handler multiple_handler, unsigned int flags, unsigned int no_doc,
939 unsigned int alias, size_t argc, ...);
940
941/*!
942 * \brief Register a field within an object
943 *
944 * \param sorcery Pointer to a sorcery structure
945 * \param type Type of object
946 * \param name Name of the field
947 * \param default_val Default value of the field
948 * \param opt_type Option type
949 * \param flags Option type specific flags
950 *
951 * \retval 0 success
952 * \retval -1 failure
953 */
954#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags, ...) \
955 __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 0, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
956
957/*!
958 * \brief Register a field within an object as an alias
959 *
960 * \param sorcery Pointer to a sorcery structure
961 * \param type Type of object
962 * \param name Name of the field
963 * \param default_val Default value of the field
964 * \param opt_type Option type
965 * \param flags Option type specific flags
966 *
967 * \retval 0 success
968 * \retval -1 failure
969 */
970#define ast_sorcery_object_field_register_alias(sorcery, type, name, default_val, opt_type, flags, ...) \
971 __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 1, 1, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
972
973/*!
974 * \brief Register a field within an object without documentation
975 *
976 * \param sorcery Pointer to a sorcery structure
977 * \param type Type of object
978 * \param name Name of the field
979 * \param default_val Default value of the field
980 * \param opt_type Option type
981 * \param flags Option type specific flags
982 *
983 * \retval 0 success
984 * \retval -1 failure
985 */
986#define ast_sorcery_object_field_register_nodoc(sorcery, type, name, default_val, opt_type, flags, ...) \
987 __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 1, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
988
989/*!
990 * \brief Register a field within an object with custom handlers
991 *
992 * \param sorcery Pointer to a sorcery structure
993 * \param type Type of object
994 * \param name Name of the field
995 * \param default_val Default value of the field
996 * \param config_handler Custom configuration handler
997 * \param sorcery_handler Custom sorcery handler
998 * \param multiple_handler Custom multiple handler
999 * \param flags Option type specific flags
1000 *
1001 * \retval 0 success
1002 * \retval -1 failure
1003 */
1004#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags, ...) \
1005 __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 0, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__);
1006
1007/*!
1008 * \brief Register a field within an object with custom handlers as an alias
1009 *
1010 * \param sorcery Pointer to a sorcery structure
1011 * \param type Type of object
1012 * \param name Name of the field
1013 * \param default_val Default value of the field
1014 * \param config_handler Custom configuration handler
1015 * \param sorcery_handler Custom sorcery handler
1016 * \param multiple_handler Custom multiple handler
1017 * \param flags Option type specific flags
1018 *
1019 * \retval 0 success
1020 * \retval -1 failure
1021 */
1022#define ast_sorcery_object_field_register_custom_alias(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags, ...) \
1023 __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 1, 1, VA_NARGS(__VA_ARGS__), __VA_ARGS__);
1024
1025/*!
1026 * \brief Register a field within an object with custom handlers without documentation
1027 *
1028 * \param sorcery Pointer to a sorcery structure
1029 * \param type Type of object
1030 * \param name Name of the field
1031 * \param default_val Default value of the field
1032 * \param config_handler Custom configuration handler
1033 * \param sorcery_handler Custom sorcery handler
1034 * \param multiple_handler Custom multiple handler
1035 * \param flags Option type specific flags
1036 *
1037 * \retval 0 success
1038 * \retval -1 failure
1039 */
1040#define ast_sorcery_object_field_register_custom_nodoc(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags, ...) \
1041 __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 1, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__);
1042
1043/*!
1044 * \brief Inform any wizards to load persistent objects
1045 *
1046 * \param sorcery Pointer to a sorcery structure
1047 */
1048void ast_sorcery_load(const struct ast_sorcery *sorcery);
1049
1050/*!
1051 * \brief Inform any wizards of a specific object type to load persistent objects
1052 *
1053 * \param sorcery Pointer to a sorcery structure
1054 * \param type Name of the object type to load
1055 */
1056void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type);
1057
1058/*!
1059 * \brief Inform any wizards to reload persistent objects
1060 *
1061 * \param sorcery Pointer to a sorcery structure
1062 */
1063void ast_sorcery_reload(const struct ast_sorcery *sorcery);
1064
1065/*!
1066 * \brief Inform any wizards to reload persistent objects, even if no changes determined
1067 *
1068 * \param sorcery Pointer to a sorcery structure
1069 *
1070 * \since 13.32.0
1071 * \since 16.9.0
1072 * \since 17.3.0
1073 */
1074void ast_sorcery_force_reload(const struct ast_sorcery *sorcery);
1075
1076/*!
1077 * \brief Inform any wizards of a specific object type to reload persistent objects
1078 *
1079 * \param sorcery Pointer to a sorcery structure
1080 * \param type Name of the object type to reload
1081 */
1082void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type);
1083
1084/*!
1085 * \brief Inform any wizards of a specific object type to reload persistent objects
1086 * even if no changes determined
1087 *
1088 * \param sorcery Pointer to a sorcery structure
1089 * \param type Name of the object type to reload
1090 *
1091 * \since 13.32.0
1092 * \since 16.9.0
1093 * \since 17.3.0
1094 */
1095void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type);
1096
1097/*!
1098 * \brief Increase the reference count of a sorcery structure
1099 *
1100 * \param sorcery Pointer to a sorcery structure
1101 */
1102void ast_sorcery_ref(struct ast_sorcery *sorcery);
1103
1104
1105/*!
1106 * \brief Create an object set (KVP list) for an object
1107 *
1108 * \param sorcery Pointer to a sorcery structure
1109 * \param object Pointer to a sorcery object
1110 * \param flags Flags indicating which handler to use and in what order.
1111 *
1112 * \retval non-NULL success
1113 * \retval NULL if error occurred
1114 *
1115 * \note The returned ast_variable list must be destroyed using ast_variables_destroy
1116 */
1118 const void *object, enum ast_sorcery_field_handler_flags flags);
1119
1120/*!
1121 * \brief Create an object set (KVP list) for an object
1122 *
1123 * \param sorcery Pointer to a sorcery structure
1124 * \param object Pointer to a sorcery object
1125 *
1126 * \retval non-NULL success
1127 * \retval NULL if error occurred
1128 *
1129 * \note The returned ast_variable list must be destroyed using ast_variables_destroy
1130 *
1131 * \note This function attempts to use a field's sorcery_fields_handler first and if that
1132 * doesn't exist or fails, a field's sorcery_field_handler is used. The difference is
1133 * that the former may return multiple list entries for the same field and the latter will only
1134 * return 1. It's up to the field itself to determine what the appropriate content is.
1135 */
1136#define ast_sorcery_objectset_create(sorcery, object) \
1137 ast_sorcery_objectset_create2(sorcery, object, AST_HANDLER_PREFER_LIST)
1138
1139/*!
1140 * \brief Create an object set in JSON format for an object
1141 *
1142 * \param sorcery Pointer to a sorcery structure
1143 * \param object Pointer to a sorcery object
1144 *
1145 * \retval non-NULL success
1146 * \retval NULL if error occurred
1147 *
1148 * \note The returned ast_json object must be unreferenced using ast_json_unref
1149 */
1150struct ast_json *ast_sorcery_objectset_json_create(const struct ast_sorcery *sorcery, const void *object);
1151
1152/*!
1153 * \brief Apply an object set (KVP list) to an object
1154 *
1155 * \param sorcery Pointer to a sorcery structure
1156 * \param object Pointer to a sorcery object
1157 * \param objectset Object set itself
1158 *
1159 * \retval 0 success
1160 * \retval -1 failure
1161 *
1162 * \note This operation is *not* atomic. If this fails it is possible for the object to be left with a partially
1163 * applied object set.
1164 */
1165int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset);
1166
1167/*!
1168 * \brief Create a changeset given two object sets
1169 *
1170 * \param original Original object set
1171 * \param modified Modified object set
1172 * \param changes Pointer to hold any changes between the object sets
1173 *
1174 * \retval 0 success
1175 * \retval -1 failure
1176 *
1177 * \note The returned ast_variable list must be destroyed using ast_variables_destroy
1178 */
1179int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes);
1180
1181/*!
1182 * \brief Allocate a generic sorcery capable object
1183 *
1184 * \param size Size of the object
1185 * \param destructor Optional destructor function
1186 *
1187 * \retval non-NULL success
1188 * \retval NULL failure
1189 *
1190 * \note The returned object does not support AO2 locking.
1191 */
1192void *ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor);
1193
1194/*!
1195 * \since 14.1.0
1196 * \brief Allocate a generic sorcery capable object with locking.
1197 *
1198 * \details Sorcery objects may be replaced with new allocations during reloads.
1199 * If locking is required on sorcery objects it must be shared between the old
1200 * object and the new one. lockobj can be any AO2 object with locking enabled,
1201 * but in most cases named locks should be used to provide stable locking.
1202 *
1203 * \param size Size of the object
1204 * \param destructor Optional destructor function
1205 * \param lockobj An AO2 object that will provide locking.
1206 *
1207 * \retval non-NULL success
1208 * \retval NULL failure
1209 */
1210void *ast_sorcery_lockable_alloc(size_t size, ao2_destructor_fn destructor, void *lockobj);
1211
1212/*!
1213 * \brief Allocate an object
1214 *
1215 * \param sorcery Pointer to a sorcery structure
1216 * \param type Type of object to allocate
1217 * \param id Optional unique identifier, if none is provided one will be generated
1218 *
1219 * \retval non-NULL success
1220 * \retval NULL failure
1221 */
1222void *ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id);
1223
1224/*!
1225 * \brief Create a copy of an object
1226 *
1227 * \param sorcery Pointer to a sorcery structure
1228 * \param object Existing object
1229 *
1230 * \retval non-NULL success
1231 * \retval NULL failure
1232 */
1233void *ast_sorcery_copy(const struct ast_sorcery *sorcery, const void *object);
1234
1235/*!
1236 * \brief Create a changeset of two objects
1237 *
1238 * \param sorcery Pointer to a sorcery structure
1239 * \param original Original object
1240 * \param modified Modified object
1241 * \param changes Pointer which will be populated with changes if any exist
1242 *
1243 * \retval 0 success
1244 * \retval -1 failure
1245 *
1246 * \note The returned ast_variable list must be destroyed using ast_variables_destroy
1247 *
1248 * \note While the objects must be of the same type they do not have to be the same object
1249 */
1250int ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes);
1251
1252/*!
1253 * \brief Add a global observer to sorcery
1254 *
1255 * \param callbacks Implementation of the global observer interface
1256 *
1257 * \retval 0 success
1258 * \retval -1 failure
1259 *
1260 * \note You must be ready to accept observer invocations before this function is called
1261 */
1263
1264/*!
1265 * \brief Remove a global observer from sorcery.
1266 *
1267 * A global observer is notified...
1268 * After a new wizard is registered.
1269 * After a new sorcery instance is opened.
1270 * Before an instance is destroyed.
1271 * Before a wizard is unregistered.
1272 *
1273 * \param callbacks Implementation of the global observer interface
1274 */
1276
1277/*!
1278 * \brief Add an observer to a sorcery instance
1279 *
1280 * \param sorcery Pointer to a sorcery structure
1281 * \param callbacks Implementation of the instance observer interface
1282 *
1283 * An instance observer is notified...
1284 * Before an instance is loaded or reloaded.
1285 * After an instance is loaded or reloaded.
1286 * After a wizard is mapped to an object type.
1287 * After an object type is registered.
1288 * Before an object type is loaded or reloaded.
1289 * After an object type is loaded or reloaded.
1290 *
1291 * \retval 0 success
1292 * \retval -1 failure
1293 *
1294 * \note You must be ready to accept observer invocations before this function is called
1295 */
1298
1299/*!
1300 * \brief Remove an observer from a sorcery instance
1301 *
1302 * \param sorcery Pointer to a sorcery structure
1303 * \param callbacks Implementation of the instance observer interface
1304 */
1307
1308/*!
1309 * \brief Add an observer to a sorcery wizard
1310 *
1311 * \param wizard Pointer to a previously registered wizard structure
1312 * \param callbacks Implementation of the wizard observer interface
1313 *
1314 * A wizard observer is notified...
1315 * Before a wizard is loaded or reloaded.
1316 * After a wizard is loaded or reloaded.
1317 *
1318 * \retval 0 success
1319 * \retval -1 failure
1320 *
1321 * \note You must be ready to accept observer invocations before this function is called
1322 */
1325
1326/*!
1327 * \brief Remove an observer from a sorcery wizard.
1328 *
1329 * \param interface Pointer to a sorcery structure
1330 * \param callbacks Implementation of the wizard observer interface
1331 */
1334
1335/*!
1336 * \brief Add an observer to a specific object type
1337 *
1338 * \param sorcery Pointer to a sorcery structure
1339 * \param type Type of object that should be observed
1340 * \param callbacks Implementation of the observer interface
1341 *
1342 * \retval 0 success
1343 * \retval -1 failure
1344 *
1345 * \note You must be ready to accept observer invocations before this function is called
1346 */
1347int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks);
1348
1349/*!
1350 * \brief Remove an observer from a specific object type
1351 *
1352 * \param sorcery Pointer to a sorcery structure
1353 * \param type Type of object that should no longer be observed
1354 * \param callbacks Implementation of the observer interface
1355 */
1356void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks);
1357
1358/*!
1359 * \brief Create and potentially persist an object using an available wizard
1360 *
1361 * \param sorcery Pointer to a sorcery structure
1362 * \param object Pointer to a sorcery object
1363 *
1364 * \retval 0 success
1365 * \retval -1 failure
1366 */
1367int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object);
1368
1369/*!
1370 * \brief Retrieve an object using its unique identifier
1371 *
1372 * \param sorcery Pointer to a sorcery structure
1373 * \param type Type of object to retrieve
1374 * \param id Unique object identifier
1375 *
1376 * \retval non-NULL if found
1377 * \retval NULL if not found
1378 */
1379void *ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id);
1380
1381/*!
1382 * \brief Retrieve an object or multiple objects using specific fields
1383 * \since 13.9.0
1384 *
1385 * \param sorcery Pointer to a sorcery structure
1386 * \param type Type of object to retrieve
1387 * \param flags Flags to control behavior
1388 * \param fields Optional object fields and values to match against
1389 *
1390 * \retval non-NULL if found
1391 * \retval NULL if not found
1392 *
1393 * \note If the AST_RETRIEVE_FLAG_MULTIPLE flag is specified the returned value will be an
1394 * ao2_container that must be unreferenced after use.
1395 *
1396 * \note If the AST_RETRIEVE_FLAG_ALL flag is used you may omit fields to retrieve all objects
1397 * of the given type.
1398 *
1399 * \note The fields parameter can contain realtime-style expressions in variable->name.
1400 * All operators defined for ast_strings_match can be used except for regex as
1401 * there's no common support for regex in the realtime backends at this time.
1402 * If multiple variables are in the fields list, all must match for an object to
1403 * be returned. See ast_strings_match for more information.
1404 *
1405 * Example:
1406 *
1407 * The following code can be significantly faster when a realtime backend is in use
1408 * because the expression "qualify_frequency > 0" is passed to the database to limit
1409 * the number of rows returned.
1410 *
1411 * struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", "");
1412 * struct ao2_container *aors;
1413 *
1414 * if (!var) {
1415 * return;
1416 * }
1417 *
1418 * aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
1419 * "aor", AST_RETRIEVE_FLAG_MULTIPLE, var);
1420 *
1421 */
1422void *ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields);
1423
1424/*!
1425 * \brief Retrieve multiple objects using a regular expression on their id
1426 *
1427 * \param sorcery Pointer to a sorcery structure
1428 * \param type Type of object to retrieve
1429 * \param regex Regular expression
1430 *
1431 * \retval non-NULL if error occurs
1432 * \retval NULL success
1433 *
1434 * \note The provided regex is treated as extended case sensitive.
1435 */
1436struct ao2_container *ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex);
1437
1438/*!
1439 * \brief Retrieve multiple objects whose id begins with the specified prefix
1440 * \since 13.19.0
1441 *
1442 * \param sorcery Pointer to a sorcery structure
1443 * \param type Type of object to retrieve
1444 * \param prefix Object id prefix
1445 * \param prefix_len The length of prefix in bytes
1446 *
1447 * \retval non-NULL if error occurs
1448 * \retval NULL success
1449 *
1450 * \note The prefix is matched in a case sensitive manner.
1451 */
1452struct ao2_container *ast_sorcery_retrieve_by_prefix(const struct ast_sorcery *sorcery, const char *type, const char *prefix, const size_t prefix_len);
1453
1454/*!
1455 * \brief Update an object
1456 *
1457 * \param sorcery Pointer to a sorcery structure
1458 * \param object Pointer to a sorcery object
1459 *
1460 * \retval 0 success
1461 * \retval -1 failure
1462 */
1463int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object);
1464
1465/*!
1466 * \brief Delete an object
1467 *
1468 * \param sorcery Pointer to a sorcery structure
1469 * \param object Pointer to a sorcery object
1470 *
1471 * \retval 0 success
1472 * \retval -1 failure
1473 */
1474int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object);
1475
1476/*!
1477 * \brief Determine if a sorcery object is stale with respect to its backing datastore
1478 * \since 14.0.0
1479 *
1480 * This function will query the wizard(s) backing the particular sorcery object to
1481 * determine if the in-memory object is now stale. No action is taken to update
1482 * the object. Callers of this function may use one of the ast_sorcery_retrieve
1483 * functions to obtain a new instance of the object if desired.
1484 *
1485 * \retval 0 the object is not stale
1486 * \retval 1 the object is stale
1487 */
1488int ast_sorcery_is_stale(const struct ast_sorcery *sorcery, void *object);
1489
1490/*!
1491 * \brief Decrease the reference count of a sorcery structure
1492 *
1493 * \param sorcery Pointer to a sorcery structure
1494 *
1495 * \note Prior to 16.0.0 this was a function which had to be used.
1496 * Now you can use any variant of ao2_cleanup or ao2_ref to
1497 * release a reference.
1498 */
1499#define ast_sorcery_unref(sorcery) \
1500 ao2_cleanup(sorcery)
1501
1502/*!
1503 * \brief Get the unique identifier of a sorcery object
1504 *
1505 * \param object Pointer to a sorcery object
1506 *
1507 * \return unique identifier
1508 */
1509const char *ast_sorcery_object_get_id(const void *object);
1510
1511/*!
1512 * \since 14.0.0
1513 * \brief Get when the sorcery object was created
1514 *
1515 * \param object Pointer to a sorcery object
1516 *
1517 * \return The time when the object was created
1518 */
1519const struct timeval ast_sorcery_object_get_created(const void *object);
1520
1521/*!
1522 * \brief Get the type of a sorcery object
1523 *
1524 * \param object Pointer to a sorcery object
1525 *
1526 * \return type of object
1527 */
1528const char *ast_sorcery_object_get_type(const void *object);
1529
1530/*!
1531 * \brief Get an extended field value from a sorcery object
1532 *
1533 * \param object Pointer to a sorcery object
1534 * \param name Name of the extended field value
1535 *
1536 * \retval non-NULL if found
1537 * \retval NULL if not found
1538 *
1539 * \note The returned string does NOT need to be freed and is guaranteed to remain valid for the lifetime of the object
1540 */
1541const char *ast_sorcery_object_get_extended(const void *object, const char *name);
1542
1543/*!
1544 * \brief Set an extended field value on a sorcery object
1545 *
1546 * \param object Pointer to a sorcery object
1547 * \param name Name of the extended field
1548 * \param value Value of the extended field
1549 *
1550 * \retval 0 success
1551 * \retval -1 failure
1552 *
1553 * \note The field name MUST begin with '@' to indicate it is an extended field.
1554 * \note If the extended field already exists it will be overwritten with the new value.
1555 */
1556int ast_sorcery_object_set_extended(const void *object, const char *name, const char *value);
1557
1558/*!
1559 * \brief Get whether an object contains dynamic contents or not
1560 *
1561 * \param object Pointer to a sorcery object
1562 *
1563 * \since 19
1564 * \since 18.3.0
1565 * \since 16.17.0
1566 */
1567unsigned int ast_sorcery_object_has_dynamic_contents(const void *object);
1568
1569/*!
1570 * \brief Set the dynamic contents flag on a sorcery object
1571 *
1572 * \param object Pointer to a sorcery object
1573 *
1574 * \since 19
1575 * \since 18.3.0
1576 * \since 16.17.0
1577 */
1578void ast_sorcery_object_set_has_dynamic_contents(const void *object);
1579
1580/*!
1581 * \brief ao2 object comparator based on sorcery id.
1582 */
1583int ast_sorcery_object_id_compare(void *obj, void *arg, int flags);
1584
1585/*!
1586 * \brief ao2 object sorter based on sorcery id.
1587 */
1588int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags);
1589
1590/*!
1591 * \brief ao2 object hasher based on sorcery id.
1592 */
1593int ast_sorcery_object_id_hash(const void *obj, int flags);
1594
1595/*!
1596 * \brief Get the sorcery object type given a type name.
1597 *
1598 * \param sorcery The sorcery from which to retrieve the object type
1599 * \param type The type name
1600 */
1602 const char *type);
1603
1604/*!
1605 * \brief Determine if a particular object field has been registered with sorcery
1606 *
1607 * \param object_type The object type to check against
1608 * \param field_name The name of the field to check
1609 *
1610 * \retval 0 The field is not registered for this sorcery type
1611 * \retval 1 The field is registered for this sorcery type
1612 */
1614 const char *field_name);
1615
1616/*!
1617 * \brief Get the module that has opened the provided sorcery instance.
1618 *
1619 * \param sorcery The sorcery instance
1620 *
1621 * \return The module
1622 */
1623const char *ast_sorcery_get_module(const struct ast_sorcery *sorcery);
1624
1625/**
1626 * \brief Global control for optional update->create fallback in backends.
1627 *
1628 * When non-zero, writable Sorcery backends may attempt to call create()
1629 * if update() indicates the object is missing (e.g., 0 rows affected or
1630 * NOT_FOUND). This helps re-populate backends that temporarily missed an
1631 * insert.
1632 *
1633 * Default is 0 (off) to maintain legacy behavior.
1634 *
1635 * Configured via sorcery.conf:
1636 * [general]
1637 * update_or_create_on_update_miss = yes|no
1638 *
1639 * NOTE: Backends MUST gate their fallback logic on this variable.
1640 */
1642
1643/*!
1644 * \section AstSorceryConvenienceMacros Simple Sorcery Convenience Macros
1645 *
1646 * For simple scenarios, the following macros can be used to register
1647 * common object fields. The only requirement is that your source code's
1648 * definition of it's sorcery handle be named "sorcery".
1649 *
1650 * Example structure:
1651 * \code
1652 * struct my_sorcery_object {
1653 * SORCERY_OBJECT(details);
1654 * AST_DECLARE_STRING_FIELDS(
1655 * AST_STRING_FIELD(mystring);
1656 * );
1657 * enum some_enum_type myenum;
1658 * int myint;
1659 * unsigned int myuint;
1660 * int mybool;
1661 * };
1662 * \endcode
1663 *
1664 * Example object type registration:
1665 * \code
1666 * ast_sorcery_object_register(sorcery, "myobject", ...);
1667 * \endcode
1668 */
1669
1670/*!
1671 * \brief Register a boolean field as type OPT_YESNO_T within an object.
1672 * \param object The unquoted object type.
1673 * \param structure The unquoted name of the structure that contains the field
1674 * without the "struct" prefix.
1675 * \param option The unquoted name of the option as it appears in the config file.
1676 * \param field The unquoted name of the field in the structure.
1677 * \param def_value The quoted default value of the field. Should be "yes" or "no"
1678 *
1679 * \code
1680 * ast_sorcery_register_bool(myobject, my_sorcery_object, mybool, mybool, "yes");
1681 * \endcode
1682 */
1683#define ast_sorcery_register_bool(object, structure, option, field, def_value) \
1684 ast_sorcery_object_field_register(sorcery, #object, #option, \
1685 def_value, OPT_YESNO_T, 1, \
1686 FLDSET(struct structure, field))
1687
1688/*!
1689 * \internal
1690 * \brief Stringify a value.
1691 *
1692 * Needed because the preprocessor doesn't evaluate macros before it stringifies them.
1693 */
1694#define _sorcery_stringify(val) #val
1695
1696/*!
1697 * \brief Register an int field as type OPT_INT_T within an object.
1698 * \param object The unquoted object type.
1699 * \param structure The unquoted name of the structure that contains the field
1700 * without the "struct" prefix.
1701 * \param option The unquoted name of the option as it appears in the config file.
1702 * \param field The unquoted name of the field in the structure.
1703 * \param def_value The unquoted default value of the field.
1704 *
1705 * \code
1706 * ast_sorcery_register_int(myobject, my_sorcery_object, myint, myint, -32);
1707 * \endcode
1708 */
1709#define ast_sorcery_register_int(object, structure, option, field, def_value) \
1710 ast_sorcery_object_field_register(sorcery, #object, #option, \
1711 _sorcery_stringify(def_value), OPT_INT_T, PARSE_IN_RANGE, \
1712 FLDSET(struct structure, field), INT_MIN, INT_MAX)
1713
1714/*!
1715 * \brief Register an unsigned int field as type OPT_UINT_T within an object.
1716 * \param object The unquoted object type.
1717 * \param structure The unquoted name of the structure that contains the field
1718 * without the "struct" prefix.
1719 * \param option The unquoted name of the option as it appears in the config file.
1720 * \param field The unquoted name of the field in the structure.
1721 * \param def_value The unquoted default value of the field.
1722 *
1723 * \code
1724 * ast_sorcery_register_uint(myobject, my_sorcery_object, myint, myint, 32);
1725 * \endcode
1726 */
1727#define ast_sorcery_register_uint(object, structure, option, field, def_value) \
1728 ast_sorcery_object_field_register(sorcery, #object, #option, \
1729 _stringify(def_value), OPT_UINT_T, PARSE_IN_RANGE, \
1730 FLDSET(struct structure, field), 0, UINT_MAX)
1731
1732/*!
1733 * \brief Register a stringfield field as type OPT_STRINGFIELD_T within an object.
1734 * \param object The unquoted object type.
1735 * \param structure The unquoted name of the structure that contains the field
1736 * without the "struct" prefix.
1737 * \param option The unquoted name of the option as it appears in the config file.
1738 * \param field The unquoted name of the field in the structure.
1739 * \param def_value The quoted default value of the field.
1740 *
1741 * \code
1742 * ast_sorcery_register_sf(myobject, my_sorcery_object, mystring, mystring, "");
1743 * \endcode
1744 */
1745#define ast_sorcery_register_sf(object, structure, option, field, def_value) \
1746 ast_sorcery_object_field_register(sorcery, #object, #option, \
1747 def_value, OPT_STRINGFIELD_T, 0, \
1748 STRFLDSET(struct structure, field))
1749
1750/*!
1751 * \brief Register a custom field within an object.
1752 * \param object The unquoted object type.
1753 * \param structure The unquoted name of the structure that contains the field
1754 * without the "struct" prefix.
1755 * \param option The unquoted name of the option as it appears in the config file.
1756 *
1757 * \code
1758 * ast_sorcery_register_cust(myobject, my_sorcery_object, mystring);
1759 * \endcode
1760 *
1761 * \note
1762 * You must have defined the following standard sorcery custom handler functions:
1763 * \li myobject_mystring_from_str(const struct aco_option *opt, struct ast_variable *var, void *obj)
1764 * \li myobject_mystring_to_str(const void *obj, const intptr_t *args, char **buf)
1765 */
1766#define ast_sorcery_register_cust(object, option, def_value) \
1767 ast_sorcery_object_field_register_custom(sorcery, #object, #option, \
1768 def_value, object ## _ ## option ## _from_str, \
1769 object ## _ ## option ## _to_str, NULL, 0, 0)
1770
1771
1772#if defined(__cplusplus) || defined(c_plusplus)
1773}
1774#endif
1775
1776#endif /* _ASTERISK_SORCERY_H */
static int copy(char *infile, char *outfile)
Utility function to copy a file.
void(* ao2_destructor_fn)(void *vdoomed)
Typedef for an object destructor.
Definition astobj2.h:358
static const char type[]
int(* aco_option_handler)(const struct aco_option *opt, struct ast_variable *var, void *obj)
A callback function for handling a particular option.
aco_option_type
The option types.
void *(* aco_type_item_alloc)(const char *category)
Allocate a configurable ao2 object.
static const char name[]
Definition format_mp3.c:68
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
static char prefix[MAX_PREFIX]
Definition http.c:144
static struct ast_sorcery * sorcery
struct @506 callbacks
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
Definition sorcery.c:2399
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
Definition sorcery.c:2487
int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
Register a regex for multiple fields within an object.
Definition sorcery.c:1224
int ast_sorcery_object_set_extended(const void *object, const char *name, const char *value)
Set an extended field value on a sorcery object.
Definition sorcery.c:2413
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
Definition sorcery.c:601
struct ast_variable *(* sorcery_transform_handler)(struct ast_variable *set)
A callback function for performing a transformation on an object set.
Definition sorcery.h:181
void ast_sorcery_load(const struct ast_sorcery *sorcery)
Inform any wizards to load persistent objects.
Definition sorcery.c:1441
void ast_sorcery_wizard_observer_remove(struct ast_sorcery_wizard *interface, const struct ast_sorcery_wizard_observer *callbacks)
Remove an observer from a sorcery wizard.
Definition sorcery.c:632
const char * ast_sorcery_get_module(const struct ast_sorcery *sorcery)
Get the module that has opened the provided sorcery instance.
Definition sorcery.c:2600
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition sorcery.c:2393
int ast_sorcery_update_or_create_on_update_miss
Global control for optional update->create fallback in backends.
Definition sorcery.c:288
int(* sorcery_fields_handler)(const void *obj, struct ast_variable **fields)
A callback function for translating multiple values into an ast_variable list.
Definition sorcery.h:169
void ast_sorcery_object_set_copy_handler(struct ast_sorcery *sorcery, const char *type, sorcery_copy_handler copy)
Set the copy handler for an object type.
Definition sorcery.c:1192
void ast_sorcery_object_set_has_dynamic_contents(const void *object)
Set the dynamic contents flag on a sorcery object.
Definition sorcery.c:2448
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
Definition sorcery.c:2126
struct ast_sorcery_object_type * ast_sorcery_get_object_type(const struct ast_sorcery *sorcery, const char *type)
Get the sorcery object type given a type name.
Definition sorcery.c:2558
int ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes)
Create a changeset of two objects.
Definition sorcery.c:1869
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition sorcery.c:1917
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
Definition sorcery.c:1472
int ast_sorcery_get_wizard_mapping_count(struct ast_sorcery *sorcery, const char *type)
Return the number of wizards mapped to an object type.
Definition sorcery.c:842
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
Definition sorcery.c:2018
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
Definition sorcery.c:2455
enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching, int position)
Insert an additional object wizard mapping at a specific position in the wizard list.
Definition sorcery.c:1031
void ast_sorcery_force_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects, even if no changes determined.
Definition sorcery.c:1489
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
Definition sorcery.c:1457
int(* sorcery_apply_handler)(const struct ast_sorcery *sorcery, void *obj)
A callback function for when an object set is successfully applied to an object.
Definition sorcery.h:194
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition sorcery.c:1792
int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type)
Unregister an object type.
Definition sorcery.c:1125
int __ast_sorcery_remove_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name)
Remove an object wizard mapping.
Definition sorcery.c:914
int(* sorcery_diff_handler)(const void *original, const void *modified, struct ast_variable **changes)
A callback function for generating a changeset between two objects.
Definition sorcery.h:217
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition sorcery.c:2528
int(* sorcery_copy_handler)(const void *src, void *dst)
A callback function for copying the contents of one object to another.
Definition sorcery.h:205
unsigned int ast_sorcery_object_has_dynamic_contents(const void *object)
Get whether an object contains dynamic contents or not.
Definition sorcery.c:2441
void ast_sorcery_ref(struct ast_sorcery *sorcery)
Increase the reference count of a sorcery structure.
Definition sorcery.c:1537
int __ast_sorcery_object_field_register(struct ast_sorcery *sorcery, const char *type, const char *name, const char *default_val, enum aco_option_type opt_type, aco_option_handler config_handler, sorcery_field_handler sorcery_handler, sorcery_fields_handler multiple_handler, unsigned int flags, unsigned int no_doc, unsigned int alias, size_t argc,...)
Register a field within an object.
Definition sorcery.c:1256
int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply)
Register an object type.
Definition sorcery.c:1144
int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
Create a changeset given two object sets.
Definition sorcery.c:1727
@ AST_SORCERY_WIZARD_POSITION_FIRST
Definition sorcery.h:519
@ AST_SORCERY_WIZARD_POSITION_LAST
Definition sorcery.h:518
int ast_sorcery_is_object_field_registered(const struct ast_sorcery_object_type *object_type, const char *field_name)
Determine if a particular object field has been registered with sorcery.
Definition sorcery.c:2578
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition sorcery.c:1808
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition sorcery.c:2504
const struct timeval ast_sorcery_object_get_created(const void *object)
Get when the sorcery object was created.
Definition sorcery.c:2387
void * ast_sorcery_lockable_alloc(size_t size, ao2_destructor_fn destructor, void *lockobj)
Allocate a generic sorcery capable object with locking.
Definition sorcery.c:1776
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
Definition sorcery.c:2214
int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
Apply an object set (KVP list) to an object.
Definition sorcery.c:1696
int ast_sorcery_get_wizard_mapping(struct ast_sorcery *sorcery, const char *type, int index, struct ast_sorcery_wizard **wizard, void **data)
By index, return a wizard mapped to an object type.
Definition sorcery.c:854
ast_sorcery_field_handler_flags
Field handler flags.
Definition sorcery.h:129
void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects even if no changes determin...
Definition sorcery.c:1521
int(* sorcery_field_handler)(const void *obj, const intptr_t *args, char **buf)
A callback function for translating a value into a string.
Definition sorcery.h:158
int __ast_sorcery_object_type_remove_wizard(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args)
Remove an object wizard mapping.
Definition sorcery.c:884
int ast_sorcery_wizard_observer_add(struct ast_sorcery_wizard *wizard, const struct ast_sorcery_wizard_observer *callbacks)
Add an observer to a sorcery wizard.
Definition sorcery.c:607
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks)
Remove a global observer from sorcery.
Definition sorcery.c:578
struct ast_json * ast_sorcery_objectset_json_create(const struct ast_sorcery *sorcery, const void *object)
Create an object set in JSON format for an object.
Definition sorcery.c:1629
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
Definition sorcery.c:562
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
Definition sorcery.c:1506
struct ast_variable * ast_sorcery_objectset_create2(const struct ast_sorcery *sorcery, const void *object, enum ast_sorcery_field_handler_flags flags)
Create an object set (KVP list) for an object.
Definition sorcery.c:1575
int ast_sorcery_is_stale(const struct ast_sorcery *sorcery, void *object)
Determine if a sorcery object is stale with respect to its backing datastore.
Definition sorcery.c:2352
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
Definition sorcery.c:584
int ast_sorcery_object_id_hash(const void *obj, int flags)
ao2 object hasher based on sorcery id.
Definition sorcery.c:2539
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition sorcery.c:1961
int ast_sorcery_object_set_congestion_levels(struct ast_sorcery *sorcery, const char *type, long low_water, long high_water)
Set the high and low alert water marks of the sorcery object type.
Definition sorcery.c:1178
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
Definition sorcery.c:2302
void * ast_sorcery_copy(const struct ast_sorcery *sorcery, const void *object)
Create a copy of an object.
Definition sorcery.c:1842
ast_sorcery_wizard_apply_flags
Wizard Apply Flags.
Definition sorcery.h:575
@ AST_SORCERY_WIZARD_APPLY_NONE
Definition sorcery.h:577
@ AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE
Definition sorcery.h:583
@ AST_SORCERY_WIZARD_APPLY_READONLY
Definition sorcery.h:581
@ AST_SORCERY_WIZARD_APPLY_CACHING
Definition sorcery.h:579
struct ao2_container * ast_sorcery_retrieve_by_prefix(const struct ast_sorcery *sorcery, const char *type, const char *prefix, const size_t prefix_len)
Retrieve multiple objects whose id begins with the specified prefix.
Definition sorcery.c:2053
enum ast_sorcery_apply_result __ast_sorcery_object_type_insert_wizard(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, enum ast_sorcery_wizard_apply_flags flags, int position, struct ast_sorcery_wizard **wizard, void **wizard_data)
Insert an additional object wizard mapping at a specific position in the wizard list returning wizard...
Definition sorcery.c:933
ast_sorcery_apply_result
Definition sorcery.h:423
void ast_sorcery_object_set_diff_handler(struct ast_sorcery *sorcery, const char *type, sorcery_diff_handler diff)
Set the diff handler for an object type.
Definition sorcery.c:1203
Generic container type.
Abstract JSON element (object, array, string, int, ...).
Interface for the global sorcery observer.
Definition sorcery.h:220
Interface for the sorcery instance observer.
Definition sorcery.h:237
Structure for registered object type.
Definition sorcery.c:149
Interface for a sorcery object type observer.
Definition sorcery.h:332
Interface for the sorcery wizard observer.
Definition sorcery.h:265
Interface for a sorcery wizard.
Definition sorcery.h:276
Full structure for sorcery.
Definition sorcery.c:231
Structure for variables, used for configurations and for channel variables.
int value
Definition syslog.c:37

◆ ast_sorcery_apply_default

#define ast_sorcery_apply_default (   sorcery,
  type,
  name,
  data 
)     __ast_sorcery_apply_default((sorcery), (type), AST_MODULE, (name), (data))

Definition at line 476 of file sorcery.h.

◆ ast_sorcery_apply_wizard_mapping

#define ast_sorcery_apply_wizard_mapping (   sorcery,
  type,
  name,
  data,
  caching 
)     __ast_sorcery_apply_wizard_mapping((sorcery), (type), AST_MODULE, (name), (data), (caching));

Apply additional object wizard mappings.

Parameters
sorceryPointer to a sorcery structure
typeType of object to apply to
nameName of the wizard to use
dataData to be passed to wizard
cachingWizard should cache
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings

Definition at line 510 of file sorcery.h.

◆ ast_sorcery_insert_wizard_mapping

#define ast_sorcery_insert_wizard_mapping (   sorcery,
  type,
  name,
  data,
  caching,
  position 
)
Value:
(caching), (position))
#define AST_MODULE

Insert an additional object wizard mapping at a specific position in the wizard list.

Parameters
sorceryPointer to a sorcery structure
typeType of object to apply to
nameName of the wizard to use
dataData to be passed to wizard
cachingWizard should cache
positionOne of ast_sorcery_wizard_position
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings
Since
13.4.0

Definition at line 562 of file sorcery.h.

◆ ast_sorcery_internal_object_register

#define ast_sorcery_internal_object_register (   sorcery,
  type,
  alloc,
  transform,
  apply 
)     __ast_sorcery_object_register((sorcery), (type), 1, 1, (alloc), (transform), (apply))

Register an internal, hidden object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
allocRequired object allocation callback
transformOptional transformation callback
applyOptional object set apply callback
Return values
0success
-1failure

Definition at line 867 of file sorcery.h.

◆ ast_sorcery_object_field_register

#define ast_sorcery_object_field_register (   sorcery,
  type,
  name,
  default_val,
  opt_type,
  flags,
  ... 
)     __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 0, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__)

Register a field within an object.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
opt_typeOption type
flagsOption type specific flags
Return values
0success
-1failure

Definition at line 955 of file sorcery.h.

◆ ast_sorcery_object_field_register_alias

#define ast_sorcery_object_field_register_alias (   sorcery,
  type,
  name,
  default_val,
  opt_type,
  flags,
  ... 
)     __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 1, 1, VA_NARGS(__VA_ARGS__), __VA_ARGS__)

Register a field within an object as an alias.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
opt_typeOption type
flagsOption type specific flags
Return values
0success
-1failure

Definition at line 971 of file sorcery.h.

◆ ast_sorcery_object_field_register_custom

#define ast_sorcery_object_field_register_custom (   sorcery,
  type,
  name,
  default_val,
  config_handler,
  sorcery_handler,
  multiple_handler,
  flags,
  ... 
)     __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 0, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__);

Register a field within an object with custom handlers.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
config_handlerCustom configuration handler
sorcery_handlerCustom sorcery handler
multiple_handlerCustom multiple handler
flagsOption type specific flags
Return values
0success
-1failure

Definition at line 1005 of file sorcery.h.

◆ ast_sorcery_object_field_register_custom_alias

#define ast_sorcery_object_field_register_custom_alias (   sorcery,
  type,
  name,
  default_val,
  config_handler,
  sorcery_handler,
  multiple_handler,
  flags,
  ... 
)     __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 1, 1, VA_NARGS(__VA_ARGS__), __VA_ARGS__);

Register a field within an object with custom handlers as an alias.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
config_handlerCustom configuration handler
sorcery_handlerCustom sorcery handler
multiple_handlerCustom multiple handler
flagsOption type specific flags
Return values
0success
-1failure

Definition at line 1023 of file sorcery.h.

◆ ast_sorcery_object_field_register_custom_nodoc

#define ast_sorcery_object_field_register_custom_nodoc (   sorcery,
  type,
  name,
  default_val,
  config_handler,
  sorcery_handler,
  multiple_handler,
  flags,
  ... 
)     __ast_sorcery_object_field_register(sorcery, type, name, default_val, OPT_CUSTOM_T, config_handler, sorcery_handler, multiple_handler, flags, 1, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__);

Register a field within an object with custom handlers without documentation.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
config_handlerCustom configuration handler
sorcery_handlerCustom sorcery handler
multiple_handlerCustom multiple handler
flagsOption type specific flags
Return values
0success
-1failure

Definition at line 1041 of file sorcery.h.

◆ ast_sorcery_object_field_register_nodoc

#define ast_sorcery_object_field_register_nodoc (   sorcery,
  type,
  name,
  default_val,
  opt_type,
  flags,
  ... 
)     __ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, NULL, NULL, NULL, flags, 1, 0, VA_NARGS(__VA_ARGS__), __VA_ARGS__)

Register a field within an object without documentation.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
opt_typeOption type
flagsOption type specific flags
Return values
0success
-1failure

Definition at line 987 of file sorcery.h.

◆ ast_sorcery_object_register

#define ast_sorcery_object_register (   sorcery,
  type,
  alloc,
  transform,
  apply 
)     __ast_sorcery_object_register((sorcery), (type), 0, 1, (alloc), (transform), (apply))

Register an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
allocRequired object allocation callback
transformOptional transformation callback
applyOptional object set apply callback
Return values
0success
-1failure

Definition at line 837 of file sorcery.h.

◆ ast_sorcery_object_register_no_reload

#define ast_sorcery_object_register_no_reload (   sorcery,
  type,
  alloc,
  transform,
  apply 
)     __ast_sorcery_object_register((sorcery), (type), 0, 0, (alloc), (transform), (apply))

Register an object type that is not reloadable.

Parameters
sorceryPointer to a sorcery structure
typeType of object
allocRequired object allocation callback
transformOptional transformation callback
applyOptional object set apply callback
Return values
0success
-1failure

Definition at line 852 of file sorcery.h.

◆ ast_sorcery_object_type_apply_wizard

#define ast_sorcery_object_type_apply_wizard (   sorcery,
  object_type_name,
  wizard_type_name,
  wizard_args,
  flags,
  wizard,
  wizard_data 
)
Value:
(object_type_name), AST_MODULE, (wizard_type_name), (wizard_args), (flags), \
AST_SORCERY_WIZARD_POSITION_LAST, (wizard), (wizard_data))

Apply additional object wizard mappings returning wizard information.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to apply to
wizard_type_nameName of the wizard type to use
wizard_argsOpaque string to be passed to the wizard May be NULL but see note below
flagsOne or more of enum ast_sorcery_wizard_apply_flags
[out]wizardA variable to receive a pointer to the ast_sorcery_wizard structure. May be NULL if not needed.
[out]wizard_dataA variable to receive a pointer to the wizard's internal data. May be NULL if not needed.
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings
Although wizard_args is an optional parameter it is highly recommended to supply one. If you use the AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE flag, and you intend to ever remove a wizard mapping, you'll need wizard_args to remove specific instances.

Definition at line 678 of file sorcery.h.

◆ ast_sorcery_object_type_insert_wizard

#define ast_sorcery_object_type_insert_wizard (   sorcery,
  object_type_name,
  wizard_type_name,
  wizard_args,
  flags,
  position,
  wizard,
  wizard_data 
)
Value:
(object_type_name), AST_MODULE, (wizard_type_name), (wizard_args), (flags), \
position, (wizard), (wizard_data))

Insert an additional object wizard mapping at a specific position in the wizard list returning wizard information.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to apply to
wizard_type_nameName of the wizard type to use
wizard_argsOpaque string to be passed to the wizard May be NULL but see note below
flagsOne or more of enum ast_sorcery_wizard_apply_flags
positionAn index to insert to or one of ast_sorcery_wizard_position
[out]wizardA variable to receive a pointer to the ast_sorcery_wizard structure. May be NULL if not needed.
[out]wizard_dataA variable to receive a pointer to the wizard's internal data. May be NULL if not needed.
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings
Although wizard_args is an optional parameter it is highly recommended to supply one. If you use the AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE flag, and you intend to ever remove a wizard mapping, you'll need wizard_args to remove specific instances.

Definition at line 646 of file sorcery.h.

◆ ast_sorcery_object_type_remove_wizard

#define ast_sorcery_object_type_remove_wizard (   sorcery,
  object_type_name,
  wizard_type_name,
  wizard_args 
)
Value:
AST_MODULE, (wizard_type_name), (wizard_args))

Remove an object wizard mapping.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to remove from
wizard_type_nameThe name of the of the wizard type to remove
wizard_argsOpaque string originally passed to the wizard
Return values
0success
-1failure
Note
If there were multiple instances of the same wizard type added to this object type without using wizard_args, then only the first wizard matching wizard_type will be removed.

Definition at line 724 of file sorcery.h.

◆ ast_sorcery_objectset_create

#define ast_sorcery_objectset_create (   sorcery,
  object 
)     ast_sorcery_objectset_create2(sorcery, object, AST_HANDLER_PREFER_LIST)

Create an object set (KVP list) for an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
non-NULLsuccess
NULLif error occurred
Note
The returned ast_variable list must be destroyed using ast_variables_destroy
This function attempts to use a field's sorcery_fields_handler first and if that doesn't exist or fails, a field's sorcery_field_handler is used. The difference is that the former may return multiple list entries for the same field and the latter will only return 1. It's up to the field itself to determine what the appropriate content is.

Definition at line 1137 of file sorcery.h.

◆ ast_sorcery_open

#define ast_sorcery_open ( )    __ast_sorcery_open(AST_MODULE, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Open a new sorcery structure.

Parameters
moduleThe module name (AST_MODULE)

When called, this will automatically also call __ast_sorcery_apply_config() with the module name as the configuration section.

Return values
non-NULLsuccess
NULLif allocation failed

Definition at line 406 of file sorcery.h.

◆ ast_sorcery_register_bool

#define ast_sorcery_register_bool (   object,
  structure,
  option,
  field,
  def_value 
)
Value:
def_value, OPT_YESNO_T, 1, \
FLDSET(struct structure, field))
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_YESNO_T
Type for default option handler for bools (ast_true/ast_false)
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition sorcery.h:955

Register a boolean field as type OPT_YESNO_T within an object.

Simple Sorcery Convenience Macros

For simple scenarios, the following macros can be used to register common object fields. The only requirement is that your source code's definition of it's sorcery handle be named "sorcery".

Example structure:

struct my_sorcery_object {
SORCERY_OBJECT(details);
AST_STRING_FIELD(mystring);
);
enum some_enum_type myenum;
int myint;
unsigned int myuint;
int mybool;
};
#define SORCERY_OBJECT(details)
Macro which must be used at the beginning of each sorcery capable object.
Definition sorcery.h:356
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define AST_STRING_FIELD(name)
Declare a string field.

Example object type registration:

#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition sorcery.h:837
Parameters
objectThe unquoted object type.
structureThe unquoted name of the structure that contains the field without the "struct" prefix.
optionThe unquoted name of the option as it appears in the config file.
fieldThe unquoted name of the field in the structure.
def_valueThe quoted default value of the field. Should be "yes" or "no"
ast_sorcery_register_bool(myobject, my_sorcery_object, mybool, mybool, "yes");
#define ast_sorcery_register_bool(object, structure, option, field, def_value)
Register a boolean field as type OPT_YESNO_T within an object.
Definition sorcery.h:1684

Definition at line 1684 of file sorcery.h.

◆ ast_sorcery_register_cust

#define ast_sorcery_register_cust (   object,
  option,
  def_value 
)
Value:
def_value, object ## _ ## option ## _from_str, \
object ## _ ## option ## _to_str, NULL, 0, 0)
#define _(msgid)
#define NULL
Definition resample.c:96
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
Definition sorcery.h:1005

Register a custom field within an object.

Parameters
objectThe unquoted object type.
structureThe unquoted name of the structure that contains the field without the "struct" prefix.
optionThe unquoted name of the option as it appears in the config file.
ast_sorcery_register_cust(myobject, my_sorcery_object, mystring);
#define ast_sorcery_register_cust(object, option, def_value)
Register a custom field within an object.
Definition sorcery.h:1767
Note
You must have defined the following standard sorcery custom handler functions:
  • myobject_mystring_from_str(const struct aco_option *opt, struct ast_variable *var, void *obj)
  • myobject_mystring_to_str(const void *obj, const intptr_t *args, char **buf)

Definition at line 1767 of file sorcery.h.

◆ ast_sorcery_register_int

#define ast_sorcery_register_int (   object,
  structure,
  option,
  field,
  def_value 
)
Value:
FLDSET(struct structure, field), INT_MIN, INT_MAX)
@ OPT_INT_T
Type for default option handler for signed integers.
#define _sorcery_stringify(val)
Definition sorcery.h:1695

Register an int field as type OPT_INT_T within an object.

Parameters
objectThe unquoted object type.
structureThe unquoted name of the structure that contains the field without the "struct" prefix.
optionThe unquoted name of the option as it appears in the config file.
fieldThe unquoted name of the field in the structure.
def_valueThe unquoted default value of the field.
ast_sorcery_register_int(myobject, my_sorcery_object, myint, myint, -32);
#define ast_sorcery_register_int(object, structure, option, field, def_value)
Register an int field as type OPT_INT_T within an object.
Definition sorcery.h:1710

Definition at line 1710 of file sorcery.h.

◆ ast_sorcery_register_sf

#define ast_sorcery_register_sf (   object,
  structure,
  option,
  field,
  def_value 
)
Value:
def_value, OPT_STRINGFIELD_T, 0, \
STRFLDSET(struct structure, field))
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.

Register a stringfield field as type OPT_STRINGFIELD_T within an object.

Parameters
objectThe unquoted object type.
structureThe unquoted name of the structure that contains the field without the "struct" prefix.
optionThe unquoted name of the option as it appears in the config file.
fieldThe unquoted name of the field in the structure.
def_valueThe quoted default value of the field.
ast_sorcery_register_sf(myobject, my_sorcery_object, mystring, mystring, "");
#define ast_sorcery_register_sf(object, structure, option, field, def_value)
Register a stringfield field as type OPT_STRINGFIELD_T within an object.
Definition sorcery.h:1746

Definition at line 1746 of file sorcery.h.

◆ ast_sorcery_register_uint

#define ast_sorcery_register_uint (   object,
  structure,
  option,
  field,
  def_value 
)
Value:
_stringify(def_value), OPT_UINT_T, PARSE_IN_RANGE, \
FLDSET(struct structure, field), 0, UINT_MAX)
@ OPT_UINT_T
Type for default option handler for unsigned integers.

Register an unsigned int field as type OPT_UINT_T within an object.

Parameters
objectThe unquoted object type.
structureThe unquoted name of the structure that contains the field without the "struct" prefix.
optionThe unquoted name of the option as it appears in the config file.
fieldThe unquoted name of the field in the structure.
def_valueThe unquoted default value of the field.
ast_sorcery_register_uint(myobject, my_sorcery_object, myint, myint, 32);
#define ast_sorcery_register_uint(object, structure, option, field, def_value)
Register an unsigned int field as type OPT_UINT_T within an object.
Definition sorcery.h:1728

Definition at line 1728 of file sorcery.h.

◆ ast_sorcery_remove_wizard_mapping

#define ast_sorcery_remove_wizard_mapping (   sorcery,
  type,
  name 
)     __ast_sorcery_remove_wizard_mapping((sorcery), (type), AST_MODULE, (name))

Remove an object wizard mapping.

Parameters
sorceryPointer to a sorcery structure
typeType of object to remove from
nameThe name of the wizard to remove
Return values
0success
-1failure
Since
13.4.0

Definition at line 757 of file sorcery.h.

◆ ast_sorcery_unref

#define ast_sorcery_unref (   sorcery)     ao2_cleanup(sorcery)

Decrease the reference count of a sorcery structure.

Parameters
sorceryPointer to a sorcery structure
Note
Prior to 16.0.0 this was a function which had to be used. Now you can use any variant of ao2_cleanup or ao2_ref to release a reference.

Definition at line 1500 of file sorcery.h.

◆ ast_sorcery_wizard_register

#define ast_sorcery_wizard_register (   interface)    __ast_sorcery_wizard_register(interface, AST_MODULE_SELF)

See __ast_sorcery_wizard_register()

Definition at line 383 of file sorcery.h.

◆ MAX_OBJECT_FIELD

#define MAX_OBJECT_FIELD   128

Maximum length of an object field name.

Definition at line 110 of file sorcery.h.

◆ MAX_OBJECT_TYPE

#define MAX_OBJECT_TYPE   64

Maximum size of an object type.

Definition at line 107 of file sorcery.h.

◆ SORCERY_OBJECT

#define SORCERY_OBJECT (   details)
Value:
struct { \
struct ast_sorcery_object_details details; \
} \
Structure which contains details about a sorcery object.
Definition sorcery.h:350

Macro which must be used at the beginning of each sorcery capable object.

Definition at line 356 of file sorcery.h.

357 { \
358 struct ast_sorcery_object_details details; \
359} \
360

Typedef Documentation

◆ sorcery_apply_handler

typedef int(* sorcery_apply_handler) (const struct ast_sorcery *sorcery, void *obj)

A callback function for when an object set is successfully applied to an object.

Note
On a failure return, the state of the object is left undefined. It is a bad idea to try to use this object.
Parameters
sorcerySorcery structure in use
objThe object itself
Return values
0Success
non-zeroFailure

Definition at line 194 of file sorcery.h.

◆ sorcery_copy_handler

typedef int(* sorcery_copy_handler) (const void *src, void *dst)

A callback function for copying the contents of one object to another.

Parameters
srcThe source object
dstThe destination object
Return values
0success
-1failure

Definition at line 205 of file sorcery.h.

◆ sorcery_diff_handler

typedef int(* sorcery_diff_handler) (const void *original, const void *modified, struct ast_variable **changes)

A callback function for generating a changeset between two objects.

Parameters
originalThe original object
modifiedThe modified object
changesThe changeset
Return values
0success
-1failure

Definition at line 217 of file sorcery.h.

◆ sorcery_field_handler

typedef int(* sorcery_field_handler) (const void *obj, const intptr_t *args, char **buf)

A callback function for translating a value into a string.

Parameters
objObject to get value from
argsWhere the field is
bufPointer to the buffer that the handler has created which contains the field value
Return values
0success
-1failure

Definition at line 158 of file sorcery.h.

◆ sorcery_fields_handler

typedef int(* sorcery_fields_handler) (const void *obj, struct ast_variable **fields)

A callback function for translating multiple values into an ast_variable list.

Parameters
objObject to get values from
fieldsPointer to store the list of fields
Return values
0success
-1failure

Definition at line 169 of file sorcery.h.

◆ sorcery_transform_handler

typedef struct ast_variable *(* sorcery_transform_handler) (struct ast_variable *set)

A callback function for performing a transformation on an object set.

Parameters
setThe existing object set
Return values
non-NULLnew object set if changed
NULLif no changes present
Note
The returned ast_variable list must be new. You can not return the input set.

Definition at line 169 of file sorcery.h.

Enumeration Type Documentation

◆ ast_sorcery_apply_result

Enumerator
AST_SORCERY_APPLY_FAIL 

Sorcery wizard failed to apply.

AST_SORCERY_APPLY_SUCCESS 

Sorcery wizard applied successfully.

AST_SORCERY_APPLY_DUPLICATE 

Sorcery wizard has already been applied to the object type.

AST_SORCERY_APPLY_DEFAULT_UNNECESSARY 

Default sorcery wizard is unnecessary since a wizard has already been applied to the object type.

AST_SORCERY_APPLY_NO_CONFIGURATION 

No sorcery.conf configuration file was found to apply.

Definition at line 423 of file sorcery.h.

423 {
424 /*! Sorcery wizard failed to apply. */
426 /*! Sorcery wizard applied successfully. */
428 /*! Sorcery wizard has already been applied to the object type. */
430 /*! Default sorcery wizard is unnecessary since a wizard has already been applied to the object type. */
432 /*! No sorcery.conf configuration file was found to apply. */
434};
@ AST_SORCERY_APPLY_SUCCESS
Definition sorcery.h:427
@ AST_SORCERY_APPLY_NO_CONFIGURATION
Definition sorcery.h:433
@ AST_SORCERY_APPLY_FAIL
Definition sorcery.h:425
@ AST_SORCERY_APPLY_DUPLICATE
Definition sorcery.h:429
@ AST_SORCERY_APPLY_DEFAULT_UNNECESSARY
Definition sorcery.h:431

◆ ast_sorcery_field_handler_flags

Field handler flags.

Enumerator
AST_HANDLER_PREFER_STRING 

Try both handlers, string first.

AST_HANDLER_PREFER_LIST 

Try both handlers, list first.

AST_HANDLER_ONLY_STRING 

Use string handler only.

AST_HANDLER_ONLY_LIST 

Use list handler only.

Definition at line 129 of file sorcery.h.

129 {
130 /*! \brief Try both handlers, string first */
132
133 /*! \brief Try both handlers, list first */
135
136 /*! \brief Use string handler only */
138
139 /*! \brief Use list handler only */
141};
@ AST_HANDLER_PREFER_STRING
Try both handlers, string first.
Definition sorcery.h:131
@ AST_HANDLER_PREFER_LIST
Try both handlers, list first.
Definition sorcery.h:134
@ AST_HANDLER_ONLY_LIST
Use list handler only.
Definition sorcery.h:140
@ AST_HANDLER_ONLY_STRING
Use string handler only.
Definition sorcery.h:137

◆ ast_sorcery_retrieve_flags

Retrieval flags.

Enumerator
AST_RETRIEVE_FLAG_DEFAULT 

Default retrieval flags.

AST_RETRIEVE_FLAG_MULTIPLE 

Return all matching objects.

AST_RETRIEVE_FLAG_ALL 

Perform no matching, return all objects.

Definition at line 115 of file sorcery.h.

115 {
116 /*! \brief Default retrieval flags */
118
119 /*! \brief Return all matching objects */
121
122 /*! \brief Perform no matching, return all objects */
123 AST_RETRIEVE_FLAG_ALL = (1 << 1),
124};
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition sorcery.h:120
@ AST_RETRIEVE_FLAG_DEFAULT
Default retrieval flags.
Definition sorcery.h:117
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition sorcery.h:123

◆ ast_sorcery_wizard_apply_flags

Wizard Apply Flags.

These flags apply only to a wizard/object-type combination. The same wizard may be applied to a different object-type with different flags and behavior. If ALLOW_DUPLICATE is set the wizard could even be applied to the same object-type with different flags.

Enumerator
AST_SORCERY_WIZARD_APPLY_NONE 

Apply no special behavior

AST_SORCERY_WIZARD_APPLY_CACHING 

This wizard will cache this object type's entries

AST_SORCERY_WIZARD_APPLY_READONLY 

This wizard won't allow Create, Update or Delete operations on this object type

AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE 

This wizard will allow other instances of itself on the same object type

Definition at line 575 of file sorcery.h.

575 {
576 /*! Apply no special behavior */
578 /*! This wizard will cache this object type's entries */
580 /*! This wizard won't allow Create, Update or Delete operations on this object type */
582 /*! This wizard will allow other instances of itself on the same object type */
584};

◆ ast_sorcery_wizard_position

Pre-defined locations to insert at.

Enumerator
AST_SORCERY_WIZARD_POSITION_LAST 
AST_SORCERY_WIZARD_POSITION_FIRST 

Definition at line 517 of file sorcery.h.

Function Documentation

◆ __ast_sorcery_apply_config()

enum ast_sorcery_apply_result __ast_sorcery_apply_config ( struct ast_sorcery sorcery,
const char *  name,
const char *  module 
)

Apply configured wizard mappings.

Parameters
sorceryPointer to a sorcery structure
nameName of the category to use within the configuration file, normally the module name
moduleThe module name (AST_MODULE)

This function is called automatically by __ast_sorcery_open() using the module name as the configuration category. The only reason you should call this function is if your module wishes to apply configuration from additional sections of sorcery.conf.

If a configuration section attempts to apply the same sorcery wizard to an object type more than once, the wizard will only be applied one time.

Returns
What happened when attempting to apply the config.

Definition at line 1049 of file sorcery.c.

1050{
1051 struct ast_flags flags = { 0 };
1052 struct ast_config *config = ast_config_load2("sorcery.conf", "sorcery", flags);
1053 struct ast_variable *mapping;
1054 int res = AST_SORCERY_APPLY_SUCCESS;
1055
1056 if (!config) {
1058 }
1059
1062 }
1063
1064 for (mapping = ast_variable_browse(config, name); mapping; mapping = mapping->next) {
1065 RAII_VAR(char *, mapping_name, ast_strdup(mapping->name), ast_free);
1066 RAII_VAR(char *, mapping_value, ast_strdup(mapping->value), ast_free);
1067 char *options = mapping_name;
1068 char *type = strsep(&options, "/");
1069 char *data = mapping_value;
1070 char *wizard = strsep(&data, ",");
1071 unsigned int caching = 0;
1072
1073 /* If no object type or wizard exists just skip, nothing we can do */
1074 if (ast_strlen_zero(type) || ast_strlen_zero(wizard)) {
1075 continue;
1076 }
1077
1078 /* If the wizard is configured as a cache treat it as such */
1079 if (!ast_strlen_zero(options) && strstr(options, "cache")) {
1080 caching = 1;
1081 }
1082
1083 /* Any error immediately causes us to stop */
1084 if (__ast_sorcery_apply_wizard_mapping(sorcery, type, module, wizard, data, caching) == AST_SORCERY_APPLY_FAIL) {
1086 break;
1087 }
1088 }
1089
1091
1092 return res;
1093}
char * strsep(char **str, const char *delims)
#define ast_free(a)
Definition astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
static const char config[]
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition extconf.c:1213
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching)
Internal function which creates an object type and adds a wizard mapping.
Definition sorcery.c:1041
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
Structure used to handle boolean flags.
Definition utils.h:220
unsigned int flags
Definition utils.h:221
struct ast_variable * next
static struct test_options options
#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:981

References __ast_sorcery_apply_wizard_mapping(), ast_config_destroy(), ast_config_load2(), ast_free, AST_SORCERY_APPLY_FAIL, AST_SORCERY_APPLY_NO_CONFIGURATION, AST_SORCERY_APPLY_SUCCESS, ast_strdup, ast_strlen_zero(), ast_variable_browse(), config, CONFIG_STATUS_FILEINVALID, ast_flags::flags, name, ast_variable::name, ast_variable::next, options, RAII_VAR, sorcery, strsep(), type, and ast_variable::value.

Referenced by __ast_sorcery_open().

◆ __ast_sorcery_apply_default()

enum ast_sorcery_apply_result __ast_sorcery_apply_default ( struct ast_sorcery sorcery,
const char *  type,
const char *  module,
const char *  name,
const char *  data 
)

Apply default object wizard mappings.

Parameters
sorceryPointer to a sorcery structure
typeType of object to apply to
moduleThe name of the module, typically AST_MODULE
nameName of the wizard to use
dataData to be passed to wizard
Returns
What occurred when applying the default
Note
This should be called after applying configuration sourced mappings
Only a single default can exist per object type

Definition at line 1095 of file sorcery.c.

1096{
1098
1099 /* Defaults can not be added if any existing mapping exists */
1100 if (object_type) {
1102 }
1103
1104 return __ast_sorcery_apply_wizard_mapping(sorcery, type, module, name, data, 0);
1105}
#define OBJ_KEY
Definition astobj2.h:1151
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736
struct ao2_container * types
Container for known object types.
Definition sorcery.c:233

References __ast_sorcery_apply_wizard_mapping(), ao2_cleanup, ao2_find, AST_SORCERY_APPLY_DEFAULT_UNNECESSARY, name, OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

◆ __ast_sorcery_apply_wizard_mapping()

enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping ( struct ast_sorcery sorcery,
const char *  type,
const char *  module,
const char *  name,
const char *  data,
unsigned int  caching 
)

Apply additional object wizard mappings.

Parameters
sorceryPointer to a sorcery structure
typeType of object to apply to
moduleThe name of the module, typically AST_MODULE
nameName of the wizard to use
dataData to be passed to wizard
cachingWizard should cache
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings

Apply additional object wizard mappings.

Definition at line 1041 of file sorcery.c.

1044{
1046 data, caching, AST_SORCERY_WIZARD_POSITION_LAST);
1047}
enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching, int position)
Internal function which creates an object type and inserts a wizard mapping.
Definition sorcery.c:1031

References __ast_sorcery_insert_wizard_mapping(), AST_SORCERY_WIZARD_POSITION_LAST, ast_sorcery_object_wizard::caching, ast_sorcery_object_wizard::data, name, sorcery, and type.

Referenced by __ast_sorcery_apply_config(), and __ast_sorcery_apply_default().

◆ __ast_sorcery_insert_wizard_mapping()

enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping ( struct ast_sorcery sorcery,
const char *  type,
const char *  module,
const char *  name,
const char *  data,
unsigned int  caching,
int  position 
)

Insert an additional object wizard mapping at a specific position in the wizard list.

Parameters
sorceryPointer to a sorcery structure
typeType of object to apply to
moduleThe name of the module, typically AST_MODULE
nameName of the wizard to use
dataData to be passed to wizard
cachingWizard should cache
positionAn index to insert to or one of ast_sorcery_wizard_position
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings
Wizards can be retrieved by using ast_sorcery_get_wizard_mapping_count and iterating over them using ast_sorcery_get_wizard_mapping.
Since
13.4.0

Insert an additional object wizard mapping at a specific position in the wizard list.

Definition at line 1031 of file sorcery.c.

1034{
1037 position, NULL, NULL);
1038}
enum ast_sorcery_apply_result __ast_sorcery_object_type_insert_wizard(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, enum ast_sorcery_wizard_apply_flags flags, int position, struct ast_sorcery_wizard **wizard, void **wizard_data)
Insert an additional object wizard mapping at a specific position in the wizard list returning wizard...
Definition sorcery.c:933

References __ast_sorcery_object_type_insert_wizard(), AST_SORCERY_WIZARD_APPLY_CACHING, AST_SORCERY_WIZARD_APPLY_NONE, ast_sorcery_object_wizard::caching, ast_sorcery_object_wizard::data, name, NULL, sorcery, and type.

Referenced by __ast_sorcery_apply_wizard_mapping().

◆ __ast_sorcery_object_field_register()

int __ast_sorcery_object_field_register ( struct ast_sorcery sorcery,
const char *  type,
const char *  name,
const char *  default_val,
enum aco_option_type  opt_type,
aco_option_handler  config_handler,
sorcery_field_handler  sorcery_handler,
sorcery_fields_handler  multiple_handler,
unsigned int  flags,
unsigned int  no_doc,
unsigned int  alias,
size_t  argc,
  ... 
)

Register a field within an object.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
config_handlerA custom handler for translating the string representation of the fields
sorcery_handlerA custom handler for translating the native representation of the fields
multiple_handlerA custom handler for translating the native representation of the fields
opt_typeOption type
flagsOption type specific flags
no_docField should not be documented
aliasInterpret and apply field value only
argc
Return values
0success
-1failure

Definition at line 1256 of file sorcery.c.

1258{
1260 RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
1261 int pos;
1262 va_list args;
1263
1264 if (!strcmp(type, "id") || !object_type || !object_type->type.item_alloc) {
1265 return -1;
1266 }
1267
1268 if (!sorcery_handler) {
1269 sorcery_handler = sorcery_field_default_handler(opt_type);
1270 }
1271
1272 if (!(object_field = ao2_alloc(sizeof(*object_field) + argc * sizeof(object_field->args[0]), NULL))) {
1273 return -1;
1274 }
1275
1276 ast_copy_string(object_field->name, name, sizeof(object_field->name));
1277 object_field->handler = sorcery_handler;
1278 object_field->multiple_handler = multiple_handler;
1279
1280 va_start(args, argc);
1281 for (pos = 0; pos < argc; pos++) {
1282 object_field->args[pos] = va_arg(args, size_t);
1283 }
1284 va_end(args);
1285
1286 if (!alias) {
1287 ao2_link(object_type->fields, object_field);
1288 }
1289
1290 /* TODO: Improve this hack */
1291 if (!argc) {
1292 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc);
1293 } else if (argc == 1) {
1294 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1295 object_field->args[0]);
1296 } else if (argc == 2) {
1297 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1298 object_field->args[0], object_field->args[1]);
1299 } else if (argc == 3) {
1300 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1301 object_field->args[0], object_field->args[1], object_field->args[2]);
1302 } else {
1303 ast_assert(0); /* The hack... she does us no good for this */
1304 }
1305
1306 return 0;
1307}
#define ao2_link(container, obj)
Add an object to a container.
Definition astobj2.h:1532
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
@ ACO_EXACT
int __aco_option_register(struct aco_info *info, const char *name, enum aco_matchtype match_type, struct aco_type **types, const char *default_val, enum aco_option_type type, aco_option_handler handler, unsigned int flags, unsigned int no_doc, size_t argc,...)
register a config option
static struct @519 args
static sorcery_field_handler sorcery_field_default_handler(enum aco_option_type type)
Definition sorcery.c:345
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
Structure for registered object field.
Definition sorcery.c:206
#define ast_assert(a)
Definition utils.h:779

References __aco_option_register(), ACO_EXACT, ao2_alloc, ao2_cleanup, ao2_find, ao2_link, args, ast_assert, ast_copy_string(), ast_sorcery_object_field::multiple_handler, name, NULL, OBJ_KEY, RAII_VAR, sorcery, sorcery_field_default_handler(), type, and ast_sorcery::types.

◆ __ast_sorcery_object_register()

int __ast_sorcery_object_register ( struct ast_sorcery sorcery,
const char *  type,
unsigned int  hidden,
unsigned int  reloadable,
aco_type_item_alloc  alloc,
sorcery_transform_handler  transform,
sorcery_apply_handler  apply 
)

Register an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
hiddenAll objects of this type are internal and should not be manipulated by users
reloadableAll objects of this type are reloadable
allocRequired object allocation callback
transformOptional transformation callback
applyOptional object set apply callback
Note
In general, this function should not be used directly. One of the various macro'd versions should be used instead.
Return values
0success
-1failure

Definition at line 1144 of file sorcery.c.

1145{
1147
1148 if (!object_type || object_type->type.item_alloc) {
1149 return -1;
1150 }
1151
1152 object_type->type.name = object_type->name;
1153 object_type->type.type = ACO_ITEM;
1154 object_type->type.category = ".?";
1155 object_type->type.item_alloc = alloc;
1156 object_type->type.hidden = hidden;
1157
1158 object_type->reloadable = reloadable;
1159 object_type->transform = transform;
1160 object_type->apply = apply;
1161 object_type->file->types[0] = &object_type->type;
1162 object_type->file->types[1] = NULL;
1163
1164 if (aco_info_init(object_type->info)) {
1165 return -1;
1166 }
1167
1169 return -1;
1170 }
1171
1172 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, object_type_registered,
1174
1175 return 0;
1176}
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
@ ACO_ITEM
int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
Register a regex for multiple fields within an object.
Definition sorcery.c:1224
static int sorcery_extended_fields_handler(const void *obj, struct ast_variable **fields)
Definition sorcery.c:1112
#define NOTIFY_INSTANCE_OBSERVERS(container, callback,...)
Definition sorcery.c:80
static int sorcery_extended_config_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition sorcery.c:1107
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition sorcery.c:239
struct ao2_container * observers
Observers.
Definition sorcery.c:236

References aco_info_init(), ACO_ITEM, ao2_cleanup, ao2_find, ast_sorcery_object_type::apply, ast_sorcery_object_fields_register(), ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, NULL, OBJ_KEY, ast_sorcery::observers, RAII_VAR, ast_sorcery_object_type::reloadable, sorcery, sorcery_extended_config_handler(), sorcery_extended_fields_handler(), ast_sorcery_object_type::transform, type, and ast_sorcery::types.

◆ __ast_sorcery_object_type_insert_wizard()

enum ast_sorcery_apply_result __ast_sorcery_object_type_insert_wizard ( struct ast_sorcery sorcery,
const char *  object_type_name,
const char *  module,
const char *  wizard_type_name,
const char *  wizard_args,
enum ast_sorcery_wizard_apply_flags  flags,
int  position,
struct ast_sorcery_wizard **  wizard,
void **  wizard_data 
)

Insert an additional object wizard mapping at a specific position in the wizard list returning wizard information.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to apply to
moduleThe name of the module, typically AST_MODULE
wizard_type_nameName of the wizard type to use
wizard_argsOpaque string to be passed to the wizard May be NULL but see note below
flagsOne or more of enum ast_sorcery_wizard_apply_flags
positionAn index to insert to or one of ast_sorcery_wizard_position
[out]wizardA variable to receive a pointer to the ast_sorcery_wizard structure. May be NULL if not needed.
[out]wizard_dataA variable to receive a pointer to the wizard's internal data. May be NULL if not needed.
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings
Although wizard_args is an optional parameter it is highly recommended to supply one. If you use the AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE flag, and you intend to ever remove a wizard mapping, you'll need wizard_args to remove specific instances of a wizard type.

Definition at line 933 of file sorcery.c.

937{
938 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, object_type_name, OBJ_KEY), ao2_cleanup);
939 RAII_VAR(struct ast_sorcery_internal_wizard *, internal_wizard, ao2_find(wizards, wizard_type_name, OBJ_KEY), ao2_cleanup);
940 RAII_VAR(struct ast_sorcery_object_wizard *, object_wizard, NULL, ao2_cleanup);
941 int created = 0;
942
943 object_wizard = ao2_alloc(sizeof(*object_wizard)
944 + (ast_strlen_zero(wizard_args) ? 0 : strlen(wizard_args) + 1),
946
947 if (!object_wizard) {
949 }
950
951 if (!internal_wizard
952 || internal_wizard->callbacks.module != ast_module_running_ref(internal_wizard->callbacks.module)) {
954 "Wizard '%s' could not be applied to object type '%s' as it was not found\n",
955 wizard_type_name, object_type_name);
957 }
958
959 if (!object_type) {
960 if (!(object_type = sorcery_object_type_alloc(object_type_name, module))) {
961 ast_module_unref(internal_wizard->callbacks.module);
963 }
964 created = 1;
965 }
966
967 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
968 if (!created) {
969 struct ast_sorcery_object_wizard *found;
970
971#define WIZARD_COMPARE(a, b) ((a)->wizard == (b))
972 found = AST_VECTOR_GET_CMP(&object_type->wizards, internal_wizard, WIZARD_COMPARE);
973#undef WIZARD_COMPARE
974 if (found
976 ast_debug(1, "Wizard %s already applied to object type %s\n",
977 internal_wizard->callbacks.name, object_type->name);
978 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
979 ast_module_unref(internal_wizard->callbacks.module);
981 }
982 }
983
984 ast_debug(5, "Calling wizard %s open callback on object type %s\n",
985 wizard_type_name, object_type->name);
986 if (internal_wizard->callbacks.open && !(object_wizard->data = internal_wizard->callbacks.open(wizard_args))) {
987 ast_log(LOG_WARNING, "Wizard '%s' failed to open mapping for object type '%s' with data: %s\n",
988 wizard_type_name, object_type->name, S_OR(wizard_args, ""));
989 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
990 ast_module_unref(internal_wizard->callbacks.module);
992 }
993
994 object_wizard->wizard = ao2_bump(internal_wizard);
995 object_wizard->caching = !!(flags & AST_SORCERY_WIZARD_APPLY_CACHING);
996 object_wizard->read_only = !!(flags & AST_SORCERY_WIZARD_APPLY_READONLY);
997 if (wizard_args) {
998 strcpy(object_wizard->wizard_args, wizard_args); /* Safe */
999 }
1000
1001 if (position == AST_SORCERY_WIZARD_POSITION_LAST) {
1002 position = AST_VECTOR_SIZE(&object_type->wizards);
1003 }
1004
1005 if (AST_VECTOR_INSERT_AT(&object_type->wizards, position, object_wizard) != 0) {
1006 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1008 }
1009 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1010 ao2_bump(object_wizard);
1011
1012 if (created) {
1013 ao2_link(sorcery->types, object_type);
1014 }
1015
1017 sorcery->module_name, sorcery, object_type_name, &internal_wizard->callbacks, wizard_args,
1018 object_wizard->data);
1019
1020 if (wizard) {
1021 *wizard = &internal_wizard->callbacks;
1022 }
1023 if (wizard_data) {
1024 *wizard_data = object_wizard->data;
1025 }
1026
1028}
#define ast_log
Definition astobj2.c:42
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition astobj2.h:480
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_WARNING
#define ast_module_unref(mod)
Release a reference to the module.
Definition module.h:483
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition module.h:469
#define WIZARD_COMPARE(a, b)
static struct ao2_container * wizards
Registered sorcery wizards.
Definition sorcery.c:258
static struct ast_sorcery_object_type * sorcery_object_type_alloc(const char *type, const char *module)
Internal function which allocates an object type structure.
Definition sorcery.c:764
static void sorcery_object_wizard_destructor(void *obj)
Object wizard destructor.
Definition sorcery.c:826
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition strings.h:80
Structure for an internal wizard instance.
Definition sorcery.c:90
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition sorcery.c:97
Structure for a wizard instance which operates on objects.
Definition sorcery.c:104
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition sorcery.c:106
unsigned int allow_duplicates
Wizard allows others of the same type.
Definition sorcery.c:118
char wizard_args[0]
Wizard arguments.
Definition sorcery.c:121
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:620
#define AST_VECTOR_INSERT_AT(vec, idx, elem)
Insert an element at a specific position in a vector, growing the vector if needed.
Definition vector.h:349
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition vector.h:898
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition vector.h:908
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition vector.h:742

References ast_sorcery_object_wizard::allow_duplicates, ao2_alloc, ao2_bump, ao2_cleanup, ao2_find, ao2_link, ast_debug, ast_log, ast_module_running_ref, ast_module_unref, AST_SORCERY_APPLY_DUPLICATE, AST_SORCERY_APPLY_FAIL, AST_SORCERY_APPLY_SUCCESS, AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE, AST_SORCERY_WIZARD_APPLY_CACHING, AST_SORCERY_WIZARD_APPLY_READONLY, AST_SORCERY_WIZARD_POSITION_LAST, ast_strlen_zero(), AST_VECTOR_GET_CMP, AST_VECTOR_INSERT_AT, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, LOG_ERROR, LOG_WARNING, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, NULL, OBJ_KEY, ast_sorcery::observers, RAII_VAR, S_OR, sorcery, sorcery_object_type_alloc(), sorcery_object_wizard_destructor(), ast_sorcery::types, ast_sorcery_object_wizard::wizard, ast_sorcery_object_wizard::wizard_args, WIZARD_COMPARE, and wizards.

Referenced by __ast_sorcery_insert_wizard_mapping().

◆ __ast_sorcery_object_type_remove_wizard()

int __ast_sorcery_object_type_remove_wizard ( struct ast_sorcery sorcery,
const char *  object_type_name,
const char *  module,
const char *  wizard_type_name,
const char *  wizard_args 
)

Remove an object wizard mapping.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to remove from
moduleThe name of the module, typically AST_MODULE
wizard_type_nameThe name of the of the wizard type to remove
wizard_argsOpaque string originally passed to the wizard
Return values
0success
-1failure
Note
If there were multiple instances of the same wizard type added to this object type without using wizard_args, then only the first wizard matching wizard_type will be removed.

Definition at line 884 of file sorcery.c.

887{
888 RAII_VAR(struct ast_sorcery_object_type *, object_type,
889 ao2_find(sorcery->types, object_type_name, OBJ_SEARCH_KEY), ao2_cleanup);
890 int res = -1;
891 int i;
892
893 if (!object_type) {
894 return res;
895 }
896
897 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
898 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
899 struct ast_sorcery_object_wizard *wizard = AST_VECTOR_GET(&object_type->wizards, i);
900
901 if (strcmp(wizard->wizard->callbacks.name, wizard_type_name) == 0
902 && strcmp(S_OR(wizard->wizard_args, ""), S_OR(wizard_args, "")) == 0) {
903 ao2_cleanup(AST_VECTOR_REMOVE_ORDERED(&object_type->wizards, i));
904 res = 0;
905 break;
906 }
907 }
908 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
909
910 return res;
911}
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition astobj2.h:1101
const char * name
Name of the wizard.
Definition sorcery.h:278
#define AST_VECTOR_REMOVE_ORDERED(vec, idx)
Remove an element from a vector by index while maintaining order.
Definition vector.h:459
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:691

References ao2_cleanup, ao2_find, AST_VECTOR_GET, AST_VECTOR_REMOVE_ORDERED, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_wizard::name, OBJ_SEARCH_KEY, RAII_VAR, S_OR, sorcery, ast_sorcery::types, ast_sorcery_object_wizard::wizard, and ast_sorcery_object_wizard::wizard_args.

◆ __ast_sorcery_open()

struct ast_sorcery * __ast_sorcery_open ( const char *  module,
const char *  file,
int  line,
const char *  func 
)

Definition at line 665 of file sorcery.c.

666{
667 struct sorcery_proxy *proxy;
668 struct ast_sorcery *sorcery;
669
671
674 __PRETTY_FUNCTION__, file, line, func);
675 if (sorcery) {
677
678 return sorcery;
679 }
680
681 proxy = ao2_t_weakproxy_alloc(sizeof(*proxy) + strlen(module_name) + 1, NULL, module_name);
682 if (!proxy) {
683 goto failure_cleanup;
684 }
685 strcpy(proxy->module_name, module_name); /* Safe */
686
688 if (!sorcery) {
689 goto failure_cleanup;
690 }
691
693
694 /* We have exclusive access to proxy and sorcery, no need for locking here. */
695 if (ao2_t_weakproxy_set_object(proxy, sorcery, OBJ_NOLOCK, "weakproxy link")) {
696 goto failure_cleanup;
697 }
698
700 goto failure_cleanup;
701 }
702
704 ast_sorcery_object_type_hash_fn, NULL, ast_sorcery_object_type_cmp_fn);
705 if (!sorcery->types) {
706 goto failure_cleanup;
707 }
708
710 goto failure_cleanup;
711 }
712
714 ast_log(LOG_ERROR, "Error attempting to apply configuration %s to sorcery.\n", module_name);
715 goto failure_cleanup;
716 }
717
719 ao2_ref(proxy, -1);
720
722
724 return sorcery;
725
726failure_cleanup:
727 /* cleanup of sorcery may result in locking instances, so make sure we unlock first. */
730 ao2_cleanup(proxy);
731
732 return NULL;
733}
int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
Request notification when weakproxy points to NULL.
Definition astobj2.c:934
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition astobj2.h:365
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition astobj2.h:363
#define ao2_wrlock(a)
Definition astobj2.h:719
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition astobj2.h:1554
#define ao2_t_weakproxy_alloc(data_size, destructor_fn, tag)
Definition astobj2.h:553
#define ao2_unlock(a)
Definition astobj2.h:729
void * __ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition astobj2.h:1063
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition astobj2.h:1327
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition astobj2.c:768
#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.
Definition astobj2.h:1303
#define ao2_t_weakproxy_set_object(weakproxy, obj, flags, tag)
Definition astobj2.h:582
#define NOTIFY_GLOBAL_OBSERVERS(container, callback,...)
Definition sorcery.c:77
static void sorcery_destructor(void *obj)
Destructor called when sorcery structure is destroyed.
Definition sorcery.c:645
static void sorcery_proxy_cb(void *weakproxy, void *data)
Hashing function for sorcery types.
Definition sorcery.c:660
enum ast_sorcery_apply_result __ast_sorcery_apply_config(struct ast_sorcery *sorcery, const char *name, const char *module)
Apply configured wizard mappings.
Definition sorcery.c:1049
static struct ao2_container * instances
Registered sorcery instances.
Definition sorcery.c:285
struct ao2_container * observers
Registered global observers.
Definition sorcery.c:282
#define TYPE_BUCKETS
Number of buckets for types (should be prime for performance reasons)
Definition sorcery.c:55
Proxy object for sorcery.
Definition sorcery.c:224
char module_name[0]
The name of the module owning this sorcery instance.
Definition sorcery.c:227

References __ao2_alloc(), __ao2_weakproxy_find(), __ast_sorcery_apply_config(), AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_cleanup, ao2_container_alloc_hash, ao2_container_alloc_list, ao2_link_flags, ao2_ref, ao2_t_weakproxy_alloc, ao2_t_weakproxy_set_object, ao2_unlock, ao2_weakproxy_subscribe(), ao2_wrlock, ast_assert, ast_log, AST_SORCERY_APPLY_FAIL, instances, LOG_ERROR, sorcery_proxy::module_name, ast_sorcery::module_name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_NOLOCK, OBJ_SEARCH_KEY, ast_sorcery::observers, observers, sorcery, sorcery_destructor(), sorcery_proxy_cb(), TYPE_BUCKETS, and ast_sorcery::types.

◆ __ast_sorcery_remove_wizard_mapping()

int __ast_sorcery_remove_wizard_mapping ( struct ast_sorcery sorcery,
const char *  type,
const char *  module,
const char *  name 
)

Remove an object wizard mapping.

Parameters
sorceryPointer to a sorcery structure
typeType of object to remove from
moduleThe name of the module, typically AST_MODULE
nameThe name of the wizard to remove
Return values
0success
-1failure
Since
13.4.0

Remove an object wizard mapping.

Definition at line 914 of file sorcery.c.

916{
918 int res;
919
920 if (!object_type) {
921 return -1;
922 }
923
924 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
925#define WIZARD_NAME_COMPARE(a, b) (strcmp((a)->wizard->callbacks.name, (b)) == 0)
927#undef WIZARD_NAME_COMPARE
928 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
929
930 return res;
931}
#define WIZARD_NAME_COMPARE(a, b)
#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison while maintaining order.
Definition vector.h:551

References ao2_cleanup, ao2_find, AST_VECTOR_REMOVE_CMP_ORDERED, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, name, OBJ_KEY, RAII_VAR, sorcery, type, ast_sorcery::types, and WIZARD_NAME_COMPARE.

◆ __ast_sorcery_wizard_register()

int __ast_sorcery_wizard_register ( const struct ast_sorcery_wizard interface,
struct ast_module module 
)

Register a sorcery wizard.

Parameters
interfacePointer to a wizard interface
modulePointer to the module implementing the interface
Return values
0success
-1failure

Definition at line 496 of file sorcery.c.

497{
498 struct ast_sorcery_internal_wizard *wizard;
499 int res = -1;
500
501 ast_assert(!ast_strlen_zero(interface->name));
502
504
505 if ((wizard = ao2_find(wizards, interface->name, OBJ_KEY | OBJ_NOLOCK))) {
506 ast_log(LOG_WARNING, "Attempted to register sorcery wizard '%s' twice\n",
507 interface->name);
508 goto done;
509 }
510
511 if (!(wizard = ao2_alloc(sizeof(*wizard), sorcery_internal_wizard_destructor))) {
512 goto done;
513 }
514
515 wizard->callbacks = *interface;
516 wizard->callbacks.module = module;
517
519 if (!wizard->observers) {
520 goto done;
521 }
522
524 res = 0;
525
526 ast_verb(5, "Sorcery registered wizard '%s'\n", interface->name);
527
528 NOTIFY_GLOBAL_OBSERVERS(observers, wizard_registered,
529 interface->name, interface);
530
531done:
532 ao2_cleanup(wizard);
534
535 return res;
536}
#define ao2_lock(a)
Definition astobj2.h:717
#define ast_verb(level,...)
static void sorcery_internal_wizard_destructor(void *obj)
Definition sorcery.c:489
struct ao2_container * observers
Observers.
Definition sorcery.c:100
int done

References ao2_alloc, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_find, ao2_link_flags, ao2_lock, ao2_unlock, ast_assert, ast_log, ast_strlen_zero(), ast_verb, ast_sorcery_internal_wizard::callbacks, done, LOG_WARNING, ast_sorcery_wizard::name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_KEY, OBJ_NOLOCK, ast_sorcery_internal_wizard::observers, observers, sorcery_internal_wizard_destructor(), and wizards.

Referenced by ast_bucket_init().

◆ ast_sorcery_alloc()

void * ast_sorcery_alloc ( const struct ast_sorcery sorcery,
const char *  type,
const char *  id 
)

Allocate an object.

Parameters
sorceryPointer to a sorcery structure
typeType of object to allocate
idOptional unique identifier, if none is provided one will be generated
Return values
non-NULLsuccess
NULLfailure

Definition at line 1808 of file sorcery.c.

1809{
1811 struct ast_sorcery_object_details *details;
1812
1813 if (!object_type || !object_type->type.item_alloc ||
1814 !(details = object_type->type.item_alloc(id))) {
1815 return NULL;
1816 }
1817
1818 if (ast_strlen_zero(id)) {
1819 char uuid[AST_UUID_STR_LEN];
1820
1822 details->object->id = ast_strdup(uuid);
1823 } else {
1824 details->object->id = ast_strdup(id);
1825 }
1826 if (!details->object->id) {
1827 ao2_ref(details, -1);
1828 return NULL;
1829 }
1830
1831 details->object->created = ast_tvnow();
1832 ast_copy_string(details->object->type, type, sizeof(details->object->type));
1833
1834 if (aco_set_defaults(&object_type->type, id, details)) {
1835 ao2_ref(details, -1);
1836 return NULL;
1837 }
1838
1839 return details;
1840}
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
static int uuid(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition func_uuid.c:52
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition sorcery.h:352
struct timeval created
Time that the object was created.
Definition sorcery.c:142
char type[MAX_OBJECT_TYPE]
Type of object.
Definition sorcery.c:133
char * id
Unique identifier of this object.
Definition sorcery.c:130
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159
#define AST_UUID_STR_LEN
Definition uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition uuid.c:141

References aco_set_defaults(), ao2_cleanup, ao2_find, ao2_ref, ast_copy_string(), ast_strdup, ast_strlen_zero(), ast_tvnow(), ast_uuid_generate_str(), AST_UUID_STR_LEN, ast_sorcery_object::created, ast_sorcery_object::id, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, type, ast_sorcery_object::type, ast_sorcery::types, and uuid().

Referenced by alloc_artificial_auth(), ast_ari_asterisk_update_object(), ast_bucket_alloc(), ast_bucket_file_alloc(), ast_mwi_mailbox_alloc(), ast_sip_initialize_system(), ast_sip_location_create_contact(), ast_sorcery_copy(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), create_artificial_endpoint(), create_effective_profile(), create_object(), default_profile_create(), global_loaded_observer(), load_module(), load_module(), mock_retrieve_id(), permanent_uri_handler(), sip_cli_print_global(), sip_cli_print_system(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_config_internal_load(), sorcery_memory_cache_thrash_update(), sorcery_realtime_retrieve_fields(), sorcery_realtime_retrieve_multiple(), sorcery_test_retrieve_id(), and subscription_persistence_create().

◆ ast_sorcery_changeset_create()

int ast_sorcery_changeset_create ( const struct ast_variable original,
const struct ast_variable modified,
struct ast_variable **  changes 
)

Create a changeset given two object sets.

Parameters
originalOriginal object set
modifiedModified object set
changesPointer to hold any changes between the object sets
Return values
0success
-1failure
Note
The returned ast_variable list must be destroyed using ast_variables_destroy

Definition at line 1727 of file sorcery.c.

1728{
1729 const struct ast_variable *field;
1730 int res = 0;
1731
1732 *changes = NULL;
1733
1734 /* Unless the ast_variable list changes when examined... it can't differ from itself */
1735 if (original == modified) {
1736 return 0;
1737 }
1738
1739 for (field = modified; field; field = field->next) {
1740 const char *old_value = ast_variable_find_in_list(original, field->name);
1741
1742 if (!old_value || strcmp(old_value, field->value)) {
1743 struct ast_variable *tmp;
1744
1745 if (!(tmp = ast_variable_new(field->name, field->value, ""))) {
1746 res = -1;
1747 break;
1748 }
1749
1750 tmp->next = *changes;
1751 *changes = tmp;
1752 }
1753 }
1754
1755 /* If an error occurred do not return a partial changeset */
1756 if (res) {
1757 ast_variables_destroy(*changes);
1758 *changes = NULL;
1759 }
1760
1761 return res;
1762}
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260

References ast_variable_find_in_list(), ast_variable_new, ast_variables_destroy(), ast_variable::name, ast_variable::next, NULL, and ast_variable::value.

Referenced by ast_sorcery_diff(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), can_reuse_registration(), and sorcery_is_criteria_met().

◆ ast_sorcery_copy()

void * ast_sorcery_copy ( const struct ast_sorcery sorcery,
const void *  object 
)

Create a copy of an object.

Parameters
sorceryPointer to a sorcery structure
objectExisting object
Return values
non-NULLsuccess
NULLfailure

Definition at line 1842 of file sorcery.c.

1843{
1844 const struct ast_sorcery_object_details *details = object;
1845 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1847 RAII_VAR(struct ast_variable *, objectset, NULL, ast_variables_destroy);
1848 int res = 0;
1849
1850 if (!copy) {
1851 return NULL;
1852 } else if (object_type->copy) {
1853 res = object_type->copy(object, copy);
1854 } else if ((objectset = ast_sorcery_objectset_create(sorcery, object))) {
1855 res = ast_sorcery_objectset_apply(sorcery, copy, objectset);
1856 } else {
1857 /* No native copy available and could not create an objectset, this copy has failed */
1858 res = -1;
1859 }
1860
1861 if (res) {
1863 copy = NULL;
1864 }
1865
1866 return copy;
1867}
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition sorcery.c:1808
int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
Apply an object set (KVP list) to an object.
Definition sorcery.c:1696
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition sorcery.h:1137

References ao2_cleanup, ao2_find, ast_sorcery_alloc(), ast_sorcery_objectset_apply(), ast_sorcery_objectset_create, ast_variables_destroy(), copy(), ast_sorcery_object::id, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by ast_ari_asterisk_update_object(), ast_bucket_clone(), ast_bucket_file_clone(), ast_mwi_mailbox_copy(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and register_aor_core().

◆ ast_sorcery_create()

int ast_sorcery_create ( const struct ast_sorcery sorcery,
void *  object 
)

Create and potentially persist an object using an available wizard.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2126 of file sorcery.c.

2127{
2128 const struct ast_sorcery_object_details *details = object;
2129 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2130 struct ast_sorcery_object_wizard *object_wizard = NULL;
2131 struct ast_sorcery_object_wizard *found_wizard;
2132 int i;
2133 struct sorcery_details sdetails = {
2134 .sorcery = sorcery,
2135 .obj = object,
2136 };
2137
2138 if (!object_type) {
2139 return -1;
2140 }
2141
2142 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2143 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2144 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2145 if (!found_wizard->caching
2146 && sorcery_wizard_create(found_wizard, &sdetails) == CMP_MATCH) {
2147 object_wizard = found_wizard;
2148 }
2149 }
2150
2151 if (object_wizard) {
2152 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2153 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2154 if (found_wizard->caching) {
2155 sorcery_wizard_create(found_wizard, &sdetails);
2156 }
2157 }
2158
2159 if (ao2_container_count(object_type->observers)) {
2160 struct sorcery_observer_invocation *invocation;
2161
2162 invocation = sorcery_observer_invocation_alloc(object_type, object);
2163 if (invocation
2165 invocation)) {
2166 ao2_cleanup(invocation);
2167 }
2168 }
2169 }
2170
2172
2173 return object_wizard ? 0 : -1;
2174}
@ CMP_MATCH
Definition astobj2.h:1027
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static int sorcery_observers_notify_create(void *data)
Internal callback function which notifies observers that an object has been created.
Definition sorcery.c:2116
static int sorcery_wizard_create(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if the wizard has created the object.
Definition sorcery.c:2089
static struct sorcery_observer_invocation * sorcery_observer_invocation_alloc(struct ast_sorcery_object_type *object_type, void *object)
Allocator function for observer invocation.
Definition sorcery.c:1356
struct ast_sorcery_object_wizards wizards
Wizard instances.
Definition sorcery.c:166
struct ast_taskprocessor * serializer
Serializer for observers.
Definition sorcery.c:184
unsigned int caching
Wizard is acting as an object cache.
Definition sorcery.c:112
Structure used when calling create, update, or delete.
Definition sorcery.c:1895
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Definition sorcery.c:1897
Structure used for observer invocations.
Definition sorcery.c:197
struct ast_sorcery_object_type * object_type
Pointer to the object type.
Definition sorcery.c:199
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition vector.h:888

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery_details::sorcery, sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_create(), sorcery_wizard_create(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by ast_ari_asterisk_update_object(), ast_bucket_create(), ast_bucket_file_create(), ast_mwi_mailbox_update(), ast_sip_location_create_contact(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), create_effective_profile(), default_profile_create(), load_module(), and subscription_persistence_create().

◆ ast_sorcery_delete()

int ast_sorcery_delete ( const struct ast_sorcery sorcery,
void *  object 
)

Delete an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2302 of file sorcery.c.

2303{
2304 const struct ast_sorcery_object_details *details = object;
2305 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2306 struct ast_sorcery_object_wizard *object_wizard = NULL;
2307 struct ast_sorcery_object_wizard *found_wizard;
2308 int i;
2309 struct sorcery_details sdetails = {
2310 .sorcery = sorcery,
2311 .obj = object,
2312 };
2313
2314 if (!object_type) {
2315 return -1;
2316 }
2317
2318 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2319 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2320 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2321 if (!found_wizard->caching
2322 && sorcery_wizard_delete(found_wizard, &sdetails) == CMP_MATCH) {
2323 object_wizard = found_wizard;
2324 }
2325 }
2326
2327 if (object_wizard) {
2328 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2329 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2330 if (found_wizard->caching) {
2331 sorcery_wizard_delete(found_wizard, &sdetails);
2332 }
2333 }
2334
2335 if (ao2_container_count(object_type->observers)) {
2336 struct sorcery_observer_invocation *invocation;
2337
2338 invocation = sorcery_observer_invocation_alloc(object_type, object);
2339 if (invocation
2341 invocation)) {
2342 ao2_cleanup(invocation);
2343 }
2344 }
2345 }
2346
2348
2349 return object_wizard ? 0 : -1;
2350}
static int sorcery_observers_notify_delete(void *data)
Internal callback function which notifies observers that an object has been deleted.
Definition sorcery.c:2277
static int sorcery_wizard_delete(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if a wizard has deleted the object.
Definition sorcery.c:2288

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery_details::sorcery, sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_delete(), sorcery_wizard_delete(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by ast_ari_asterisk_delete_object(), ast_bucket_delete(), ast_bucket_file_delete(), ast_sip_location_delete_contact(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), bucket_http_wizard_retrieve_id(), mwi_mailbox_delete(), sub_persistence_recreate(), subscription_persistence_recreate(), subscription_persistence_remove(), and unload_module().

◆ ast_sorcery_diff()

int ast_sorcery_diff ( const struct ast_sorcery sorcery,
const void *  original,
const void *  modified,
struct ast_variable **  changes 
)

Create a changeset of two objects.

Parameters
sorceryPointer to a sorcery structure
originalOriginal object
modifiedModified object
changesPointer which will be populated with changes if any exist
Return values
0success
-1failure
Note
The returned ast_variable list must be destroyed using ast_variables_destroy
While the objects must be of the same type they do not have to be the same object

Definition at line 1869 of file sorcery.c.

1870{
1872
1873 *changes = NULL;
1874
1875 if (strcmp(ast_sorcery_object_get_type(original), ast_sorcery_object_get_type(modified))) {
1876 return -1;
1877 }
1878
1879 if (original == modified) {
1880 return 0;
1881 } else if (!object_type->diff) {
1882 RAII_VAR(struct ast_variable *, objectset1, NULL, ast_variables_destroy);
1883 RAII_VAR(struct ast_variable *, objectset2, NULL, ast_variables_destroy);
1884
1885 objectset1 = ast_sorcery_objectset_create(sorcery, original);
1886 objectset2 = ast_sorcery_objectset_create(sorcery, modified);
1887
1888 return ast_sorcery_changeset_create(objectset1, objectset2, changes);
1889 } else {
1890 return object_type->diff(original, modified, changes);
1891 }
1892}
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition sorcery.c:2393
int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
Create a changeset given two object sets.
Definition sorcery.c:1727

References ao2_cleanup, ao2_find, ast_sorcery_changeset_create(), ast_sorcery_object_get_type(), ast_sorcery_objectset_create, ast_variables_destroy(), NULL, OBJ_KEY, RAII_VAR, sorcery, and ast_sorcery::types.

Referenced by ari_conf_owc_detect_changes(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_get_field_diff(), and transport_apply().

◆ ast_sorcery_force_reload()

void ast_sorcery_force_reload ( const struct ast_sorcery sorcery)

Inform any wizards to reload persistent objects, even if no changes determined.

Parameters
sorceryPointer to a sorcery structure
Since
13.32.0
16.9.0
17.3.0

Definition at line 1489 of file sorcery.c.

1490{
1491 struct sorcery_load_details details = {
1492 .sorcery = sorcery,
1493 .reload = 1,
1494 .force = 1,
1495 };
1496
1497 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1499
1501
1504}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition astobj2.h:1693
@ OBJ_NODATA
Definition astobj2.h:1044
static int sorcery_object_load(void *obj, void *arg, int flags)
Definition sorcery.c:1400
Structure for passing load/reload details.
Definition sorcery.c:243
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition sorcery.c:245

References ao2_callback, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, OBJ_NODATA, ast_sorcery::observers, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), and ast_sorcery::types.

◆ ast_sorcery_force_reload_object()

void ast_sorcery_force_reload_object ( const struct ast_sorcery sorcery,
const char *  type 
)

Inform any wizards of a specific object type to reload persistent objects even if no changes determined.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to reload
Since
13.32.0
16.9.0
17.3.0

Definition at line 1521 of file sorcery.c.

1522{
1524 struct sorcery_load_details details = {
1525 .sorcery = sorcery,
1526 .reload = 1,
1527 .force = 1,
1528 };
1529
1530 if (!object_type) {
1531 return;
1532 }
1533
1534 sorcery_object_load(object_type, &details, 0);
1535}

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), type, and ast_sorcery::types.

Referenced by acl_change_stasis_cb(), acl_change_stasis_cb(), as_config_reload(), global_loaded(), profile_reload(), tn_config_reload(), vs_config_reload(), and ws_client_load().

◆ ast_sorcery_generic_alloc()

void * ast_sorcery_generic_alloc ( size_t  size,
ao2_destructor_fn  destructor 
)

Allocate a generic sorcery capable object.

Parameters
sizeSize of the object
destructorOptional destructor function
Return values
non-NULLsuccess
NULLfailure
Note
The returned object does not support AO2 locking.

Definition at line 1792 of file sorcery.c.

1793{
1794 void *object = ao2_alloc_options(size + sizeof(struct ast_sorcery_object),
1796 struct ast_sorcery_object_details *details = object;
1797
1798 if (!object) {
1799 return NULL;
1800 }
1801
1802 details->object = object + size;
1803 details->object->destructor = destructor;
1804
1805 return object;
1806}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
static void sorcery_object_destructor(void *object)
Definition sorcery.c:1764
Structure for internal sorcery object information.
Definition sorcery.c:128
ao2_destructor_fn destructor
Optional object destructor.
Definition sorcery.c:136

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_sorcery_object::destructor, NULL, ast_sorcery_object_details::object, and sorcery_object_destructor().

Referenced by acl_alloc(), ast_sip_endpoint_alloc(), asterisk_publication_config_alloc(), attestation_alloc(), auth_alloc(), bucket_alloc(), bucket_file_alloc(), client_config_alloc(), contact_alloc(), domain_alias_alloc(), general_alloc(), geoloc_location_alloc(), geoloc_profile_alloc(), global_alloc(), ip_identify_alloc(), mapping_alloc(), mwi_sorcery_object_alloc(), outbound_websocket_alloc(), phoneprov_alloc(), profile_alloc(), publication_resource_alloc(), resource_list_alloc(), sip_nat_hook_alloc(), sip_outbound_publish_alloc(), sip_outbound_registration_alloc(), sip_transport_alloc(), subscription_persistence_alloc(), system_alloc(), test_data_alloc(), test_sorcery_object_alloc(), test_sorcery_object_alloc(), test_sorcery_object_alloc(), tn_alloc(), user_alloc(), verification_alloc(), and wc_alloc().

◆ ast_sorcery_get_module()

const char * ast_sorcery_get_module ( const struct ast_sorcery sorcery)

Get the module that has opened the provided sorcery instance.

Parameters
sorceryThe sorcery instance
Returns
The module

Definition at line 2600 of file sorcery.c.

2601{
2602 return sorcery->module_name;
2603}

References ast_sorcery::module_name, and sorcery.

Referenced by sorcery_memory_cache_load().

◆ ast_sorcery_get_object_type()

struct ast_sorcery_object_type * ast_sorcery_get_object_type ( const struct ast_sorcery sorcery,
const char *  type 
)

Get the sorcery object type given a type name.

Parameters
sorceryThe sorcery from which to retrieve the object type
typeThe type name

Definition at line 2558 of file sorcery.c.

2560{
2562}

References ao2_find, OBJ_SEARCH_KEY, sorcery, type, and ast_sorcery::types.

Referenced by ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), AST_TEST_DEFINE(), load_module(), sorcery_astdb_filter_objectset(), sorcery_is_explicit_name_met(), and sorcery_realtime_filter_objectset().

◆ ast_sorcery_get_wizard_mapping()

int ast_sorcery_get_wizard_mapping ( struct ast_sorcery sorcery,
const char *  type,
int  index,
struct ast_sorcery_wizard **  wizard,
void **  data 
)

By index, return a wizard mapped to an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
indexIndex of the wizard
wizardA pointer to receive the wizard pointer
dataA pointer to receive the data pointer
Return values
0success
-1failure
Warning
The wizard will have its reference count bumped so you must call ao2_cleanup when you're done with it.
Note
The wizard and data returned are valid only for this object type and only while the wizard is applied to the object type.
Since
13.4.0

Definition at line 854 of file sorcery.c.

856{
858 struct ast_sorcery_object_wizard *owizard;
859
860 if (!object_type) {
861 return -1;
862 }
863
864 if (index < 0 || index >= AST_VECTOR_SIZE(&object_type->wizards)) {
865 return -1;
866 }
867
868 owizard = AST_VECTOR_GET(&object_type->wizards, index);
869
870 if (wizard != NULL) {
871 *wizard = &(owizard->wizard->callbacks);
872 ao2_bump(owizard->wizard);
873 } else {
874 return -1;
875 }
876
877 if (data != NULL) {
878 *data = owizard->data;
879 }
880
881 return 0;
882}
void * data
Unique data for the wizard.
Definition sorcery.c:109

References ao2_bump, ao2_cleanup, ao2_find, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, NULL, OBJ_KEY, RAII_VAR, sorcery, type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_get_wizard_mapping_count()

int ast_sorcery_get_wizard_mapping_count ( struct ast_sorcery sorcery,
const char *  type 
)

Return the number of wizards mapped to an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
Returns
Number of wizards or -1 for error
Since
13.4.0

Definition at line 842 of file sorcery.c.

844{
846
847 if (!object_type) {
848 return -1;
849 }
850
851 return AST_VECTOR_SIZE(&object_type->wizards);
852}

References ao2_cleanup, ao2_find, AST_VECTOR_SIZE, OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by AST_TEST_DEFINE(), and AST_TEST_DEFINE().

◆ ast_sorcery_global_observer_add()

int ast_sorcery_global_observer_add ( const struct ast_sorcery_global_observer callbacks)

Add a global observer to sorcery.

Parameters
callbacksImplementation of the global observer interface
Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 562 of file sorcery.c.

563{
564 struct sorcery_global_observer *cb;
565
566 cb = ao2_alloc(sizeof(*cb), NULL);
567 if (!cb) {
568 return -1;
569 }
570
571 cb->callbacks = callbacks;
572 ao2_link(observers, cb);
573 ao2_ref(cb, -1);
574
575 return 0;
576}
A global observer wrapper.
Definition sorcery.c:267
const struct ast_sorcery_global_observer * callbacks
Definition sorcery.c:268

References ao2_alloc, ao2_link, ao2_ref, sorcery_global_observer::callbacks, callbacks, NULL, and observers.

Referenced by AST_TEST_DEFINE(), and load_module().

◆ ast_sorcery_global_observer_remove()

void ast_sorcery_global_observer_remove ( const struct ast_sorcery_global_observer callbacks)

Remove a global observer from sorcery.

A global observer is notified... After a new wizard is registered. After a new sorcery instance is opened. Before an instance is destroyed. Before a wizard is unregistered.

Parameters
callbacksImplementation of the global observer interface

Definition at line 578 of file sorcery.c.

580{
582}
@ OBJ_UNLINK
Definition astobj2.h:1039
static int sorcery_generic_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing a generic observer.
Definition sorcery.c:555

References ao2_callback, callbacks, OBJ_NODATA, OBJ_UNLINK, observers, and sorcery_generic_observer_remove().

Referenced by AST_TEST_DEFINE(), and unload_module().

◆ ast_sorcery_init()

int ast_sorcery_init ( void  )

Initialize the sorcery API.

Return values
0success
-1failure

Definition at line 444 of file sorcery.c.

445{
448 .auto_increment = 1,
449 .max_size = 0,
450 .idle_timeout = 60,
451 .initial_size = 1,
452 .minimum_size = 1,
453 };
455
457
458 taskpool = ast_taskpool_create("sorcery", &options);
459 if (!taskpool) {
460 return -1;
461 }
462
464 ast_sorcery_internal_wizard_hash_fn, NULL, ast_sorcery_internal_wizard_cmp_fn);
465 if (!wizards) {
466 return -1;
467 }
468
470 if (!observers) {
471 return -1;
472 }
473
475 sorcery_proxy_hash_fn, NULL, sorcery_proxy_cmp_fn);
476 if (!instances) {
477 return -1;
478 }
479
481 return -1;
482 }
483
485
486 return 0;
487}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition clicompat.c:19
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
#define INSTANCE_BUCKETS
Number of buckets for instances (should be prime for performance reasons)
Definition sorcery.c:58
static void parse_general_options(void)
Compare function for sorcery instances.
Definition sorcery.c:425
static struct ast_cli_entry cli_commands[]
Definition sorcery.c:397
#define WIZARD_BUCKETS
Number of buckets for wizards (should be prime for performance reasons)
Definition sorcery.c:52
static struct ast_taskpool * taskpool
Taskpool for observers.
Definition sorcery.c:87
static void sorcery_cleanup(void)
Cleanup function for graceful shutdowns.
Definition sorcery.c:402
#define AST_TASKPOOL_OPTIONS_VERSION
Definition taskpool.h:69
struct ast_taskpool * ast_taskpool_create(const char *name, const struct ast_taskpool_options *options)
Create a new taskpool.
Definition taskpool.c:324
#define ARRAY_LEN(a)
Definition utils.h:706

References AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_container_alloc_hash, ao2_container_alloc_list, ARRAY_LEN, ast_assert, ast_cli_register_multiple, ast_register_cleanup(), ast_taskpool_create(), AST_TASKPOOL_OPTIONS_VERSION, cli_commands, INSTANCE_BUCKETS, instances, NULL, observers, options, parse_general_options(), sorcery_cleanup(), taskpool, WIZARD_BUCKETS, and wizards.

Referenced by asterisk_daemon().

◆ ast_sorcery_instance_observer_add()

int ast_sorcery_instance_observer_add ( struct ast_sorcery sorcery,
const struct ast_sorcery_instance_observer callbacks 
)

Add an observer to a sorcery instance.

Parameters
sorceryPointer to a sorcery structure
callbacksImplementation of the instance observer interface

An instance observer is notified... Before an instance is loaded or reloaded. After an instance is loaded or reloaded. After a wizard is mapped to an object type. After an object type is registered. Before an object type is loaded or reloaded. After an object type is loaded or reloaded.

Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 584 of file sorcery.c.

586{
587 struct sorcery_instance_observer *cb;
588
589 cb = ao2_alloc(sizeof(*cb), NULL);
590 if (!cb) {
591 return -1;
592 }
593
594 cb->callbacks = callbacks;
596 ao2_ref(cb, -1);
597
598 return 0;
599}
An instance observer wrapper.
Definition sorcery.c:272
const struct ast_sorcery_instance_observer * callbacks
Definition sorcery.c:273

References ao2_alloc, ao2_link, ao2_ref, sorcery_instance_observer::callbacks, callbacks, NULL, ast_sorcery::observers, and sorcery.

Referenced by ast_sip_initialize_sorcery_global(), AST_TEST_DEFINE(), instance_created_observer(), load_module(), load_module(), and pjsip_outbound_registration_metrics_init().

◆ ast_sorcery_instance_observer_remove()

void ast_sorcery_instance_observer_remove ( struct ast_sorcery sorcery,
const struct ast_sorcery_instance_observer callbacks 
)

Remove an observer from a sorcery instance.

Parameters
sorceryPointer to a sorcery structure
callbacksImplementation of the instance observer interface

Definition at line 601 of file sorcery.c.

References ao2_callback, callbacks, OBJ_NODATA, OBJ_UNLINK, ast_sorcery::observers, sorcery, and sorcery_generic_observer_remove().

Referenced by ast_sip_destroy_sorcery_global(), AST_TEST_DEFINE(), instance_destroying_observer(), pjsip_outbound_registration_metrics_init(), pjsip_outbound_registration_metrics_unload_cb(), and unload_module().

◆ ast_sorcery_is_object_field_registered()

int ast_sorcery_is_object_field_registered ( const struct ast_sorcery_object_type object_type,
const char *  field_name 
)

Determine if a particular object field has been registered with sorcery.

Parameters
object_typeThe object type to check against
field_nameThe name of the field to check
Return values
0The field is not registered for this sorcery type
1The field is registered for this sorcery type

Definition at line 2578 of file sorcery.c.

2580{
2581 struct ast_sorcery_object_field *object_field;
2582 int res = 1;
2583
2584 ast_assert(object_type != NULL);
2585
2586 object_field = ao2_find(object_type->fields, field_name, OBJ_SEARCH_KEY);
2587
2588 if (!object_field) {
2589 object_field = ao2_callback(object_type->fields, 0, is_registered_cb, (char *)field_name);
2590 }
2591
2592 if (!object_field) {
2593 res = 0;
2594 }
2595
2596 ao2_cleanup(object_field);
2597 return res;
2598}
static int is_registered_cb(void *obj, void *arg, int flags)
Definition sorcery.c:2564
struct ao2_container * fields
Object fields.
Definition sorcery.c:169

References ao2_callback, ao2_cleanup, ao2_find, ast_assert, ast_sorcery_object_type::fields, is_registered_cb(), NULL, and OBJ_SEARCH_KEY.

Referenced by AST_TEST_DEFINE(), sorcery_astdb_filter_objectset(), sorcery_is_explicit_name_met(), and sorcery_realtime_filter_objectset().

◆ ast_sorcery_is_stale()

int ast_sorcery_is_stale ( const struct ast_sorcery sorcery,
void *  object 
)

Determine if a sorcery object is stale with respect to its backing datastore.

Since
14.0.0

This function will query the wizard(s) backing the particular sorcery object to determine if the in-memory object is now stale. No action is taken to update the object. Callers of this function may use one of the ast_sorcery_retrieve functions to obtain a new instance of the object if desired.

Return values
0the object is not stale
1the object is stale

Definition at line 2352 of file sorcery.c.

2353{
2354 const struct ast_sorcery_object_details *details = object;
2355 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2356 struct ast_sorcery_object_wizard *found_wizard;
2357 int res = 0;
2358 int i;
2359
2360 if (!object_type) {
2361 return -1;
2362 }
2363
2364 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2365 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2366 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2367
2368 if (found_wizard->wizard->callbacks.is_stale) {
2369 res |= found_wizard->wizard->callbacks.is_stale(sorcery, found_wizard->data, object);
2370 ast_debug(5, "After calling wizard '%s', object '%s' is %s\n",
2371 found_wizard->wizard->callbacks.name,
2373 res ? "stale" : "not stale");
2374 }
2375 }
2376 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2377
2378 return res;
2379}
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
int(* is_stale)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for whether or not the wizard believes the object is stale.
Definition sorcery.h:325

References ao2_cleanup, ao2_find, ast_debug, ast_sorcery_object_get_id(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, ast_sorcery_wizard::is_stale, ast_sorcery_wizard::name, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by ast_bucket_file_is_stale(), ast_bucket_is_stale(), and AST_TEST_DEFINE().

◆ ast_sorcery_load()

void ast_sorcery_load ( const struct ast_sorcery sorcery)

◆ ast_sorcery_load_object()

void ast_sorcery_load_object ( const struct ast_sorcery sorcery,
const char *  type 
)

Inform any wizards of a specific object type to load persistent objects.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to load

Definition at line 1457 of file sorcery.c.

1458{
1460 struct sorcery_load_details details = {
1461 .sorcery = sorcery,
1462 .reload = 0,
1463 };
1464
1465 if (!object_type) {
1466 return;
1467 }
1468
1469 sorcery_object_load(object_type, &details, 0);
1470}

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), type, and ast_sorcery::types.

Referenced by ari_conf_load(), as_config_load(), ast_sip_initialize_sorcery_global(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), load_module(), load_module(), load_module(), load_module(), profile_load(), reregister_all(), tn_config_load(), and vs_config_load().

◆ ast_sorcery_lockable_alloc()

void * ast_sorcery_lockable_alloc ( size_t  size,
ao2_destructor_fn  destructor,
void *  lockobj 
)

Allocate a generic sorcery capable object with locking.

Since
14.1.0

Sorcery objects may be replaced with new allocations during reloads. If locking is required on sorcery objects it must be shared between the old object and the new one. lockobj can be any AO2 object with locking enabled, but in most cases named locks should be used to provide stable locking.

Parameters
sizeSize of the object
destructorOptional destructor function
lockobjAn AO2 object that will provide locking.
Return values
non-NULLsuccess
NULLfailure

Definition at line 1776 of file sorcery.c.

1777{
1778 void *object = ao2_alloc_with_lockobj(size + sizeof(struct ast_sorcery_object),
1779 sorcery_object_destructor, lockobj, "");
1780 struct ast_sorcery_object_details *details = object;
1781
1782 if (!object) {
1783 return NULL;
1784 }
1785
1786 details->object = object + size;
1787 details->object->destructor = destructor;
1788
1789 return object;
1790}
#define ao2_alloc_with_lockobj(data_size, destructor_fn, lockobj, tag)
Allocate and initialize an object with separate locking.
Definition astobj2.h:431

References ao2_alloc_with_lockobj, ast_sorcery_object::destructor, NULL, ast_sorcery_object_details::object, and sorcery_object_destructor().

Referenced by aor_alloc().

◆ ast_sorcery_object_fields_register()

int ast_sorcery_object_fields_register ( struct ast_sorcery sorcery,
const char *  type,
const char *  regex,
aco_option_handler  config_handler,
sorcery_fields_handler  sorcery_handler 
)

Register a regex for multiple fields within an object.

Parameters
sorceryPointer to a sorcery structure
typeType of object
regexA regular expression pattern for the fields
config_handlerA custom handler for translating the string representation of the fields
sorcery_handlerA custom handler for translating the native representation of the fields
Return values
0success
-1failure

Definition at line 1224 of file sorcery.c.

1225{
1226#define MAX_REGEX_ERROR_LEN 128
1228 RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
1229 int rc;
1230
1231 if (!object_type || !object_type->type.item_alloc || !config_handler
1232 || !(object_field = ao2_alloc(sizeof(*object_field), sorcery_object_field_destructor))) {
1233 return -1;
1234 }
1235
1236 ast_copy_string(object_field->name, regex, sizeof(object_field->name));
1237 object_field->multiple_handler = sorcery_handler;
1238
1239 if (!(object_field->name_regex = ast_calloc(1, sizeof(regex_t)))) {
1240 return -1;
1241 }
1242
1243 if ((rc = regcomp(object_field->name_regex, regex, REG_EXTENDED | REG_NOSUB))) {
1244 char *regerr = ast_alloca(MAX_REGEX_ERROR_LEN);
1245 regerror(rc, object_field->name_regex, regerr, MAX_REGEX_ERROR_LEN);
1246 ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n", regex, regerr);
1247 return -1;
1248 }
1249
1250 ao2_link(object_type->fields, object_field);
1251 __aco_option_register(object_type->info, regex, ACO_REGEX, object_type->file->types, "", OPT_CUSTOM_T, config_handler, 0, 1, 0);
1252
1253 return 0;
1254}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
@ ACO_REGEX
@ OPT_CUSTOM_T
Type for a custom (user-defined) option handler.
#define MAX_REGEX_ERROR_LEN
static void sorcery_object_field_destructor(void *obj)
Definition sorcery.c:1214

References __aco_option_register(), ACO_REGEX, ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ast_alloca, ast_calloc, ast_copy_string(), ast_log, LOG_ERROR, MAX_REGEX_ERROR_LEN, NULL, OBJ_KEY, OPT_CUSTOM_T, RAII_VAR, regex(), sorcery, sorcery_object_field_destructor(), type, and ast_sorcery::types.

Referenced by __ast_sorcery_object_register(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), load_module(), and load_module().

◆ ast_sorcery_object_get_created()

const struct timeval ast_sorcery_object_get_created ( const void *  object)

Get when the sorcery object was created.

Since
14.0.0
Parameters
objectPointer to a sorcery object
Returns
The time when the object was created

Definition at line 2387 of file sorcery.c.

2388{
2389 const struct ast_sorcery_object_details *details = object;
2390 return details->object->created;
2391}

References ast_sorcery_object::created, and ast_sorcery_object_details::object.

◆ ast_sorcery_object_get_extended()

const char * ast_sorcery_object_get_extended ( const void *  object,
const char *  name 
)

Get an extended field value from a sorcery object.

Parameters
objectPointer to a sorcery object
nameName of the extended field value
Return values
non-NULLif found
NULLif not found
Note
The returned string does NOT need to be freed and is guaranteed to remain valid for the lifetime of the object

Definition at line 2399 of file sorcery.c.

2400{
2401 const struct ast_sorcery_object_details *details = object;
2402 struct ast_variable *field;
2403
2404 for (field = details->object->extended; field; field = field->next) {
2405 if (!strcmp(field->name + 1, name)) {
2406 return field->value;
2407 }
2408 }
2409
2410 return NULL;
2411}
struct ast_variable * extended
Extended object fields.
Definition sorcery.c:139

References ast_sorcery_object::extended, name, ast_variable::name, ast_variable::next, NULL, ast_sorcery_object_details::object, and ast_variable::value.

Referenced by AST_TEST_DEFINE(), asterisk_start_devicestate_publishing(), asterisk_start_mwi_publishing(), delete_existing_cb(), and publisher_start().

◆ ast_sorcery_object_get_id()

const char * ast_sorcery_object_get_id ( const void *  object)

Get the unique identifier of a sorcery object.

Parameters
objectPointer to a sorcery object
Returns
unique identifier

Definition at line 2381 of file sorcery.c.

2382{
2383 const struct ast_sorcery_object_details *details = object;
2384 return details->object->id;
2385}

References ast_sorcery_object::id, and ast_sorcery_object_details::object.

Referenced by __print_debug_details(), aeap_cli_show(), aeap_tab_complete_name(), allocate_subscription_tree(), allow_and_or_replace_unsolicited(), ami_outbound_registration_task(), ami_show_registration_contact_statuses(), anonymous_identify(), aor_deleted_observer(), apply_acls(), ari_conf_get_owc_for_app(), ari_conf_owc_detect_changes(), ari_show_owc(), ari_show_user(), ast_ari_create_per_call_websocket(), ast_bucket_file_json(), ast_bucket_json(), ast_geoloc_eprofile_create_from_profile(), ast_mwi_mailbox_get_id(), ast_mwi_mailbox_update(), ast_res_pjsip_find_or_create_contact_status(), ast_res_pjsip_initialize_configuration(), ast_sip_create_dialog_uac(), ast_sip_create_subscription(), ast_sip_for_each_contact(), ast_sip_format_contact_ami(), ast_sip_get_contact_status(), ast_sip_get_device_state(), ast_sip_initialize_sorcery_auth(), ast_sip_initialize_sorcery_transport(), ast_sip_location_create_contact(), ast_sip_location_retrieve_aor_contacts_nolock_filtered(), ast_sip_session_alloc(), ast_sip_session_create_outgoing(), ast_sip_session_get_name(), ast_sip_set_tpselector_from_transport(), ast_sip_subscription_destroy(), ast_sorcery_is_stale(), ast_sorcery_object_id_hash(), ast_sorcery_object_id_sort(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_connect(), ast_websocket_client_get_field_diff(), asterisk_publication_devicestate(), asterisk_publication_devicestate_refresh(), asterisk_publication_devicestate_state_change(), asterisk_publication_mailboxstate(), asterisk_publication_mwi_refresh(), asterisk_publication_mwi_state_change(), attestation_apply(), auth_apply(), auth_observer(), bucket_file_run_curl(), bucket_http_test_wizard_create(), bucket_http_test_wizard_delete(), bucket_http_test_wizard_update(), build_resource_tree(), can_reuse_registration(), cancel_and_unpublish(), challenge(), chan_pjsip_indicate(), chan_pjsip_new(), change_outgoing_sdp_stream_media_address(), change_outgoing_sdp_stream_media_address(), check_algorithm(), check_state(), cli_aor_get_id(), cli_aor_print_body(), cli_complete_endpoint(), cli_complete_registration(), cli_complete_uri(), cli_contact_print_body(), cli_endpoint_print_body(), cli_iterator(), cli_list_subscriptions_detail(), cli_print_body(), cli_print_body(), cli_print_body(), cli_print_body(), cli_show_subscriptions_detail(), client_config_apply(), codec_prefs_handler(), common_identify(), complete_sorcery_object(), config_object_cli_show(), config_object_tab_complete_name(), connected_line_method_handler(), contact_apply_handler(), contact_function_get_permanent(), create_dialog_uas(), create_effective_profile(), create_out_of_dialog_request(), create_outgoing_sdp_stream(), create_rtp(), create_unsolicited_mwi_subscriptions(), current_state_reusable(), destroy_subscription(), digest_check_auth(), digest_create_request_with_auth(), digest_lookup(), direct_media_glare_mitigation_handler(), direct_media_method_handler(), domain_alias_apply(), endpt_send_request(), eprofile_apply(), expire_objects_from_cache(), file_extension_from_url_path(), find_authorization(), find_internal_state_by_transport(), find_or_create_temporary_state(), find_registrar_aor(), format_ami_aor_handler(), format_ami_auth_handler(), format_ami_endpoint_identify(), format_ami_endpoint_transport(), from_user_handler(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_location_apply_handler(), geoloc_profile_apply_handler(), get_account_id(), get_creds_for_header(), get_curl_instance(), get_resource_display_name(), handle_export_primitives(), handle_incoming_request(), handle_incoming_request(), handle_outgoing_request(), handle_slash(), has_mwi_subscription(), header_identify_match_check(), ident_handler(), internal_state_alloc(), ip_identify_apply(), ip_identify_match_check(), ip_identify_match_handler(), line_identify(), load_engine(), load_module(), load_module(), log_caps(), mark_object_as_stale_in_cache(), matches_engine(), media_cache_handle_show_item(), media_cache_item_del_from_astdb(), media_cache_item_sync_to_astdb(), media_cache_prnt_summary(), memory_cache_stale_update_object(), msg_send(), mwi_contact_changed(), mwi_observe_delete(), mwi_post_event(), mwi_subscription_alloc(), mwi_validate_for_aor(), new_subscribe(), outbound_session_apply_config(), outbound_session_create(), outbound_websocket_apply(), outbound_websocket_dtor(), outbound_websocket_validate_cb(), outbound_websocket_websocket_client_id_from_str(), password_digest_handler(), permanent_uri_handler(), permanent_uri_sort_fn(), persistent_endpoint_find_or_create(), pjsip_aor_function_read(), profile_apply(), publish_request_initial(), publisher_start(), publisher_stop(), pubsub_on_rx_mwi_notify_request(), pubsub_on_rx_publish_request(), pubsub_on_rx_refresh(), pubsub_on_rx_subscribe_request(), qualify_contact_cb(), read_pjsip(), redirect_method_handler(), refer_client_on_evsub_state(), refer_incoming_ari_request(), refer_incoming_attended_request(), refer_incoming_blind_request(), refer_incoming_invite_request(), refer_incoming_refer_request(), refer_progress_alloc(), refer_send(), register_aor_core(), registrar_contact_delete(), registrar_on_rx_request(), registration_deleted_observer(), registration_state_cmp(), registration_state_hash(), remove_from_cache(), remove_subscription(), request_identify_match_check(), resource_list_apply_handler(), rfc3326_add_reason_header(), rx_data_to_ast_msg(), session_destructor(), session_inv_on_redirected(), session_inv_on_tsx_state_changed(), session_outgoing_nat_hook(), show_owc_cb(), show_users_cb(), sip_aor_to_ami(), sip_endpoint_apply_handler(), sip_options_aor_alloc(), sip_options_aor_observer_deleted_task(), sip_options_aor_observer_modified_task(), sip_options_apply_aor_configuration(), sip_options_contact_status_notify_task(), sip_options_endpoint_observer_deleted_task(), sip_options_endpoint_observer_modified_task(), sip_options_endpoint_state_compositor_find_or_alloc(), sip_options_endpoint_unlink_aor_feeders(), sip_options_qualify_contact(), sip_options_remove_contact_status(), sip_options_synchronize_aor(), sip_options_synchronize_endpoint(), sip_outbound_publish_apply(), sip_outbound_publish_callback(), sip_outbound_publish_state_alloc(), sip_outbound_publish_synchronize(), sip_outbound_publisher_alloc(), sip_outbound_publisher_init(), sip_outbound_publisher_set_uris(), sip_outbound_registration_apply(), sip_outbound_registration_regc_alloc(), sip_outbound_registration_state_alloc(), sip_sorcery_object_ami_set_type_name(), sip_subscription_send_request(), sip_subscription_to_ami(), sorcery_astdb_create(), sorcery_astdb_delete(), sorcery_astdb_update(), sorcery_config_fields_cmp(), sorcery_memory_cache_complete_object_name(), sorcery_memory_cache_create(), sorcery_memory_cache_delete(), sorcery_memory_cache_fields_cmp(), sorcery_memory_cache_print_object(), sorcery_memory_cache_retrieve_id(), sorcery_memory_cached_object_cmp(), sorcery_memory_cached_object_hash(), sorcery_memory_cmp(), sorcery_memory_create(), sorcery_memory_delete(), sorcery_memory_fields_cmp(), sorcery_memory_hash(), sorcery_memory_update(), sorcery_realtime_create(), sorcery_realtime_delete(), sorcery_realtime_update(), stale_item_update(), stir_shaken_handler(), subscription_established(), subscription_persistence_create(), subscription_persistence_remove(), subscription_tree_destructor(), t38_initialize_session(), tn_apply(), tn_get_etn(), tos_handler(), transport_apply(), transport_tls_file_handler(), transport_tos_handler(), uac_algorithms_handler(), uas_algorithms_handler(), unload_engine(), update_devstate(), user_apply(), user_dtor(), users_apply_handler(), validate_publish_config(), verification_apply(), verify(), wc_apply(), and wc_dtor().

◆ ast_sorcery_object_get_type()

const char * ast_sorcery_object_get_type ( const void *  object)

Get the type of a sorcery object.

Parameters
objectPointer to a sorcery object
Returns
type of object

Definition at line 2393 of file sorcery.c.

2394{
2395 const struct ast_sorcery_object_details *details = object;
2396 return details->object->type;
2397}

References ast_sorcery_object_details::object, and ast_sorcery_object::type.

Referenced by aeap_cli_show(), ast_sorcery_diff(), AST_TEST_DEFINE(), config_object_cli_show(), memory_cache_stale_check_object(), memory_cache_stale_update_object(), sip_aor_to_ami(), sip_sorcery_object_ami_set_type_name(), sorcery_astdb_create(), sorcery_astdb_delete(), sorcery_astdb_update(), and stale_item_update().

◆ ast_sorcery_object_has_dynamic_contents()

unsigned int ast_sorcery_object_has_dynamic_contents ( const void *  object)

Get whether an object contains dynamic contents or not.

Parameters
objectPointer to a sorcery object
Since
19
18.3.0
16.17.0

Definition at line 2441 of file sorcery.c.

2442{
2443 const struct ast_sorcery_object_details *details = object;
2444
2445 return details->object->has_dynamic_contents;
2446}
unsigned int has_dynamic_contents
Whether this object has dynamic contents or not.
Definition sorcery.c:145

References ast_sorcery_object::has_dynamic_contents, and ast_sorcery_object_details::object.

Referenced by sorcery_config_internal_load().

◆ ast_sorcery_object_id_compare()

int ast_sorcery_object_id_compare ( void *  obj,
void *  arg,
int  flags 
)

ao2 object comparator based on sorcery id.

Definition at line 2528 of file sorcery.c.

2529{
2530 int cmp;
2531
2532 cmp = ast_sorcery_object_id_sort(obj, arg, flags);
2533 if (cmp) {
2534 return 0;
2535 }
2536 return CMP_MATCH;
2537}
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition sorcery.c:2504

References ast_sorcery_object_id_sort(), and CMP_MATCH.

Referenced by ast_media_cache_init(), ast_sorcery_retrieve_by_fields(), ast_sorcery_retrieve_by_prefix(), ast_sorcery_retrieve_by_regex(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), handle_registrations(), register_aor_core(), sip_options_aor_alloc(), and sorcery_config_internal_load().

◆ ast_sorcery_object_id_hash()

int ast_sorcery_object_id_hash ( const void *  obj,
int  flags 
)

ao2 object hasher based on sorcery id.

Definition at line 2539 of file sorcery.c.

2540{
2541 const char *key;
2542
2543 switch (flags & OBJ_SEARCH_MASK) {
2544 case OBJ_SEARCH_KEY:
2545 key = obj;
2546 break;
2547 case OBJ_SEARCH_OBJECT:
2548 key = ast_sorcery_object_get_id(obj);
2549 break;
2550 default:
2551 /* Hash can only work on something with a full key. */
2552 ast_assert(0);
2553 return 0;
2554 }
2555 return ast_str_hash(key);
2556}
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition astobj2.h:1087
@ OBJ_SEARCH_MASK
Search option field mask.
Definition astobj2.h:1072
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition strings.h:1259

References ast_assert, ast_sorcery_object_get_id(), ast_str_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by ast_media_cache_init(), sip_options_aor_alloc(), and sorcery_config_internal_load().

◆ ast_sorcery_object_id_sort()

int ast_sorcery_object_id_sort ( const void *  obj,
const void *  arg,
int  flags 
)

ao2 object sorter based on sorcery id.

Definition at line 2504 of file sorcery.c.

2505{
2506 const void *object_left = obj;
2507 const void *object_right = arg;
2508 const char *right_key = arg;
2509 int cmp;
2510
2511 switch (flags & OBJ_SEARCH_MASK) {
2512 case OBJ_SEARCH_OBJECT:
2513 right_key = ast_sorcery_object_get_id(object_right);
2514 /* Fall through */
2515 case OBJ_SEARCH_KEY:
2516 cmp = strcmp(ast_sorcery_object_get_id(object_left), right_key);
2517 break;
2519 cmp = strncmp(ast_sorcery_object_get_id(object_left), right_key, strlen(right_key));
2520 break;
2521 default:
2522 cmp = 0;
2523 break;
2524 }
2525 return cmp;
2526}
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition astobj2.h:1116

References ast_sorcery_object_get_id(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by ast_sorcery_object_id_compare(), ast_sorcery_retrieve_by_fields(), ast_sorcery_retrieve_by_prefix(), ast_sorcery_retrieve_by_regex(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_config_show_profiles(), and sip_options_aor_alloc().

◆ ast_sorcery_object_set_congestion_levels()

int ast_sorcery_object_set_congestion_levels ( struct ast_sorcery sorcery,
const char *  type,
long  low_water,
long  high_water 
)

Set the high and low alert water marks of the sorcery object type.

Since
13.10.0
Parameters
sorceryPointer to a sorcery structure
typeType of object
low_waterNew queue low water mark. (-1 to set as 90% of high_water)
high_waterNew queue high water mark.
Return values
0on success.
-1on error (water marks not changed).

Definition at line 1178 of file sorcery.c.

1179{
1180 struct ast_sorcery_object_type *object_type;
1181 int res = -1;
1182
1183 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1184 if (object_type) {
1186 low_water, high_water);
1187 ao2_ref(object_type, -1);
1188 }
1189 return res;
1190}
int ast_taskprocessor_alert_set_levels(struct ast_taskprocessor *tps, long low_water, long high_water)
Set the high and low alert water marks of the given taskprocessor queue.

References ao2_find, ao2_ref, ast_taskprocessor_alert_set_levels(), OBJ_SEARCH_KEY, ast_sorcery_object_type::serializer, sorcery, type, and ast_sorcery::types.

Referenced by ast_sip_initialize_sorcery_location().

◆ ast_sorcery_object_set_copy_handler()

void ast_sorcery_object_set_copy_handler ( struct ast_sorcery sorcery,
const char *  type,
sorcery_copy_handler  copy 
)

Set the copy handler for an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
copyCopy handler

Definition at line 1192 of file sorcery.c.

1193{
1195
1196 if (!object_type) {
1197 return;
1198 }
1199
1200 object_type->copy = copy;
1201}

References ao2_cleanup, ao2_find, copy(), OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by ast_bucket_init(), and AST_TEST_DEFINE().

◆ ast_sorcery_object_set_diff_handler()

void ast_sorcery_object_set_diff_handler ( struct ast_sorcery sorcery,
const char *  type,
sorcery_diff_handler  diff 
)

Set the diff handler for an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
diffDiff handler

Definition at line 1203 of file sorcery.c.

1204{
1206
1207 if (!object_type) {
1208 return;
1209 }
1210
1211 object_type->diff = diff;
1212}

References ao2_cleanup, ao2_find, ast_sorcery_object_type::diff, OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_object_set_extended()

int ast_sorcery_object_set_extended ( const void *  object,
const char *  name,
const char *  value 
)

Set an extended field value on a sorcery object.

Parameters
objectPointer to a sorcery object
nameName of the extended field
valueValue of the extended field
Return values
0success
-1failure
Note
The field name MUST begin with '@' to indicate it is an extended field.
If the extended field already exists it will be overwritten with the new value.

Definition at line 2413 of file sorcery.c.

2414{
2416 struct ast_variable *extended = ast_variable_new(name, value, ""), *previous = NULL;
2417 const struct ast_sorcery_object_details *details = object;
2418
2419 if (!extended) {
2420 return -1;
2421 }
2422
2423 for (field = details->object->extended; field; previous = field, field = field->next) {
2424 if (!strcmp(field->name, name)) {
2425 if (previous) {
2426 previous->next = field->next;
2427 } else {
2428 details->object->extended = field->next;
2429 }
2430 field->next = NULL;
2431 break;
2432 }
2433 }
2434
2435 extended->next = details->object->extended;
2436 details->object->extended = extended;
2437
2438 return 0;
2439}

References ast_variable_new, ast_variables_destroy(), ast_sorcery_object::extended, name, ast_variable::next, NULL, ast_sorcery_object_details::object, RAII_VAR, and value.

Referenced by AST_TEST_DEFINE(), and sorcery_extended_config_handler().

◆ ast_sorcery_object_set_has_dynamic_contents()

void ast_sorcery_object_set_has_dynamic_contents ( const void *  object)

Set the dynamic contents flag on a sorcery object.

Parameters
objectPointer to a sorcery object
Since
19
18.3.0
16.17.0

Definition at line 2448 of file sorcery.c.

2449{
2450 const struct ast_sorcery_object_details *details = object;
2451
2452 details->object->has_dynamic_contents = 1;
2453}

References ast_sorcery_object::has_dynamic_contents, and ast_sorcery_object_details::object.

Referenced by ip_identify_apply(), and transport_tls_file_handler().

◆ ast_sorcery_object_unregister()

int ast_sorcery_object_unregister ( struct ast_sorcery sorcery,
const char *  type 
)

Unregister an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
Return values
0success
-1failure

Definition at line 1125 of file sorcery.c.

1126{
1127 struct ast_sorcery_object_type *object_type;
1128 int res = -1;
1129
1131 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1132 if (object_type && object_type->type.type == ACO_ITEM) {
1133 ao2_unlink_flags(sorcery->types, object_type, OBJ_NOLOCK);
1134 res = 0;
1135 }
1137
1138 /* XXX may need to add an instance unregister observer callback on success. */
1139
1140 ao2_cleanup(object_type);
1141 return res;
1142}
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
Definition astobj2.h:1600
enum aco_type_t type
struct aco_type type
Type details.
Definition sorcery.c:178

References ACO_ITEM, ao2_cleanup, ao2_find, ao2_unlink_flags, ao2_unlock, ao2_wrlock, OBJ_NOLOCK, OBJ_SEARCH_KEY, sorcery, type, aco_type::type, ast_sorcery_object_type::type, and ast_sorcery::types.

Referenced by geoloc_config_unload(), unload_module(), unload_module(), and unload_module().

◆ ast_sorcery_objectset_apply()

int ast_sorcery_objectset_apply ( const struct ast_sorcery sorcery,
void *  object,
struct ast_variable objectset 
)

Apply an object set (KVP list) to an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
objectsetObject set itself
Return values
0success
-1failure
Note
This operation is not atomic. If this fails it is possible for the object to be left with a partially applied object set.

Definition at line 1696 of file sorcery.c.

1697{
1698 const struct ast_sorcery_object_details *details = object;
1699 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1700 RAII_VAR(struct ast_variable *, transformed, NULL, ast_variables_destroy);
1701 struct ast_variable *field;
1702 int res = 0;
1703
1704 if (!object_type) {
1705 return -1;
1706 }
1707
1708 if (object_type->transform && (transformed = object_type->transform(objectset))) {
1709 field = transformed;
1710 } else {
1711 field = objectset;
1712 }
1713
1714 for (; field; field = field->next) {
1715 if ((res = aco_process_var(&object_type->type, details->object->id, field, object))) {
1716 break;
1717 }
1718 }
1719
1720 if (!res && object_type->apply) {
1721 res = object_type->apply(sorcery, object);
1722 }
1723
1724 return res;
1725}
int aco_process_var(struct aco_type *type, const char *cat, struct ast_variable *var, void *obj)
Parse a single ast_variable and apply it to an object.

References aco_process_var(), ao2_cleanup, ao2_find, ast_variables_destroy(), ast_sorcery_object::id, ast_variable::next, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by ast_ari_asterisk_update_object(), ast_sorcery_copy(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), create_effective_profile(), create_object(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_config_internal_load(), sorcery_realtime_retrieve_fields(), and sorcery_realtime_retrieve_multiple().

◆ ast_sorcery_objectset_create2()

struct ast_variable * ast_sorcery_objectset_create2 ( const struct ast_sorcery sorcery,
const void *  object,
enum ast_sorcery_field_handler_flags  flags 
)

Create an object set (KVP list) for an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
flagsFlags indicating which handler to use and in what order.
Return values
non-NULLsuccess
NULLif error occurred
Note
The returned ast_variable list must be destroyed using ast_variables_destroy

Definition at line 1575 of file sorcery.c.

1577{
1578 const struct ast_sorcery_object_details *details = object;
1579 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1580 struct ao2_iterator i;
1581 struct ast_sorcery_object_field *object_field;
1582 struct ast_variable *head = NULL;
1583 struct ast_variable *tail = NULL;
1584
1585 if (!object_type) {
1586 return NULL;
1587 }
1588
1589 i = ao2_iterator_init(object_type->fields, 0);
1590
1591 for (; (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1592 struct ast_variable *tmp;
1593
1594 switch (flags) {
1596 if ((tmp = get_multiple_fields_as_var_list(object, object_field)) ||
1597 (tmp = get_single_field_as_var_list(object, object_field))) {
1598 break;
1599 }
1600 continue;
1602 if ((tmp = get_single_field_as_var_list(object, object_field)) ||
1603 (tmp = get_multiple_fields_as_var_list(object, object_field))) {
1604 break;
1605 }
1606 continue;
1608 if ((tmp = get_multiple_fields_as_var_list(object, object_field))) {
1609 break;
1610 }
1611 continue;
1613 if ((tmp = get_single_field_as_var_list(object, object_field))) {
1614 break;
1615 }
1616 continue;
1617 default:
1618 continue;
1619 }
1620
1621 tail = ast_variable_list_append_hint(&head, tail, tmp);
1622 }
1623
1625
1626 return head;
1627}
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct ast_variable * ast_variable_list_append_hint(struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *new_var)
Appends a variable list to the end of another list.
static struct ast_variable * get_single_field_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition sorcery.c:1542
static struct ast_variable * get_multiple_fields_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition sorcery.c:1559
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821

References ao2_cleanup, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_HANDLER_ONLY_LIST, AST_HANDLER_ONLY_STRING, AST_HANDLER_PREFER_LIST, AST_HANDLER_PREFER_STRING, ast_variable_list_append_hint(), get_multiple_fields_as_var_list(), get_single_field_as_var_list(), NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by ast_sip_sorcery_object_to_ami(), config_object_cli_show(), and sip_aor_to_ami().

◆ ast_sorcery_objectset_json_create()

struct ast_json * ast_sorcery_objectset_json_create ( const struct ast_sorcery sorcery,
const void *  object 
)

Create an object set in JSON format for an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
non-NULLsuccess
NULLif error occurred
Note
The returned ast_json object must be unreferenced using ast_json_unref

Definition at line 1629 of file sorcery.c.

1630{
1631 const struct ast_sorcery_object_details *details = object;
1632 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1633 struct ao2_iterator i;
1634 struct ast_sorcery_object_field *object_field;
1635 struct ast_json *json = ast_json_object_create();
1636 int res = 0;
1637
1638 if (!object_type || !json) {
1639 ast_json_unref(json);
1640 return NULL;
1641 }
1642
1643 i = ao2_iterator_init(object_type->fields, 0);
1644
1645 for (; !res && (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1646 if (object_field->multiple_handler) {
1647 struct ast_variable *tmp = NULL;
1648 struct ast_variable *field;
1649
1650 if ((res = object_field->multiple_handler(object, &tmp))) {
1652 ao2_ref(object_field, -1);
1653 break;
1654 }
1655
1656 for (field = tmp; field; field = field->next) {
1657 struct ast_json *value = ast_json_string_create(field->value);
1658
1659 if (!value || ast_json_object_set(json, field->name, value)) {
1660 res = -1;
1661 break;
1662 }
1663 }
1664
1666 } else if (object_field->handler) {
1667 char *buf = NULL;
1668 struct ast_json *value = NULL;
1669
1670 if (object_field->handler(object, object_field->args, &buf)
1672 || ast_json_object_set(json, object_field->name, value)) {
1673 ast_free(buf);
1674 ast_debug(5, "Skipping field '%s' for object type '%s'\n",
1675 object_field->name, object_type->name);
1676 continue;
1677 }
1678
1679 ast_free(buf);
1680 } else {
1681 continue;
1682 }
1683 }
1684
1686
1687 /* If any error occurs we destroy the JSON object so a partial objectset is not returned */
1688 if (res) {
1689 ast_json_unref(json);
1690 json = NULL;
1691 }
1692
1693 return json;
1694}
char buf[BUFSIZE]
Definition eagi_proxy.c:66
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition json.c:278
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition json.c:73
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
Definition json.c:399
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition json.c:414

References ao2_cleanup, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_sorcery_object_field::args, ast_debug, ast_free, ast_json_object_create(), ast_json_object_set(), ast_json_string_create(), ast_json_unref(), ast_variables_destroy(), buf, ast_sorcery_object_field::handler, ast_sorcery_object_field::multiple_handler, ast_variable::name, ast_sorcery_object_field::name, ast_variable::next, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, ast_sorcery_object::type, ast_sorcery::types, ast_variable::value, and value.

Referenced by ast_bucket_file_json(), ast_bucket_json(), AST_TEST_DEFINE(), and sorcery_astdb_create().

◆ ast_sorcery_observer_add()

int ast_sorcery_observer_add ( const struct ast_sorcery sorcery,
const char *  type,
const struct ast_sorcery_observer callbacks 
)

Add an observer to a specific object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object that should be observed
callbacksImplementation of the observer interface
Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 2455 of file sorcery.c.

2456{
2459 int res;
2460
2461 if (!object_type || !callbacks) {
2462 return -1;
2463 }
2464
2465 if (!(observer = ao2_alloc(sizeof(*observer), NULL))) {
2466 return -1;
2467 }
2468
2469 observer->callbacks = callbacks;
2470 res = 0;
2471 if (!ao2_link(object_type->observers, observer)) {
2472 res = -1;
2473 }
2474 ao2_ref(observer, -1);
2475
2476 return res;
2477}
struct ast_sorcery_instance_observer observer
Structure for registered object type observer.
Definition sorcery.c:191

References ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ao2_ref, callbacks, NULL, OBJ_KEY, observer, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by ari_conf_init(), ari_sorcery_observer_add(), ast_bucket_file_observer_add(), ast_bucket_observer_add(), ast_res_pjsip_initialize_configuration(), ast_sip_initialize_distributor(), ast_sip_initialize_sorcery_auth(), ast_sip_initialize_sorcery_location(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), ast_websocket_client_observer_add(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), pjsip_outbound_registration_metrics_init(), and sip_options_init_task().

◆ ast_sorcery_observer_remove()

void ast_sorcery_observer_remove ( const struct ast_sorcery sorcery,
const char *  type,
const struct ast_sorcery_observer callbacks 
)

Remove an observer from a specific object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object that should no longer be observed
callbacksImplementation of the observer interface

Definition at line 2487 of file sorcery.c.

2488{
2489 RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
2490 struct ast_sorcery_observer *cbs = (struct ast_sorcery_observer *) callbacks;/* Remove const for traversal. */
2491
2492 if (!sorcery) {
2493 return;
2494 }
2495 object_type = ao2_find(sorcery->types, type, OBJ_KEY);
2496 if (!object_type) {
2497 return;
2498 }
2499
2500 ao2_callback(object_type->observers, OBJ_NODATA | OBJ_UNLINK,
2502}
static int sorcery_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing an observer.
Definition sorcery.c:2480

References ao2_callback, ao2_cleanup, ao2_find, callbacks, NULL, OBJ_KEY, OBJ_NODATA, OBJ_UNLINK, RAII_VAR, sorcery, sorcery_observer_remove(), type, and ast_sorcery::types.

Referenced by ari_sorcery_observer_remove(), ast_bucket_file_observer_remove(), ast_bucket_observer_remove(), ast_res_pjsip_cleanup_options_handling(), ast_sip_destroy_distributor(), ast_sip_destroy_sorcery_auth(), ast_sip_destroy_sorcery_location(), ast_sip_destroy_transport_management(), ast_websocket_client_observer_remove(), load_module(), pjsip_outbound_registration_metrics_init(), pjsip_outbound_registration_metrics_unload_cb(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), and unload_module().

◆ ast_sorcery_ref()

void ast_sorcery_ref ( struct ast_sorcery sorcery)

Increase the reference count of a sorcery structure.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1537 of file sorcery.c.

1538{
1539 ao2_ref(sorcery, +1);
1540}

References ao2_ref, and sorcery.

Referenced by geoloc_get_sorcery().

◆ ast_sorcery_reload()

void ast_sorcery_reload ( const struct ast_sorcery sorcery)

Inform any wizards to reload persistent objects.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1472 of file sorcery.c.

1473{
1474 struct sorcery_load_details details = {
1475 .sorcery = sorcery,
1476 .reload = 1,
1477 };
1478
1479 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1481
1483
1486
1487}

References ao2_callback, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, OBJ_NODATA, ast_sorcery::observers, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), and ast_sorcery::types.

Referenced by ast_res_pjsip_reload_configuration(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_reload(), geoloc_config_reload(), load_module(), reload_module(), reload_module(), reload_module(), and reload_module().

◆ ast_sorcery_reload_object()

void ast_sorcery_reload_object ( const struct ast_sorcery sorcery,
const char *  type 
)

Inform any wizards of a specific object type to reload persistent objects.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to reload

Definition at line 1506 of file sorcery.c.

1507{
1509 struct sorcery_load_details details = {
1510 .sorcery = sorcery,
1511 .reload = 1,
1512 };
1513
1514 if (!object_type) {
1515 return;
1516 }
1517
1518 sorcery_object_load(object_type, &details, 0);
1519}

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), type, and ast_sorcery::types.

Referenced by apply_list_configuration(), ari_conf_load(), ast_sip_initialize_distributor(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), load_users(), reload_module(), reload_module(), reload_module(), and reload_module().

◆ ast_sorcery_retrieve_by_fields()

void * ast_sorcery_retrieve_by_fields ( const struct ast_sorcery sorcery,
const char *  type,
unsigned int  flags,
struct ast_variable fields 
)

Retrieve an object or multiple objects using specific fields.

Since
13.9.0
Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
flagsFlags to control behavior
fieldsOptional object fields and values to match against
Return values
non-NULLif found
NULLif not found
Note
If the AST_RETRIEVE_FLAG_MULTIPLE flag is specified the returned value will be an ao2_container that must be unreferenced after use.
If the AST_RETRIEVE_FLAG_ALL flag is used you may omit fields to retrieve all objects of the given type.
The fields parameter can contain realtime-style expressions in variable->name. All operators defined for ast_strings_match can be used except for regex as there's no common support for regex in the realtime backends at this time. If multiple variables are in the fields list, all must match for an object to be returned. See ast_strings_match for more information.

Example:

The following code can be significantly faster when a realtime backend is in use because the expression "qualify_frequency > 0" is passed to the database to limit the number of rows returned.

struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", ""); struct ao2_container *aors;

if (!var) { return; }

aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "aor", AST_RETRIEVE_FLAG_MULTIPLE, var);

Definition at line 1961 of file sorcery.c.

1962{
1964 void *object = NULL;
1965 int i;
1966 unsigned int cached = 0;
1967
1968 if (!object_type) {
1969 return NULL;
1970 }
1971
1972 /* If returning multiple objects create a container to store them in */
1973 if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1975 if (!object) {
1976 return NULL;
1977 }
1978 }
1979
1980 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1981 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1983 AST_VECTOR_GET(&object_type->wizards, i);
1984
1985 if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1986 if (wizard->wizard->callbacks.retrieve_multiple) {
1987 wizard->wizard->callbacks.retrieve_multiple(sorcery, wizard->data, object_type->name, object, fields);
1988 }
1989 } else if (fields && wizard->wizard->callbacks.retrieve_fields) {
1990 if (wizard->wizard->callbacks.retrieve_fields) {
1991 object = wizard->wizard->callbacks.retrieve_fields(sorcery, wizard->data, object_type->name, fields);
1992 }
1993 }
1994
1995 if (((flags & AST_RETRIEVE_FLAG_MULTIPLE) && (!ao2_container_count(object) || !wizard->caching)) || !object) {
1996 continue;
1997 }
1998
1999 cached = wizard->caching;
2000
2001 break;
2002 }
2003
2004 /* If we are returning a single object and it came from a non-cache source create it in any caches */
2005 if (!(flags & AST_RETRIEVE_FLAG_MULTIPLE) && !cached && object) {
2006 struct sorcery_details sdetails = {
2007 .sorcery = sorcery,
2008 .obj = object,
2009 };
2010
2011 AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, &sdetails, 0);
2012 }
2013 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2014
2015 return object;
2016}
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
Definition astobj2.h:1188
static int sorcery_cache_create(void *obj, void *arg, int flags)
Internal function used to create an object in caching wizards.
Definition sorcery.c:1903
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition sorcery.c:2528
void(* retrieve_multiple)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const struct ast_variable *fields)
Optional callback for retrieving multiple objects using some optional field criteria.
Definition sorcery.h:313
void *(* retrieve_fields)(const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields)
Optional callback for retrieving an object using fields.
Definition sorcery.h:310
#define AST_VECTOR_CALLBACK(vec, callback, default_value,...)
Execute a callback on every element in a vector returning the first matched.
Definition vector.h:776

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_container_count(), ao2_find, AST_RETRIEVE_FLAG_MULTIPLE, ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), AST_VECTOR_CALLBACK, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, NULL, OBJ_KEY, RAII_VAR, ast_sorcery_wizard::retrieve_fields, ast_sorcery_wizard::retrieve_multiple, sorcery_details::sorcery, sorcery, sorcery_cache_create(), type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by acl_on_rx_msg(), ami_show_registration_contact_statuses(), ami_show_resource_lists(), ari_conf_get_owcs(), ari_conf_get_users(), ast_aeap_client_configs_get(), ast_mwi_mailbox_get_all(), ast_sip_get_endpoints(), ast_sip_initialize_sorcery_transport(), ast_sip_initialize_system(), ast_sip_location_prune_boot_contacts(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_retrieve_all(), asterisk_publication_send_refresh(), auth_observer(), check_expiration_thread(), cli_complete_registration(), cli_contact_get_container(), cli_get_aors(), cli_get_auths(), cli_iterator(), common_identify(), create_mwi_subscriptions(), eprofile_get_all(), format_ami_endpoint_identify(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_config_show_profiles(), get_all_contacts(), get_publishes_and_update_state(), get_registrations(), get_system_cfg(), get_tn_all(), global_loaded_observer(), handle_export_primitives(), load_all_endpoints(), load_users(), memory_cache_populate(), process_nat(), profile_get_all(), sip_options_aor_observer_modified_task(), sip_options_synchronize_task(), stale_cache_update(), and subscription_persistence_load().

◆ ast_sorcery_retrieve_by_id()

void * ast_sorcery_retrieve_by_id ( const struct ast_sorcery sorcery,
const char *  type,
const char *  id 
)

Retrieve an object using its unique identifier.

Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
idUnique object identifier
Return values
non-NULLif found
NULLif not found

Definition at line 1917 of file sorcery.c.

1918{
1919 struct ast_sorcery_object_type *object_type;
1920 void *object = NULL;
1921 int i;
1922 unsigned int cached = 0;
1923
1924 if (ast_strlen_zero(id)) {
1925 return NULL;
1926 }
1927
1928 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1929 if (!object_type) {
1930 return NULL;
1931 }
1932
1933 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1934 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1936 AST_VECTOR_GET(&object_type->wizards, i);
1937
1938 if (wizard->wizard->callbacks.retrieve_id &&
1939 !(object = wizard->wizard->callbacks.retrieve_id(sorcery, wizard->data, object_type->name, id))) {
1940 continue;
1941 }
1942
1943 cached = wizard->caching;
1944 break;
1945 }
1946
1947 if (!cached && object) {
1948 struct sorcery_details sdetails = {
1949 .sorcery = sorcery,
1950 .obj = object,
1951 };
1952
1953 AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, &sdetails, 0);
1954 }
1955 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1956
1957 ao2_ref(object_type, -1);
1958 return object;
1959}
char name[MAX_OBJECT_TYPE]
Unique name of the object type.
Definition sorcery.c:151
void *(* retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving an object using an id.
Definition sorcery.h:296

References ao2_find, ao2_ref, ast_strlen_zero(), AST_VECTOR_CALLBACK, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_type::name, NULL, OBJ_SEARCH_KEY, ast_sorcery_wizard::retrieve_id, sorcery_details::sorcery, sorcery, sorcery_cache_create(), type, ast_sorcery::types, ast_sorcery_object_wizard::wizard, and ast_sorcery_object_type::wizards.

Referenced by add_security_headers(), ami_show_endpoint(), ami_sip_qualify(), anonymous_identify(), ari_conf_get_general(), ari_conf_get_owc(), ari_conf_get_user(), ari_conf_validate_user(), as_get_cfg(), as_is_config_loaded(), ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), ast_bucket_file_retrieve(), ast_bucket_retrieve(), ast_geoloc_datastore_create_from_profile_name(), ast_geoloc_eprofile_refresh_location(), ast_geoloc_get_location(), ast_geoloc_get_profile(), ast_mwi_mailbox_get(), ast_mwi_mailbox_update(), ast_sip_default_outbound_endpoint(), ast_sip_for_each_auth(), ast_sip_location_retrieve_aor(), ast_sip_location_retrieve_contact(), ast_sip_retrieve_auths(), ast_sip_retrieve_auths_vector(), ast_sip_rewrite_uri_to_local(), ast_sip_set_tpselector_from_transport_name(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_retrieve_by_id(), asterisk_publication_devicestate_state_change(), asterisk_publication_mwi_state_change(), asterisk_publication_new(), chan_pjsip_devicestate(), check_state(), cli_aor_retrieve_by_id(), cli_endpoint_retrieve_by_id(), cli_iterate(), cli_qualify(), cli_reload_qualify_aor(), cli_reload_qualify_endpoint(), cli_retrieve_by_id(), cli_retrieve_by_id(), cli_retrieve_by_id(), cli_retrieve_by_id(), cli_show_qualify_endpoint(), client_config_get(), common_identify(), contact_observer_updated(), create_effective_profile(), create_rtp(), eprofile_get_cfg(), find_aor2(), find_aor_name(), find_endpoint(), format_ami_endpoint_transport(), geoloc_profile_apply_handler(), get_log_mappings(), get_write_timeout(), handle_atsign(), handle_registration_response(), handle_single_token(), handle_slash(), line_identify(), load_endpoint(), mwi_contact_changed(), mwi_contact_deleted(), mwi_subscription_shutdown(), on_rx_process_symmetric_transport(), outbound_websocket_validate_cb(), pjsip_acf_dial_contacts_read(), pjsip_aor_function_read(), pjsip_contact_function_read(), pjsip_endpoint_function_read(), process_nat(), profile_get_cfg(), publish_request_initial(), push_notify(), request(), retrieve_resource_list(), send_unsolicited_mwi_notify(), sip_options_contact_add_management_task(), sip_options_qualify_contact(), sorcery_function_read(), sorcery_memory_cache_thrash_retrieve(), stale_item_update(), sub_persistence_recreate(), t38_initialize_session(), tn_get_cfg(), tn_get_etn(), transfer(), vs_get_cfg(), and vs_is_config_loaded().

◆ ast_sorcery_retrieve_by_module_name()

struct ast_sorcery * ast_sorcery_retrieve_by_module_name ( const char *  module_name)

Retrieves an existing sorcery instance by module name.

Parameters
module_nameThe module name
Return values
non-NULLsuccess
NULLif no instance was found
Note
The returned instance has its reference count incremented. The caller must decrement the count when they're finished with it.

Retrieves an existing sorcery instance by module name.

Definition at line 736 of file sorcery.c.

737{
738 return ao2_weakproxy_find(instances, module_name, OBJ_SEARCH_KEY, "");
739}
#define ao2_weakproxy_find(c, arg, flags, tag)
Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.
Definition astobj2.h:1748

References ao2_weakproxy_find, instances, ast_sorcery::module_name, and OBJ_SEARCH_KEY.

Referenced by ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), AST_TEST_DEFINE(), and sorcery_function_read().

◆ ast_sorcery_retrieve_by_prefix()

struct ao2_container * ast_sorcery_retrieve_by_prefix ( const struct ast_sorcery sorcery,
const char *  type,
const char *  prefix,
const size_t  prefix_len 
)

Retrieve multiple objects whose id begins with the specified prefix.

Since
13.19.0
Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
prefixObject id prefix
prefix_lenThe length of prefix in bytes
Return values
non-NULLif error occurs
NULLsuccess
Note
The prefix is matched in a case sensitive manner.

Definition at line 2053 of file sorcery.c.

2054{
2056 struct ao2_container *objects;
2057 int i;
2058
2059 if (!object_type) {
2060 return NULL;
2061 }
2062
2064 if (!objects) {
2065 return NULL;
2066 }
2067
2068 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2069 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2071 AST_VECTOR_GET(&object_type->wizards, i);
2072
2073 if (!wizard->wizard->callbacks.retrieve_prefix) {
2074 continue;
2075 }
2076
2077 wizard->wizard->callbacks.retrieve_prefix(sorcery, wizard->data, object_type->name, objects, prefix, prefix_len);
2078
2079 if (wizard->caching && ao2_container_count(objects)) {
2080 break;
2081 }
2082 }
2083 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2084
2085 return objects;
2086}
void(* retrieve_prefix)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *prefix, const size_t prefix_len)
Optional callback for retrieving multiple objects by matching their id with a prefix.
Definition sorcery.h:302

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_container_count(), ao2_find, ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, NULL, OBJ_KEY, prefix, RAII_VAR, ast_sorcery_wizard::retrieve_prefix, sorcery, type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by aor_deleted_observer(), ast_sip_location_retrieve_aor_contacts_nolock_filtered(), cli_complete_endpoint(), and sip_options_apply_aor_configuration().

◆ ast_sorcery_retrieve_by_regex()

struct ao2_container * ast_sorcery_retrieve_by_regex ( const struct ast_sorcery sorcery,
const char *  type,
const char *  regex 
)

Retrieve multiple objects using a regular expression on their id.

Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
regexRegular expression
Return values
non-NULLif error occurs
NULLsuccess
Note
The provided regex is treated as extended case sensitive.

Definition at line 2018 of file sorcery.c.

2019{
2021 struct ao2_container *objects;
2022 int i;
2023
2024 if (!object_type) {
2025 return NULL;
2026 }
2027
2029 if (!objects) {
2030 return NULL;
2031 }
2032
2033 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2034 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2036 AST_VECTOR_GET(&object_type->wizards, i);
2037
2038 if (!wizard->wizard->callbacks.retrieve_regex) {
2039 continue;
2040 }
2041
2042 wizard->wizard->callbacks.retrieve_regex(sorcery, wizard->data, object_type->name, objects, regex);
2043
2044 if (wizard->caching && ao2_container_count(objects)) {
2045 break;
2046 }
2047 }
2048 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2049
2050 return objects;
2051}
void(* retrieve_regex)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *regex)
Callback for retrieving multiple objects using a regex on their id.
Definition sorcery.h:299

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_container_count(), ao2_find, ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, NULL, OBJ_KEY, RAII_VAR, regex(), ast_sorcery_wizard::retrieve_regex, sorcery, type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by ast_mwi_mailbox_get_by_regex(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), cli_aor_get_container(), cli_contact_get_container(), cli_endpoint_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), geoloc_config_list_locations(), geoloc_config_list_profiles(), and geoloc_config_show_profiles().

◆ ast_sorcery_update()

int ast_sorcery_update ( const struct ast_sorcery sorcery,
void *  object 
)

Update an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2214 of file sorcery.c.

2215{
2216 const struct ast_sorcery_object_details *details = object;
2217 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2218 struct ast_sorcery_object_wizard *object_wizard = NULL;
2219 struct ast_sorcery_object_wizard *found_wizard;
2220 int i;
2221 struct sorcery_details sdetails = {
2222 .sorcery = sorcery,
2223 .obj = object,
2224 };
2225
2226 if (!object_type) {
2227 return -1;
2228 }
2229
2230 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2231 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2232 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2233 if (!found_wizard->caching
2234 && sorcery_wizard_update(found_wizard, &sdetails) == CMP_MATCH) {
2235 object_wizard = found_wizard;
2236 }
2237 }
2238
2239 if (object_wizard) {
2240 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2241 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2242 if (found_wizard->caching) {
2243 sorcery_wizard_update(found_wizard, &sdetails);
2244 }
2245 }
2246
2247 if (ao2_container_count(object_type->observers)) {
2248 struct sorcery_observer_invocation *invocation;
2249
2250 invocation = sorcery_observer_invocation_alloc(object_type, object);
2251 if (invocation
2253 invocation)) {
2254 ao2_cleanup(invocation);
2255 }
2256 }
2257 }
2258
2260
2261 return object_wizard ? 0 : -1;
2262}
static int sorcery_wizard_update(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if a wizard has updated the object.
Definition sorcery.c:2200
static int sorcery_observers_notify_update(void *data)
Internal callback function which notifies observers that an object has been updated.
Definition sorcery.c:2189

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery_details::sorcery, sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_update(), sorcery_wizard_update(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by ast_ari_asterisk_update_object(), ast_bucket_file_update(), ast_mwi_mailbox_update(), ast_sip_location_update_contact(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), create_effective_profile(), sorcery_memory_cache_thrash_update(), and subscription_persistence_update().

◆ ast_sorcery_wizard_observer_add()

int ast_sorcery_wizard_observer_add ( struct ast_sorcery_wizard wizard,
const struct ast_sorcery_wizard_observer callbacks 
)

Add an observer to a sorcery wizard.

Parameters
wizardPointer to a previously registered wizard structure
callbacksImplementation of the wizard observer interface

A wizard observer is notified... Before a wizard is loaded or reloaded. After a wizard is loaded or reloaded.

Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 607 of file sorcery.c.

609{
610 RAII_VAR(struct ast_sorcery_internal_wizard *, wizard,
611 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL,
613
614 if (wizard) {
615 struct sorcery_wizard_observer *cb;
616
617 cb = ao2_alloc(sizeof(*cb), NULL);
618 if (!cb) {
619 return -1;
620 }
621
622 cb->callbacks = callbacks;
623 ao2_link(wizard->observers, cb);
624 ao2_ref(cb, -1);
625
626 return 0;
627 }
628
629 return -1;
630}
A wizard observer wrapper.
Definition sorcery.c:277
const struct ast_sorcery_wizard_observer * callbacks
Definition sorcery.c:278

References ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ao2_ref, sorcery_wizard_observer::callbacks, callbacks, ast_sorcery_wizard::name, NULL, OBJ_SEARCH_KEY, RAII_VAR, and wizards.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_wizard_observer_remove()

void ast_sorcery_wizard_observer_remove ( struct ast_sorcery_wizard interface,
const struct ast_sorcery_wizard_observer callbacks 
)

Remove an observer from a sorcery wizard.

Parameters
interfacePointer to a sorcery structure
callbacksImplementation of the wizard observer interface

Definition at line 632 of file sorcery.c.

634{
635 RAII_VAR(struct ast_sorcery_internal_wizard *, wizard,
636 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL,
638
639 if (wizard) {
641 }
642}

References ao2_callback, ao2_cleanup, ao2_find, callbacks, ast_sorcery_wizard::name, NULL, OBJ_NODATA, OBJ_SEARCH_KEY, OBJ_UNLINK, RAII_VAR, sorcery_generic_observer_remove(), and wizards.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_wizard_unregister()

int ast_sorcery_wizard_unregister ( const struct ast_sorcery_wizard interface)

Unregister a sorcery wizard.

Parameters
interfacePointer to the wizard interface
Return values
0success
-1failure

Definition at line 538 of file sorcery.c.

539{
540 struct ast_sorcery_internal_wizard *wizard =
541 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL;
542
543 if (wizard) {
544 NOTIFY_GLOBAL_OBSERVERS(observers, wizard_unregistering, wizard->callbacks.name, &wizard->callbacks);
545 ao2_unlink(wizards, wizard);
546 ao2_ref(wizard, -1);
547 ast_verb(5, "Sorcery unregistered wizard '%s'\n", interface->name);
548 return 0;
549 } else {
550 return -1;
551 }
552}
if(!yyg->yy_init)
Definition ast_expr2f.c:854
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition astobj2.h:1578

References ao2_find, ao2_ref, ao2_unlink, ast_verb, ast_sorcery_internal_wizard::callbacks, if(), name, ast_sorcery_wizard::name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_SEARCH_KEY, observers, and wizards.

Referenced by AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), bucket_cleanup(), sorcery_memory_cache_thrash_destroy(), unload_module(), unload_module(), unload_module(), unload_module(), and unload_module().

Variable Documentation

◆ ast_sorcery_update_or_create_on_update_miss

int ast_sorcery_update_or_create_on_update_miss
extern

Global control for optional update->create fallback in backends.

When non-zero, writable Sorcery backends may attempt to call create() if update() indicates the object is missing (e.g., 0 rows affected or NOT_FOUND). This helps re-populate backends that temporarily missed an insert.

Default is 0 (off) to maintain legacy behavior.

Configured via sorcery.conf: [general] update_or_create_on_update_miss = yes|no

NOTE: Backends MUST gate their fallback logic on this variable.

Definition at line 288 of file sorcery.c.

Referenced by AST_TEST_DEFINE(), cli_show_settings(), parse_general_options(), sorcery_astdb_update(), sorcery_memory_update(), and sorcery_realtime_update().