Files
asterisk/main/stasis_system.c
George Joseph b794dda76e docs: Add version information to manager event instance XML elements
* Do a git blame on the embedded XML managerEvent elements.

* From the commit hash, grab the summary line.

* Do a git log --grep <summary> to find the cherry-pick commits in all
  branches that match.

* Do a git patch-id to ensure the commits are all related and didn't get
  a false match on the summary.

* Do a git tag --contains <commit> to find the tags that contain each
  commit.

* Weed out all tags not ..0.

* Sort and discard any .0.0 and following tags where the commit
  appeared in an earlier branch.

* The result is a single tag for each branch where the application or function
  was defined.

The events defined in res/res_pjsip/pjsip_manager.xml were done by hand
because the XML was extracted from the C source file relatively recently.

Two bugs were fixed along the way...

* The get_documentation awk script was exiting after it processed the first
  DOCUMENTATION block it found in a file.  We have at least 1 source file
  with multiple DOCUMENTATION blocks so only the first one in them was being
  processed.  The awk script was changed to continue searching rather
  than exiting after the first block.

* Fixing the awk script revealed an issue in logger.c where the third
  DOCUMENTATION block contained a XML fragment that consisted only of
  a managerEventInstance element that wasn't wrapped in a managerEvent
  element.  Since logger_doc.xml already existed, the remaining fragments
  in logger.c were moved to it and properly organized.

(cherry picked from commit 936e88512e)
2025-01-23 18:42:29 +00:00

437 lines
14 KiB
C

