33 #include <uuid/uuid.h>
42 #define MODULE_DESCRIPTION "AudioSocket support functions for Asterisk"
44 #define MAX_CONNECT_TIMEOUT_MSEC 2000
57 static int handle_audiosocket_connection(
const char *server,
60 struct pollfd pfds[1];
64 reslen =
sizeof(conresult);
66 pfds[0].fd = netsockfd;
67 pfds[0].events = POLLOUT;
69 while ((res = ast_poll(pfds, 1, MAX_CONNECT_TIMEOUT_MSEC)) != 1) {
72 ast_log(LOG_WARNING,
"AudioSocket connection to '%s' timed"
73 "out after MAX_CONNECT_TIMEOUT_MSEC (%d) milliseconds.\n",
74 server, MAX_CONNECT_TIMEOUT_MSEC);
76 ast_log(LOG_WARNING,
"Connect to '%s' failed: %s\n", server,
84 if (getsockopt(pfds[0].fd, SOL_SOCKET, SO_ERROR, &conresult, &reslen) < 0) {
85 ast_log(LOG_WARNING,
"Connection to %s failed with error: %s\n",
91 ast_log(LOG_WARNING,
"Connecting to '%s' failed for url '%s': %s\n",
103 int num_addrs = 0, i = 0;
106 ast_log(LOG_WARNING,
"Failed to start autoservice for channel "
107 "%s\n", ast_channel_name(chan));
111 if (ast_strlen_zero(server)) {
112 ast_log(LOG_ERROR,
"No AudioSocket server provided\n");
118 ast_log(LOG_ERROR,
"Failed to resolve AudioSocket service using %s - "
119 "requires a valid hostname and port\n", server);
124 for (i = 0; i < num_addrs; i++) {
130 ast_log(LOG_ERROR,
"No port provided for %s\n",
138 ast_log(LOG_WARNING,
"Unable to create socket: %s\n", strerror(errno));
142 if (
ast_connect(s, &addrs[i]) && errno == EINPROGRESS) {
144 if (handle_audiosocket_connection(server, addrs[i], s)) {
150 ast_log(LOG_ERROR,
"Connection to %s failed with unexpected error: %s\n",
165 ast_log(LOG_WARNING,
"Failed to stop autoservice for channel %s\n",
166 ast_channel_name(chan));
171 if (i == num_addrs) {
172 ast_log(LOG_ERROR,
"Failed to connect to AudioSocket service\n");
186 if (ast_strlen_zero(
id)) {
187 ast_log(LOG_ERROR,
"No UUID for AudioSocket\n");
191 if (uuid_parse(
id, uu)) {
192 ast_log(LOG_ERROR,
"Failed to parse UUID '%s'\n",
id);
199 memcpy(buf + 3, uu, 16);
201 if (write(svc, buf, 3 + 16) != 3 + 16) {
202 ast_log(LOG_WARNING,
"Failed to write data to AudioSocket\n");
224 ast_log(LOG_WARNING,
"Failed to write data to AudioSocket\n");
234 int i = 0, n = 0, ret = 0, not_audio = 0;
238 .src =
"AudioSocket",
247 n = read(svc, &kind, 1);
248 if (n < 0 && errno == EAGAIN) {
255 ast_log(LOG_WARNING,
"Failed to read type header from AudioSocket\n");
264 ast_log(LOG_WARNING,
"Received non-audio AudioSocket message\n");
268 n = read(svc, &len_high, 1);
270 ast_log(LOG_WARNING,
"Failed to read data length from AudioSocket\n");
273 len += len_high * 256;
274 n = read(svc, &len_low, 1);
276 ast_log(LOG_WARNING,
"Failed to read data length from AudioSocket\n");
287 ast_log(LOG_ERROR,
"Failed to allocate for data from AudioSocket\n");
295 n = read(svc, data + i, len - i);
297 ast_log(LOG_ERROR,
"Failed to read data from AudioSocket\n");
302 ast_log(LOG_ERROR,
"Insufficient data read from AudioSocket\n");
327 static int load_module(
void)
329 ast_verb(5,
"Loading AudioSocket Support module\n");
333 static int unload_module(
void)
335 ast_verb(5,
"Unloading AudioSocket Support module\n");
339 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER,
"AudioSocket support",
340 .support_level = AST_MODULE_SUPPORT_EXTENDED,
342 .unload = unload_module,
const int ast_audiosocket_init(const int svc, const char *id)
Send the initial message to an AudioSocket server.
struct ast_frame * ast_audiosocket_receive_frame(const int svc)
Receive an Asterisk frame from an AudioSocket server.
Main Channel structure associated with a channel.
const int ast_audiosocket_send_frame(const int svc, const struct ast_frame *f)
Send an Asterisk audio frame to an AudioSocket server.
Asterisk main include file. File version handling, generic pbx functions.
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
#define ast_socket_nonblock(domain, type, protocol)
Create a non-blocking socket.
Universally unique identifier support.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
Socket address structure.
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
General Asterisk PBX channel definitions.
AudioSocket support functions.
#define ast_malloc(len)
A wrapper for malloc()
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
union ast_frame::@224 data
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
struct ast_frame ast_null_frame
Data structure associated with a single frame of data.
enum ast_frame_type frametype
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
const int ast_audiosocket_connect(const char *server, struct ast_channel *chan)
Send the initial message to an AudioSocket server.
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.