2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@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.
21 * \brief Stream to an icecast server via ICES (see contrib/asterisk-ices.xml)
23 * \author Mark Spencer <markster@digium.com>
25 * \ingroup applications
30 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
41 #include "asterisk/lock.h"
42 #include "asterisk/file.h"
43 #include "asterisk/logger.h"
44 #include "asterisk/channel.h"
45 #include "asterisk/frame.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/module.h"
48 #include "asterisk/translate.h"
49 #include "asterisk/options.h"
51 #define ICES "/usr/bin/ices"
52 #define LOCAL_ICES "/usr/local/bin/ices"
54 static char *app
= "ICES";
56 static char *synopsis
= "Encode and stream using 'ices'";
58 static char *descrip
=
59 " ICES(config.xml) Streams to an icecast server using ices\n"
60 "(available separately). A configuration file must be supplied\n"
61 "for ices (see examples/asterisk-ices.conf). \n";
64 static int icesencode(char *filename
, int fd
)
68 sigset_t fullset
, oldset
;
71 pthread_sigmask(SIG_BLOCK
, &fullset
, &oldset
);
75 ast_log(LOG_WARNING
, "Fork failed\n");
77 pthread_sigmask(SIG_SETMASK
, &oldset
, NULL
);
81 /* Stop ignoring PIPE */
82 signal(SIGPIPE
, SIG_DFL
);
83 pthread_sigmask(SIG_UNBLOCK
, &fullset
, NULL
);
85 if (ast_opt_high_priority
)
87 dup2(fd
, STDIN_FILENO
);
88 for (x
=STDERR_FILENO
+ 1;x
<1024;x
++) {
89 if ((x
!= STDIN_FILENO
) && (x
!= STDOUT_FILENO
))
92 /* Most commonly installed in /usr/local/bin */
93 execl(ICES
, "ices", filename
, (char *)NULL
);
94 /* But many places has it in /usr/bin */
95 execl(LOCAL_ICES
, "ices", filename
, (char *)NULL
);
96 /* As a last-ditch effort, try to use PATH */
97 execlp("ices", "ices", filename
, (char *)NULL
);
98 ast_log(LOG_WARNING
, "Execute of ices failed\n");
102 static int ices_exec(struct ast_channel
*chan
, void *data
)
105 struct ast_module_user
*u
;
113 char filename
[256]="";
116 if (ast_strlen_zero(data
)) {
117 ast_log(LOG_WARNING
, "ICES requires an argument (configfile.xml)\n");
121 u
= ast_module_user_add(chan
);
126 ast_log(LOG_WARNING
, "Unable to create pipe\n");
127 ast_module_user_remove(u
);
130 flags
= fcntl(fds
[1], F_GETFL
);
131 fcntl(fds
[1], F_SETFL
, flags
| O_NONBLOCK
);
133 ast_stopstream(chan
);
135 if (chan
->_state
!= AST_STATE_UP
)
136 res
= ast_answer(chan
);
141 ast_log(LOG_WARNING
, "Answer failed!\n");
142 ast_module_user_remove(u
);
146 oreadformat
= chan
->readformat
;
147 res
= ast_set_read_format(chan
, AST_FORMAT_SLINEAR
);
151 ast_log(LOG_WARNING
, "Unable to set write format to signed linear\n");
152 ast_module_user_remove(u
);
155 if (((char *)data
)[0] == '/')
156 ast_copy_string(filename
, (char *) data
, sizeof(filename
));
158 snprintf(filename
, sizeof(filename
), "%s/%s", (char *)ast_config_AST_CONFIG_DIR
, (char *)data
);
159 /* Placeholder for options */
160 c
= strchr(filename
, '|');
163 res
= icesencode(filename
, fds
[0]);
168 /* Wait for audio, and stream */
169 ms
= ast_waitfor(chan
, -1);
171 ast_log(LOG_DEBUG
, "Hangup detected\n");
177 ast_log(LOG_DEBUG
, "Null frame == hangup() detected\n");
181 if (f
->frametype
== AST_FRAME_VOICE
) {
182 res
= write(fds
[1], f
->data
, f
->datalen
);
184 if (errno
!= EAGAIN
) {
185 ast_log(LOG_WARNING
, "Write failed to pipe: %s\n", strerror(errno
));
199 if (!res
&& oreadformat
)
200 ast_set_read_format(chan
, oreadformat
);
202 ast_module_user_remove(u
);
207 static int unload_module(void)
211 res
= ast_unregister_application(app
);
213 ast_module_user_hangup_all();
218 static int load_module(void)
220 return ast_register_application(app
, ices_exec
, synopsis
, descrip
);
223 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Encode and Stream via icecast and ices");