mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-13 00:04:53 +00:00
Migrate a large number of AMI events over to Stasis-Core
This patch moves a number of AMI events over to the Stasis-Core message bus. This includes: * ChanSpyStart/Stop * MonitorStart/Stop * MusicOnHoldStart/Stop * FullyBooted/Reload * All Voicemail/MWI related events In addition, it adds some Stasis-Core and AMI support for generic AMI messages, refactors the message router in AMI to use a single router with topic forwarding for the topics that AMI cares about, and refactors MWI message types and topics to be more name compliant. Review: https://reviewboard.asterisk.org/r/2532 (closes issue ASTERISK-21462) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389733 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -51,6 +51,20 @@ int ast_msg_init(void); /*!< Provided by message.c */
|
||||
void ast_msg_shutdown(void); /*!< Provided by message.c */
|
||||
int aco_init(void); /*!< Provided by config_options.c */
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Possible return types for \ref ast_module_reload
|
||||
*/
|
||||
enum ast_module_reload_result {
|
||||
AST_MODULE_RELOAD_SUCCESS = 0, /*!< The module was reloaded succesfully */
|
||||
AST_MODULE_RELOAD_QUEUED, /*!< The module reload request was queued */
|
||||
AST_MODULE_RELOAD_NOT_FOUND, /*!< The requested module was not found */
|
||||
AST_MODULE_RELOAD_ERROR, /*!< An error occurred while reloading the module */
|
||||
AST_MODULE_RELOAD_IN_PROGRESS, /*!< A module reload request is already in progress */
|
||||
AST_MODULE_RELOAD_UNINITIALIZED, /*!< The module has not been initialized */
|
||||
AST_MODULE_RELOAD_NOT_IMPLEMENTED, /*!< This module doesn't support reloading */
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Initialize the bridging system.
|
||||
* \since 12.0.0
|
||||
@@ -78,13 +92,10 @@ int ast_local_init(void);
|
||||
*
|
||||
* \note Modules are reloaded using their reload() functions, not unloading
|
||||
* them and loading them again.
|
||||
*
|
||||
* \return 0 if the specified module was not found.
|
||||
* \retval 1 if the module was found but cannot be reloaded.
|
||||
* \retval -1 if a reload operation is already in progress.
|
||||
* \retval 2 if the specfied module was found and reloaded.
|
||||
*
|
||||
* \retval The \ref ast_module_reload_result status of the module load request
|
||||
*/
|
||||
int ast_module_reload(const char *name);
|
||||
enum ast_module_reload_result ast_module_reload(const char *name);
|
||||
|
||||
/*!
|
||||
* \brief Process reload requests received during startup.
|
||||
|
@@ -1104,8 +1104,8 @@ void ast_safe_fork_cleanup(void);
|
||||
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Publish a MWI state update via stasis
|
||||
* \param[in] uniqueid A unique identifier for this mailbox (usually mailbox@context)
|
||||
* \param[in] mailbox The number identifying this mailbox
|
||||
* \param[in] context The context this mailbox resides in
|
||||
* \param[in] new_msgs The number of new messages in this mailbox
|
||||
@@ -1114,26 +1114,44 @@ int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen def
|
||||
* \retval -1 Failure
|
||||
* \since 12
|
||||
*/
|
||||
#define stasis_publish_mwi_state(mailbox, context, new_msgs, old_msgs) \
|
||||
stasis_publish_mwi_state_full(mailbox, context, new_msgs, old_msgs, NULL)
|
||||
#define ast_publish_mwi_state(mailbox, context, new_msgs, old_msgs) \
|
||||
ast_publish_mwi_state_full(mailbox, context, new_msgs, old_msgs, NULL, NULL)
|
||||
|
||||
/*!
|
||||
* \brief Publish a MWI state update via stasis with EID
|
||||
* \param[in] uniqueid A unique identifier for this mailbox (usually mailbox@context)
|
||||
* \since 12
|
||||
* \brief Publish a MWI state update associated with some channel
|
||||
* \param[in] mailbox The number identifying this mailbox
|
||||
* \param[in] context The context this mailbox resides in
|
||||
* \param[in] new_msgs The number of new messages in this mailbox
|
||||
* \param[in] old_msgs The number of old messages in this mailbox
|
||||
* \param[in] channel_id A unique identifier for a channel associated with this
|
||||
* change in mailbox state
|
||||
* \retval 0 Success
|
||||
* \retval -1 Failure
|
||||
* \since 12
|
||||
*/
|
||||
#define ast_publish_mwi_state_channel(mailbox, context, new_msgs, old_msgs, channel_id) \
|
||||
ast_publish_mwi_state_full(mailbox, context, new_msgs, old_msgs, channel_id, NULL)
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Publish a MWI state update via stasis with all parameters
|
||||
* \param[in] mailbox The number identifying this mailbox
|
||||
* \param[in] context The context this mailbox resides in
|
||||
* \param[in] new_msgs The number of new messages in this mailbox
|
||||
* \param[in] old_msgs The number of old messages in this mailbox
|
||||
* \param[in] channel_id A unique identifier for a channel associated with this
|
||||
* \param[in] eid The EID of the server that originally published the message
|
||||
* \retval 0 Success
|
||||
* \retval -1 Failure
|
||||
* \since 12
|
||||
*/
|
||||
int stasis_publish_mwi_state_full(
|
||||
int ast_publish_mwi_state_full(
|
||||
const char *mailbox,
|
||||
const char *context,
|
||||
int new_msgs,
|
||||
int old_msgs,
|
||||
const char *channel_id,
|
||||
struct ast_eid *eid);
|
||||
|
||||
/*! \addtogroup StasisTopicsAndMessages
|
||||
@@ -1144,49 +1162,103 @@ int stasis_publish_mwi_state_full(
|
||||
* \brief The structure that contains MWI state
|
||||
* \since 12
|
||||
*/
|
||||
struct stasis_mwi_state {
|
||||
struct ast_mwi_state {
|
||||
AST_DECLARE_STRING_FIELDS(
|
||||
AST_STRING_FIELD(uniqueid); /*!< Unique identifier for this mailbox/context */
|
||||
AST_STRING_FIELD(mailbox); /*!< Mailbox for this event */
|
||||
AST_STRING_FIELD(context); /*!< Context that this mailbox belongs to */
|
||||
AST_STRING_FIELD(uniqueid); /*!< Unique identifier for this mailbox/context */
|
||||
AST_STRING_FIELD(mailbox); /*!< Mailbox for this event */
|
||||
AST_STRING_FIELD(context); /*!< Context that this mailbox belongs to */
|
||||
);
|
||||
int new_msgs; /*!< The current number of new messages for this mailbox */
|
||||
int old_msgs; /*!< The current number of old messages for this mailbox */
|
||||
struct ast_eid eid; /*!< The EID of the server where this message originated */
|
||||
int new_msgs; /*!< The current number of new messages for this mailbox */
|
||||
int old_msgs; /*!< The current number of old messages for this mailbox */
|
||||
/*! If applicable, a snapshot of the channel that caused this MWI change */
|
||||
struct ast_channel_snapshot *snapshot;
|
||||
struct ast_eid eid; /*!< The EID of the server where this message originated */
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Get the Stasis topic for MWI messages
|
||||
* \brief Object that represents an MWI update with some additional application
|
||||
* defined data
|
||||
*/
|
||||
struct ast_mwi_blob {
|
||||
struct ast_mwi_state *mwi_state; /*!< MWI state */
|
||||
struct ast_json *blob; /*!< JSON blob of data */
|
||||
};
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Create a \ref ast_mwi_state object
|
||||
*
|
||||
* \retval \ref ast_mwi_state object on success
|
||||
* \retval NULL on error
|
||||
*/
|
||||
struct ast_mwi_state *ast_mwi_create(const char *mailbox, const char *context);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Creates a \ref ast_mwi_blob message.
|
||||
*
|
||||
* The \a blob JSON object requires a \c "type" field describing the blob. It
|
||||
* should also be treated as immutable and not modified after it is put into the
|
||||
* message.
|
||||
*
|
||||
* \param mwi_state MWI state associated with the update
|
||||
* \param message_type The type of message to create
|
||||
* \param blob JSON object representing the data.
|
||||
* \return \ref ast_mwi_blob message.
|
||||
* \return \c NULL on error
|
||||
*/
|
||||
struct stasis_message *ast_mwi_blob_create(struct ast_mwi_state *mwi_state,
|
||||
struct stasis_message_type *message_type,
|
||||
struct ast_json *blob);
|
||||
|
||||
/*!
|
||||
* \brief Get the \ref stasis topic for MWI messages
|
||||
* \retval The topic structure for MWI messages
|
||||
* \retval NULL if it has not been allocated
|
||||
* \since 12
|
||||
*/
|
||||
struct stasis_topic *stasis_mwi_topic_all(void);
|
||||
struct stasis_topic *ast_mwi_topic_all(void);
|
||||
|
||||
/*!
|
||||
* \brief Get the Stasis topic for MWI messages on a unique ID
|
||||
* \brief Get the \ref stasis topic for MWI messages on a unique ID
|
||||
* \param uniqueid The unique id for which to get the topic
|
||||
* \retval The topic structure for MWI messages for a given uniqueid
|
||||
* \retval NULL if it failed to be found or allocated
|
||||
* \since 12
|
||||
*/
|
||||
struct stasis_topic *stasis_mwi_topic(const char *uniqueid);
|
||||
struct stasis_topic *ast_mwi_topic(const char *uniqueid);
|
||||
|
||||
/*!
|
||||
* \brief Get the Stasis caching topic for MWI messages
|
||||
* \brief Get the \ref stasis caching topic for MWI messages
|
||||
* \retval The caching topic structure for MWI messages
|
||||
* \retval NULL if it has not been allocated
|
||||
* \since 12
|
||||
*/
|
||||
struct stasis_caching_topic *stasis_mwi_topic_cached(void);
|
||||
struct stasis_caching_topic *ast_mwi_topic_cached(void);
|
||||
|
||||
/*!
|
||||
* \brief Get the Stasis message type for MWI messages
|
||||
* \brief Get the \ref stasis message type for MWI messages
|
||||
* \retval The message type structure for MWI messages
|
||||
* \retval NULL if it has not been allocated
|
||||
* \retval NULL on error
|
||||
* \since 12
|
||||
*/
|
||||
struct stasis_message_type *stasis_mwi_state_type(void);
|
||||
struct stasis_message_type *ast_mwi_state_type(void);
|
||||
|
||||
/*!
|
||||
* \brief Get the \ref stasis message type for voicemail application specific messages
|
||||
*
|
||||
* This message type exists for those messages a voicemail application may wish to send
|
||||
* that have no logical relationship with other voicemail applications. Voicemail apps
|
||||
* that use this message type must pass a \ref ast_mwi_blob. Any extraneous information
|
||||
* in the JSON blob must be packed as key/value pair tuples of strings.
|
||||
*
|
||||
* At least one key/value tuple must have a key value of "Event".
|
||||
*
|
||||
* \retval The \ref stasis_message_type for voicemail application specific messages
|
||||
* \retval NULL on error
|
||||
* \since 12
|
||||
*/
|
||||
struct stasis_message_type *ast_mwi_vm_app_type(void);
|
||||
|
||||
/*! @} */
|
||||
|
||||
|
@@ -125,6 +125,8 @@ struct ast_json *ast_json_ref(struct ast_json *value);
|
||||
/*!
|
||||
* \brief Decrease refcount on \a value. If refcount reaches zero, \a value is freed.
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \note It is safe to pass \c NULL to this function.
|
||||
*/
|
||||
void ast_json_unref(struct ast_json *value);
|
||||
|
||||
@@ -601,6 +603,15 @@ struct ast_json_iter *ast_json_object_iter_next(struct ast_json *object, struct
|
||||
*/
|
||||
const char *ast_json_object_iter_key(struct ast_json_iter *iter);
|
||||
|
||||
/*!
|
||||
* \brief Retrieve the iterator object for a particular key
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \param key Key of the field the \c ast_json_iter points to
|
||||
* \return \ref ast_json_iter object that points to \a key
|
||||
*/
|
||||
struct ast_json_iter *ast_json_object_key_to_iter(const char *key);
|
||||
|
||||
/*!
|
||||
* \brief Get the value from an iterator.
|
||||
* \since 12.0.0
|
||||
@@ -628,6 +639,23 @@ struct ast_json *ast_json_object_iter_value(struct ast_json_iter *iter);
|
||||
*/
|
||||
int ast_json_object_iter_set(struct ast_json *object, struct ast_json_iter *iter, struct ast_json *value);
|
||||
|
||||
/*!
|
||||
* \brief Iterate over key/value pairs
|
||||
*
|
||||
* \note This is a reproduction of the jansson library's \ref json_object_foreach
|
||||
* using the equivalent ast_* wrapper functions. This creates a for loop using the various
|
||||
* iteration function calls.
|
||||
*
|
||||
* \param object The \ref ast_json object that contains key/value tuples to iterate over
|
||||
* \param key A \c const char pointer key for the key/value tuple
|
||||
* \param value A \ref ast_json object for the key/value tuple
|
||||
*/
|
||||
#define ast_json_object_foreach(object, key, value) \
|
||||
for (key = ast_json_object_iter_key(ast_json_object_iter(object)); \
|
||||
key && (value = ast_json_object_iter_value(ast_json_object_key_to_iter(key))); \
|
||||
key = ast_json_object_iter_key(ast_json_object_iter_next(object, ast_json_object_key_to_iter(key))))
|
||||
|
||||
|
||||
/*!@}*/
|
||||
|
||||
/*!@{*/
|
||||
|
@@ -330,7 +330,7 @@ struct ast_channel_snapshot;
|
||||
* \retval NULL on error
|
||||
* \retval ast_str* on success (must be ast_freed by caller)
|
||||
*/
|
||||
struct ast_str *ast_manager_build_channel_state_string_suffix(
|
||||
struct ast_str *ast_manager_build_channel_state_string_prefix(
|
||||
const struct ast_channel_snapshot *snapshot,
|
||||
const char *suffix);
|
||||
|
||||
@@ -350,6 +350,32 @@ struct ast_str *ast_manager_build_channel_state_string(
|
||||
/*! \brief Struct representing a snapshot of bridge state */
|
||||
struct ast_bridge_snapshot;
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Callback used to determine whether a key should be skipped when converting a
|
||||
* JSON object to a manager blob
|
||||
* \param key Key from JSON blob to be evaluated
|
||||
* \retval non-zero if the key should be excluded
|
||||
* \retval zero if the key should not be excluded
|
||||
*/
|
||||
typedef int (*key_exclusion_cb)(const char *key);
|
||||
|
||||
struct ast_json;
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Convert a JSON object into an AMI compatible string
|
||||
*
|
||||
* \param blob The JSON blob containing key/value pairs to convert
|
||||
* \param exclusion_cb A \ref key_exclusion_cb pointer to a function that will exclude
|
||||
* keys from the final AMI string
|
||||
*
|
||||
* \retval A malloc'd \ref ast_str object. Callers of this function should free
|
||||
* the returned \ref ast_str object
|
||||
* \retval NULL on error
|
||||
*/
|
||||
struct ast_str *ast_manager_str_from_json_object(struct ast_json *blob, key_exclusion_cb exclusion_cb);
|
||||
|
||||
/*!
|
||||
* \brief Generate the AMI message body from a bridge snapshot
|
||||
* \since 12
|
||||
@@ -398,12 +424,20 @@ ast_manager_event_blob_create(
|
||||
|
||||
/*!
|
||||
* \brief Initialize support for AMI channel events.
|
||||
* \return 0 on success.
|
||||
* \return non-zero on error.
|
||||
* \retval 0 on success.
|
||||
* \retval non-zero on error.
|
||||
* \since 12
|
||||
*/
|
||||
int manager_channels_init(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Initialize support for AMI MWI events.
|
||||
* \retval 0 on success
|
||||
* \retval non-zero on error
|
||||
*/
|
||||
int manager_mwi_init(void);
|
||||
|
||||
/*!
|
||||
* \brief Initialize support for AMI channel events.
|
||||
* \return 0 on success.
|
||||
@@ -412,4 +446,54 @@ int manager_channels_init(void);
|
||||
*/
|
||||
int manager_bridging_init(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Get the \ref stasis_message_type for generic messages
|
||||
*
|
||||
* A generic AMI message expects a JSON only payload. The payload must have the following
|
||||
* structure:
|
||||
* {type: s, class_type: i, event: [ {s: s}, ...] }
|
||||
*
|
||||
* - type is the AMI event type
|
||||
* - class_type is the class authorization type for the event
|
||||
* - event is a list of key/value tuples to be sent out in the message
|
||||
*
|
||||
* \retval A \ref stasis_message_type for AMI messages
|
||||
*/
|
||||
struct stasis_message_type *ast_manager_get_generic_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Get the \ref stasis topic for AMI
|
||||
*
|
||||
* \retval The \ref stasis topic for AMI
|
||||
* \retval NULL on error
|
||||
*/
|
||||
struct stasis_topic *ast_manager_get_topic(void);
|
||||
|
||||
struct ast_json;
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Publish a generic \ref stasis_message_type to the \ref stasis_topic for AMI
|
||||
*
|
||||
* Publishes a message to the \ref stasis message bus solely for the consumption of AMI.
|
||||
* The message will be of the type provided by \ref ast_manager_get_type, and will be
|
||||
* published to the topic provided by \ref ast_manager_get_topic. As such, the JSON must
|
||||
* be constructed as defined by the \ref ast_manager_get_type message.
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
int ast_manager_publish_message(struct ast_json *json);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Get the \ref stasis_message_router for AMI
|
||||
*
|
||||
* \retval The \ref stasis_message_router for AMI
|
||||
* \retval NULL on error
|
||||
*/
|
||||
struct stasis_message_router *ast_manager_get_message_router(void);
|
||||
|
||||
#endif /* _ASTERISK_MANAGER_H */
|
||||
|
@@ -125,14 +125,15 @@ struct ast_channel_snapshot *ast_channel_snapshot_create(
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Get the most recent snapshot for channel with the given \a uniqueid.
|
||||
* \brief Obtain the latest \ref ast_channel_snapshot from the \ref stasis cache. This is
|
||||
* an ao2 object, so use \ref ao2_cleanup() to deallocate.
|
||||
*
|
||||
* \param uniqueid Uniqueid of the snapshot to fetch.
|
||||
* \return Most recent channel snapshot
|
||||
* \return \c NULL on error
|
||||
* \param unique_id The channel's unique ID
|
||||
*
|
||||
* \retval A \ref ast_channel_snapshot on success
|
||||
* \retval NULL on error
|
||||
*/
|
||||
struct ast_channel_snapshot *ast_channel_snapshot_get_latest(
|
||||
const char *uniqueid);
|
||||
struct ast_channel_snapshot *ast_channel_snapshot_get_latest(const char *uniqueid);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
@@ -152,6 +153,27 @@ struct ast_channel_snapshot *ast_channel_snapshot_get_latest(
|
||||
struct stasis_message *ast_channel_blob_create(struct ast_channel *chan,
|
||||
struct stasis_message_type *type, struct ast_json *blob);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Creates a \ref ast_channel_blob message using the current cached
|
||||
* \ref ast_channel_snapshot for the passed in \ref ast_channel
|
||||
*
|
||||
* The given \a blob should be treated as immutable and not modified after it is
|
||||
* put into the message.
|
||||
*
|
||||
* \param chan Channel blob is associated with, or \c NULL for global/all channels.
|
||||
* \param type Message type for this blob.
|
||||
* \param blob JSON object representing the data, or \c NULL for no data. If
|
||||
* \c NULL, ast_json_null() is put into the object.
|
||||
*
|
||||
* \param chan Channel blob is associated with
|
||||
* \param blob JSON object representing the data.
|
||||
* \return \ref ast_channel_blob message.
|
||||
* \return \c NULL on error
|
||||
*/
|
||||
struct stasis_message *ast_channel_cached_blob_create(struct ast_channel *chan,
|
||||
struct stasis_message_type *type, struct ast_json *blob);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Create a \ref ast_channel_blob message, pulling channel state from
|
||||
@@ -317,6 +339,70 @@ struct stasis_message_type *ast_channel_dtmf_begin_type(void);
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_dtmf_end_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Message type for when a channel starts spying on another channel
|
||||
*
|
||||
* \retval A stasis message type
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_chanspy_start_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Message type for when a channel stops spying on another channel
|
||||
*
|
||||
* \retval A stasis message type
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_chanspy_stop_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Message type for a fax operation
|
||||
*
|
||||
* \retval A stasis message type
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_fax_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Message type for hangup handler related actions
|
||||
*
|
||||
* \retval A stasis message type
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_hangup_handler_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Message type for starting monitor on a channel
|
||||
*
|
||||
* \retval A stasis message type
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_monitor_start_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Message type for stopping monitor on a channel
|
||||
*
|
||||
* \retval A stasis message type
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_monitor_stop_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Message type for starting music on hold on a channel
|
||||
*
|
||||
* \retval A stasis message type
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_moh_start_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Message type for stopping music on hold on a channel
|
||||
*
|
||||
* \retval A stasis message type
|
||||
*/
|
||||
struct stasis_message_type *ast_channel_moh_stop_type(void);
|
||||
|
||||
/*!
|
||||
* \since 12
|
||||
* \brief Publish in the \ref ast_channel_topic or \ref ast_channel_topic_all
|
||||
|
Reference in New Issue
Block a user