Merged revisions 134814 via svnmerge from
[asterisk-bristuff.git] / res / res_ais.c
blob865f42458c05f16f0123cef1b0ff967347c950c1
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2007 - 2008, Digium, Inc.
6 * Russell Bryant <russell@digium.com>
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.
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.
19 /*!
20 * \file
21 * \author Russell Bryant <russell@digium.com>
23 * \brief Usage of the SAForum AIS (Application Interface Specification)
25 * \arg http://www.openais.org/
27 * This file contains the common code between the uses of the different AIS
28 * services.
31 /*** MODULEINFO
32 <depend>ais</depend>
33 ***/
35 #include "asterisk.h"
37 ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <errno.h>
44 #include <signal.h>
45 #include <pthread.h>
47 #include "ais/ais.h"
49 #include "asterisk/module.h"
50 #include "asterisk/options.h"
51 #include "asterisk/logger.h"
52 #include "asterisk/channel.h"
53 #include "asterisk/utils.h"
54 #include "asterisk/cli.h"
56 static struct {
57 pthread_t id;
58 unsigned int stop:1;
59 } dispatch_thread = {
60 .id = AST_PTHREADT_NULL,
63 SaVersionT ais_version = { 'B', 1, 1 };
65 static const struct ais_error {
66 SaAisErrorT error;
67 const char *desc;
68 } ais_errors[] = {
69 { SA_AIS_OK, "OK" },
70 { SA_AIS_ERR_LIBRARY, "Library Error" },
71 { SA_AIS_ERR_VERSION, "Version Not Compatible" },
72 { SA_AIS_ERR_INIT, "Callback Not Registered" },
73 { SA_AIS_ERR_TIMEOUT, "Timeout" },
74 { SA_AIS_ERR_TRY_AGAIN , "Try Again" },
75 { SA_AIS_ERR_INVALID_PARAM, "Invalid Parameter" },
76 { SA_AIS_ERR_NO_MEMORY, "No Memory" },
77 { SA_AIS_ERR_BAD_HANDLE, "Invalid Handle" },
78 { SA_AIS_ERR_BUSY, "Resource Already In Use" },
79 { SA_AIS_ERR_ACCESS, "Access Denied" },
80 { SA_AIS_ERR_NOT_EXIST, "Does Not Exist" },
81 { SA_AIS_ERR_NAME_TOO_LONG, "Name Too Long" },
82 { SA_AIS_ERR_EXIST, "Already Exists" },
83 { SA_AIS_ERR_NO_SPACE, "Buffer Too Small" },
84 { SA_AIS_ERR_INTERRUPT, "Request Interrupted" },
85 { SA_AIS_ERR_NAME_NOT_FOUND, "Name Not Found" },
86 { SA_AIS_ERR_NO_RESOURCES, "Not Enough Resources" },
87 { SA_AIS_ERR_NOT_SUPPORTED, "Requested Function Not Supported" },
88 { SA_AIS_ERR_BAD_OPERATION, "Operation Not Allowed" },
89 { SA_AIS_ERR_FAILED_OPERATION, "Operation Failed" },
90 { SA_AIS_ERR_MESSAGE_ERROR, "Communication Error" },
91 { SA_AIS_ERR_QUEUE_FULL, "Destination Queue Full" },
92 { SA_AIS_ERR_QUEUE_NOT_AVAILABLE, "Destination Queue Not Available" },
93 { SA_AIS_ERR_BAD_FLAGS, "Invalid Flags" },
94 { SA_AIS_ERR_TOO_BIG, "Value Too Large" },
95 { SA_AIS_ERR_NO_SECTIONS, "No More Sections to Initialize" },
98 const char *ais_err2str(SaAisErrorT error)
100 int x;
102 for (x = 0; x < ARRAY_LEN(ais_errors); x++) {
103 if (ais_errors[x].error == error)
104 return ais_errors[x].desc;
107 return "Unknown";
110 static void *dispatch_thread_handler(void *data)
112 SaSelectionObjectT clm_fd, evt_fd, max_fd;
113 int res;
114 fd_set read_fds;
115 SaAisErrorT ais_res;
117 ais_res = saClmSelectionObjectGet(clm_handle, &clm_fd);
118 if (ais_res != SA_AIS_OK) {
119 ast_log(LOG_ERROR, "Failed to retrieve select fd for CLM service. "
120 "This module will not operate.\n");
121 return NULL;
124 ais_res = saEvtSelectionObjectGet(evt_handle, &evt_fd);
125 if (ais_res != SA_AIS_OK) {
126 ast_log(LOG_ERROR, "Failed to retrieve select fd for EVT service. "
127 "This module will not operate.\n");
128 return NULL;
131 max_fd = clm_fd > evt_fd ? clm_fd : evt_fd;
133 while (!dispatch_thread.stop) {
134 FD_ZERO(&read_fds);
135 FD_SET(clm_fd, &read_fds);
136 FD_SET(evt_fd, &read_fds);
138 res = ast_select(max_fd + 1, &read_fds, NULL, NULL, NULL);
139 if (res == -1 && errno != EINTR && errno != EAGAIN) {
140 ast_log(LOG_ERROR, "Select error (%s) dispatch thread going away now, "
141 "and the module will no longer operate.\n", strerror(errno));
142 break;
145 if (FD_ISSET(clm_fd, &read_fds))
146 saClmDispatch(clm_handle, SA_DISPATCH_ALL);
147 if (FD_ISSET(evt_fd, &read_fds))
148 saEvtDispatch(evt_handle, SA_DISPATCH_ALL);
151 return NULL;
154 static int load_module(void)
156 if (ast_ais_clm_load_module())
157 goto return_error;
159 if (ast_ais_evt_load_module())
160 goto evt_failed;
162 if (ast_pthread_create_background(&dispatch_thread.id, NULL,
163 dispatch_thread_handler, NULL)) {
164 ast_log(LOG_ERROR, "Error starting AIS dispatch thread.\n");
165 goto dispatch_failed;
168 return AST_MODULE_LOAD_SUCCESS;
170 dispatch_failed:
171 ast_ais_evt_unload_module();
172 evt_failed:
173 ast_ais_clm_unload_module();
174 return_error:
175 return AST_MODULE_LOAD_DECLINE;
178 static int unload_module(void)
180 ast_ais_clm_unload_module();
181 ast_ais_evt_unload_module();
183 if (dispatch_thread.id != AST_PTHREADT_NULL) {
184 dispatch_thread.stop = 1;
185 pthread_kill(dispatch_thread.id, SIGURG); /* poke! */
186 pthread_join(dispatch_thread.id, NULL);
189 return 0;
192 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SAForum AIS");