00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "asterisk.h"
00040
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 179166 $");
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <string.h>
00046 #include <unistd.h>
00047 #include <errno.h>
00048 #include <signal.h>
00049 #include <pthread.h>
00050
00051 #include "ais/ais.h"
00052
00053 #include "asterisk/module.h"
00054 #include "asterisk/options.h"
00055 #include "asterisk/logger.h"
00056 #include "asterisk/channel.h"
00057 #include "asterisk/utils.h"
00058 #include "asterisk/cli.h"
00059
00060 static struct {
00061 pthread_t id;
00062 unsigned int stop:1;
00063 } dispatch_thread = {
00064 .id = AST_PTHREADT_NULL,
00065 };
00066
00067 SaVersionT ais_version = { 'B', 1, 1 };
00068
00069 static const struct ais_error {
00070 SaAisErrorT error;
00071 const char *desc;
00072 } ais_errors[] = {
00073 { SA_AIS_OK, "OK" },
00074 { SA_AIS_ERR_LIBRARY, "Library Error" },
00075 { SA_AIS_ERR_VERSION, "Version Not Compatible" },
00076 { SA_AIS_ERR_INIT, "Callback Not Registered" },
00077 { SA_AIS_ERR_TIMEOUT, "Timeout" },
00078 { SA_AIS_ERR_TRY_AGAIN , "Try Again" },
00079 { SA_AIS_ERR_INVALID_PARAM, "Invalid Parameter" },
00080 { SA_AIS_ERR_NO_MEMORY, "No Memory" },
00081 { SA_AIS_ERR_BAD_HANDLE, "Invalid Handle" },
00082 { SA_AIS_ERR_BUSY, "Resource Already In Use" },
00083 { SA_AIS_ERR_ACCESS, "Access Denied" },
00084 { SA_AIS_ERR_NOT_EXIST, "Does Not Exist" },
00085 { SA_AIS_ERR_NAME_TOO_LONG, "Name Too Long" },
00086 { SA_AIS_ERR_EXIST, "Already Exists" },
00087 { SA_AIS_ERR_NO_SPACE, "Buffer Too Small" },
00088 { SA_AIS_ERR_INTERRUPT, "Request Interrupted" },
00089 { SA_AIS_ERR_NAME_NOT_FOUND, "Name Not Found" },
00090 { SA_AIS_ERR_NO_RESOURCES, "Not Enough Resources" },
00091 { SA_AIS_ERR_NOT_SUPPORTED, "Requested Function Not Supported" },
00092 { SA_AIS_ERR_BAD_OPERATION, "Operation Not Allowed" },
00093 { SA_AIS_ERR_FAILED_OPERATION, "Operation Failed" },
00094 { SA_AIS_ERR_MESSAGE_ERROR, "Communication Error" },
00095 { SA_AIS_ERR_QUEUE_FULL, "Destination Queue Full" },
00096 { SA_AIS_ERR_QUEUE_NOT_AVAILABLE, "Destination Queue Not Available" },
00097 { SA_AIS_ERR_BAD_FLAGS, "Invalid Flags" },
00098 { SA_AIS_ERR_TOO_BIG, "Value Too Large" },
00099 { SA_AIS_ERR_NO_SECTIONS, "No More Sections to Initialize" },
00100 };
00101
00102 const char *ais_err2str(SaAisErrorT error)
00103 {
00104 int x;
00105
00106 for (x = 0; x < ARRAY_LEN(ais_errors); x++) {
00107 if (ais_errors[x].error == error)
00108 return ais_errors[x].desc;
00109 }
00110
00111 return "Unknown";
00112 }
00113
00114 static void *dispatch_thread_handler(void *data)
00115 {
00116 SaSelectionObjectT clm_fd, evt_fd, max_fd;
00117 int res;
00118 fd_set read_fds;
00119 SaAisErrorT ais_res;
00120
00121 ais_res = saClmSelectionObjectGet(clm_handle, &clm_fd);
00122 if (ais_res != SA_AIS_OK) {
00123 ast_log(LOG_ERROR, "Failed to retrieve select fd for CLM service. "
00124 "This module will not operate.\n");
00125 return NULL;
00126 }
00127
00128 ais_res = saEvtSelectionObjectGet(evt_handle, &evt_fd);
00129 if (ais_res != SA_AIS_OK) {
00130 ast_log(LOG_ERROR, "Failed to retrieve select fd for EVT service. "
00131 "This module will not operate.\n");
00132 return NULL;
00133 }
00134
00135 max_fd = clm_fd > evt_fd ? clm_fd : evt_fd;
00136
00137 while (!dispatch_thread.stop) {
00138 FD_ZERO(&read_fds);
00139 FD_SET(clm_fd, &read_fds);
00140 FD_SET(evt_fd, &read_fds);
00141
00142 res = ast_select(max_fd + 1, &read_fds, NULL, NULL, NULL);
00143 if (res == -1 && errno != EINTR && errno != EAGAIN) {
00144 ast_log(LOG_ERROR, "Select error (%s) dispatch thread going away now, "
00145 "and the module will no longer operate.\n", strerror(errno));
00146 break;
00147 }
00148
00149 if (FD_ISSET(clm_fd, &read_fds))
00150 saClmDispatch(clm_handle, SA_DISPATCH_ALL);
00151 if (FD_ISSET(evt_fd, &read_fds))
00152 saEvtDispatch(evt_handle, SA_DISPATCH_ALL);
00153 }
00154
00155 return NULL;
00156 }
00157
00158 static int load_module(void)
00159 {
00160 if (ast_ais_clm_load_module())
00161 goto return_error;
00162
00163 if (ast_ais_evt_load_module())
00164 goto evt_failed;
00165
00166 if (ast_pthread_create_background(&dispatch_thread.id, NULL,
00167 dispatch_thread_handler, NULL)) {
00168 ast_log(LOG_ERROR, "Error starting AIS dispatch thread.\n");
00169 goto dispatch_failed;
00170 }
00171
00172 return AST_MODULE_LOAD_SUCCESS;
00173
00174 dispatch_failed:
00175 ast_ais_evt_unload_module();
00176 evt_failed:
00177 ast_ais_clm_unload_module();
00178 return_error:
00179 return AST_MODULE_LOAD_DECLINE;
00180 }
00181
00182 static int unload_module(void)
00183 {
00184 ast_ais_clm_unload_module();
00185 ast_ais_evt_unload_module();
00186
00187 if (dispatch_thread.id != AST_PTHREADT_NULL) {
00188 dispatch_thread.stop = 1;
00189 pthread_kill(dispatch_thread.id, SIGURG);
00190 pthread_join(dispatch_thread.id, NULL);
00191 }
00192
00193 return 0;
00194 }
00195
00196 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SAForum AIS");