/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 2013, Digium, Inc.
*
* Jason Parker <jparker@digium.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
/*! \file
*
* \brief Stasis Messages and Data Types for System events
*
* \author Jason Parker <jparker@digium.com>
*/
/*** MODULEINFO
<support_level>core</support_level>
***/
#include "asterisk.h"
#include "asterisk/astobj2.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_system.h"
/*** DOCUMENTATION
<managerEvent language="en_US" name="Registry">
<managerEventInstance class="EVENT_FLAG_SYSTEM">
<since><version>12.0.0</version></since>
<synopsis>Raised when an outbound registration completes.</synopsis>
<syntax>
<parameter name="ChannelType">
<para>The type of channel that was registered (or not).</para>
</parameter>
<parameter name="Username">
<para>The username portion of the registration.</para>
</parameter>
<parameter name="Domain">
<para>The address portion of the registration.</para>
</parameter>
<parameter name="Status">
<para>The status of the registration request.</para>
<enumlist>
<enum name="Registered"/>
<enum name="Unregistered"/>
<enum name="Rejected"/>
<enum name="Failed"/>
</enumlist>
</parameter>
<parameter name="Cause">
<para>What caused the rejection of the request, if available.</para>
</parameter>
</syntax>
</managerEventInstance>
</managerEvent>
***/
/*! \brief The \ref stasis topic for system level changes */
static struct stasis_topic *system_topic;
static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_available_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_offertimerstart_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_requested_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_requestacknowledged_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_callerstopmonitoring_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_callerstartmonitoring_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_callerrecalling_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_recallcomplete_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_failure_to_ami(struct stasis_message *message);
static struct ast_manager_event_blob *cc_monitorfailed_to_ami(struct stasis_message *message);
STASIS_MESSAGE_TYPE_DEFN(ast_network_change_type);
STASIS_MESSAGE_TYPE_DEFN(ast_system_registry_type,
.to_ami = system_registry_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_available_type,
.to_ami = cc_available_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_offertimerstart_type,
.to_ami = cc_offertimerstart_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_requested_type,
.to_ami = cc_requested_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_requestacknowledged_type,
.to_ami = cc_requestacknowledged_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerstopmonitoring_type,
.to_ami = cc_callerstopmonitoring_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerstartmonitoring_type,
.to_ami = cc_callerstartmonitoring_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerrecalling_type,
.to_ami = cc_callerrecalling_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_recallcomplete_type,
.to_ami = cc_recallcomplete_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_failure_type,
.to_ami = cc_failure_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cc_monitorfailed_type,
.to_ami = cc_monitorfailed_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_cluster_discovery_type);
void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause)
{
struct ast_json *registry;
struct ast_json_payload *payload;
struct stasis_message *message;
if (!ast_system_registry_type()) {
return;
}
registry = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s}",
"type", "registry",
"channeltype", channeltype,
"username", username,
"domain", domain,
"status", status,
"cause", S_OR(cause, ""));
payload = ast_json_payload_create(registry);
ast_json_unref(registry);
if (!payload) {
return;
}
message = stasis_message_create(ast_system_registry_type(), payload);
ao2_ref(payload, -1);
if (!message) {
return;
}
stasis_publish(ast_system_topic(), message);
ao2_ref(message, -1);
}
static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
const char *channeltype;
const char *username;
const char *domain;
const char *status;
const char *cause;
RAII_VAR(struct ast_str *, cause_string, ast_str_create(32), ast_free);
if (!cause_string) {
return NULL;
}
channeltype = ast_json_string_get(ast_json_object_get(payload->json, "channeltype"));
username = ast_json_string_get(ast_json_object_get(payload->json, "username"));
domain = ast_json_string_get(ast_json_object_get(payload->json, "domain"));
status = ast_json_string_get(ast_json_object_get(payload->json, "status"));
cause = ast_json_string_get(ast_json_object_get(payload->json, "cause"));
if (!ast_strlen_zero(cause)) {
ast_str_set(&cause_string, 0, "Cause: %s\r\n", cause);
}
return ast_manager_event_blob_create(EVENT_FLAG_SYSTEM, "Registry",
"ChannelType: %s\r\n"
"Username: %s\r\n"
"Domain: %s\r\n"
"Status: %s\r\n"
"%s",
channeltype, username, domain, status, ast_str_buffer(cause_string));
}
static struct ast_manager_event_blob *cc_available_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *callee;
const char *service;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
service = ast_json_string_get(ast_json_object_get(payload->json, "service"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCAvailable",
"CoreID: %d\r\n"
"Callee: %s\r\n"
"Service: %s\r\n",
core_id, callee, service);
}
static struct ast_manager_event_blob *cc_offertimerstart_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *caller;
unsigned int expires;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
expires = ast_json_integer_get(ast_json_object_get(payload->json, "expires"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCOfferTimerStart",
"CoreID: %d\r\n"
"Caller: %s\r\n"
"Expires: %u\r\n",
core_id, caller, expires);
}
static struct ast_manager_event_blob *cc_requested_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *caller;
const char *callee;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRequested",
"CoreID: %d\r\n"
"Caller: %s\r\n"
"Callee: %s\r\n",
core_id, caller, callee);
}
static struct ast_manager_event_blob *cc_requestacknowledged_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *caller;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRequestAcknowledged",
"CoreID: %d\r\n"
"Caller: %s\r\n",
core_id, caller);
}
static struct ast_manager_event_blob *cc_callerstopmonitoring_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *caller;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerStopMonitoring",
"CoreID: %d\r\n"
"Caller: %s\r\n",
core_id, caller);
}
static struct ast_manager_event_blob *cc_callerstartmonitoring_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *caller;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerStartMonitoring",
"CoreID: %d\r\n"
"Caller: %s\r\n",
core_id, caller);
}
static struct ast_manager_event_blob *cc_callerrecalling_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *caller;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerRecalling",
"CoreID: %d\r\n"
"Caller: %s\r\n",
core_id, caller);
}
static struct ast_manager_event_blob *cc_recallcomplete_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *caller;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRecallComplete",
"CoreID: %d\r\n"
"Caller: %s\r\n",
core_id, caller);
}
static struct ast_manager_event_blob *cc_failure_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *caller;
const char *reason;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
reason = ast_json_string_get(ast_json_object_get(payload->json, "reason"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCFailure",
"CoreID: %d\r\n"
"Caller: %s\r\n"
"Reason: %s\r\n",
core_id, caller, reason);
}
static struct ast_manager_event_blob *cc_monitorfailed_to_ami(struct stasis_message *message)
{
struct ast_json_payload *payload = stasis_message_data(message);
int core_id;
const char *callee;
core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCMonitorFailed",
"CoreID: %d\r\n"
"Callee: %s\r\n",
core_id, callee);
}
struct stasis_topic *ast_system_topic(void)
{
return system_topic;
}
/*! \brief Cleanup the \ref stasis system level items */
static void stasis_system_cleanup(void)
{
ao2_cleanup(system_topic);
system_topic = NULL;
STASIS_MESSAGE_TYPE_CLEANUP(ast_network_change_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_system_registry_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_available_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_offertimerstart_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_requested_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_requestacknowledged_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerstopmonitoring_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerstartmonitoring_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerrecalling_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_recallcomplete_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_failure_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_monitorfailed_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_cluster_discovery_type);
}
/*! \brief Initialize the system level items for \ref stasis */
int ast_stasis_system_init(void)
{
ast_register_cleanup(stasis_system_cleanup);
system_topic = stasis_topic_create("system:all");
if (!system_topic) {
return 1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_network_change_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_system_registry_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_available_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_offertimerstart_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_requested_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_requestacknowledged_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerstopmonitoring_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerstartmonitoring_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerrecalling_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_recallcomplete_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_failure_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cc_monitorfailed_type) != 0) {
return -1;
}
if (STASIS_MESSAGE_TYPE_INIT(ast_cluster_discovery_type) != 0) {
return -1;
}
return 0;
}