Move channel driver Registry manager events to core.
authorJason Parker <jparker@digium.com>
Mon, 8 Jul 2013 14:42:57 +0000 (14:42 +0000)
committerJason Parker <jparker@digium.com>
Mon, 8 Jul 2013 14:42:57 +0000 (14:42 +0000)
This also shuffles the stasis system topic and related handling.

(closes issue ASTERISK-21488)

Review: https://reviewboard.asterisk.org/r/2631/

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393804 65c4cc65-6c06-0410-ace0-fbb531ad65f3

12 files changed:
channels/chan_iax2.c
channels/chan_sip.c
include/asterisk.h
include/asterisk/manager.h
include/asterisk/stasis_system.h [new file with mode: 0644]
main/asterisk.c
main/file.c
main/manager.c
main/manager_system.c [new file with mode: 0644]
main/sounds_index.c
main/stasis_system.c [new file with mode: 0644]
res/res_stun_monitor.c

index 2300636..38b94ac 100644 (file)
@@ -103,6 +103,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/security_events.h"
 #include "asterisk/stasis_endpoints.h"
 #include "asterisk/bridging.h"
+#include "asterisk/stasis.h"
+#include "asterisk/stasis_system.h"
 
 #include "iax2/include/iax2.h"
 #include "iax2/include/firmware.h"
@@ -8376,6 +8378,11 @@ static int complete_transfer(int callno, struct iax_ies *ies)
        return 0;
 }
 
+static void iax2_publish_registry(const char *username, const char *domain, const char *status, const char *cause)
+{
+       ast_system_publish_registry("IAX2", username, domain, status, cause);
+}
+
 /*! \brief Acknowledgment received for OUR registration */
 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
 {
@@ -8437,7 +8444,7 @@ static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int c
                }
                snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
                ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
-               manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
+               iax2_publish_registry(reg->username, ast_inet_ntoa(sin->sin_addr), "Registered", NULL);
        }
        reg->regstate = REG_STATE_REGISTERED;
        return 0;
@@ -11179,8 +11186,8 @@ immediatedial:
                                if (iaxs[fr->callno]->reg) {
                                        if (authdebug) {
                                                ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr));
-                                               manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
                                        }
+                                       iax2_publish_registry(iaxs[fr->callno]->reg->username, ast_inet_ntoa(sin.sin_addr), "Rejected", S_OR(ies.cause, "<unknown>"));
                                        iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
                                }
                                /* Send ack immediately, before we destroy */
index 9373a64..3c1f97b 100644 (file)
@@ -294,7 +294,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/sip_api.h"
 #include "asterisk/app.h"
 #include "asterisk/bridging.h"
+#include "asterisk/stasis.h"
 #include "asterisk/stasis_endpoints.h"
+#include "asterisk/stasis_system.h"
 #include "asterisk/stasis_channels.h"
 #include "asterisk/features_config.h"
 
@@ -15076,6 +15078,11 @@ static const char *regstate2str(enum sipregistrystate regstate)
        return map_x_s(regstatestrings, regstate, "Unknown");
 }
 
+static void sip_publish_registry(const char *username, const char *domain, const char *status)
+{
+       ast_system_publish_registry("SIP", username, domain, status, NULL);
+}
+
 /*! \brief Update registration with SIP Proxy.
  * Called from the scheduler when the previous registration expires,
  * so we don't have to cancel the pending event.
@@ -15176,7 +15183,7 @@ static int sip_reg_timeout(const void *data)
                transmit_register(r, SIP_REGISTER, NULL, NULL);
                ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts);
        }
-       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
+       sip_publish_registry(r->username, r->hostname, regstate2str(r->regstate));
        registry_unref(r, "unreffing registry_unref r");
        return 0;
 }
@@ -23692,7 +23699,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res
                        r->regstate = REG_STATE_UNREGISTERED;
                        transmit_register(r, SIP_REGISTER, NULL, NULL);
                }
-               manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
+               sip_publish_registry(r->username, r->hostname, regstate2str(r->regstate));
                break;
        case 479:       /* SER: Not able to process the URI - address is wrong in register*/
                ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname);
@@ -23711,7 +23718,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res
 
                r->regstate = REG_STATE_REGISTERED;
                r->regtime = ast_tvnow();               /* Reset time of last successful registration */
