Fix DEBUG_THREADS when lock is acquired in __constructor__
[asterisk/asterisk.git] / main / manager_endpoints.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  * David M. Lee, II <dlee@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 /*! \file
21  *
22  * \brief The Asterisk Management Interface - AMI (endpoint handling)
23  *
24  * \author Joshua Colp <jcolp@digium.com>
25  * \author David M. Lee, II <dlee@digium.com>
26  *
27   */
28
29 #include "asterisk.h"
30
31 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
32
33 #include "asterisk/callerid.h"
34 #include "asterisk/channel.h"
35 #include "asterisk/manager.h"
36 #include "asterisk/stasis_message_router.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/stasis_endpoints.h"
39
40 static struct stasis_message_router *endpoint_router;
41
42 static void manager_endpoints_shutdown(void)
43 {
44         stasis_message_router_unsubscribe_and_join(endpoint_router);
45         endpoint_router = NULL;
46 }
47
48 static void endpoint_state_cb(void *data, struct stasis_subscription *sub,
49         struct stasis_topic *topic,
50         struct stasis_message *message)
51 {
52         /* XXX This looks wrong. Nothing should post or forward to a caching
53          * topic directly. Maybe ast_endpoint_topic() would be correct? I'd have
54          * to dig to make sure I don't break anything, though.
55          */
56         stasis_forward_message(ast_manager_get_topic(), ast_endpoint_topic_all_cached(), message);
57 }
58
59 int manager_endpoints_init(void)
60 {
61         struct stasis_topic *endpoint_topic;
62         int ret = 0;
63
64         if (endpoint_router) {
65                 /* Already initialized */
66                 return 0;
67         }
68
69         ast_register_atexit(manager_endpoints_shutdown);
70
71         endpoint_topic = ast_endpoint_topic_all_cached();
72         if (!endpoint_topic) {
73                 return -1;
74         }
75
76         endpoint_router = stasis_message_router_create(endpoint_topic);
77
78         if (!endpoint_router) {
79                 return -1;
80         }
81
82         ret |= stasis_message_router_add(endpoint_router, ast_endpoint_state_type(), endpoint_state_cb, NULL);
83
84         /* If somehow we failed to add any routes, just shut down the whole
85          * thing and fail it.
86          */
87         if (ret) {
88                 manager_endpoints_shutdown();
89                 return -1;
90         }
91
92         return 0;
93 }
94