PJPROJECT logging: Made easier to get available logging levels.
[asterisk/asterisk.git] / main / stasis_system.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Jason Parker <jparker@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 /*! \file
20  *
21  * \brief Stasis Messages and Data Types for System events
22  *
23  * \author Jason Parker <jparker@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 #include "asterisk/astobj2.h"
33 #include "asterisk/stasis.h"
34 #include "asterisk/stasis_system.h"
35
36 /*** DOCUMENTATION
37         <managerEvent language="en_US" name="Registry">
38                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
39                         <synopsis>Raised when an outbound registration completes.</synopsis>
40                         <syntax>
41                                 <parameter name="ChannelType">
42                                         <para>The type of channel that was registered (or not).</para>
43                                 </parameter>
44                                 <parameter name="Username">
45                                         <para>The username portion of the registration.</para>
46                                 </parameter>
47                                 <parameter name="Domain">
48                                         <para>The address portion of the registration.</para>
49                                 </parameter>
50                                 <parameter name="Status">
51                                         <para>The status of the registration request.</para>
52                                         <enumlist>
53                                                 <enum name="Registered"/>
54                                                 <enum name="Unregistered"/>
55                                                 <enum name="Rejected"/>
56                                                 <enum name="Failed"/>
57                                         </enumlist>
58                                 </parameter>
59                                 <parameter name="Cause">
60                                         <para>What caused the rejection of the request, if available.</para>
61                                 </parameter>
62                         </syntax>
63                 </managerEventInstance>
64         </managerEvent>
65  ***/
66
67 /*! \brief The \ref stasis topic for system level changes */
68 static struct stasis_topic *system_topic;
69
70 static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message);
71 static struct ast_manager_event_blob *cc_available_to_ami(struct stasis_message *message);
72 static struct ast_manager_event_blob *cc_offertimerstart_to_ami(struct stasis_message *message);
73 static struct ast_manager_event_blob *cc_requested_to_ami(struct stasis_message *message);
74 static struct ast_manager_event_blob *cc_requestacknowledged_to_ami(struct stasis_message *message);
75 static struct ast_manager_event_blob *cc_callerstopmonitoring_to_ami(struct stasis_message *message);
76 static struct ast_manager_event_blob *cc_callerstartmonitoring_to_ami(struct stasis_message *message);
77 static struct ast_manager_event_blob *cc_callerrecalling_to_ami(struct stasis_message *message);
78 static struct ast_manager_event_blob *cc_recallcomplete_to_ami(struct stasis_message *message);
79 static struct ast_manager_event_blob *cc_failure_to_ami(struct stasis_message *message);
80 static struct ast_manager_event_blob *cc_monitorfailed_to_ami(struct stasis_message *message);
81
82 STASIS_MESSAGE_TYPE_DEFN(ast_network_change_type);
83 STASIS_MESSAGE_TYPE_DEFN(ast_system_registry_type,
84         .to_ami = system_registry_to_ami,
85         );
86 STASIS_MESSAGE_TYPE_DEFN(ast_cc_available_type,
87         .to_ami = cc_available_to_ami,
88         );
89 STASIS_MESSAGE_TYPE_DEFN(ast_cc_offertimerstart_type,
90         .to_ami = cc_offertimerstart_to_ami,
91         );
92 STASIS_MESSAGE_TYPE_DEFN(ast_cc_requested_type,
93         .to_ami = cc_requested_to_ami,
94         );
95 STASIS_MESSAGE_TYPE_DEFN(ast_cc_requestacknowledged_type,
96         .to_ami = cc_requestacknowledged_to_ami,
97         );
98 STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerstopmonitoring_type,
99         .to_ami = cc_callerstopmonitoring_to_ami,
100         );
101 STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerstartmonitoring_type,
102         .to_ami = cc_callerstartmonitoring_to_ami,
103         );
104 STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerrecalling_type,
105         .to_ami = cc_callerrecalling_to_ami,
106         );
107 STASIS_MESSAGE_TYPE_DEFN(ast_cc_recallcomplete_type,
108         .to_ami = cc_recallcomplete_to_ami,
109         );
110 STASIS_MESSAGE_TYPE_DEFN(ast_cc_failure_type,
111         .to_ami = cc_failure_to_ami,
112         );
113 STASIS_MESSAGE_TYPE_DEFN(ast_cc_monitorfailed_type,
114         .to_ami = cc_monitorfailed_to_ami,
115         );
116 STASIS_MESSAGE_TYPE_DEFN(ast_cluster_discovery_type);
117
118 void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause)
119 {
120         RAII_VAR(struct ast_json *, registry, NULL, ast_json_unref);
121         RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
122         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
123
124         if (!ast_system_registry_type()) {
125                 return;
126         }
127
128         registry = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s}",
129                 "type", "registry",
130                 "channeltype", channeltype,
131                 "username", username,
132                 "domain", domain,
133                 "status", status,
134                 "cause", S_OR(cause, ""));
135
136         if (!(payload = ast_json_payload_create(registry))) {
137                 return;
138         }
139
140         if (!(message = stasis_message_create(ast_system_registry_type(), payload))) {
141                 return;
142         }
143
144         stasis_publish(ast_system_topic(), message);
145 }
146
147 static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message)
148 {
149         struct ast_json_payload *payload = stasis_message_data(message);
150         const char *channeltype;
151         const char *username;
152         const char *domain;
153         const char *status;
154         const char *cause;
155         RAII_VAR(struct ast_str *, cause_string, ast_str_create(32), ast_free);
156
157         if (!cause_string) {
158                 return NULL;
159         }
160
161         channeltype = ast_json_string_get(ast_json_object_get(payload->json, "channeltype"));
162         username = ast_json_string_get(ast_json_object_get(payload->json, "username"));
163         domain = ast_json_string_get(ast_json_object_get(payload->json, "domain"));
164         status = ast_json_string_get(ast_json_object_get(payload->json, "status"));
165         cause = ast_json_string_get(ast_json_object_get(payload->json, "cause"));
166
167         if (!ast_strlen_zero(cause)) {
168                 ast_str_set(&cause_string, 0, "Cause: %s\r\n", cause);
169         }
170
171         return ast_manager_event_blob_create(EVENT_FLAG_SYSTEM, "Registry",
172                 "ChannelType: %s\r\n"
173                 "Username: %s\r\n"
174                 "Domain: %s\r\n"
175                 "Status: %s\r\n"
176                 "%s",
177                 channeltype, username, domain, status, ast_str_buffer(cause_string));
178 }
179
180 static struct ast_manager_event_blob *cc_available_to_ami(struct stasis_message *message)
181 {
182         struct ast_json_payload *payload = stasis_message_data(message);
183         int core_id;
184         const char *callee;
185         const char *service;
186
187         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
188         callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
189         service = ast_json_string_get(ast_json_object_get(payload->json, "service"));
190
191         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCAvailable",
192                 "CoreID: %d\r\n"
193                 "Callee: %s\r\n"
194                 "Service: %s\r\n",
195                 core_id, callee, service);
196 }
197
198 static struct ast_manager_event_blob *cc_offertimerstart_to_ami(struct stasis_message *message)
199 {
200         struct ast_json_payload *payload = stasis_message_data(message);
201         int core_id;
202         const char *caller;
203         unsigned int expires;
204
205         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
206         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
207         expires = ast_json_integer_get(ast_json_object_get(payload->json, "expires"));
208
209         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCOfferTimerStart",
210                 "CoreID: %d\r\n"
211                 "Caller: %s\r\n"
212                 "Expires: %u\r\n",
213                 core_id, caller, expires);
214 }
215
216 static struct ast_manager_event_blob *cc_requested_to_ami(struct stasis_message *message)
217 {
218         struct ast_json_payload *payload = stasis_message_data(message);
219         int core_id;
220         const char *caller;
221         const char *callee;
222
223         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
224         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
225         callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
226
227         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRequested",
228                 "CoreID: %d\r\n"
229                 "Caller: %s\r\n"
230                 "Callee: %s\r\n",
231                 core_id, caller, callee);
232 }
233
234 static struct ast_manager_event_blob *cc_requestacknowledged_to_ami(struct stasis_message *message)
235 {
236         struct ast_json_payload *payload = stasis_message_data(message);
237         int core_id;
238         const char *caller;
239
240         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
241         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
242
243         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRequestAcknowledged",
244                 "CoreID: %d\r\n"
245                 "Caller: %s\r\n",
246                 core_id, caller);
247 }
248
249 static struct ast_manager_event_blob *cc_callerstopmonitoring_to_ami(struct stasis_message *message)
250 {
251         struct ast_json_payload *payload = stasis_message_data(message);
252         int core_id;
253         const char *caller;
254
255         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
256         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
257
258         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerStopMonitoring",
259                 "CoreID: %d\r\n"
260                 "Caller: %s\r\n",
261                 core_id, caller);
262 }
263
264 static struct ast_manager_event_blob *cc_callerstartmonitoring_to_ami(struct stasis_message *message)
265 {
266         struct ast_json_payload *payload = stasis_message_data(message);
267         int core_id;
268         const char *caller;
269
270         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
271         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
272
273         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerStartMonitoring",
274                 "CoreID: %d\r\n"
275                 "Caller: %s\r\n",
276                 core_id, caller);
277 }
278
279 static struct ast_manager_event_blob *cc_callerrecalling_to_ami(struct stasis_message *message)
280 {
281         struct ast_json_payload *payload = stasis_message_data(message);
282         int core_id;
283         const char *caller;
284
285         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
286         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
287
288         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerRecalling",
289                 "CoreID: %d\r\n"
290                 "Caller: %s\r\n",
291                 core_id, caller);
292 }
293
294 static struct ast_manager_event_blob *cc_recallcomplete_to_ami(struct stasis_message *message)
295 {
296         struct ast_json_payload *payload = stasis_message_data(message);
297         int core_id;
298         const char *caller;
299
300         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
301         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
302
303         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRecallComplete",
304                 "CoreID: %d\r\n"
305                 "Caller: %s\r\n",
306                 core_id, caller);
307 }
308
309 static struct ast_manager_event_blob *cc_failure_to_ami(struct stasis_message *message)
310 {
311         struct ast_json_payload *payload = stasis_message_data(message);
312         int core_id;
313         const char *caller;
314         const char *reason;
315
316         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
317         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
318         reason = ast_json_string_get(ast_json_object_get(payload->json, "reason"));
319
320         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCFailure",
321                 "CoreID: %d\r\n"
322                 "Caller: %s\r\n"
323                 "Reason: %s\r\n",
324                 core_id, caller, reason);
325 }
326
327 static struct ast_manager_event_blob *cc_monitorfailed_to_ami(struct stasis_message *message)
328 {
329         struct ast_json_payload *payload = stasis_message_data(message);
330         int core_id;
331         const char *callee;
332
333         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
334         callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
335
336         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCMonitorFailed",
337                 "CoreID: %d\r\n"
338                 "Callee: %s\r\n",
339                 core_id, callee);
340 }
341
342 struct stasis_topic *ast_system_topic(void)
343 {
344         return system_topic;
345 }
346
347 /*! \brief Cleanup the \ref stasis system level items */
348 static void stasis_system_cleanup(void)
349 {
350         ao2_cleanup(system_topic);
351         system_topic = NULL;
352         STASIS_MESSAGE_TYPE_CLEANUP(ast_network_change_type);
353         STASIS_MESSAGE_TYPE_CLEANUP(ast_system_registry_type);
354         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_available_type);
355         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_offertimerstart_type);
356         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_requested_type);
357         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_requestacknowledged_type);
358         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerstopmonitoring_type);
359         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerstartmonitoring_type);
360         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerrecalling_type);
361         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_recallcomplete_type);
362         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_failure_type);
363         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_monitorfailed_type);
364         STASIS_MESSAGE_TYPE_CLEANUP(ast_cluster_discovery_type);
365 }
366
367 /*! \brief Initialize the system level items for \ref stasis */
368 int ast_stasis_system_init(void)
369 {
370         ast_register_cleanup(stasis_system_cleanup);
371
372         system_topic = stasis_topic_create("ast_system");
373         if (!system_topic) {
374                 return 1;
375         }
376
377         if (STASIS_MESSAGE_TYPE_INIT(ast_network_change_type) != 0) {
378                 return -1;
379         }
380
381         if (STASIS_MESSAGE_TYPE_INIT(ast_system_registry_type) != 0) {
382                 return -1;
383         }
384
385         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_available_type) != 0) {
386                 return -1;
387         }
388
389         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_offertimerstart_type) != 0) {
390                 return -1;
391         }
392
393         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_requested_type) != 0) {
394                 return -1;
395         }
396
397         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_requestacknowledged_type) != 0) {
398                 return -1;
399         }
400
401         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerstopmonitoring_type) != 0) {
402                 return -1;
403         }
404
405         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerstartmonitoring_type) != 0) {
406                 return -1;
407         }
408
409         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerrecalling_type) != 0) {
410                 return -1;
411         }
412
413         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_recallcomplete_type) != 0) {
414                 return -1;
415         }
416
417         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_failure_type) != 0) {
418                 return -1;
419         }
420
421         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_monitorfailed_type) != 0) {
422                 return -1;
423         }
424
425         if (STASIS_MESSAGE_TYPE_INIT(ast_cluster_discovery_type) != 0) {
426                 return -1;
427         }
428
429         return 0;
430 }