-               manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
+               sip_publish_registry(r->username, r->hostname, regstate2str(r->regstate));
                r->regattempts = 0;
                ast_debug(1, "Registration successful\n");
                if (r->timeout > -1) {
index 87ebec0..35628d2 100644 (file)
@@ -216,27 +216,6 @@ int64_t ast_mark(int, int start1_stop0);
 #define ast_mark(a, b) do { } while (0)
 #endif /* LOW_MEMORY */
 
-/*!
- * \since 12
- * \brief A \ref stasis topic which publishes messages regarding system changes
- *
- * \retval \ref stasis_topic for system level changes
- * \retval NULL on error
- */
-struct stasis_topic *ast_system_topic(void);
-
-/*!
- * \since 12
- * \brief A \ref stasis_message_type for network changes
- *
- * \retval NULL on error
- * \retval \ref stasis_message_type for network changes
- *
- * \note Messages of this type should always be issued on and expected from
- *       the \ref ast_system_topic \ref stasis topic
- */
-struct stasis_message_type *ast_network_change_type(void);
-
 /*! \brief
  * Definition of various structures that many asterisk files need,
  * but only because they need to know that the type exists.
index c44d6d0..bdf2578 100644 (file)
@@ -440,6 +440,14 @@ ast_manager_event_blob_create(
 #define NO_EXTRA_FIELDS "%s", ""
 
 /*!
+ * \since 12
+ * \brief Initialize support for AMI system events.
+ * \retval 0 on success
+ * \retval non-zero on error
+ */
+int manager_system_init(void);
+
+/*!
  * \brief Initialize support for AMI channel events.
  * \retval 0 on success.
  * \retval non-zero on error.
diff --git a/include/asterisk/stasis_system.h b/include/asterisk/stasis_system.h
new file mode 100644 (file)
index 0000000..07e16a2
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#ifndef _ASTERISK_STASIS_SYSTEM_H
+#define _ASTERISK_STASIS_SYSTEM_H
+
+#include "asterisk/json.h"
+#include "asterisk/stasis.h"
+
+/*!
+ * \since 12
+ * \brief Publish a channel driver outgoing registration message
+ *
+ * \param channeltype The channel driver that published the message
+ * \param username The username that was used to register
+ * \param domain The domain that was used to register
+ * \param status The result of the registration
+ * \param cause The reason for the result
+ */
+void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause);
+
+/*!
+ * \since 12
+ * \brief A \ref stasis topic which publishes messages regarding system changes
+ *
+ * \retval \ref stasis_topic for system level changes
+ * \retval NULL on error
+ */
+struct stasis_topic *ast_system_topic(void);
+
+/*!
+ * \since 12
+ * \brief A \ref stasis_message_type for network changes
+ *
+ * \retval NULL on error
+ * \retval \ref stasis_message_type for network changes
+ *
+ * \note Messages of this type should always be issued on and expected from
+ *       the \ref ast_system_topic \ref stasis topic
+ */
+struct stasis_message_type *ast_network_change_type(void);
+
+/*!
+ * \brief A \ref stasis_message_type for outbound registration.
+ * \since 12
+ */
+struct stasis_message_type *ast_system_registry_type(void);
+
+/*!
+ * \brief Initialize the stasis system topic and message types
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_stasis_system_init(void);
+
+#endif /* _ASTERISK_STASIS_SYSTEM_H */
index b8cf43e..c7c67e7 100644 (file)
@@ -243,6 +243,7 @@ int daemon(int, int);  /* defined in libresolv of all places */
 #include "asterisk/stasis.h"
 #include "asterisk/json.h"
 #include "asterisk/stasis_endpoints.h"
+#include "asterisk/stasis_system.h"
 #include "asterisk/security_events.h"
 
 #include "../defaults.h"
@@ -448,12 +449,6 @@ static struct {
         unsigned int need_quit_handler:1;
 } sig_flags;
 
