Merge the cli_cleanup branch.
[asterisk/asterisk.git] / res / ais / clm.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! 
20  * \file
21  * \author Russell Bryant <russell@digium.com>
22  *
23  * \brief Usage of the SAForum AIS (Application Interface Specification)
24  *
25  * \arg http://www.openais.org/
26  *
27  * This file contains the code specific to the use of the CLM 
28  * (Cluster Membership) Service.
29  */
30
31 #include "asterisk.h"
32
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <unistd.h>
39 #include <errno.h>
40
41 #include "ais.h"
42
43 #include "asterisk/module.h"
44 #include "asterisk/utils.h"
45 #include "asterisk/cli.h"
46 #include "asterisk/logger.h"
47
48 SaClmHandleT clm_handle;
49
50 static void clm_node_get_cb(SaInvocationT invocation, 
51         const SaClmClusterNodeT *cluster_node, SaAisErrorT error);
52 static void clm_track_cb(const SaClmClusterNotificationBufferT *notif_buffer,
53         SaUint32T num_members, SaAisErrorT error);
54
55 static const SaClmCallbacksT clm_callbacks = {
56         .saClmClusterNodeGetCallback = clm_node_get_cb,
57         .saClmClusterTrackCallback   = clm_track_cb,
58 };
59
60 static void clm_node_get_cb(SaInvocationT invocation, 
61         const SaClmClusterNodeT *cluster_node, SaAisErrorT error)
62 {
63
64 }
65
66 static void clm_track_cb(const SaClmClusterNotificationBufferT *notif_buffer,
67         SaUint32T num_members, SaAisErrorT error)
68 {
69
70 }
71
72 static char *ais_clm_show_members(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
73 {
74         int i;
75         SaClmClusterNotificationBufferT buf;
76         SaClmClusterNotificationT notif[64];
77         SaAisErrorT ais_res;
78
79         switch (cmd) {
80         case CLI_INIT:
81                 e->command = "ais show clm members";
82                 e->usage =
83                         "Usage: ais show clm members\n"
84                         "       List members of the cluster using the CLM (Cluster Membership) service.\n";
85                 return NULL;
86
87         case CLI_GENERATE:
88                 return NULL;    /* no completion */
89         }
90
91         if (a->argc != e->args)
92                 return CLI_SHOWUSAGE;
93
94         buf.notification = notif;
95         buf.numberOfItems = ARRAY_LEN(notif);
96
97         ais_res = saClmClusterTrack(clm_handle, SA_TRACK_CURRENT, &buf);
98         if (ais_res != SA_AIS_OK) {
99                 ast_cli(a->fd, "Error retrieving current cluster members.\n");
100                 return CLI_FAILURE;
101         }
102
103         ast_cli(a->fd, "\n"
104                     "=============================================================\n"
105                     "=== Cluster Members =========================================\n"
106                     "=============================================================\n"
107                     "===\n");
108
109         for (i = 0; i < buf.numberOfItems; i++) {
110                 SaClmClusterNodeT *node = &buf.notification[i].clusterNode;
111
112                 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
113                                "=== Node Name: %s\n"
114                                "=== ==> ID: 0x%x\n"
115                                "=== ==> Address: %s\n"
116                                "=== ==> Member: %s\n",
117                                (char *) node->nodeName.value, (int) node->nodeId, 
118                                (char *) node->nodeAddress.value,
119                                node->member ? "Yes" : "No");
120
121                 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
122                                "===\n");
123         }
124
125         ast_cli(a->fd, "=============================================================\n"
126                        "\n");
127
128         return CLI_SUCCESS;
129 }
130
131 static struct ast_cli_entry ais_cli[] = {
132         AST_CLI_DEFINE(ais_clm_show_members, "List current members of the cluster"),
133 };
134
135 int ast_ais_clm_load_module(void)
136 {
137         SaAisErrorT ais_res;
138
139         ais_res = saClmInitialize(&clm_handle, &clm_callbacks, &ais_version);
140         if (ais_res != SA_AIS_OK) {
141                 ast_log(LOG_ERROR, "Could not initialize cluster membership service: %s\n",
142                         ais_err2str(ais_res));
143                 return -1;
144         }
145
146         ast_cli_register_multiple(ais_cli, ARRAY_LEN(ais_cli));
147
148         return 0;
149 }
150
151 int ast_ais_clm_unload_module(void)
152 {
153         SaAisErrorT ais_res;
154
155         ast_cli_unregister_multiple(ais_cli, ARRAY_LEN(ais_cli));
156
157         ais_res = saClmFinalize(clm_handle);
158         if (ais_res != SA_AIS_OK) {
159                 ast_log(LOG_ERROR, "Problem stopping cluster membership service: %s\n", 
160                         ais_err2str(ais_res));
161                 return -1;
162         }
163
164         return 0;
165 }