CI: Various updates to buildAsterisk.sh
[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         struct ast_json *registry;
121         struct ast_json_payload *payload;
122         struct stasis_message *message;
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         payload = ast_json_payload_create(registry);
137         ast_json_unref(registry);
138         if (!payload) {
139                 return;
140         }
141
142         message = stasis_message_create(ast_system_registry_type(), payload);
143         ao2_ref(payload, -1);
144         if (!message) {
145                 return;
146         }
147
148         stasis_publish(ast_system_topic(), message);
149         ao2_ref(message, -1);
150 }
151
152 static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message)
153 {
154         struct ast_json_payload *payload = stasis_message_data(message);
155         const char *channeltype;
156         const char *username;
157         const char *domain;
158         const char *status;
159         const char *cause;
160         RAII_VAR(struct ast_str *, cause_string, ast_str_create(32), ast_free);
161
162         if (!cause_string) {
163                 return NULL;
164         }
165
166         channeltype = ast_json_string_get(ast_json_object_get(payload->json, "channeltype"));
167         username = ast_json_string_get(ast_json_object_get(payload->json, "username"));
168         domain = ast_json_string_get(ast_json_object_get(payload->json, "domain"));
169         status = ast_json_string_get(ast_json_object_get(payload->json, "status"));
170         cause = ast_json_string_get(ast_json_object_get(payload->json, "cause"));
171
172         if (!ast_strlen_zero(cause)) {
173                 ast_str_set(&cause_string, 0, "Cause: %s\r\n", cause);
174         }
175
176         return ast_manager_event_blob_create(EVENT_FLAG_SYSTEM, "Registry",
177                 "ChannelType: %s\r\n"
178                 "Username: %s\r\n"
179                 "Domain: %s\r\n"
180                 "Status: %s\r\n"
181                 "%s",
182                 channeltype, username, domain, status, ast_str_buffer(cause_string));
183 }
184
185 static struct ast_manager_event_blob *cc_available_to_ami(struct stasis_message *message)
186 {
187         struct ast_json_payload *payload = stasis_message_data(message);
188         int core_id;
189         const char *callee;
190         const char *service;
191
192         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
193         callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
194         service = ast_json_string_get(ast_json_object_get(payload->json, "service"));
195
196         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCAvailable",
197                 "CoreID: %d\r\n"
198                 "Callee: %s\r\n"
199                 "Service: %s\r\n",
200                 core_id, callee, service);
201 }
202
203 static struct ast_manager_event_blob *cc_offertimerstart_to_ami(struct stasis_message *message)
204 {
205         struct ast_json_payload *payload = stasis_message_data(message);
206         int core_id;
207         const char *caller;
208         unsigned int expires;
209
210         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
211         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
212         expires = ast_json_integer_get(ast_json_object_get(payload->json, "expires"));
213
214         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCOfferTimerStart",
215                 "CoreID: %d\r\n"
216                 "Caller: %s\r\n"
217                 "Expires: %u\r\n",
218                 core_id, caller, expires);
219 }
220
221 static struct ast_manager_event_blob *cc_requested_to_ami(struct stasis_message *message)
222 {
223         struct ast_json_payload *payload = stasis_message_data(message);
224         int core_id;
225         const char *caller;
226         const char *callee;
227
228         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
229         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
230         callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
231
232         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRequested",
233                 "CoreID: %d\r\n"
234                 "Caller: %s\r\n"
235                 "Callee: %s\r\n",
236                 core_id, caller, callee);
237 }
238
239 static struct ast_manager_event_blob *cc_requestacknowledged_to_ami(struct stasis_message *message)
240 {
241         struct ast_json_payload *payload = stasis_message_data(message);
242         int core_id;
243         const char *caller;
244
245         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
246         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
247
248         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRequestAcknowledged",
249                 "CoreID: %d\r\n"
250                 "Caller: %s\r\n",
251                 core_id, caller);
252 }
253
254 static struct ast_manager_event_blob *cc_callerstopmonitoring_to_ami(struct stasis_message *message)
255 {
256         struct ast_json_payload *payload = stasis_message_data(message);
257         int core_id;
258         const char *caller;
259
260         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
261         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
262
263         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerStopMonitoring",
264                 "CoreID: %d\r\n"
265                 "Caller: %s\r\n",
266                 core_id, caller);
267 }
268
269 static struct ast_manager_event_blob *cc_callerstartmonitoring_to_ami(struct stasis_message *message)
270 {
271         struct ast_json_payload *payload = stasis_message_data(message);
272         int core_id;
273         const char *caller;
274
275         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
276         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
277
278         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerStartMonitoring",
279                 "CoreID: %d\r\n"
280                 "Caller: %s\r\n",
281                 core_id, caller);
282 }
283
284 static struct ast_manager_event_blob *cc_callerrecalling_to_ami(struct stasis_message *message)
285 {
286         struct ast_json_payload *payload = stasis_message_data(message);
287         int core_id;
288         const char *caller;
289
290         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
291         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
292
293         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerRecalling",
294                 "CoreID: %d\r\n"
295                 "Caller: %s\r\n",
296                 core_id, caller);
297 }
298
299 static struct ast_manager_event_blob *cc_recallcomplete_to_ami(struct stasis_message *message)
300 {
301         struct ast_json_payload *payload = stasis_message_data(message);
302         int core_id;
303         const char *caller;
304
305         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
306         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
307
308         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRecallComplete",
309                 "CoreID: %d\r\n"
310                 "Caller: %s\r\n",
311                 core_id, caller);
312 }
313
314 static struct ast_manager_event_blob *cc_failure_to_ami(struct stasis_message *message)
315 {
316         struct ast_json_payload *payload = stasis_message_data(message);
317         int core_id;
318         const char *caller;
319         const char *reason;
320
321         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
322         caller = ast_json_string_get(ast_json_object_get(payload->json, "caller"));
323         reason = ast_json_string_get(ast_json_object_get(payload->json, "reason"));
324
325         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCFailure",
326                 "CoreID: %d\r\n"
327                 "Caller: %s\r\n"
328                 "Reason: %s\r\n",
329                 core_id, caller, reason);
330 }
331
332 static struct ast_manager_event_blob *cc_monitorfailed_to_ami(struct stasis_message *message)
333 {
334         struct ast_json_payload *payload = stasis_message_data(message);
335         int core_id;
336         const char *callee;
337
338         core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id"));
339         callee = ast_json_string_get(ast_json_object_get(payload->json, "callee"));
340
341         return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCMonitorFailed",
342                 "CoreID: %d\r\n"
343                 "Callee: %s\r\n",
344                 core_id, callee);
345 }
346
347 struct stasis_topic *ast_system_topic(void)
348 {
349         return system_topic;
350 }
351
352 /*! \brief Cleanup the \ref stasis system level items */
353 static void stasis_system_cleanup(void)
354 {
355         ao2_cleanup(system_topic);
356         system_topic = NULL;
357         STASIS_MESSAGE_TYPE_CLEANUP(ast_network_change_type);
358         STASIS_MESSAGE_TYPE_CLEANUP(ast_system_registry_type);
359         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_available_type);
360         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_offertimerstart_type);
361         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_requested_type);
362         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_requestacknowledged_type);
363         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerstopmonitoring_type);
364         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerstartmonitoring_type);
365         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerrecalling_type);
366         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_recallcomplete_type);
367         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_failure_type);
368         STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_monitorfailed_type);
369         STASIS_MESSAGE_TYPE_CLEANUP(ast_cluster_discovery_type);
370 }
371
372 /*! \brief Initialize the system level items for \ref stasis */
373 int ast_stasis_system_init(void)
374 {
375         ast_register_cleanup(stasis_system_cleanup);
376
377         system_topic = stasis_topic_create("ast_system");
378         if (!system_topic) {
379                 return 1;
380         }
381
382         if (STASIS_MESSAGE_TYPE_INIT(ast_network_change_type) != 0) {
383                 return -1;
384         }
385
386         if (STASIS_MESSAGE_TYPE_INIT(ast_system_registry_type) != 0) {
387                 return -1;
388         }
389
390         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_available_type) != 0) {
391                 return -1;
392         }
393
394         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_offertimerstart_type) != 0) {
395                 return -1;
396         }
397
398         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_requested_type) != 0) {
399                 return -1;
400         }
401
402         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_requestacknowledged_type) != 0) {
403                 return -1;
404         }
405
406         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerstopmonitoring_type) != 0) {
407                 return -1;
408         }
409
410         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerstartmonitoring_type) != 0) {
411                 return -1;
412         }
413
414         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerrecalling_type) != 0) {
415                 return -1;
416         }
417
418         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_recallcomplete_type) != 0) {
419                 return -1;
420         }
421
422         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_failure_type) != 0) {
423                 return -1;
424         }
425
426         if (STASIS_MESSAGE_TYPE_INIT(ast_cc_monitorfailed_type) != 0) {
427                 return -1;
428         }
429
430         if (STASIS_MESSAGE_TYPE_INIT(ast_cluster_discovery_type) != 0) {
431                 return -1;
432         }
433
434         return 0;
435 }