-/*! \brief The \ref stasis topic for system level changes */
-static struct stasis_topic *system_topic;
-
-/*!\ brief The \ref stasis_message_type for network changes */
-STASIS_MESSAGE_TYPE_DEFN(ast_network_change_type);
-
 #if !defined(LOW_MEMORY)
 struct file_version {
        AST_RWLIST_ENTRY(file_version) list;
@@ -461,9 +456,6 @@ struct file_version {
        char *version;
 };
 
-/*! \brief The \ref stasis topic for system level changes */
-static struct stasis_topic *system_topic;
-
 static AST_RWLIST_HEAD_STATIC(file_versions, file_version);
 
 void ast_register_file_version(const char *file, const char *version)
@@ -1098,36 +1090,6 @@ static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct
 
 #endif /* ! LOW_MEMORY */
 
-struct stasis_topic *ast_system_topic(void)
-{
-       return system_topic;
-}
-
-/*! \brief Cleanup the \ref stasis system level items */
-static void stasis_system_topic_cleanup(void)
-{
-       ao2_cleanup(system_topic);
-       system_topic = NULL;
-       STASIS_MESSAGE_TYPE_CLEANUP(ast_network_change_type);
-}
-
-/*! \brief Initialize the system level items for \ref stasis */
-static int stasis_system_topic_init(void)
-{
-       ast_register_cleanup(stasis_system_topic_cleanup);
-
-       system_topic = stasis_topic_create("ast_system");
-       if (!system_topic) {
-               return 1;
-       }
-
-       if (STASIS_MESSAGE_TYPE_INIT(ast_network_change_type) != 0) {
-               return -1;
-       }
-
-       return 0;
-}
-
 static void publish_fully_booted(void)
 {
        RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
@@ -4218,7 +4180,7 @@ int main(int argc, char *argv[])
                exit(1);
        }
 
-       if (stasis_system_topic_init()) {
+       if (ast_stasis_system_init()) {
                printf("Stasis system-level information initialization failed.\n%s", term_quit());
                exit(1);
        }
index cb495b3..a351fd4 100644 (file)
@@ -53,6 +53,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/test.h"
 #include "asterisk/stasis.h"
 #include "asterisk/json.h"
+#include "asterisk/stasis_system.h"
 
 /*! \brief
  * The following variable controls the layout of localized sound files.
index b1c7b53..b8b067d 100644 (file)
@@ -7827,6 +7827,10 @@ static int __init_manager(int reload, int by_external_config)
                        ast_log(AST_LOG_ERROR, "Failed to initialize manager subscriptions\n");
                        return -1;
                }
+               if (manager_system_init()) {
+                       ast_log(AST_LOG_ERROR, "Failed to initialize manager system handling\n");
+                       return -1;
+               }
                if (manager_channels_init()) {
                        ast_log(AST_LOG_ERROR, "Failed to initialize manager channel handling\n");
                        return -1;
diff --git a/main/manager_system.c b/main/manager_system.c
new file mode 100644 (file)
index 0000000..4fef11d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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 System AMI event handling
+ *
+ * \author Jason Parker <jparker@digium.com>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/stasis.h"
+#include "asterisk/stasis_message_router.h"
+#include "asterisk/stasis_system.h"
+
+/*! \brief The \ref stasis subscription returned by the forwarding of the system topic
+ * to the manager topic
+ */
+static struct stasis_subscription *topic_forwarder;
+
+static void manager_system_shutdown(void)
+{
+       stasis_unsubscribe(topic_forwarder);
+       topic_forwarder = NULL;
+}
+
+int manager_system_init(void)
+{
+       int ret = 0;
+       struct stasis_topic *manager_topic;
+       struct stasis_topic *system_topic;
+       struct stasis_message_router *message_router;
+
+       manager_topic = ast_manager_get_topic();
+       if (!manager_topic) {
+               return -1;
+       }
+       message_router = ast_manager_get_message_router();
+       if (!message_router) {
+               return -1;
+       }
+       system_topic = ast_system_topic();
+       if (!system_topic) {
+               return -1;
+       }
+
+       topic_forwarder = stasis_forward_all(system_topic, manager_topic);
+       if (!topic_forwarder) {
+               return -1;
+       }
+
+       ast_register_atexit(manager_system_shutdown);
+
+       /* If somehow we failed to add any routes, just shut down the whole
+        * thing and fail it.
+        */
+       if (ret) {
+               manager_system_shutdown();
+               return -1;
+       }
+
+       return 0;
+}
index a627f68..ff9a458 100644 (file)
@@ -36,6 +36,7 @@
 #include "asterisk/cli.h"
 #include "asterisk/_private.h"
 #include "asterisk/stasis_message_router.h"
+#include "asterisk/stasis_system.h"
 
 /*** MODULEINFO
        <support_level>core</support_level>
diff --git a/main/stasis_system.c b/main/stasis_system.c
new file mode 100644 (file)
index 0000000..15451ed
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#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">
+                       <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);
+
+STASIS_MESSAGE_TYPE_DEFN(ast_network_change_type);
+STASIS_MESSAGE_TYPE_DEFN(ast_system_registry_type,
+       .to_ami = system_registry_to_ami,
+       );
+
+void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause)
+{
+       RAII_VAR(struct ast_json *, registry, NULL, ast_json_unref);
+       RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
+       RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+
+       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, ""));
+
+       if (!(payload = ast_json_payload_create(registry))) {
+               return;
+       }
+
+       if (!(message = stasis_message_create(ast_system_registry_type(), payload))) {
+               return;
+       }
+
+       stasis_publish(ast_system_topic(), message);
+}
+
+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));
+}
+
+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);
+}
+
+/*! \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("ast_system");
+       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;
+       }
+
+       return 0;
+}
index 58b52a6..42ba106 100644 (file)
@@ -39,8 +39,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/lock.h"
 #include "asterisk/acl.h"
 #include "asterisk/cli.h"
-#include "asterisk/stasis.h"
 #include "asterisk/json.h"
+#include "asterisk/stasis.h"
+#include "asterisk/stasis_system.h"
 #include "asterisk/astobj2.h"
 
 #include <fcntl.h>