res_ais.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2007 - 2008, 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. * \file
  20. * \author Russell Bryant <russell@digium.com>
  21. *
  22. * \brief Usage of the SAForum AIS (Application Interface Specification)
  23. *
  24. * \arg http://www.openais.org/
  25. *
  26. * This file contains the common code between the uses of the different AIS
  27. * services.
  28. *
  29. * \note This module is still considered experimental, as it exposes the
  30. * internal binary format of events between Asterisk servers over a network.
  31. * However, this format is still subject to change between 1.6.X releases.
  32. */
  33. /*** MODULEINFO
  34. <depend>ais</depend>
  35. <support_level>extended</support_level>
  36. <defaultenabled>no</defaultenabled>
  37. ***/
  38. #include "asterisk.h"
  39. ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
  40. #include <stdlib.h>
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <unistd.h>
  44. #include <errno.h>
  45. #include <signal.h>
  46. #include <pthread.h>
  47. #include "ais/ais.h"
  48. #include "asterisk/module.h"
  49. #include "asterisk/options.h"
  50. #include "asterisk/logger.h"
  51. #include "asterisk/channel.h"
  52. #include "asterisk/utils.h"
  53. #include "asterisk/cli.h"
  54. static struct {
  55. pthread_t id;
  56. unsigned int stop:1;
  57. } dispatch_thread = {
  58. .id = AST_PTHREADT_NULL,
  59. };
  60. SaVersionT ais_version = { 'B', 1, 1 };
  61. static const struct ais_error {
  62. SaAisErrorT error;
  63. const char *desc;
  64. } ais_errors[] = {
  65. { SA_AIS_OK, "OK" },
  66. { SA_AIS_ERR_LIBRARY, "Library Error" },
  67. { SA_AIS_ERR_VERSION, "Version Not Compatible" },
  68. { SA_AIS_ERR_INIT, "Callback Not Registered" },
  69. { SA_AIS_ERR_TIMEOUT, "Timeout" },
  70. { SA_AIS_ERR_TRY_AGAIN , "Try Again" },
  71. { SA_AIS_ERR_INVALID_PARAM, "Invalid Parameter" },
  72. { SA_AIS_ERR_NO_MEMORY, "No Memory" },
  73. { SA_AIS_ERR_BAD_HANDLE, "Invalid Handle" },
  74. { SA_AIS_ERR_BUSY, "Resource Already In Use" },
  75. { SA_AIS_ERR_ACCESS, "Access Denied" },
  76. { SA_AIS_ERR_NOT_EXIST, "Does Not Exist" },
  77. { SA_AIS_ERR_NAME_TOO_LONG, "Name Too Long" },
  78. { SA_AIS_ERR_EXIST, "Already Exists" },
  79. { SA_AIS_ERR_NO_SPACE, "Buffer Too Small" },
  80. { SA_AIS_ERR_INTERRUPT, "Request Interrupted" },
  81. { SA_AIS_ERR_NAME_NOT_FOUND, "Name Not Found" },
  82. { SA_AIS_ERR_NO_RESOURCES, "Not Enough Resources" },
  83. { SA_AIS_ERR_NOT_SUPPORTED, "Requested Function Not Supported" },
  84. { SA_AIS_ERR_BAD_OPERATION, "Operation Not Allowed" },
  85. { SA_AIS_ERR_FAILED_OPERATION, "Operation Failed" },
  86. { SA_AIS_ERR_MESSAGE_ERROR, "Communication Error" },
  87. { SA_AIS_ERR_QUEUE_FULL, "Destination Queue Full" },
  88. { SA_AIS_ERR_QUEUE_NOT_AVAILABLE, "Destination Queue Not Available" },
  89. { SA_AIS_ERR_BAD_FLAGS, "Invalid Flags" },
  90. { SA_AIS_ERR_TOO_BIG, "Value Too Large" },
  91. { SA_AIS_ERR_NO_SECTIONS, "No More Sections to Initialize" },
  92. };
  93. const char *ais_err2str(SaAisErrorT error)
  94. {
  95. int x;
  96. for (x = 0; x < ARRAY_LEN(ais_errors); x++) {
  97. if (ais_errors[x].error == error)
  98. return ais_errors[x].desc;
  99. }
  100. return "Unknown";
  101. }
  102. static void *dispatch_thread_handler(void *data)
  103. {
  104. SaSelectionObjectT clm_fd, evt_fd;
  105. int res;
  106. struct pollfd pfd[2] = { { .events = POLLIN, }, { .events = POLLIN, } };
  107. SaAisErrorT ais_res;
  108. ais_res = saClmSelectionObjectGet(clm_handle, &clm_fd);
  109. if (ais_res != SA_AIS_OK) {
  110. ast_log(LOG_ERROR, "Failed to retrieve select fd for CLM service. "
  111. "This module will not operate.\n");
  112. return NULL;
  113. }
  114. ais_res = saEvtSelectionObjectGet(evt_handle, &evt_fd);
  115. if (ais_res != SA_AIS_OK) {
  116. ast_log(LOG_ERROR, "Failed to retrieve select fd for EVT service. "
  117. "This module will not operate.\n");
  118. return NULL;
  119. }
  120. pfd[0].fd = clm_fd;
  121. pfd[1].fd = evt_fd;
  122. while (!dispatch_thread.stop) {
  123. pfd[0].revents = 0;
  124. pfd[1].revents = 0;
  125. res = ast_poll(pfd, 2, -1);
  126. if (res == -1 && errno != EINTR && errno != EAGAIN) {
  127. ast_log(LOG_ERROR, "Select error (%s) dispatch thread going away now, "
  128. "and the module will no longer operate.\n", strerror(errno));
  129. break;
  130. }
  131. if (pfd[0].revents & POLLIN) {
  132. saClmDispatch(clm_handle, SA_DISPATCH_ALL);
  133. }
  134. if (pfd[1].revents & POLLIN) {
  135. saEvtDispatch(evt_handle, SA_DISPATCH_ALL);
  136. }
  137. }
  138. return NULL;
  139. }
  140. static int load_module(void)
  141. {
  142. if (ast_ais_clm_load_module())
  143. goto return_error;
  144. if (ast_ais_evt_load_module())
  145. goto evt_failed;
  146. if (ast_pthread_create_background(&dispatch_thread.id, NULL,
  147. dispatch_thread_handler, NULL)) {
  148. ast_log(LOG_ERROR, "Error starting AIS dispatch thread.\n");
  149. goto dispatch_failed;
  150. }
  151. return AST_MODULE_LOAD_SUCCESS;
  152. dispatch_failed:
  153. ast_ais_evt_unload_module();
  154. evt_failed:
  155. ast_ais_clm_unload_module();
  156. return_error:
  157. return AST_MODULE_LOAD_DECLINE;
  158. }
  159. static int unload_module(void)
  160. {
  161. ast_ais_clm_unload_module();
  162. ast_ais_evt_unload_module();
  163. if (dispatch_thread.id != AST_PTHREADT_NULL) {
  164. dispatch_thread.stop = 1;
  165. pthread_kill(dispatch_thread.id, SIGURG); /* poke! */
  166. pthread_join(dispatch_thread.id, NULL);
  167. }
  168. return 0;
  169. }
  170. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SAForum AIS");