diff options
author | Matthew Jordan <mjordan@digium.com> | 2013-05-24 20:44:07 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2013-05-24 20:44:07 +0000 |
commit | 06be8463b683333c79845402d55168ef1b582fa9 (patch) | |
tree | 2fe0871cfec4d5edf3aae763541ff7efa32a444a /include/asterisk | |
parent | c1b51fd2654736fd7c614d1571f904e236006651 (diff) |
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
Diffstat (limited to 'include/asterisk')
-rw-r--r-- | include/asterisk/_private.h | 23 | ||||
-rw-r--r-- | include/asterisk/app.h | 116 | ||||
-rw-r--r-- | include/asterisk/json.h | 28 | ||||
-rw-r--r-- | include/asterisk/manager.h | 90 | ||||
-rw-r--r-- | include/asterisk/stasis_channels.h | 98 |
5 files changed, 318 insertions, 37 deletions
diff --git a/include/asterisk/_private.h b/include/asterisk/_private.h index 3fe35e58c..1d0844924 100644 --- a/include/asterisk/_private.h +++ b/include/asterisk/_private.h @@ -52,6 +52,20 @@ 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. diff --git a/include/asterisk/app.h b/include/asterisk/app.h index 6cfb38004..85c2aefb1 100644 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -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) + +/*! + * \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) /*! - * \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 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 *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 *stasis_mwi_state_type(void); +struct stasis_message_type *ast_mwi_vm_app_type(void); /*! @} */ diff --git a/include/asterisk/json.h b/include/asterisk/json.h index 978d6396a..baf8cf6a2 100644 --- a/include/asterisk/json.h +++ b/include/asterisk/json.h @@ -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); @@ -602,6 +604,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)))) + + /*!@}*/ /*!@{*/ diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h index 4e9b8d14a..6b1402bc3 100644 --- a/include/asterisk/manager.h +++ b/include/asterisk/manager.h @@ -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); @@ -351,6 +351,32 @@ struct ast_str *ast_manager_build_channel_state_string( 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,13 +424,21 @@ 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. * \return non-zero on error. @@ -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 */ diff --git a/include/asterisk/stasis_channels.h b/include/asterisk/stasis_channels.h index dace99af5..7c214d5a7 100644 --- a/include/asterisk/stasis_channels.h +++ b/include/asterisk/stasis_channels.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 @@ -154,6 +155,27 @@ struct stasis_message *ast_channel_blob_create(struct ast_channel *chan, /*! * \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 * the cache. * @@ -319,6 +341,70 @@ 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 * topics a stasis message for the channels involved in a dial operation. * |