stasis_system.c 14 KB

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